mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-04-15 16:19:28 +02:00
* fix methodpointers in registers on big endian targets
git-svn-id: trunk@22362 -
This commit is contained in:
parent
a74b6e8573
commit
67744ef46e
@ -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,
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user