mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-08-14 14:09:20 +02:00
* fix register method pointer for ppc64 and x86_64-linux
git-svn-id: trunk@22351 -
This commit is contained in:
parent
95c69f1f9e
commit
d93cee995b
@ -465,6 +465,7 @@ unit cgobj;
|
|||||||
tcg128 = class
|
tcg128 = class
|
||||||
procedure a_load128_reg_reg(list : TAsmList;regsrc,regdst : tregister128);virtual;
|
procedure a_load128_reg_reg(list : TAsmList;regsrc,regdst : tregister128);virtual;
|
||||||
procedure a_load128_reg_ref(list : TAsmList;reg : tregister128;const ref : treference);virtual;
|
procedure a_load128_reg_ref(list : TAsmList;reg : tregister128;const ref : treference);virtual;
|
||||||
|
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_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_reg_loc(list : TAsmList;reg : tregister128;const l : tlocation);virtual;
|
||||||
|
|
||||||
@ -2636,6 +2637,41 @@ implementation
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
procedure tcg128.a_load128_ref_reg(list: TAsmList; const ref: treference;
|
||||||
|
reg: tregister128);
|
||||||
|
var
|
||||||
|
tmpreg: tregister;
|
||||||
|
tmpref: treference;
|
||||||
|
begin
|
||||||
|
if target_info.endian = endian_big then
|
||||||
|
begin
|
||||||
|
tmpreg := reg.reglo;
|
||||||
|
reg.reglo := reg.reghi;
|
||||||
|
reg.reghi := tmpreg;
|
||||||
|
end;
|
||||||
|
tmpref := ref;
|
||||||
|
if (tmpref.base=reg.reglo) then
|
||||||
|
begin
|
||||||
|
tmpreg:=cg.getaddressregister(list);
|
||||||
|
cg.a_load_reg_reg(list,OS_ADDR,OS_ADDR,tmpref.base,tmpreg);
|
||||||
|
tmpref.base:=tmpreg;
|
||||||
|
end
|
||||||
|
else
|
||||||
|
{ this works only for the i386, thus the i386 needs to override }
|
||||||
|
{ this method and this method must be replaced by a more generic }
|
||||||
|
{ implementation FK }
|
||||||
|
if (tmpref.index=reg.reglo) then
|
||||||
|
begin
|
||||||
|
tmpreg:=cg.getaddressregister(list);
|
||||||
|
cg.a_load_reg_reg(list,OS_ADDR,OS_ADDR,tmpref.index,tmpreg);
|
||||||
|
tmpref.index:=tmpreg;
|
||||||
|
end;
|
||||||
|
cg.a_load_ref_reg(list,OS_64,OS_64,tmpref,reg.reglo);
|
||||||
|
inc(tmpref.offset,8);
|
||||||
|
cg.a_load_ref_reg(list,OS_64,OS_64,tmpref,reg.reghi);
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
procedure tcg128.a_load128_loc_ref(list: TAsmList; const l: tlocation;
|
procedure tcg128.a_load128_loc_ref(list: TAsmList; const l: tlocation;
|
||||||
const ref: treference);
|
const ref: treference);
|
||||||
begin
|
begin
|
||||||
|
@ -1359,7 +1359,7 @@ implementation
|
|||||||
begin
|
begin
|
||||||
{$ifdef cpu64bitalu}
|
{$ifdef cpu64bitalu}
|
||||||
{ use cg128 only if no "chained" location is used }
|
{ use cg128 only if no "chained" location is used }
|
||||||
if (l.size in [OS_128,OS_S128]) and (cgpara.Size in [OS_128,OS_S128]) then
|
if is_methodpointer(cgpara.def) and (l.size in [OS_128,OS_S128]) and (cgpara.Size in [OS_128,OS_S128]) then
|
||||||
cg128.a_load128_loc_cgpara(list,l,cgpara)
|
cg128.a_load128_loc_cgpara(list,l,cgpara)
|
||||||
else
|
else
|
||||||
{$else cpu64bitalu}
|
{$else cpu64bitalu}
|
||||||
|
@ -716,11 +716,15 @@ implementation
|
|||||||
LOC_REGISTER,
|
LOC_REGISTER,
|
||||||
LOC_CREGISTER :
|
LOC_CREGISTER :
|
||||||
begin
|
begin
|
||||||
{$ifndef cpu64bitalu}
|
{$ifdef cpu64bitalu}
|
||||||
|
if left.location.size in [OS_128,OS_S128] then
|
||||||
|
cg128.a_load128_ref_reg(current_asmdata.CurrAsmList,right.location.reference,left.location.register128)
|
||||||
|
else
|
||||||
|
{$else cpu64bitalu}
|
||||||
if left.location.size in [OS_64,OS_S64] then
|
if left.location.size in [OS_64,OS_S64] then
|
||||||
cg64.a_load64_ref_reg(current_asmdata.CurrAsmList,right.location.reference,left.location.register64)
|
cg64.a_load64_ref_reg(current_asmdata.CurrAsmList,right.location.reference,left.location.register64)
|
||||||
else
|
else
|
||||||
{$endif not cpu64bitalu}
|
{$endif cpu64bitalu}
|
||||||
hlcg.a_load_ref_reg(current_asmdata.CurrAsmList,right.resultdef,left.resultdef,right.location.reference,left.location.register);
|
hlcg.a_load_ref_reg(current_asmdata.CurrAsmList,right.resultdef,left.resultdef,right.location.reference,left.location.register);
|
||||||
end;
|
end;
|
||||||
LOC_FPUREGISTER,
|
LOC_FPUREGISTER,
|
||||||
|
@ -205,7 +205,7 @@ implementation
|
|||||||
if getsupreg(location.register64.reghi)<first_int_imreg then
|
if getsupreg(location.register64.reghi)<first_int_imreg then
|
||||||
cg.ungetcpuregister(list,location.register64.reghi);
|
cg.ungetcpuregister(list,location.register64.reghi);
|
||||||
end
|
end
|
||||||
{$endif}
|
{$endif cpu64bitalu}
|
||||||
else
|
else
|
||||||
if getsupreg(location.register)<first_int_imreg then
|
if getsupreg(location.register)<first_int_imreg then
|
||||||
cg.ungetcpuregister(list,location.register);
|
cg.ungetcpuregister(list,location.register);
|
||||||
@ -317,7 +317,17 @@ implementation
|
|||||||
end;
|
end;
|
||||||
LOC_CREGISTER,LOC_REGISTER,LOC_CREFERENCE,LOC_REFERENCE :
|
LOC_CREGISTER,LOC_REGISTER,LOC_CREFERENCE,LOC_REFERENCE :
|
||||||
begin
|
begin
|
||||||
{$ifndef cpu64bitalu}
|
{$ifdef cpu64bitalu}
|
||||||
|
if opsize in [OS_128,OS_S128] then
|
||||||
|
begin
|
||||||
|
hlcg.location_force_reg(list,p.location,p.resultdef,hlcg.tcgsize2orddef(opsize),true);
|
||||||
|
tmpreg:=cg.getintregister(list,OS_64);
|
||||||
|
cg.a_op_reg_reg_reg(list,OP_OR,OS_64,p.location.register128.reglo,p.location.register128.reghi,tmpreg);
|
||||||
|
location_reset(p.location,LOC_REGISTER,OS_64);
|
||||||
|
p.location.register:=tmpreg;
|
||||||
|
opsize:=OS_64;
|
||||||
|
end;
|
||||||
|
{$else cpu64bitalu}
|
||||||
if opsize in [OS_64,OS_S64] then
|
if opsize in [OS_64,OS_S64] then
|
||||||
begin
|
begin
|
||||||
hlcg.location_force_reg(list,p.location,p.resultdef,hlcg.tcgsize2orddef(opsize),true);
|
hlcg.location_force_reg(list,p.location,p.resultdef,hlcg.tcgsize2orddef(opsize),true);
|
||||||
@ -327,7 +337,7 @@ implementation
|
|||||||
p.location.register:=tmpreg;
|
p.location.register:=tmpreg;
|
||||||
opsize:=OS_32;
|
opsize:=OS_32;
|
||||||
end;
|
end;
|
||||||
{$endif not cpu64bitalu}
|
{$endif cpu64bitalu}
|
||||||
cg.a_cmp_const_loc_label(list,opsize,OC_NE,0,p.location,current_procinfo.CurrTrueLabel);
|
cg.a_cmp_const_loc_label(list,opsize,OC_NE,0,p.location,current_procinfo.CurrTrueLabel);
|
||||||
cg.a_jmp_always(list,current_procinfo.CurrFalseLabel);
|
cg.a_jmp_always(list,current_procinfo.CurrFalseLabel);
|
||||||
end;
|
end;
|
||||||
@ -614,14 +624,21 @@ implementation
|
|||||||
location_reset(l,LOC_CREGISTER,l.size)
|
location_reset(l,LOC_CREGISTER,l.size)
|
||||||
else
|
else
|
||||||
location_reset(l,LOC_REGISTER,l.size);
|
location_reset(l,LOC_REGISTER,l.size);
|
||||||
{$ifndef cpu64bitalu}
|
{$ifdef cpu64bitalu}
|
||||||
|
if l.size in [OS_128,OS_S128,OS_F128] then
|
||||||
|
begin
|
||||||
|
l.register128.reglo:=cg.getintregister(list,OS_64);
|
||||||
|
l.register128.reghi:=cg.getintregister(list,OS_64);
|
||||||
|
end
|
||||||
|
else
|
||||||
|
{$else cpu64bitalu}
|
||||||
if l.size in [OS_64,OS_S64,OS_F64] then
|
if l.size in [OS_64,OS_S64,OS_F64] then
|
||||||
begin
|
begin
|
||||||
l.register64.reglo:=cg.getintregister(list,OS_32);
|
l.register64.reglo:=cg.getintregister(list,OS_32);
|
||||||
l.register64.reghi:=cg.getintregister(list,OS_32);
|
l.register64.reghi:=cg.getintregister(list,OS_32);
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
{$endif not cpu64bitalu}
|
{$endif cpu64bitalu}
|
||||||
l.register:=cg.getintregister(list,l.size);
|
l.register:=cg.getintregister(list,l.size);
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
@ -773,7 +790,14 @@ implementation
|
|||||||
case loc.loc of
|
case loc.loc of
|
||||||
LOC_CREGISTER:
|
LOC_CREGISTER:
|
||||||
begin
|
begin
|
||||||
{$ifndef cpu64bitalu}
|
{$ifdef cpu64bitalu}
|
||||||
|
if loc.size in [OS_128,OS_S128] then
|
||||||
|
begin
|
||||||
|
loc.register128.reglo:=cg.getintregister(list,OS_64);
|
||||||
|
loc.register128.reghi:=cg.getintregister(list,OS_64);
|
||||||
|
end
|
||||||
|
else
|
||||||
|
{$else cpu64bitalu}
|
||||||
if loc.size in [OS_64,OS_S64] then
|
if loc.size in [OS_64,OS_S64] then
|
||||||
begin
|
begin
|
||||||
loc.register64.reglo:=cg.getintregister(list,OS_32);
|
loc.register64.reglo:=cg.getintregister(list,OS_32);
|
||||||
@ -803,14 +827,21 @@ implementation
|
|||||||
begin
|
begin
|
||||||
{ Allocate register already, to prevent first allocation to be
|
{ Allocate register already, to prevent first allocation to be
|
||||||
inside a loop }
|
inside a loop }
|
||||||
{$ifndef cpu64bitalu}
|
{$ifdef cpu64bitalu}
|
||||||
|
if sym.initialloc.size in [OS_128,OS_S128] then
|
||||||
|
begin
|
||||||
|
cg.a_reg_sync(list,sym.initialloc.register128.reglo);
|
||||||
|
cg.a_reg_sync(list,sym.initialloc.register128.reghi);
|
||||||
|
end
|
||||||
|
else
|
||||||
|
{$else cpu64bitalu}
|
||||||
if sym.initialloc.size in [OS_64,OS_S64] then
|
if sym.initialloc.size in [OS_64,OS_S64] then
|
||||||
begin
|
begin
|
||||||
cg.a_reg_sync(list,sym.initialloc.register64.reglo);
|
cg.a_reg_sync(list,sym.initialloc.register64.reglo);
|
||||||
cg.a_reg_sync(list,sym.initialloc.register64.reghi);
|
cg.a_reg_sync(list,sym.initialloc.register64.reghi);
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
{$endif not cpu64bitalu}
|
{$endif cpu64bitalu}
|
||||||
cg.a_reg_sync(list,sym.initialloc.register);
|
cg.a_reg_sync(list,sym.initialloc.register);
|
||||||
end;
|
end;
|
||||||
sym.localloc:=sym.initialloc;
|
sym.localloc:=sym.initialloc;
|
||||||
@ -897,7 +928,53 @@ implementation
|
|||||||
LOC_REGISTER,
|
LOC_REGISTER,
|
||||||
LOC_CREGISTER :
|
LOC_CREGISTER :
|
||||||
begin
|
begin
|
||||||
{$ifndef cpu64bitalu}
|
{$ifdef cpu64bitalu}
|
||||||
|
if (para.size in [OS_128,OS_S128,OS_F128]) and
|
||||||
|
({ in case of fpu emulation, or abi's that pass fpu values
|
||||||
|
via integer registers }
|
||||||
|
(vardef.typ=floatdef) or
|
||||||
|
is_methodpointer(vardef)) then
|
||||||
|
begin
|
||||||
|
case paraloc^.loc of
|
||||||
|
LOC_REGISTER:
|
||||||
|
begin
|
||||||
|
if not assigned(paraloc^.next) then
|
||||||
|
internalerror(200410104);
|
||||||
|
if (target_info.endian=ENDIAN_BIG) then
|
||||||
|
begin
|
||||||
|
{ paraloc^ -> high
|
||||||
|
paraloc^.next -> low }
|
||||||
|
unget_para(paraloc^);
|
||||||
|
gen_alloc_regloc(list,destloc);
|
||||||
|
{ reg->reg, alignment is irrelevant }
|
||||||
|
cg.a_load_cgparaloc_anyreg(list,OS_64,paraloc^,destloc.register128.reghi,8);
|
||||||
|
unget_para(paraloc^.next^);
|
||||||
|
cg.a_load_cgparaloc_anyreg(list,OS_64,paraloc^.next^,destloc.register128.reglo,8);
|
||||||
|
end
|
||||||
|
else
|
||||||
|
begin
|
||||||
|
{ paraloc^ -> low
|
||||||
|
paraloc^.next -> high }
|
||||||
|
unget_para(paraloc^);
|
||||||
|
gen_alloc_regloc(list,destloc);
|
||||||
|
cg.a_load_cgparaloc_anyreg(list,OS_64,paraloc^,destloc.register128.reglo,8);
|
||||||
|
unget_para(paraloc^.next^);
|
||||||
|
cg.a_load_cgparaloc_anyreg(list,OS_64,paraloc^.next^,destloc.register128.reghi,8);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
LOC_REFERENCE:
|
||||||
|
begin
|
||||||
|
gen_alloc_regloc(list,destloc);
|
||||||
|
reference_reset_base(href,paraloc^.reference.index,paraloc^.reference.offset,para.alignment);
|
||||||
|
cg128.a_load128_ref_reg(list,href,destloc.register128);
|
||||||
|
unget_para(paraloc^);
|
||||||
|
end;
|
||||||
|
else
|
||||||
|
internalerror(2012090607);
|
||||||
|
end
|
||||||
|
end
|
||||||
|
else
|
||||||
|
{$else cpu64bitalu}
|
||||||
if (para.size in [OS_64,OS_S64,OS_F64]) and
|
if (para.size in [OS_64,OS_S64,OS_F64]) and
|
||||||
(is_64bit(vardef) or
|
(is_64bit(vardef) or
|
||||||
{ in case of fpu emulation, or abi's that pass fpu values
|
{ in case of fpu emulation, or abi's that pass fpu values
|
||||||
@ -944,7 +1021,7 @@ implementation
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
{$endif not cpu64bitalu}
|
{$endif cpu64bitalu}
|
||||||
begin
|
begin
|
||||||
if assigned(paraloc^.next) then
|
if assigned(paraloc^.next) then
|
||||||
internalerror(200410105);
|
internalerror(200410105);
|
||||||
@ -1520,14 +1597,21 @@ implementation
|
|||||||
begin
|
begin
|
||||||
case location.loc of
|
case location.loc of
|
||||||
LOC_CREGISTER:
|
LOC_CREGISTER:
|
||||||
{$ifndef cpu64bitalu}
|
{$ifdef cpu64bitalu}
|
||||||
|
if location.size in [OS_128,OS_S128] then
|
||||||
|
begin
|
||||||
|
rv.intregvars.addnodup(getsupreg(location.register128.reglo));
|
||||||
|
rv.intregvars.addnodup(getsupreg(location.register128.reghi));
|
||||||
|
end
|
||||||
|
else
|
||||||
|
{$else cpu64bitalu}
|
||||||
if location.size in [OS_64,OS_S64] then
|
if location.size in [OS_64,OS_S64] then
|
||||||
begin
|
begin
|
||||||
rv.intregvars.addnodup(getsupreg(location.register64.reglo));
|
rv.intregvars.addnodup(getsupreg(location.register64.reglo));
|
||||||
rv.intregvars.addnodup(getsupreg(location.register64.reghi));
|
rv.intregvars.addnodup(getsupreg(location.register64.reghi));
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
{$endif not cpu64bitalu}
|
{$endif cpu64bitalu}
|
||||||
rv.intregvars.addnodup(getsupreg(location.register));
|
rv.intregvars.addnodup(getsupreg(location.register));
|
||||||
LOC_CFPUREGISTER:
|
LOC_CFPUREGISTER:
|
||||||
rv.fpuregvars.addnodup(getsupreg(location.register));
|
rv.fpuregvars.addnodup(getsupreg(location.register));
|
||||||
|
@ -359,7 +359,7 @@ implementation
|
|||||||
reg_cgsize:=OS_32
|
reg_cgsize:=OS_32
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
internalerror(200303181);
|
internalerror(2003031801);
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user