mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-04-17 00:19:38 +02:00
+ support for handling OS_128/OS_S128 on 64 Bit CPUs as far as needed for method pointers in registers
git-svn-id: trunk@22344 -
This commit is contained in:
parent
4514a55ec6
commit
7361e19799
compiler
@ -738,6 +738,9 @@ interface
|
||||
varsym : tsym;
|
||||
constructor create(sym : tsym;loc : tregister);
|
||||
constructor create64(sym : tsym;loc,lochi : tregister);
|
||||
{$ifdef cpu64bitalu}
|
||||
constructor create128(sym : tsym;loc,lochi : tregister);
|
||||
{$endif cpu64bitalu}
|
||||
constructor ppuload(t:taitype;ppufile:tcompilerppufile);override;
|
||||
procedure ppuwrite(ppufile:tcompilerppufile);override;
|
||||
procedure buildderefimpl;override;
|
||||
@ -917,7 +920,7 @@ implementation
|
||||
end;
|
||||
|
||||
|
||||
constructor tai_varloc.create64(sym: tsym; loc: tregister;lochi : tregister);
|
||||
constructor tai_varloc.create64(sym: tsym; loc, lochi: tregister);
|
||||
begin
|
||||
inherited Create;
|
||||
typ:=ait_varloc;
|
||||
@ -927,6 +930,18 @@ implementation
|
||||
end;
|
||||
|
||||
|
||||
{$ifdef cpu64bitalu}
|
||||
constructor tai_varloc.create128(sym: tsym; loc, lochi: tregister);
|
||||
begin
|
||||
inherited Create;
|
||||
typ:=ait_varloc;
|
||||
newlocation:=loc;
|
||||
newlocationhi:=lochi;
|
||||
varsym:=sym;
|
||||
end;
|
||||
{$endif cpu64bitalu}
|
||||
|
||||
|
||||
constructor tai_varloc.ppuload(t: taitype; ppufile: tcompilerppufile);
|
||||
begin
|
||||
inherited ppuload(t, ppufile);
|
||||
|
@ -162,6 +162,7 @@ end;
|
||||
procedure create_codegen;
|
||||
begin
|
||||
cg:=tcgalpha.create;
|
||||
cg128:=tcg128.create;
|
||||
end;
|
||||
|
||||
end.
|
||||
|
@ -61,7 +61,6 @@ unit cg64f32;
|
||||
procedure a_load64_reg_loc(list : TAsmList;reg : tregister64;const l : tlocation);override;
|
||||
|
||||
|
||||
|
||||
procedure a_load64high_reg_ref(list : TAsmList;reg : tregister;const ref : treference);override;
|
||||
procedure a_load64low_reg_ref(list : TAsmList;reg : tregister;const ref : treference);override;
|
||||
procedure a_load64high_ref_reg(list : TAsmList;const ref : treference;reg : tregister);override;
|
||||
@ -366,8 +365,6 @@ unit cg64f32;
|
||||
end;
|
||||
|
||||
|
||||
|
||||
|
||||
procedure tcg64f32.a_load64_subsetref_subsetref(list: TAsmlist; const fromsref, tosref: tsubsetreference);
|
||||
|
||||
var
|
||||
|
@ -209,6 +209,9 @@ interface
|
||||
{ A type to store register locations for 64 Bit values. }
|
||||
{$ifdef cpu64bitalu}
|
||||
tregister64 = tregister;
|
||||
tregister128 = record
|
||||
reglo,reghi : tregister;
|
||||
end;
|
||||
{$else cpu64bitalu}
|
||||
tregister64 = record
|
||||
reglo,reghi : tregister;
|
||||
@ -594,6 +597,11 @@ implementation
|
||||
OS_NO,OS_8,OS_16,OS_NO,OS_32,OS_NO,OS_NO,OS_NO,OS_64
|
||||
);
|
||||
begin
|
||||
{$ifdef cpu64bitalu}
|
||||
if a=16 then
|
||||
result:=OS_128
|
||||
else
|
||||
{$endif cpu64bitalu}
|
||||
if a>8 then
|
||||
result:=OS_NO
|
||||
else
|
||||
|
@ -458,7 +458,25 @@ unit cgobj;
|
||||
function g_indirect_sym_load(list:TAsmList;const symname: string; const flags: tindsymflags): tregister;virtual;
|
||||
end;
|
||||
|
||||
{$ifndef cpu64bitalu}
|
||||
{$ifdef cpu64bitalu}
|
||||
{ This class implements an abstract code generator class
|
||||
for 128 Bit operations, it applies currently only to 64 Bit CPUs and supports only simple operations
|
||||
}
|
||||
tcg128 = class
|
||||
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_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_loc_cgpara(list : TAsmList;const l : tlocation;const paraloc : TCGPara);virtual;
|
||||
procedure a_load128_ref_cgpara(list: TAsmList; const r: treference;const paraloc: tcgpara);
|
||||
procedure a_load128_reg_cgpara(list: TAsmList; reg: tregister128;const paraloc: tcgpara);
|
||||
end;
|
||||
|
||||
{ Creates a tregister128 record from 2 64 Bit registers. }
|
||||
function joinreg128(reglo,reghi : tregister) : tregister128;
|
||||
|
||||
{$else cpu64bitalu}
|
||||
{# @abstract(Abstract code generator for 64 Bit operations)
|
||||
This class implements an abstract code generator class
|
||||
for 64 Bit operations.
|
||||
@ -474,7 +492,6 @@ unit cgobj;
|
||||
procedure a_load64_const_loc(list : TAsmList;value : int64;const l : tlocation);virtual;abstract;
|
||||
procedure a_load64_reg_loc(list : TAsmList;reg : tregister64;const l : tlocation);virtual;abstract;
|
||||
|
||||
|
||||
procedure a_load64_subsetref_reg(list : TAsmList; const sref: tsubsetreference; destreg: tregister64);virtual;abstract;
|
||||
procedure a_load64_reg_subsetref(list : TAsmList; fromreg: tregister64; const sref: tsubsetreference);virtual;abstract;
|
||||
procedure a_load64_const_subsetref(list: TAsmlist; a: int64; const sref: tsubsetreference);virtual;abstract;
|
||||
@ -537,10 +554,13 @@ unit cgobj;
|
||||
{$endif cpu64bitalu}
|
||||
|
||||
var
|
||||
{# Main code generator class }
|
||||
{ Main code generator class }
|
||||
cg : tcg;
|
||||
{$ifndef cpu64bitalu}
|
||||
{# Code generator class for all operations working with 64-Bit operands }
|
||||
{$ifdef cpu64bitalu}
|
||||
{ Code generator class for all operations working with 128-Bit operands }
|
||||
cg128 : tcg128;
|
||||
{$else cpu64bitalu}
|
||||
{ Code generator class for all operations working with 64-Bit operands }
|
||||
cg64 : tcg64;
|
||||
{$endif cpu64bitalu}
|
||||
|
||||
@ -556,7 +576,6 @@ implementation
|
||||
tgobj,cutils,procinfo,
|
||||
ncgrtti;
|
||||
|
||||
|
||||
{*****************************************************************************
|
||||
basic functionallity
|
||||
******************************************************************************}
|
||||
@ -2508,6 +2527,204 @@ implementation
|
||||
internalerror(2006082211);
|
||||
end;
|
||||
end;
|
||||
{$else cpu64bitalu}
|
||||
|
||||
function joinreg128(reglo, reghi: tregister): tregister128;
|
||||
begin
|
||||
result.reglo:=reglo;
|
||||
result.reghi:=reghi;
|
||||
end;
|
||||
|
||||
|
||||
procedure splitparaloc128(const cgpara:tcgpara;var cgparalo,cgparahi:tcgpara);
|
||||
var
|
||||
paraloclo,
|
||||
paralochi : pcgparalocation;
|
||||
begin
|
||||
if not(cgpara.size in [OS_128,OS_S128]) then
|
||||
internalerror(2012090604);
|
||||
if not assigned(cgpara.location) then
|
||||
internalerror(2012090605);
|
||||
{ init lo/hi para }
|
||||
cgparahi.reset;
|
||||
if cgpara.size=OS_S128 then
|
||||
cgparahi.size:=OS_S64
|
||||
else
|
||||
cgparahi.size:=OS_64;
|
||||
cgparahi.intsize:=8;
|
||||
cgparahi.alignment:=cgpara.alignment;
|
||||
paralochi:=cgparahi.add_location;
|
||||
cgparalo.reset;
|
||||
cgparalo.size:=OS_64;
|
||||
cgparalo.intsize:=8;
|
||||
cgparalo.alignment:=cgpara.alignment;
|
||||
paraloclo:=cgparalo.add_location;
|
||||
{ 2 parameter fields? }
|
||||
if assigned(cgpara.location^.next) then
|
||||
begin
|
||||
{ Order for multiple locations is always
|
||||
paraloc^ -> high
|
||||
paraloc^.next -> low }
|
||||
if (target_info.endian=ENDIAN_BIG) then
|
||||
begin
|
||||
{ paraloc^ -> high
|
||||
paraloc^.next -> low }
|
||||
move(cgpara.location^,paralochi^,sizeof(paralochi^));
|
||||
move(cgpara.location^.next^,paraloclo^,sizeof(paraloclo^));
|
||||
end
|
||||
else
|
||||
begin
|
||||
{ paraloc^ -> low
|
||||
paraloc^.next -> high }
|
||||
move(cgpara.location^,paraloclo^,sizeof(paraloclo^));
|
||||
move(cgpara.location^.next^,paralochi^,sizeof(paralochi^));
|
||||
end;
|
||||
end
|
||||
else
|
||||
begin
|
||||
{ single parameter, this can only be in memory }
|
||||
if cgpara.location^.loc<>LOC_REFERENCE then
|
||||
internalerror(2012090606);
|
||||
move(cgpara.location^,paraloclo^,sizeof(paraloclo^));
|
||||
move(cgpara.location^,paralochi^,sizeof(paralochi^));
|
||||
{ for big endian low is at +8, for little endian high }
|
||||
if target_info.endian = endian_big then
|
||||
begin
|
||||
inc(cgparalo.location^.reference.offset,8);
|
||||
cgparalo.alignment:=newalignment(cgparalo.alignment,8);
|
||||
end
|
||||
else
|
||||
begin
|
||||
inc(cgparahi.location^.reference.offset,8);
|
||||
cgparahi.alignment:=newalignment(cgparahi.alignment,8);
|
||||
end;
|
||||
end;
|
||||
{ fix size }
|
||||
paraloclo^.size:=cgparalo.size;
|
||||
paraloclo^.next:=nil;
|
||||
paralochi^.size:=cgparahi.size;
|
||||
paralochi^.next:=nil;
|
||||
end;
|
||||
|
||||
|
||||
|
||||
|
||||
procedure tcg128.a_load128_reg_reg(list: TAsmList; regsrc,
|
||||
regdst: tregister128);
|
||||
begin
|
||||
cg.a_load_reg_reg(list,OS_64,OS_64,regsrc.reglo,regdst.reglo);
|
||||
cg.a_load_reg_reg(list,OS_64,OS_64,regsrc.reghi,regdst.reghi);
|
||||
end;
|
||||
|
||||
|
||||
procedure tcg128.a_load128_reg_ref(list: TAsmList; reg: tregister128;
|
||||
const ref: treference);
|
||||
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;
|
||||
cg.a_load_reg_ref(list,OS_64,OS_64,reg.reglo,ref);
|
||||
tmpref := ref;
|
||||
inc(tmpref.offset,8);
|
||||
cg.a_load_reg_ref(list,OS_64,OS_64,reg.reghi,tmpref);
|
||||
end;
|
||||
|
||||
|
||||
procedure tcg128.a_load128_loc_ref(list: TAsmList; const l: tlocation;
|
||||
const ref: treference);
|
||||
begin
|
||||
case l.loc of
|
||||
LOC_REGISTER,LOC_CREGISTER:
|
||||
a_load128_reg_ref(list,l.register128,ref);
|
||||
{ not yet implemented:
|
||||
LOC_CONSTANT :
|
||||
a_load128_const_ref(list,l.value128,ref);
|
||||
LOC_SUBSETREF, LOC_CSUBSETREF:
|
||||
a_load64_subsetref_ref(list,l.sref,ref); }
|
||||
else
|
||||
internalerror(201209061);
|
||||
end;
|
||||
end;
|
||||
|
||||
|
||||
procedure tcg128.a_load128_reg_loc(list: TAsmList; reg: tregister128;
|
||||
const l: tlocation);
|
||||
begin
|
||||
case l.loc of
|
||||
LOC_REFERENCE, LOC_CREFERENCE:
|
||||
a_load128_reg_ref(list,reg,l.reference);
|
||||
LOC_REGISTER,LOC_CREGISTER:
|
||||
a_load128_reg_reg(list,reg,l.register128);
|
||||
{ not yet implemented:
|
||||
LOC_SUBSETREF, LOC_CSUBSETREF:
|
||||
a_load64_reg_subsetref(list,reg,l.sref);
|
||||
LOC_MMREGISTER, LOC_CMMREGISTER:
|
||||
a_loadmm_intreg64_reg(list,l.size,reg,l.register); }
|
||||
else
|
||||
internalerror(201209062);
|
||||
end;
|
||||
end;
|
||||
|
||||
|
||||
procedure tcg128.a_load128_loc_cgpara(list: TAsmList; const l: tlocation;
|
||||
const paraloc: TCGPara);
|
||||
begin
|
||||
case l.loc of
|
||||
LOC_REGISTER,
|
||||
LOC_CREGISTER :
|
||||
a_load128_reg_cgpara(list,l.register128,paraloc);
|
||||
{not yet implemented:
|
||||
LOC_CONSTANT :
|
||||
a_load128_const_cgpara(list,l.value64,paraloc);
|
||||
}
|
||||
LOC_CREFERENCE,
|
||||
LOC_REFERENCE :
|
||||
a_load128_ref_cgpara(list,l.reference,paraloc);
|
||||
else
|
||||
internalerror(2012090603);
|
||||
end;
|
||||
end;
|
||||
|
||||
|
||||
procedure tcg128.a_load128_reg_cgpara(list : TAsmList;reg : tregister128;const paraloc : tcgpara);
|
||||
var
|
||||
tmplochi,tmploclo: tcgpara;
|
||||
begin
|
||||
tmploclo.init;
|
||||
tmplochi.init;
|
||||
splitparaloc128(paraloc,tmploclo,tmplochi);
|
||||
cg.a_load_reg_cgpara(list,OS_64,reg.reghi,tmplochi);
|
||||
cg.a_load_reg_cgpara(list,OS_64,reg.reglo,tmploclo);
|
||||
tmploclo.done;
|
||||
tmplochi.done;
|
||||
end;
|
||||
|
||||
|
||||
procedure tcg128.a_load128_ref_cgpara(list : TAsmList;const r : treference;const paraloc : tcgpara);
|
||||
var
|
||||
tmprefhi,tmpreflo : treference;
|
||||
tmploclo,tmplochi : tcgpara;
|
||||
begin
|
||||
tmploclo.init;
|
||||
tmplochi.init;
|
||||
splitparaloc128(paraloc,tmploclo,tmplochi);
|
||||
tmprefhi:=r;
|
||||
tmpreflo:=r;
|
||||
if target_info.endian=endian_big then
|
||||
inc(tmpreflo.offset,8)
|
||||
else
|
||||
inc(tmprefhi.offset,8);
|
||||
cg.a_load_ref_cgpara(list,OS_64,tmprefhi,tmplochi);
|
||||
cg.a_load_ref_cgpara(list,OS_64,tmpreflo,tmploclo);
|
||||
tmploclo.done;
|
||||
tmplochi.done;
|
||||
end;
|
||||
{$endif cpu64bitalu}
|
||||
|
||||
function asmsym2indsymflags(sym: TAsmSymbol): tindsymflags;
|
||||
@ -2523,7 +2740,10 @@ implementation
|
||||
begin
|
||||
cg.free;
|
||||
cg:=nil;
|
||||
{$ifndef cpu64bitalu}
|
||||
{$ifdef cpu64bitalu}
|
||||
cg128.free;
|
||||
cg128:=nil;
|
||||
{$else cpu64bitalu}
|
||||
cg64.free;
|
||||
cg64:=nil;
|
||||
{$endif cpu64bitalu}
|
||||
|
@ -127,7 +127,10 @@ unit cgutils;
|
||||
registeralias : tregister;
|
||||
{$endif m68k}
|
||||
);
|
||||
{$ifndef cpu64bitalu}
|
||||
{$ifdef cpu64bitalu}
|
||||
{ overlay a 128 Bit register type }
|
||||
2 : (register128 : tregister128);
|
||||
{$else cpu64bitalu}
|
||||
{ overlay a 64 Bit register type }
|
||||
2 : (register64 : tregister64);
|
||||
{$endif cpu64bitalu}
|
||||
|
@ -1200,11 +1200,15 @@ implementation
|
||||
LOC_CREGISTER :
|
||||
begin
|
||||
tg.gethltemp(list,size,size.size,tt_normal,r);
|
||||
{$ifndef cpu64bitalu}
|
||||
{$ifdef cpu64bitalu}
|
||||
if l.size in [OS_128,OS_S128] then
|
||||
cg128.a_load128_loc_ref(list,l,r)
|
||||
else
|
||||
{$else cpu64bitalu}
|
||||
if l.size in [OS_64,OS_S64] then
|
||||
cg64.a_load64_loc_ref(list,l,r)
|
||||
else
|
||||
{$endif not cpu64bitalu}
|
||||
{$endif cpu64bitalu}
|
||||
a_load_loc_ref(list,size,size,l,r);
|
||||
location_reset_ref(l,LOC_REFERENCE,l.size,0);
|
||||
l.reference:=r;
|
||||
@ -1329,10 +1333,8 @@ implementation
|
||||
end;
|
||||
|
||||
procedure thlcg2ll.gen_load_loc_cgpara(list: TAsmList; vardef: tdef; const l: tlocation; const cgpara: tcgpara);
|
||||
{$ifndef cpu64bitalu}
|
||||
var
|
||||
tmploc: tlocation;
|
||||
{$endif not cpu64bitalu}
|
||||
begin
|
||||
{ Handle Floating point types differently
|
||||
|
||||
@ -1355,19 +1357,28 @@ implementation
|
||||
LOC_REFERENCE,
|
||||
LOC_CREFERENCE :
|
||||
begin
|
||||
{$ifndef cpu64bitalu}
|
||||
{$ifdef cpu64bitalu}
|
||||
{ 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
|
||||
cg128.a_load128_loc_cgpara(list,l,cgpara)
|
||||
else
|
||||
{$else cpu64bitalu}
|
||||
{ use cg64 only for int64, not for 8 byte records }
|
||||
if (l.size in [OS_64,OS_S64]) and (cgpara.Size in [OS_64,OS_S64]) then
|
||||
cg64.a_load64_loc_cgpara(list,l,cgpara)
|
||||
else
|
||||
{$endif not cpu64bitalu}
|
||||
{$endif cpu64bitalu}
|
||||
begin
|
||||
{$ifndef cpu64bitalu}
|
||||
|
||||
{ Only a_load_ref_cgpara supports multiple locations, when the
|
||||
value is still a const or in a register then write it
|
||||
to a reference first. This situation can be triggered
|
||||
by typecasting an int64 constant to a record of 8 bytes }
|
||||
{$ifdef cpu64bitalu}
|
||||
if l.size in [OS_128,OS_S128] then
|
||||
{$else cpu64bitalu}
|
||||
if l.size in [OS_64,OS_S64] then
|
||||
{$endif cpu64bitalu}
|
||||
begin
|
||||
tmploc:=l;
|
||||
location_force_mem(list,tmploc,vardef);
|
||||
@ -1379,7 +1390,6 @@ implementation
|
||||
location_freetemp(list,tmploc);
|
||||
end
|
||||
else
|
||||
{$endif not cpu64bitalu}
|
||||
a_load_loc_cgpara(list,vardef,l,cgpara);
|
||||
end;
|
||||
end;
|
||||
|
@ -842,13 +842,18 @@ implementation
|
||||
LOC_REGISTER,
|
||||
LOC_CREGISTER :
|
||||
begin
|
||||
{$ifndef cpu64bitalu}
|
||||
{$ifdef cpu64bitalu}
|
||||
if left.location.size in [OS_128,OS_S128] then
|
||||
cg128.a_load128_reg_loc(current_asmdata.CurrAsmList,
|
||||
right.location.register128,left.location)
|
||||
else
|
||||
{$else cpu64bitalu}
|
||||
{ also OS_F64 in case of mmreg -> intreg }
|
||||
if left.location.size in [OS_64,OS_S64,OS_F64] then
|
||||
cg64.a_load64_reg_loc(current_asmdata.CurrAsmList,
|
||||
right.location.register64,left.location)
|
||||
else
|
||||
{$endif not cpu64bitalu}
|
||||
{$endif cpu64bitalu}
|
||||
hlcg.a_load_reg_loc(current_asmdata.CurrAsmList,right.resultdef,left.resultdef,right.location.register,left.location);
|
||||
end;
|
||||
LOC_FPUREGISTER,
|
||||
@ -1274,11 +1279,15 @@ implementation
|
||||
end;
|
||||
else
|
||||
begin
|
||||
{$ifndef cpu64bitalu}
|
||||
{$ifdef cpu64bitalu}
|
||||
if hp.left.location.size in [OS_128,OS_S128] then
|
||||
cg128.a_load128_loc_ref(current_asmdata.CurrAsmList,hp.left.location,href)
|
||||
else
|
||||
{$else cpu64bitalu}
|
||||
if hp.left.location.size in [OS_64,OS_S64] then
|
||||
cg64.a_load64_loc_ref(current_asmdata.CurrAsmList,hp.left.location,href)
|
||||
else
|
||||
{$endif not cpu64bitalu}
|
||||
{$endif cpu64bitalu}
|
||||
hlcg.a_load_loc_ref(current_asmdata.CurrAsmList,eledef,eledef,hp.left.location,href);
|
||||
end;
|
||||
end;
|
||||
|
@ -1638,9 +1638,7 @@ implementation
|
||||
preplaceregrec = ^treplaceregrec;
|
||||
treplaceregrec = record
|
||||
old, new: tregister;
|
||||
{$ifndef cpu64bitalu}
|
||||
oldhi, newhi: tregister;
|
||||
{$endif not cpu64bitalu}
|
||||
ressym: tsym;
|
||||
{ moved sym }
|
||||
sym : tsym;
|
||||
@ -1665,7 +1663,15 @@ implementation
|
||||
(tabstractnormalvarsym(tloadnode(n).symtableentry).localloc.loc in [LOC_CREGISTER,LOC_CFPUREGISTER,LOC_CMMXREGISTER,LOC_CMMREGISTER]) and
|
||||
(tabstractnormalvarsym(tloadnode(n).symtableentry).localloc.register = rr^.old) then
|
||||
begin
|
||||
{$ifndef cpu64bitalu}
|
||||
{$ifdef cpu64bitalu}
|
||||
{ it's possible a 128 bit location was shifted and/xor typecasted }
|
||||
{ in a 64 bit value, so only 1 register was left in the location }
|
||||
if (tabstractnormalvarsym(tloadnode(n).symtableentry).localloc.size in [OS_128,OS_S128]) then
|
||||
if (tabstractnormalvarsym(tloadnode(n).symtableentry).localloc.register128.reghi = rr^.oldhi) then
|
||||
tabstractnormalvarsym(tloadnode(n).symtableentry).localloc.register128.reghi := rr^.newhi
|
||||
else
|
||||
exit;
|
||||
{$else cpu64bitalu}
|
||||
{ it's possible a 64 bit location was shifted and/xor typecasted }
|
||||
{ in a 32 bit value, so only 1 register was left in the location }
|
||||
if (tabstractnormalvarsym(tloadnode(n).symtableentry).localloc.size in [OS_64,OS_S64]) then
|
||||
@ -1673,7 +1679,7 @@ implementation
|
||||
tabstractnormalvarsym(tloadnode(n).symtableentry).localloc.register64.reghi := rr^.newhi
|
||||
else
|
||||
exit;
|
||||
{$endif not cpu64bitalu}
|
||||
{$endif cpu64bitalu}
|
||||
tabstractnormalvarsym(tloadnode(n).symtableentry).localloc.register := rr^.new;
|
||||
rr^.sym := tabstractnormalvarsym(tloadnode(n).symtableentry);
|
||||
result := fen_norecurse_true;
|
||||
@ -1685,7 +1691,15 @@ implementation
|
||||
(ttemprefnode(n).tempinfo^.location.loc in [LOC_CREGISTER,LOC_CFPUREGISTER,LOC_CMMXREGISTER,LOC_CMMREGISTER]) and
|
||||
(ttemprefnode(n).tempinfo^.location.register = rr^.old) then
|
||||
begin
|
||||
{$ifndef cpu64bitalu}
|
||||
{$ifdef cpu64bitalu}
|
||||
{ it's possible a 128 bit location was shifted and/xor typecasted }
|
||||
{ in a 64 bit value, so only 1 register was left in the location }
|
||||
if (ttemprefnode(n).tempinfo^.location.size in [OS_128,OS_S128]) then
|
||||
if (ttemprefnode(n).tempinfo^.location.register128.reghi = rr^.oldhi) then
|
||||
ttemprefnode(n).tempinfo^.location.register128.reghi := rr^.newhi
|
||||
else
|
||||
exit;
|
||||
{$else cpu64bitalu}
|
||||
{ it's possible a 64 bit location was shifted and/xor typecasted }
|
||||
{ in a 32 bit value, so only 1 register was left in the location }
|
||||
if (ttemprefnode(n).tempinfo^.location.size in [OS_64,OS_S64]) then
|
||||
@ -1693,7 +1707,7 @@ implementation
|
||||
ttemprefnode(n).tempinfo^.location.register64.reghi := rr^.newhi
|
||||
else
|
||||
exit;
|
||||
{$endif not cpu64bitalu}
|
||||
{$endif cpu64bitalu}
|
||||
ttemprefnode(n).tempinfo^.location.register := rr^.new;
|
||||
result := fen_norecurse_true;
|
||||
end;
|
||||
@ -1725,13 +1739,19 @@ implementation
|
||||
rr.old := n.location.register;
|
||||
rr.ressym := nil;
|
||||
rr.sym := nil;
|
||||
{$ifndef cpu64bitalu}
|
||||
rr.oldhi := NR_NO;
|
||||
{$endif not cpu64bitalu}
|
||||
case n.location.loc of
|
||||
LOC_CREGISTER:
|
||||
begin
|
||||
{$ifndef cpu64bitalu}
|
||||
{$ifdef cpu64bitalu}
|
||||
if (n.location.size in [OS_128,OS_S128]) then
|
||||
begin
|
||||
rr.oldhi := n.location.register128.reghi;
|
||||
rr.new := cg.getintregister(current_asmdata.CurrAsmList,OS_INT);
|
||||
rr.newhi := cg.getintregister(current_asmdata.CurrAsmList,OS_INT);
|
||||
end
|
||||
else
|
||||
{$else cpu64bitalu}
|
||||
if (n.location.size in [OS_64,OS_S64]) then
|
||||
begin
|
||||
rr.oldhi := n.location.register64.reghi;
|
||||
@ -1739,7 +1759,7 @@ implementation
|
||||
rr.newhi := cg.getintregister(current_asmdata.CurrAsmList,OS_INT);
|
||||
end
|
||||
else
|
||||
{$endif not cpu64bitalu}
|
||||
{$endif cpu64bitalu}
|
||||
rr.new := cg.getintregister(current_asmdata.CurrAsmList,n.location.size);
|
||||
end;
|
||||
LOC_CFPUREGISTER:
|
||||
@ -1769,11 +1789,15 @@ implementation
|
||||
case n.location.loc of
|
||||
LOC_CREGISTER:
|
||||
begin
|
||||
{$ifndef cpu64bitalu}
|
||||
{$ifdef cpu64bitalu}
|
||||
if (n.location.size in [OS_128,OS_S128]) then
|
||||
cg128.a_load128_reg_reg(list,n.location.register128,joinreg128(rr.new,rr.newhi))
|
||||
else
|
||||
{$else cpu64bitalu}
|
||||
if (n.location.size in [OS_64,OS_S64]) then
|
||||
cg64.a_load64_reg_reg(list,n.location.register64,joinreg64(rr.new,rr.newhi))
|
||||
else
|
||||
{$endif not cpu64bitalu}
|
||||
{$endif cpu64bitalu}
|
||||
cg.a_load_reg_reg(list,n.location.size,n.location.size,n.location.register,rr.new);
|
||||
end;
|
||||
LOC_CFPUREGISTER:
|
||||
@ -1789,7 +1813,16 @@ implementation
|
||||
end;
|
||||
|
||||
{ now that we've change the loadn/temp, also change the node result location }
|
||||
{$ifndef cpu64bitalu}
|
||||
{$ifdef cpu64bitalu}
|
||||
if (n.location.size in [OS_128,OS_S128]) then
|
||||
begin
|
||||
n.location.register128.reglo := rr.new;
|
||||
n.location.register128.reghi := rr.newhi;
|
||||
if assigned(rr.sym) then
|
||||
list.concat(tai_varloc.create128(rr.sym,rr.new,rr.newhi));
|
||||
end
|
||||
else
|
||||
{$else cpu64bitalu}
|
||||
if (n.location.size in [OS_64,OS_S64]) then
|
||||
begin
|
||||
n.location.register64.reglo := rr.new;
|
||||
@ -1798,7 +1831,7 @@ implementation
|
||||
list.concat(tai_varloc.create64(rr.sym,rr.new,rr.newhi));
|
||||
end
|
||||
else
|
||||
{$endif not cpu64bitalu}
|
||||
{$endif cpu64bitalu}
|
||||
begin
|
||||
n.location.register := rr.new;
|
||||
if assigned(rr.sym) then
|
||||
@ -1825,14 +1858,21 @@ implementation
|
||||
case localloc.loc of
|
||||
LOC_CREGISTER :
|
||||
if (pi_has_label in current_procinfo.flags) then
|
||||
{$ifndef cpu64bitalu}
|
||||
{$ifdef cpu64bitalu}
|
||||
if def_cgsize(vardef) in [OS_128,OS_S128] then
|
||||
begin
|
||||
cg.a_reg_sync(list,localloc.register128.reglo);
|
||||
cg.a_reg_sync(list,localloc.register128.reghi);
|
||||
end
|
||||
else
|
||||
{$else cpu64bitalu}
|
||||
if def_cgsize(vardef) in [OS_64,OS_S64] then
|
||||
begin
|
||||
cg.a_reg_sync(list,localloc.register64.reglo);
|
||||
cg.a_reg_sync(list,localloc.register64.reghi);
|
||||
end
|
||||
else
|
||||
{$endif not cpu64bitalu}
|
||||
{$endif cpu64bitalu}
|
||||
cg.a_reg_sync(list,localloc.register);
|
||||
LOC_CFPUREGISTER,
|
||||
LOC_CMMREGISTER:
|
||||
|
@ -1987,6 +1987,7 @@ end;
|
||||
procedure create_codegen;
|
||||
begin
|
||||
cg := tcgppc.create;
|
||||
cg128:=tcg128.create;
|
||||
end;
|
||||
|
||||
end.
|
||||
|
@ -363,6 +363,7 @@ unit cgcpu;
|
||||
procedure create_codegen;
|
||||
begin
|
||||
cg:=tcgx86_64.create;
|
||||
cg128:=tcg128.create;
|
||||
end;
|
||||
|
||||
end.
|
||||
|
Loading…
Reference in New Issue
Block a user