mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-08-18 05:49:23 +02:00
* fixed procvar parameter passing on ppc/sysv (by value instead of by
reference -- except for method procvars, for tmethod record compatibility) * adapted tw11563 for corrected calling convention git-svn-id: trunk@12475 -
This commit is contained in:
parent
5ef8122b16
commit
bb9e962490
@ -130,7 +130,12 @@ unit cpupara;
|
|||||||
result:=LOC_REGISTER;
|
result:=LOC_REGISTER;
|
||||||
classrefdef:
|
classrefdef:
|
||||||
result:=LOC_REGISTER;
|
result:=LOC_REGISTER;
|
||||||
procvardef,
|
procvardef:
|
||||||
|
if (target_info.abi = abi_powerpc_aix) or
|
||||||
|
(p.size = sizeof(pint)) then
|
||||||
|
result:=LOC_REGISTER
|
||||||
|
else
|
||||||
|
result:=LOC_REFERENCE;
|
||||||
recorddef:
|
recorddef:
|
||||||
if (target_info.abi<>abi_powerpc_aix) or
|
if (target_info.abi<>abi_powerpc_aix) or
|
||||||
((p.size >= 3) and
|
((p.size >= 3) and
|
||||||
@ -181,8 +186,24 @@ unit cpupara;
|
|||||||
variantdef,
|
variantdef,
|
||||||
formaldef :
|
formaldef :
|
||||||
result:=true;
|
result:=true;
|
||||||
recorddef,
|
{ regular procvars must be passed by value, because you cannot pass
|
||||||
|
the address of a local stack location when calling e.g.
|
||||||
|
pthread_create with the address of a function (first of all it
|
||||||
|
expects the address of the function to execute and not the address
|
||||||
|
of a memory location containing that address, and secondly if you
|
||||||
|
first store the address on the stack and then pass the address of
|
||||||
|
this stack location, then this stack location may no longer be
|
||||||
|
valid when the newly started thread accesses it.
|
||||||
|
|
||||||
|
However, for "procedure of object" we must use the same calling
|
||||||
|
convention as for "8 byte record" due to the need for
|
||||||
|
interchangeability with the TMethod record type.
|
||||||
|
}
|
||||||
procvardef :
|
procvardef :
|
||||||
|
result:=
|
||||||
|
(target_info.abi <> abi_powerpc_aix) and
|
||||||
|
(def.size <> sizeof(pint));
|
||||||
|
recorddef :
|
||||||
result :=
|
result :=
|
||||||
(target_info.abi<>abi_powerpc_aix) or
|
(target_info.abi<>abi_powerpc_aix) or
|
||||||
((varspez = vs_const) and
|
((varspez = vs_const) and
|
||||||
|
@ -19,15 +19,20 @@ program ExecStack;
|
|||||||
|
|
||||||
begin
|
begin
|
||||||
{$if defined(cpupowerpc) or defined(cpupowerpc64)}
|
{$if defined(cpupowerpc) or defined(cpupowerpc64)}
|
||||||
|
ret := ($4e shl 24) or ($80 shl 16) or ($00 shl 8) or $20;
|
||||||
|
{$if defined(cpupowerpc64)}
|
||||||
{ can't use proc(@ret) because linux/ppc64 always expects some kind of
|
{ can't use proc(@ret) because linux/ppc64 always expects some kind of
|
||||||
trampoline
|
trampoline
|
||||||
}
|
}
|
||||||
ret := ($4e shl 24) or ($80 shl 16) or ($00 shl 8) or $20;
|
|
||||||
asm
|
asm
|
||||||
la r0, ret
|
la r0, ret
|
||||||
mtctr r0
|
mtctr r0
|
||||||
bctrl
|
bctrl
|
||||||
end;
|
end;
|
||||||
|
{$else}
|
||||||
|
DoNothing := proc(@ret);
|
||||||
|
DoNothing;
|
||||||
|
{$endif}
|
||||||
{$endif}
|
{$endif}
|
||||||
{$if defined(cpui386) or defined(cpux86_64)}
|
{$if defined(cpui386) or defined(cpux86_64)}
|
||||||
ret := $C3;
|
ret := $C3;
|
||||||
|
Loading…
Reference in New Issue
Block a user