mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-04-19 20:39:25 +02:00
* fix code generation for interface wrappers: adjustment of self pointers with offsets > 16 bit crashed because it tried to allocate a virtual register, but the register allocator is not called for these wrappers. Always use the R11 register, which is scratch on ppc64, for now.
git-svn-id: trunk@16272 -
This commit is contained in:
parent
0cb36ee173
commit
e215b215d6
@ -85,6 +85,15 @@ type
|
||||
procedure g_flags2reg(list: TAsmList; size: TCgSize; const f: TResFlags;
|
||||
reg: TRegister); override;
|
||||
|
||||
{ need to override this for ppc64 to avoid calling CG methods which allocate
|
||||
registers during creation of the interface wrappers to subtract ioffset from
|
||||
the self pointer. But register allocation does not take place for them (which
|
||||
would probably be the generic fix) so we need to have a specialized method
|
||||
that uses the R11 scratch register in these cases.
|
||||
At the same time this allows > 32 bit offsets as well.
|
||||
}
|
||||
procedure g_adjust_self_value(list:TAsmList;procdef: tprocdef;ioffset: aint);override;
|
||||
|
||||
procedure g_profilecode(list: TAsmList); override;
|
||||
procedure g_proc_entry(list: TAsmList; localsize: longint; nostackframe:
|
||||
boolean); override;
|
||||
@ -1379,6 +1388,36 @@ begin
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure tcgppc.g_adjust_self_value(list:TAsmList;procdef: tprocdef;ioffset: aint);
|
||||
var
|
||||
hsym : tsym;
|
||||
href : treference;
|
||||
paraloc : Pcgparalocation;
|
||||
begin
|
||||
if ((ioffset >= low(smallint)) and (ioffset < high(smallint)) then begin
|
||||
{ the original method can handle this }
|
||||
inherited g_adjust_self_value(list, procdef, ioffset);
|
||||
exit;
|
||||
end;
|
||||
{ calculate the parameter info for the procdef }
|
||||
procdef.init_paraloc_info(callerside);
|
||||
hsym:=tsym(procdef.parast.Find('self'));
|
||||
if not(assigned(hsym) and
|
||||
(hsym.typ=paravarsym)) then
|
||||
internalerror(2010103101);
|
||||
paraloc:=tparavarsym(hsym).paraloc[callerside].location;
|
||||
while paraloc<>nil do
|
||||
with paraloc^ do begin
|
||||
case loc of
|
||||
LOC_REGISTER:
|
||||
a_load_const_reg(list, size, ioffset, NR_R11);
|
||||
a_op_reg_reg(list, OP_SUB, size, NR_R11, register);
|
||||
else
|
||||
internalerror(2010103102);
|
||||
end;
|
||||
paraloc:=next;
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure tcgppc.g_profilecode(list: TAsmList);
|
||||
begin
|
||||
|
Loading…
Reference in New Issue
Block a user