Browse Source

* 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 years ago
parent
commit
c25aba7592

+ 7 - 3
compiler/cgutils.pas

@@ -61,6 +61,12 @@ unit cgutils;
 {$endif SUPPORT_UNALIGNED}
 {$endif SUPPORT_UNALIGNED}
       end;
       end;
 
 
+      tsubsetregister = record
+        subsetreg : tregister;
+        startbit, bitlen: byte;
+        subsetregsize: tcgsize;
+      end;
+
       tlocation = record
       tlocation = record
          loc  : TCGLoc;
          loc  : TCGLoc;
          size : TCGSize;
          size : TCGSize;
@@ -95,9 +101,7 @@ unit cgutils;
               );
               );
             LOC_SUBSETREG,
             LOC_SUBSETREG,
             LOC_CSUBSETREG : (
             LOC_CSUBSETREG : (
-              subsetreg : tregister;
-              startbit: byte;
-              subsetregsize: tcgsize;
+              sreg: tsubsetregister;
             );
             );
       end;
       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);
              cg.a_load_loc_reg(current_asmdata.CurrAsmList,left.location.size,right.location,left.location.register);
            LOC_SUBSETREG,
            LOC_SUBSETREG,
            LOC_CSUBSETREG :
            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
            else
              internalerror(200501311);
              internalerror(200501311);
          end;
          end;

+ 2 - 3
compiler/ncgld.pas

@@ -613,7 +613,7 @@ implementation
                         left.location.register,mms_movescalar);
                         left.location.register,mms_movescalar);
                     LOC_SUBSETREG,
                     LOC_SUBSETREG,
                     LOC_CSUBSETREG:
                     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
                     else
                       internalerror(200203284);
                       internalerror(200203284);
                   end;
                   end;
@@ -684,8 +684,7 @@ implementation
               LOC_CSUBSETREG:
               LOC_CSUBSETREG:
                 begin
                 begin
                   cg.a_load_subsetreg_loc(current_asmdata.CurrAsmList,
                   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;
                 end;
               LOC_JUMP :
               LOC_JUMP :
                 begin
                 begin

+ 8 - 6
compiler/ncgmem.pas

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

+ 2 - 2
compiler/ncgutil.pas

@@ -293,7 +293,7 @@ implementation
                      LOC_SUBSETREG,LOC_CSUBSETREG:
                      LOC_SUBSETREG,LOC_CSUBSETREG:
                        begin
                        begin
                          tmpreg := cg.getintregister(list,OS_INT);
                          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_cmp_const_reg_label(list,OS_INT,OC_NE,0,tmpreg,current_procinfo.CurrTrueLabel);
                          cg.a_jmp_always(list,current_procinfo.CurrFalseLabel);
                          cg.a_jmp_always(list,current_procinfo.CurrFalseLabel);
                        end;
                        end;
@@ -758,7 +758,7 @@ implementation
           LOC_CSUBSETREG:
           LOC_CSUBSETREG:
             begin
             begin
               tg.GetTemp(list,TCGSize2Size[l.size],tt_normal,r);
               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);
               location_reset(l,LOC_REFERENCE,l.size);
               l.reference:=r;
               l.reference:=r;
             end;
             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_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_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 }
         { fpu move instructions }
         procedure a_loadfpu_reg_reg(list: TAsmList; size: tcgsize; reg1, reg2: tregister); override;
         procedure a_loadfpu_reg_reg(list: TAsmList; size: tcgsize; reg1, reg2: tregister); override;
@@ -555,44 +553,41 @@ const
        end;
        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
        begin
          if (tcgsize2size[subsetsize] <> sizeof(aint)) then
          if (tcgsize2size[subsetsize] <> sizeof(aint)) then
            begin
            begin
              list.concat(taicpu.op_reg_reg_const_const_const(A_RLWINM,destreg,
              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,tcgsize2unsigned[subsetsize],subsetsize,destreg,destreg);
              a_load_reg_reg(list,subsetsize,tosize,destreg,destreg);
              a_load_reg_reg(list,subsetsize,tosize,destreg,destreg);
            end
            end
          else
          else
-           a_load_reg_reg(list,subsetsize,tosize,subsetreg,destreg);
+           a_load_reg_reg(list,subsetsize,tosize,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
        begin
          if ((tcgsize2size[subsetsize]) <> sizeof(aint)) then
          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
          else
-           a_load_reg_reg(list,fromsize,subsetsize,fromreg,subsetreg);
+           a_load_reg_reg(list,fromsize,subsetsize,fromreg,sreg.subsetreg);
        end;
        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
          begin
            if (tcgsize2size[fromsubsetsize] >= tcgsize2size[tosubsetsize]) then
            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
            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;
          end;
 
 
 
 

+ 18 - 23
compiler/powerpc64/cgcpu.pas

@@ -75,12 +75,9 @@ type
     procedure a_load_reg_reg(list: TAsmList; fromsize, tosize: tcgsize; reg1,
     procedure a_load_reg_reg(list: TAsmList; fromsize, tosize: tcgsize; reg1,
       reg2: tregister); override;
       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 }
     { fpu move instructions }
     procedure a_loadfpu_reg_reg(list: TAsmList; size: tcgsize; reg1, reg2:
     procedure a_loadfpu_reg_reg(list: TAsmList; size: tcgsize; reg1, reg2:
@@ -879,52 +876,50 @@ begin
   rg[R_INTREGISTER].add_move_instruction(instr);
   rg[R_INTREGISTER].add_move_instruction(instr);
 end;
 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
 var
   extrdi_startbit : byte;
   extrdi_startbit : byte;
 begin
 begin
   {$ifdef extdebug}
   {$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}
   {$endif}
   { calculate the correct startbit for the extrdi instruction, do the extraction if required and then
   { 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
     extend the sign correctly. (The latter is actually required only for signed subsets and if that
    subset is not >= the tosize). }
    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
   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;
 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
 begin
   {$ifdef extdebug}
   {$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}
   {$endif}
   { simply use the INSRDI instruction }
   { simply use the INSRDI instruction }
   if (tcgsize2size[subsetsize] <> sizeof(aint)) then
   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
   else
-    a_load_reg_reg(list, fromsize, subsetsize, fromreg, subsetreg);
+    a_load_reg_reg(list, fromsize, subsetsize, fromreg, sreg.subsetreg);
 end;
 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
 var
   tmpreg : TRegister;
   tmpreg : TRegister;
 begin
 begin
   {$ifdef extdebug}
   {$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}
   {$endif}
   { loading the constant into the lowest bits of a temp register and then inserting is
   { 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 }
     better than loading some usually large constants and do some masking and shifting on ppc64 }
   tmpreg := getintregister(list,subsetsize);
   tmpreg := getintregister(list,subsetsize);
   a_load_const_reg(list,subsetsize,a,tmpreg);
   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;
 end;
 
 
 procedure tcgppc.a_loadfpu_reg_reg(list: TAsmList; size: tcgsize;
 procedure tcgppc.a_loadfpu_reg_reg(list: TAsmList; size: tcgsize;