* 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:
Jonas Maebe 2015-02-23 22:56:00 +00:00
parent 97df25cc29
commit d6de2c03cb
6 changed files with 55 additions and 37 deletions

View File

@ -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;

View File

@ -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);

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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;