From d6de2c03cbe90221ab296f742febf3c07101116f Mon Sep 17 00:00:00 2001 From: Jonas Maebe Date: Mon, 23 Feb 2015 22:56:00 +0000 Subject: [PATCH] * 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 - --- compiler/aarch64/ncpumem.pas | 5 +-- compiler/arm/narmmem.pas | 7 +++-- compiler/i8086/n8086mem.pas | 9 +++--- compiler/m68k/n68kmem.pas | 5 +-- compiler/ncgmem.pas | 61 ++++++++++++++++++++++-------------- compiler/x86/nx86mem.pas | 5 +-- 6 files changed, 55 insertions(+), 37 deletions(-) diff --git a/compiler/aarch64/ncpumem.pas b/compiler/aarch64/ncpumem.pas index 6c92a2cd47..e33c763fbd 100644 --- a/compiler/aarch64/ncpumem.pas +++ b/compiler/aarch64/ncpumem.pas @@ -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; diff --git a/compiler/arm/narmmem.pas b/compiler/arm/narmmem.pas index cdda16413b..e316074f8f 100644 --- a/compiler/arm/narmmem.pas +++ b/compiler/arm/narmmem.pas @@ -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); diff --git a/compiler/i8086/n8086mem.pas b/compiler/i8086/n8086mem.pas index 7d12ef9223..0dc521b8fa 100644 --- a/compiler/i8086/n8086mem.pas +++ b/compiler/i8086/n8086mem.pas @@ -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; diff --git a/compiler/m68k/n68kmem.pas b/compiler/m68k/n68kmem.pas index d6cb270f0b..6c72fab54b 100644 --- a/compiler/m68k/n68kmem.pas +++ b/compiler/m68k/n68kmem.pas @@ -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; diff --git a/compiler/ncgmem.pas b/compiler/ncgmem.pas index 9ef12a62da..571c07d35a 100644 --- a/compiler/ncgmem.pas +++ b/compiler/ncgmem.pas @@ -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 pchar(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; diff --git a/compiler/x86/nx86mem.pas b/compiler/x86/nx86mem.pas index 40cb3e3bc6..f4a371e11d 100644 --- a/compiler/x86/nx86mem.pas +++ b/compiler/x86/nx86mem.pas @@ -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;