Pārlūkot izejas kodu

* cleaned up subsetreg support (put everything in a record)
* prepared support for elements with arbitrary bit length (as opposed
to a multiple of 8)

git-svn-id: trunk@4324 -

Jonas Maebe 19 gadi atpakaļ
vecāks
revīzija
c25aba7592

+ 7 - 3
compiler/cgutils.pas

@@ -61,6 +61,12 @@ unit cgutils;
 {$endif SUPPORT_UNALIGNED}
       end;
 
+      tsubsetregister = record
+        subsetreg : tregister;
+        startbit, bitlen: byte;
+        subsetregsize: tcgsize;
+      end;
+
       tlocation = record
          loc  : TCGLoc;
          size : TCGSize;
@@ -95,9 +101,7 @@ unit cgutils;
               );
             LOC_SUBSETREG,
             LOC_CSUBSETREG : (
-              subsetreg : tregister;
-              startbit: byte;
-              subsetregsize: tcgsize;
+              sreg: tsubsetregister;
             );
       end;
 

+ 1 - 1
compiler/ncgflw.pas

@@ -465,7 +465,7 @@ implementation
              cg.a_load_loc_reg(current_asmdata.CurrAsmList,left.location.size,right.location,left.location.register);
            LOC_SUBSETREG,
            LOC_CSUBSETREG :
-             cg.a_load_loc_subsetreg(current_asmdata.CurrAsmList,left.location.subsetregsize,left.location.size,left.location.startbit,right.location,left.location.subsetreg);
+             cg.a_load_loc_subsetreg(current_asmdata.CurrAsmList,left.location.size,right.location,left.location.sreg);
            else
              internalerror(200501311);
          end;

+ 2 - 3
compiler/ncgld.pas

@@ -613,7 +613,7 @@ implementation
                         left.location.register,mms_movescalar);
                     LOC_SUBSETREG,
                     LOC_CSUBSETREG:
-                      cg.a_load_ref_subsetreg(current_asmdata.CurrAsmList,right.location.size,left.location.subsetregsize,left.location.size,left.location.startbit,right.location.reference,left.location.subsetreg);
+                      cg.a_load_ref_subsetreg(current_asmdata.CurrAsmList,right.location.size,left.location.size,right.location.reference,left.location.sreg);
                     else
                       internalerror(200203284);
                   end;
@@ -684,8 +684,7 @@ implementation
               LOC_CSUBSETREG:
                 begin
                   cg.a_load_subsetreg_loc(current_asmdata.CurrAsmList,
-                      right.location.subsetregsize,right.location.size,right.location.startbit,
-                      right.location.register,left.location);
+                      right.location.size,right.location.sreg,left.location);
                 end;
               LOC_JUMP :
                 begin

+ 8 - 6
compiler/ncgmem.pas

@@ -322,12 +322,13 @@ implementation
                        else
                          location.loc := LOC_CSUBSETREG;
                        location.size:=def_cgsize(resulttype.def);
-                       location.subsetreg := left.location.register;
-                       location.subsetregsize := left.location.size;
+                       location.sreg.subsetreg := left.location.register;
+                       location.sreg.subsetregsize := left.location.size;
                        if (target_info.endian = ENDIAN_BIG) then
-                         location.startbit := (tcgsize2size[location.subsetregsize] - tcgsize2size[location.size] - vs.fieldoffset) * 8
+                         location.sreg.startbit := (tcgsize2size[location.sreg.subsetregsize] - tcgsize2size[location.size] - vs.fieldoffset) * 8
                        else
-                         location.startbit := (vs.fieldoffset * 8);
+                         location.sreg.startbit := (vs.fieldoffset * 8);
+                       location.sreg.bitlen := tcgsize2size[location.size] * 8;
                      end;
                  end;
                LOC_SUBSETREG,
@@ -335,9 +336,10 @@ implementation
                  begin
                    location.size:=def_cgsize(resulttype.def);
                    if (target_info.endian = ENDIAN_BIG) then
-                     inc(location.startbit, (left.resulttype.def.size - tcgsize2size[location.size] - vs.fieldoffset) * 8)
+                     inc(location.sreg.startbit, (left.resulttype.def.size - tcgsize2size[location.size] - vs.fieldoffset) * 8)
                    else
-                     inc(location.startbit, vs.fieldoffset * 8);
+                     inc(location.sreg.startbit, vs.fieldoffset * 8);
+                   location.sreg.bitlen := tcgsize2size[location.size] * 8;
                  end;
                else
                  internalerror(2006031901);

+ 2 - 2
compiler/ncgutil.pas

@@ -293,7 +293,7 @@ implementation
                      LOC_SUBSETREG,LOC_CSUBSETREG:
                        begin
                          tmpreg := cg.getintregister(list,OS_INT);
-                         cg.a_load_subsetreg_reg(list,p.location.subsetregsize,p.location.size,p.location.startbit,OS_INT,p.location.subsetreg,tmpreg);
+                         cg.a_load_subsetreg_reg(list,p.location.size,OS_INT,p.location.sreg,tmpreg);
                          cg.a_cmp_const_reg_label(list,OS_INT,OC_NE,0,tmpreg,current_procinfo.CurrTrueLabel);
                          cg.a_jmp_always(list,current_procinfo.CurrFalseLabel);
                        end;
@@ -758,7 +758,7 @@ implementation
           LOC_CSUBSETREG:
             begin
               tg.GetTemp(list,TCGSize2Size[l.size],tt_normal,r);
-              cg.a_load_subsetreg_ref(list,l.subsetregsize,l.size,l.startbit,l.size,l.subsetreg,r);
+              cg.a_load_subsetreg_ref(list,l.size,l.size,l.sreg,r);
               location_reset(l,LOC_REFERENCE,l.size);
               l.reference:=r;
             end;

+ 16 - 21
compiler/powerpc/cgcpu.pas

@@ -64,12 +64,10 @@ unit cgcpu;
         procedure a_load_ref_reg(list : TAsmList; fromsize, tosize : tcgsize;const Ref : treference;reg : tregister);override;
         procedure a_load_reg_reg(list : TAsmList; fromsize, tosize : tcgsize;reg1,reg2 : tregister);override;
 
-        procedure a_load_subsetreg_reg(list : TAsmList; subsetregsize, subsetsize: tcgsize;
-          startbit: byte; tosize: tcgsize; subsetreg, destreg: tregister); override;
-        procedure a_load_reg_subsetreg(list : TAsmList; fromsize: tcgsize; subsetregsize, 
-          subsetsize: tcgsize; startbit: byte; fromreg, subsetreg: tregister); override;
-       procedure a_load_subsetreg_subsetreg(list: TAsmlist; fromsubsetregsize, fromsubsetsize: tcgsize; fromstartbit: byte;
-          tosubsetregsize, tosubsetsize: tcgsize; tostartbit: byte; fromsubsetreg, tosubsetreg: tregister); override;
+        procedure a_load_subsetreg_reg(list : TAsmList; subsetsize: tcgsize;
+          tosize: tcgsize; const sreg: tsubsetregister; destreg: tregister); override;
+        procedure a_load_reg_subsetreg(list : TAsmList; fromsize, subsetsize: tcgsize; fromreg: tregister; const sreg: tsubsetregister); override;
+       procedure a_load_subsetreg_subsetreg(list: TAsmlist; fromsubsetsize, tosubsetsize: tcgsize; const fromsreg, tosreg: tsubsetregister); override;
 
         { fpu move instructions }
         procedure a_loadfpu_reg_reg(list: TAsmList; size: tcgsize; reg1, reg2: tregister); override;
@@ -555,44 +553,41 @@ const
        end;
 
 
-     procedure tcgppc.a_load_subsetreg_reg(list : TAsmList; subsetregsize, subsetsize: tcgsize;
-       startbit: byte; tosize: tcgsize; subsetreg, destreg: tregister);
+     procedure tcgppc.a_load_subsetreg_reg(list : TAsmList; subsetsize, tosize: tcgsize; const sreg: tsubsetregister; destreg: tregister);
 
        begin
          if (tcgsize2size[subsetsize] <> sizeof(aint)) then
            begin
              list.concat(taicpu.op_reg_reg_const_const_const(A_RLWINM,destreg,
-               subsetreg,(32-startbit) and 31,32-tcgsize2size[subsetsize]*8,31));
+               sreg.subsetreg,(32-sreg.startbit) and 31,32-sreg.bitlen,31));
              a_load_reg_reg(list,tcgsize2unsigned[subsetsize],subsetsize,destreg,destreg);
              a_load_reg_reg(list,subsetsize,tosize,destreg,destreg);
            end
          else
-           a_load_reg_reg(list,subsetsize,tosize,subsetreg,destreg);
+           a_load_reg_reg(list,subsetsize,tosize,sreg.subsetreg,destreg);
        end;
 
 
-     procedure tcgppc.a_load_reg_subsetreg(list : TAsmList; fromsize: tcgsize; subsetregsize, 
-       subsetsize: tcgsize; startbit: byte; fromreg, subsetreg: tregister);
+     procedure tcgppc.a_load_reg_subsetreg(list : TAsmList; fromsize, subsetsize: tcgsize; fromreg: tregister; const sreg: tsubsetregister);
 
        begin
          if ((tcgsize2size[subsetsize]) <> sizeof(aint)) then
-           list.concat(taicpu.op_reg_reg_const_const_const(A_RLWIMI,subsetreg,fromreg,
-             startbit,32-startbit-tcgsize2size[subsetsize]*8,31-startbit))
+           list.concat(taicpu.op_reg_reg_const_const_const(A_RLWIMI,sreg.subsetreg,fromreg,
+             sreg.startbit,32-sreg.startbit-sreg.bitlen,31-sreg.startbit))
          else
-           a_load_reg_reg(list,fromsize,subsetsize,fromreg,subsetreg);
+           a_load_reg_reg(list,fromsize,subsetsize,fromreg,sreg.subsetreg);
        end;
 
 
-       procedure tcgppc.a_load_subsetreg_subsetreg(list: TAsmlist; fromsubsetregsize, fromsubsetsize: tcgsize; fromstartbit: byte;
-         tosubsetregsize, tosubsetsize: tcgsize; tostartbit: byte; fromsubsetreg, tosubsetreg: tregister);
+       procedure tcgppc.a_load_subsetreg_subsetreg(list: TAsmlist; fromsubsetsize, tosubsetsize: tcgsize; const fromsreg, tosreg: tsubsetregister);
 
          begin
            if (tcgsize2size[fromsubsetsize] >= tcgsize2size[tosubsetsize]) then
-             list.concat(taicpu.op_reg_reg_const_const_const(A_RLWIMI,tosubsetreg, fromsubsetreg,
-                (tostartbit-fromstartbit) and 31,
-                32-tostartbit-tcgsize2size[tosubsetsize]*8,31-tostartbit))
+             list.concat(taicpu.op_reg_reg_const_const_const(A_RLWIMI,tosreg.subsetreg, fromsreg.subsetreg,
+                (tosreg.startbit-fromsreg.startbit) and 31,
+                32-tosreg.startbit-tosreg.bitlen,31-tosreg.startbit))
            else
-             inherited a_load_subsetreg_subsetreg(list,fromsubsetregsize,fromsubsetsize,fromstartbit,tosubsetregsize,tosubsetsize,tostartbit,fromsubsetreg,tosubsetreg);
+             inherited a_load_subsetreg_subsetreg(list,fromsubsetsize,tosubsetsize,fromsreg,tosreg);
          end;
 
 

+ 18 - 23
compiler/powerpc64/cgcpu.pas

@@ -75,12 +75,9 @@ type
     procedure a_load_reg_reg(list: TAsmList; fromsize, tosize: tcgsize; reg1,
       reg2: tregister); override;
 
-    procedure a_load_subsetreg_reg(list : TAsmList; subsetregsize, subsetsize: tcgsize;
-      startbit: byte; tosize: tcgsize; subsetreg, destreg: tregister); override;
-    procedure a_load_reg_subsetreg(list : TAsmList; fromsize: tcgsize; subsetregsize, 
-      subsetsize: tcgsize; startbit: byte; fromreg, subsetreg: tregister); override;
-    procedure a_load_const_subsetreg(list: TAsmlist; subsetregsize, subsetsize: tcgsize;
-      startbit: byte; a: aint; subsetreg: tregister); override;
+    procedure a_load_subsetreg_reg(list : TAsmList; subsetsize, tosize: tcgsize; const sreg: tsubsetregister; destreg: tregister); override;
+    procedure a_load_reg_subsetreg(list : TAsmList; fromsize, subsetsize: tcgsize; fromreg: tregister; const sreg: tsubsetregister); override;
+    procedure a_load_const_subsetreg(list: TAsmlist; subsetsize: tcgsize; a: aint; const sreg: tsubsetregister); override;
 
     { fpu move instructions }
     procedure a_loadfpu_reg_reg(list: TAsmList; size: tcgsize; reg1, reg2:
@@ -879,52 +876,50 @@ begin
   rg[R_INTREGISTER].add_move_instruction(instr);
 end;
 
-procedure tcgppc.a_load_subsetreg_reg(list : TAsmList; subsetregsize, subsetsize: tcgsize;
-  startbit: byte; tosize: tcgsize; subsetreg, destreg: tregister);
+procedure tcgppc.a_load_subsetreg_reg(list : TAsmList; subsetsize, tosize: tcgsize; const sreg: tsubsetregister; destreg: tregister);
 var
   extrdi_startbit : byte;
 begin
   {$ifdef extdebug}
-  list.concat(tai_comment.create(strpnew('a_load_subsetreg_reg subsetregsize = ' + cgsize2string(subsetregsize) + ' subsetsize = ' + cgsize2string(subsetsize) + ' startbit = ' + intToStr(startbit) + ' tosize = ' + cgsize2string(tosize))));
+  list.concat(tai_comment.create(strpnew('a_load_subsetreg_reg subsetregsize = ' + cgsize2string(sreg.subsetregsize) + ' subsetsize = ' + cgsize2string(subsetsize) + ' startbit = ' + intToStr(sreg.startbit) + ' tosize = ' + cgsize2string(tosize))));
   {$endif}
   { calculate the correct startbit for the extrdi instruction, do the extraction if required and then
     extend the sign correctly. (The latter is actually required only for signed subsets and if that
    subset is not >= the tosize). }
-  extrdi_startbit := 64 - (tcgsize2size[subsetsize]*8 + startbit);
-  if (startbit <> 0) then begin
-    list.concat(taicpu.op_reg_reg_const_const(A_EXTRDI, destreg, subsetreg, tcgsize2size[subsetsize]*8, extrdi_startbit));
-    a_load_reg_reg(list, tcgsize2unsigned[subsetregsize], subsetsize, destreg, destreg);
+  extrdi_startbit := 64 - (sreg.bitlen + sreg.startbit);
+  if (sreg.startbit <> 0) then begin
+    list.concat(taicpu.op_reg_reg_const_const(A_EXTRDI, destreg, sreg.subsetreg, sreg.bitlen, extrdi_startbit));
+    a_load_reg_reg(list, tcgsize2unsigned[sreg.subsetregsize], subsetsize, destreg, destreg);
   end else begin
-    a_load_reg_reg(list, tcgsize2unsigned[subsetregsize], subsetsize, subsetreg, destreg);
+    a_load_reg_reg(list, tcgsize2unsigned[sreg.subsetregsize], subsetsize, sreg.subsetreg, destreg);
   end;
 end;
 
-procedure tcgppc.a_load_reg_subsetreg(list : TAsmList; fromsize: tcgsize; subsetregsize, 
-  subsetsize: tcgsize; startbit: byte; fromreg, subsetreg: tregister);
+procedure tcgppc.a_load_reg_subsetreg(list : TAsmList; fromsize, subsetsize: tcgsize; fromreg: tregister; const sreg: tsubsetregister);
 begin
   {$ifdef extdebug}
-  list.concat(tai_comment.create(strpnew('a_load_reg_subsetreg fromsize = ' + cgsize2string(fromsize) + ' subsetregsize = ' + cgsize2string(subsetregsize) + ' subsetsize = ' + cgsize2string(subsetsize) + ' startbit = ' + IntToStr(startbit))));
+  list.concat(tai_comment.create(strpnew('a_load_reg_subsetreg fromsize = ' + cgsize2string(fromsize) + ' subsetregsize = ' + cgsize2string(sreg.subsetregsize) + ' subsetsize = ' + cgsize2string(subsetsize) + ' startbit = ' + IntToStr(sreg.startbit))));
   {$endif}
   { simply use the INSRDI instruction }
   if (tcgsize2size[subsetsize] <> sizeof(aint)) then
-    list.concat(taicpu.op_reg_reg_const_const(A_INSRDI, subsetreg, fromreg, tcgsize2size[subsetsize]*8, (64 - (startbit + tcgsize2size[subsetsize]*8)) and 63))
+    list.concat(taicpu.op_reg_reg_const_const(A_INSRDI, sreg.subsetreg, fromreg, sreg.bitlen, (64 - (sreg.startbit + sreg.bitlen)) and 63))
   else
-    a_load_reg_reg(list, fromsize, subsetsize, fromreg, subsetreg);
+    a_load_reg_reg(list, fromsize, subsetsize, fromreg, sreg.subsetreg);
 end;
 
-procedure tcgppc.a_load_const_subsetreg(list: TAsmlist; subsetregsize, subsetsize: tcgsize;
-  startbit: byte; a: aint; subsetreg: tregister);
+procedure tcgppc.a_load_const_subsetreg(list: TAsmlist; subsetsize: tcgsize;
+  a: aint; const sreg: tsubsetregister);
 var
   tmpreg : TRegister;
 begin
   {$ifdef extdebug}
-  list.concat(tai_comment.create(strpnew('a_load_const_subsetreg subsetregsize = ' + cgsize2string(subsetregsize) + ' subsetsize = ' + cgsize2string(subsetsize) + ' startbit = ' + intToStr(startbit) + ' a = ' + intToStr(a))));
+  list.concat(tai_comment.create(strpnew('a_load_const_subsetreg subsetregsize = ' + cgsize2string(sreg.subsetregsize) + ' subsetsize = ' + cgsize2string(subsetsize) + ' startbit = ' + intToStr(sreg.startbit) + ' a = ' + intToStr(a))));
   {$endif}
   { loading the constant into the lowest bits of a temp register and then inserting is
     better than loading some usually large constants and do some masking and shifting on ppc64 }
   tmpreg := getintregister(list,subsetsize);
   a_load_const_reg(list,subsetsize,a,tmpreg);
-  a_load_reg_subsetreg(list, subsetsize, subsetregsize, subsetsize, startbit, tmpreg, subsetreg);
+  a_load_reg_subsetreg(list, subsetsize, subsetsize, tmpreg, sreg);
 end;
 
 procedure tcgppc.a_loadfpu_reg_reg(list: TAsmList; size: tcgsize;