* 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:
tom_at_work 2010-10-31 14:47:42 +00:00
parent 0cb36ee173
commit e215b215d6

View File

@ -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