* fix methodpointers in registers on big endian targets

git-svn-id: trunk@22362 -
This commit is contained in:
florian 2012-09-09 17:54:35 +00:00
parent a74b6e8573
commit 67744ef46e
5 changed files with 43 additions and 5 deletions

View File

@ -283,6 +283,18 @@ interface
tvarregable2tcgloc : array[tvarregable] of tcgloc = (LOC_VOID,
LOC_CREGISTER,LOC_CFPUREGISTER,LOC_CMMREGISTER,LOC_CREGISTER);
{$ifdef cpu64bitalu}
{ operand size describing an unsigned value in a pair of int registers }
OS_PAIR = OS_128;
{ operand size describing an signed value in a pair of int registers }
OS_SPAIR = OS_S128;
{$else cpu64bitalu}
{ operand size describing an unsigned value in a pair of int registers }
OS_PAIR = OS_64;
{ operand size describing an signed value in a pair of int registers }
OS_SPAIR = OS_S64;
{$endif cpu64bitalu}
{ Table to convert tcgsize variables to the correspondending
unsigned types }
tcgsize2unsigned : array[tcgsize] of tcgsize = (OS_NO,

View File

@ -468,6 +468,7 @@ unit cgobj;
procedure a_load128_ref_reg(list : TAsmList;const ref : treference;reg : tregister128);virtual;
procedure a_load128_loc_ref(list : TAsmList;const l : tlocation;const ref : treference);virtual;
procedure a_load128_reg_loc(list : TAsmList;reg : tregister128;const l : tlocation);virtual;
procedure a_load128_const_reg(list : TAsmList;valuelo,valuehi : int64;reg : tregister128);virtual;
procedure a_load128_loc_cgpara(list : TAsmList;const l : tlocation;const paraloc : TCGPara);virtual;
procedure a_load128_ref_cgpara(list: TAsmList; const r: treference;const paraloc: tcgpara);
@ -2608,8 +2609,6 @@ implementation
end;
procedure tcg128.a_load128_reg_reg(list: TAsmList; regsrc,
regdst: tregister128);
begin
@ -2707,6 +2706,13 @@ implementation
end;
end;
procedure tcg128.a_load128_const_reg(list: TAsmList; valuelo,
valuehi: int64; reg: tregister128);
begin
cg.a_load_const_reg(list,OS_32,aint(valuelo),reg.reglo);
cg.a_load_const_reg(list,OS_32,aint(valuehi),reg.reghi);
end;
procedure tcg128.a_load128_loc_cgpara(list: TAsmList; const l: tlocation;
const paraloc: TCGPara);

View File

@ -3882,11 +3882,15 @@ implementation
case tstaticvarsym(p).initialloc.loc of
LOC_CREGISTER :
begin
{$ifndef cpu64bitalu}
{$ifdef cpu64bitalu}
if (tstaticvarsym(p).initialloc.size in [OS_128,OS_S128]) then
cg128.a_load128_const_reg(TAsmList(arg),0,0,tstaticvarsym(p).initialloc.register128)
else
{$else cpu64bitalu}
if (tstaticvarsym(p).initialloc.size in [OS_64,OS_S64]) then
cg64.a_load64_const_reg(TAsmList(arg),0,tstaticvarsym(p).initialloc.register64)
else
{$endif not cpu64bitalu}
{$endif cpu64bitalu}
a_load_const_reg(TAsmList(arg),tstaticvarsym(p).vardef,0,
tstaticvarsym(p).initialloc.register);
end;

View File

@ -890,7 +890,14 @@ implementation
if right.location.loc in [LOC_REFERENCE,LOC_CREFERENCE] then
cg.a_load_ref_reg(current_asmdata.CurrAsmList,OS_ADDR,OS_ADDR,right.location.reference,pvreg)
else if right.location.loc in [LOC_REGISTER,LOC_CREGISTER] then
hlcg.a_load_reg_reg(current_asmdata.CurrAsmList,voidpointertype,voidpointertype,right.location.register,pvreg)
begin
{ in case left is a method pointer and we are on a big endian target, then
the method address is stored in registerhi }
if (target_info.endian=endian_big) and (right.location.size in [OS_PAIR,OS_SPAIR]) then
hlcg.a_load_reg_reg(current_asmdata.CurrAsmList,voidpointertype,voidpointertype,right.location.registerhi,pvreg)
else
hlcg.a_load_reg_reg(current_asmdata.CurrAsmList,voidpointertype,voidpointertype,right.location.register,pvreg);
end
else
hlcg.a_load_loc_reg(current_asmdata.CurrAsmList,voidpointertype,voidpointertype,right.location,pvreg);
location_freetemp(current_asmdata.CurrAsmList,right.location);

View File

@ -531,6 +531,15 @@ implementation
location.register:=cg.getaddressregister(current_asmdata.CurrAsmList);
cg.a_loadaddr_ref_reg(current_asmdata.CurrAsmList,href,location.register);
end;
{ to get methodpointers stored correctly, code and self register must be swapped on
big endian targets }
if target_info.endian=endian_big then
begin
hregister:=location.register;
location.register:=location.registerhi;
location.registerhi:=hregister;
end;
end
else
begin