mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-08-31 01:12:04 +02:00
* generic part of r26050 from the hlcgllvm branch: made tcgvecnode hlcg-safe
o in particular, add tdef size information to the update_reference*() methods, and factored out offset adjustments into its own method o also make sure the passed size to update_reference*() corresponds to the actual size of the index, as it's no longer guaranteed to be ptruint since the previous commit git-svn-id: trunk@29967 -
This commit is contained in:
parent
97df25cc29
commit
d6de2c03cb
@ -28,6 +28,7 @@ interface
|
||||
uses
|
||||
globtype,
|
||||
cgbase,
|
||||
symtype,
|
||||
node,nmem,ncgmem;
|
||||
|
||||
type
|
||||
@ -36,7 +37,7 @@ interface
|
||||
end;
|
||||
|
||||
taarch64vecnode = class(tcgvecnode)
|
||||
procedure update_reference_reg_mul(maybe_const_reg: tregister; l: aint); override;
|
||||
procedure update_reference_reg_mul(maybe_const_reg: tregister; regsize: tdef; l: aint); override;
|
||||
end;
|
||||
|
||||
implementation
|
||||
@ -71,7 +72,7 @@ implementation
|
||||
|
||||
{ taarch64vecnode }
|
||||
|
||||
procedure taarch64vecnode.update_reference_reg_mul(maybe_const_reg: tregister; l: aint);
|
||||
procedure taarch64vecnode.update_reference_reg_mul(maybe_const_reg: tregister; regsize: tdef; l: aint);
|
||||
var
|
||||
base: tregister;
|
||||
oldoffset: asizeint;
|
||||
|
@ -27,6 +27,7 @@ interface
|
||||
|
||||
uses
|
||||
globtype,
|
||||
symtype,
|
||||
cgbase,cpubase,nmem,ncgmem;
|
||||
|
||||
type
|
||||
@ -36,7 +37,7 @@ interface
|
||||
|
||||
|
||||
tarmvecnode = class(tcgvecnode)
|
||||
procedure update_reference_reg_mul(maybe_const_reg: tregister; l: aint);override;
|
||||
procedure update_reference_reg_mul(maybe_const_reg: tregister; regsize: tdef; l: aint);override;
|
||||
end;
|
||||
|
||||
implementation
|
||||
@ -70,7 +71,7 @@ implementation
|
||||
TARMVECNODE
|
||||
*****************************************************************************}
|
||||
|
||||
procedure tarmvecnode.update_reference_reg_mul(maybe_const_reg:tregister;l:aint);
|
||||
procedure tarmvecnode.update_reference_reg_mul(maybe_const_reg: tregister; regsize: tdef; l: aint);
|
||||
var
|
||||
hreg: tregister;
|
||||
hl : longint;
|
||||
@ -79,7 +80,7 @@ implementation
|
||||
(GenerateThumbCode) or
|
||||
{ simple constant? }
|
||||
(l=1) or ispowerof2(l,hl) or ispowerof2(l+1,hl) or ispowerof2(l-1,hl) then
|
||||
inherited update_reference_reg_mul(maybe_const_reg,l)
|
||||
inherited update_reference_reg_mul(maybe_const_reg,regsize,l)
|
||||
else if (location.reference.base<>NR_NO) then
|
||||
begin
|
||||
hreg:=cg.getaddressregister(current_asmdata.CurrAsmList);
|
||||
|
@ -27,6 +27,7 @@ interface
|
||||
|
||||
uses
|
||||
globtype,
|
||||
symtype,
|
||||
cgbase,cpuinfo,cpubase,
|
||||
node,nmem,ncgmem,nx86mem,ni86mem;
|
||||
|
||||
@ -45,7 +46,7 @@ interface
|
||||
ti8086vecnode = class(tcgvecnode)
|
||||
protected
|
||||
function first_arraydef: tnode;override;
|
||||
procedure update_reference_reg_mul(maybe_const_reg:tregister;l:aint);override;
|
||||
procedure update_reference_reg_mul(maybe_const_reg: tregister; regsize: tdef; l: aint);override;
|
||||
end;
|
||||
|
||||
implementation
|
||||
@ -53,7 +54,7 @@ implementation
|
||||
uses
|
||||
systems,globals,constexp,
|
||||
cutils,verbose,
|
||||
symbase,symconst,symdef,symtable,symtype,symsym,symx86,symcpu,
|
||||
symbase,symconst,symdef,symtable,symsym,symx86,symcpu,
|
||||
parabase,paramgr,
|
||||
aasmtai,aasmdata,
|
||||
nld,ncon,nadd,ncal,ncnv,
|
||||
@ -212,13 +213,13 @@ implementation
|
||||
end;
|
||||
|
||||
|
||||
procedure ti8086vecnode.update_reference_reg_mul(maybe_const_reg:tregister;l:aint);
|
||||
procedure ti8086vecnode.update_reference_reg_mul(maybe_const_reg: tregister; regsize: tdef; l: aint);
|
||||
var
|
||||
saveseg: TRegister;
|
||||
begin
|
||||
saveseg:=location.reference.segment;
|
||||
location.reference.segment:=NR_NO;
|
||||
inherited update_reference_reg_mul(maybe_const_reg,l);
|
||||
inherited;
|
||||
location.reference.segment:=saveseg;
|
||||
end;
|
||||
|
||||
|
@ -27,12 +27,13 @@ interface
|
||||
|
||||
uses
|
||||
globtype,
|
||||
symtype,
|
||||
cgbase,cpuinfo,cpubase,
|
||||
node,nmem,ncgmem;
|
||||
|
||||
type
|
||||
t68kvecnode = class(tcgvecnode)
|
||||
procedure update_reference_reg_mul(maybe_const_reg:tregister;l:aint);override;
|
||||
procedure update_reference_reg_mul(maybe_const_reg: tregister; regsize: tdef; l: aint); override;
|
||||
//procedure pass_generate_code;override;
|
||||
end;
|
||||
|
||||
@ -59,7 +60,7 @@ implementation
|
||||
{ the live range of the LOC_CREGISTER will most likely overlap the }
|
||||
{ the live range of the target LOC_(C)REGISTER) }
|
||||
{ The passed register may be a LOC_CREGISTER as well. }
|
||||
procedure t68kvecnode.update_reference_reg_mul(maybe_const_reg:tregister;l:aint);
|
||||
procedure t68kvecnode.update_reference_reg_mul(maybe_const_reg: tregister; regsize: tdef; l: aint);
|
||||
var
|
||||
hreg: tregister;
|
||||
scaled: boolean;
|
||||
|
@ -27,7 +27,8 @@ unit ncgmem;
|
||||
interface
|
||||
|
||||
uses
|
||||
globtype,cgbase,cpuinfo,cpubase,
|
||||
globtype,cgbase,cgutils,cpuinfo,cpubase,
|
||||
symtype,
|
||||
node,nmem;
|
||||
|
||||
type
|
||||
@ -67,8 +68,9 @@ interface
|
||||
This routine should update location.reference correctly,
|
||||
so it points to the correct address.
|
||||
}
|
||||
procedure update_reference_reg_mul(maybe_const_reg:tregister;l:aint);virtual;
|
||||
procedure update_reference_reg_packed(maybe_const_reg:tregister;l:aint);virtual;
|
||||
procedure update_reference_reg_mul(maybe_const_reg: tregister;regsize: tdef; l: aint);virtual;
|
||||
procedure update_reference_reg_packed(maybe_const_reg: tregister; regsize: tdef; l: aint);virtual;
|
||||
procedure update_reference_offset(var ref: treference; index, mulsize: aint); virtual;
|
||||
procedure second_wideansistring;virtual;
|
||||
procedure second_dynamicarray;virtual;
|
||||
function valid_index_size(size: tcgsize): boolean;virtual;
|
||||
@ -82,11 +84,11 @@ implementation
|
||||
uses
|
||||
systems,
|
||||
cutils,cclasses,verbose,globals,constexp,
|
||||
symconst,symbase,symtype,symdef,symsym,symcpu,symtable,defutil,paramgr,
|
||||
symconst,symbase,symdef,symsym,symcpu,symtable,defutil,paramgr,
|
||||
aasmbase,aasmtai,aasmdata,
|
||||
procinfo,pass_2,parabase,
|
||||
pass_1,nld,ncon,nadd,ncnv,nutils,
|
||||
cgutils,cgobj,hlcgobj,
|
||||
cgobj,hlcgobj,
|
||||
tgobj,ncgutil,objcgutl,
|
||||
defcmp
|
||||
;
|
||||
@ -520,8 +522,8 @@ implementation
|
||||
}
|
||||
asmsym:=current_asmdata.RefAsmSymbol(vs.mangledname);
|
||||
reference_reset_symbol(tmpref,asmsym,0,sizeof(pint));
|
||||
location.reference.index:=cg.getaddressregister(current_asmdata.CurrAsmList);
|
||||
cg.a_load_ref_reg(current_asmdata.CurrAsmList,OS_ADDR,OS_ADDR,tmpref,location.reference.index);
|
||||
location.reference.index:=hlcg.getintregister(current_asmdata.CurrAsmList,ptruinttype);
|
||||
hlcg.a_load_ref_reg(current_asmdata.CurrAsmList,ptruinttype,ptruinttype,tmpref,location.reference.index);
|
||||
{ always packrecords C -> natural alignment }
|
||||
location.reference.alignment:=vs.vardef.alignment;
|
||||
end
|
||||
@ -614,7 +616,7 @@ implementation
|
||||
{ the live range of the LOC_CREGISTER will most likely overlap the }
|
||||
{ the live range of the target LOC_(C)REGISTER) }
|
||||
{ The passed register may be a LOC_CREGISTER as well. }
|
||||
procedure tcgvecnode.update_reference_reg_mul(maybe_const_reg:tregister;l:aint);
|
||||
procedure tcgvecnode.update_reference_reg_mul(maybe_const_reg: tregister; regsize: tdef; l: aint);
|
||||
var
|
||||
hreg: tregister;
|
||||
begin
|
||||
@ -644,7 +646,7 @@ implementation
|
||||
|
||||
|
||||
{ see remarks for tcgvecnode.update_reference_reg_mul above }
|
||||
procedure tcgvecnode.update_reference_reg_packed(maybe_const_reg:tregister;l:aint);
|
||||
procedure tcgvecnode.update_reference_reg_packed(maybe_const_reg: tregister; regsize: tdef; l:aint);
|
||||
var
|
||||
sref: tsubsetreference;
|
||||
offsetreg, hreg: tregister;
|
||||
@ -662,7 +664,7 @@ implementation
|
||||
{$endif not cpu64bitalu}
|
||||
) then
|
||||
begin
|
||||
update_reference_reg_mul(maybe_const_reg,l div 8);
|
||||
update_reference_reg_mul(maybe_const_reg,regsize,l div 8);
|
||||
exit;
|
||||
end;
|
||||
if (l > 8*sizeof(aint)) then
|
||||
@ -673,7 +675,7 @@ implementation
|
||||
cg.a_op_const_reg(current_asmdata.CurrAsmList,OP_IMUL,OS_INT,l,hreg);
|
||||
{ keep alignment for index }
|
||||
sref.ref.alignment := left.resultdef.alignment;
|
||||
if not ispowerof2(sref.ref.alignment,temp) then
|
||||
if not ispowerof2(packedbitsloadsize(l),temp) then
|
||||
internalerror(2006081201);
|
||||
alignpower:=temp;
|
||||
offsetreg := cg.getaddressregister(current_asmdata.CurrAsmList);
|
||||
@ -700,6 +702,12 @@ implementation
|
||||
end;
|
||||
|
||||
|
||||
procedure tcgvecnode.update_reference_offset(var ref: treference; index, mulsize: aint);
|
||||
begin
|
||||
inc(ref.offset,index*mulsize);
|
||||
end;
|
||||
|
||||
|
||||
procedure tcgvecnode.second_wideansistring;
|
||||
begin
|
||||
end;
|
||||
@ -861,6 +869,7 @@ implementation
|
||||
paraloc2 : tcgpara;
|
||||
subsetref : tsubsetreference;
|
||||
temp : longint;
|
||||
indexdef : tdef;
|
||||
begin
|
||||
paraloc1.init;
|
||||
paraloc2.init;
|
||||
@ -918,7 +927,7 @@ implementation
|
||||
|
||||
{ in ansistrings/widestrings S[1] is p<w>char(S)[0] }
|
||||
if not(cs_zerobasedstrings in current_settings.localswitches) then
|
||||
dec(location.reference.offset,offsetdec);
|
||||
update_reference_offset(location.reference,-1,offsetdec);
|
||||
end
|
||||
else if is_dynamic_array(left.resultdef) then
|
||||
begin
|
||||
@ -971,7 +980,7 @@ implementation
|
||||
or is_64bitint(resultdef)
|
||||
{$endif not cpu64bitalu}
|
||||
) then
|
||||
dec(location.reference.offset,bytemulsize*tarraydef(left.resultdef).lowrange);
|
||||
update_reference_offset(location.reference,-tarraydef(left.resultdef).lowrange,bytemulsize);
|
||||
|
||||
if right.nodetype=ordconstn then
|
||||
begin
|
||||
@ -992,10 +1001,10 @@ implementation
|
||||
{ only orddefs are bitpacked }
|
||||
not is_ordinal(resultdef))) then
|
||||
begin
|
||||
extraoffset:=bytemulsize*tordconstnode(right).value.svalue;
|
||||
inc(location.reference.offset,extraoffset);
|
||||
{ adjust alignment after to this change }
|
||||
location.reference.alignment:=newalignment(location.reference.alignment,extraoffset);
|
||||
extraoffset:=tordconstnode(right).value.svalue;
|
||||
update_reference_offset(location.reference,extraoffset,bytemulsize);
|
||||
{ adjust alignment after this change }
|
||||
location.reference.alignment:=newalignment(location.reference.alignment,extraoffset*bytemulsize);
|
||||
{ don't do this for floats etc.; needed to properly set the }
|
||||
{ size for bitpacked arrays (e.g. a bitpacked array of }
|
||||
{ enums who are size 2 but fit in one byte -> in the array }
|
||||
@ -1008,10 +1017,10 @@ implementation
|
||||
begin
|
||||
subsetref.ref := location.reference;
|
||||
subsetref.ref.alignment := left.resultdef.alignment;
|
||||
if not ispowerof2(subsetref.ref.alignment,temp) then
|
||||
if not ispowerof2(packedbitsloadsize(resultdef.packedbitsize),temp) then
|
||||
internalerror(2006081212);
|
||||
alignpow:=temp;
|
||||
inc(subsetref.ref.offset,((mulsize * (tordconstnode(right).value.svalue-tarraydef(left.resultdef).lowrange)) shr (3+alignpow)) shl alignpow);
|
||||
update_reference_offset(subsetref.ref,(mulsize * (tordconstnode(right).value.svalue-tarraydef(left.resultdef).lowrange)) shr (3+alignpow),1 shl alignpow);
|
||||
subsetref.bitindexreg := NR_NO;
|
||||
subsetref.startbit := (mulsize * (tordconstnode(right).value.svalue-tarraydef(left.resultdef).lowrange)) and ((1 shl (3+alignpow))-1);
|
||||
subsetref.bitlen := resultdef.packedbitsize;
|
||||
@ -1056,8 +1065,7 @@ implementation
|
||||
replacenode(rightp^,taddnode(rightp^).left);
|
||||
end;
|
||||
end;
|
||||
inc(location.reference.offset,
|
||||
mulsize*extraoffset);
|
||||
update_reference_offset(location.reference,extraoffset,mulsize);
|
||||
end;
|
||||
{ calculate from left to right }
|
||||
if not(location.loc in [LOC_CREFERENCE,LOC_REFERENCE]) then
|
||||
@ -1077,7 +1085,12 @@ implementation
|
||||
{ if mulsize = 1, we won't have to modify the index }
|
||||
if not(right.location.loc in [LOC_CREGISTER,LOC_REGISTER]) or
|
||||
not valid_index_size(right.location.size) then
|
||||
hlcg.location_force_reg(current_asmdata.CurrAsmList,right.location,right.resultdef,ptruinttype,true);
|
||||
begin
|
||||
hlcg.location_force_reg(current_asmdata.CurrAsmList,right.location,right.resultdef,ptruinttype,true);
|
||||
indexdef:=ptruinttype
|
||||
end
|
||||
else
|
||||
indexdef:=right.resultdef;
|
||||
|
||||
if isjump then
|
||||
begin
|
||||
@ -1099,9 +1112,9 @@ implementation
|
||||
{ insert the register and the multiplication factor in the
|
||||
reference }
|
||||
if not is_packed_array(left.resultdef) then
|
||||
update_reference_reg_mul(right.location.register,mulsize)
|
||||
update_reference_reg_mul(right.location.register,indexdef,mulsize)
|
||||
else
|
||||
update_reference_reg_packed(right.location.register,mulsize);
|
||||
update_reference_reg_packed(right.location.register,indexdef,mulsize);
|
||||
end;
|
||||
|
||||
location.size:=newsize;
|
||||
|
@ -27,6 +27,7 @@ interface
|
||||
uses
|
||||
globtype,
|
||||
cgbase,cpuinfo,cpubase,
|
||||
symtype,
|
||||
node,nmem,ncgmem;
|
||||
|
||||
type
|
||||
@ -35,7 +36,7 @@ interface
|
||||
end;
|
||||
|
||||
tx86vecnode = class(tcgvecnode)
|
||||
procedure update_reference_reg_mul(maybe_const_reg:tregister;l:aint);override;
|
||||
procedure update_reference_reg_mul(maybe_const_reg: tregister; regsize: tdef; l: aint);override;
|
||||
end;
|
||||
|
||||
implementation
|
||||
@ -86,7 +87,7 @@ implementation
|
||||
{ the live range of the LOC_CREGISTER will most likely overlap the }
|
||||
{ the live range of the target LOC_(C)REGISTER) }
|
||||
{ The passed register may be a LOC_CREGISTER as well. }
|
||||
procedure tx86vecnode.update_reference_reg_mul(maybe_const_reg:tregister;l:aint);
|
||||
procedure tx86vecnode.update_reference_reg_mul(maybe_const_reg: tregister; regsize: tdef; l: aint);
|
||||
var
|
||||
l2 : integer;
|
||||
hreg : tregister;
|
||||
|
Loading…
Reference in New Issue
Block a user