2
0
Эх сурвалжийг харах

* 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 -

Jonas Maebe 10 жил өмнө
parent
commit
d6de2c03cb

+ 3 - 2
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;

+ 4 - 3
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);

+ 5 - 4
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;
 

+ 3 - 2
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;

+ 37 - 24
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 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;

+ 3 - 2
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;