Bladeren bron

* fixed some alignment trouble

florian 20 jaren geleden
bovenliggende
commit
b44f17099c
2 gewijzigde bestanden met toevoegingen van 169 en 92 verwijderingen
  1. 7 3
      compiler/ncgld.pas
  2. 162 89
      compiler/sparc/cgcpu.pas

+ 7 - 3
compiler/ncgld.pas

@@ -594,8 +594,9 @@ implementation
 {$warning HACK: unaligned test, maybe remove all unaligned locations (array of char) from the compiler}
                         { Use unaligned copy when the offset is not aligned }
                         len:=left.resulttype.def.size;
-                        if (right.location.reference.offset mod sizeof(aint)<>0) and
-                           (len>sizeof(aint)) then
+                        if ((right.location.reference.offset mod sizeof(aint)<>0) or
+                            (left.location.reference.offset mod sizeof(aint)<>0)) and
+                           (len>=sizeof(aint)) then
                           cg.g_concatcopy_unaligned(exprasmlist,right.location.reference,left.location.reference,len)
                         else
                           cg.g_concatcopy(exprasmlist,right.location.reference,left.location.reference,len);
@@ -952,7 +953,10 @@ begin
 end.
 {
   $Log$
-  Revision 1.133  2004-11-29 17:32:56  peter
+  Revision 1.134  2004-12-18 15:48:27  florian
+    * fixed some alignment trouble
+
+  Revision 1.133  2004/11/29 17:32:56  peter
     * prevent some IEs with delphi methodpointers
 
   Revision 1.132  2004/11/09 17:26:47  peter

+ 162 - 89
compiler/sparc/cgcpu.pas

@@ -88,6 +88,7 @@ interface
         procedure g_save_standard_registers(list : taasmoutput);override;
         procedure g_concatcopy(list : taasmoutput;const source,dest : treference;len : aint);override;
         procedure g_concatcopy_unaligned(list : taasmoutput;const source,dest : treference;len : aint);override;
+        procedure g_concatcopy_move(list : taasmoutput;const source,dest : treference;len : aint);
       end;
 
       TCg64Sparc=class(tcg64f32)
@@ -975,94 +976,7 @@ implementation
 
     { ************* concatcopy ************ }
 
-    procedure TCgSparc.g_concatcopy(list:taasmoutput;const source,dest:treference;len:aint);
-      var
-        tmpreg1,
-        hreg,
-        countreg: TRegister;
-        src, dst: TReference;
-        lab: tasmlabel;
-        count, count2: aint;
-      begin
-        if len>high(longint) then
-          internalerror(2002072704);
-        reference_reset(src);
-        reference_reset(dst);
-        { load the address of source into src.base }
-        src.base:=GetAddressRegister(list);
-        a_loadaddr_ref_reg(list,source,src.base);
-        { load the address of dest into dst.base }
-        dst.base:=GetAddressRegister(list);
-        a_loadaddr_ref_reg(list,dest,dst.base);
-        { generate a loop }
-        count:=len div 4;
-        if count>4 then
-          begin
-            { the offsets are zero after the a_loadaddress_ref_reg and just }
-            { have to be set to 8. I put an Inc there so debugging may be   }
-            { easier (should offset be different from zero here, it will be }
-            { easy to notice in the generated assembler                     }
-            countreg:=GetIntRegister(list,OS_INT);
-            tmpreg1:=GetIntRegister(list,OS_INT);
-            a_load_const_reg(list,OS_INT,count,countreg);
-            { explicitely allocate R_O0 since it can be used safely here }
-            { (for holding date that's being copied)                    }
-            objectlibrary.getlabel(lab);
-            a_label(list, lab);
-            list.concat(taicpu.op_ref_reg(A_LD,src,tmpreg1));
-            list.concat(taicpu.op_reg_ref(A_ST,tmpreg1,dst));
-            list.concat(taicpu.op_reg_const_reg(A_ADD,src.base,4,src.base));
-            list.concat(taicpu.op_reg_const_reg(A_ADD,dst.base,4,dst.base));
-            list.concat(taicpu.op_reg_const_reg(A_SUBcc,countreg,1,countreg));
-            a_jmp_cond(list,OC_NE,lab);
-            list.concat(taicpu.op_none(A_NOP));
-            { keep the registers alive }
-            list.concat(taicpu.op_reg_reg(A_MOV,countreg,countreg));
-            list.concat(taicpu.op_reg_reg(A_MOV,src.base,src.base));
-            list.concat(taicpu.op_reg_reg(A_MOV,dst.base,dst.base));
-            len := len mod 4;
-          end;
-        { unrolled loop }
-        count:=len div 4;
-        if count>0 then
-          begin
-            tmpreg1:=GetIntRegister(list,OS_INT);
-            for count2 := 1 to count do
-              begin
-                list.concat(taicpu.op_ref_reg(A_LD,src,tmpreg1));
-                list.concat(taicpu.op_reg_ref(A_ST,tmpreg1,dst));
-                inc(src.offset,4);
-                inc(dst.offset,4);
-              end;
-            len := len mod 4;
-          end;
-        if (len and 4) <> 0 then
-          begin
-            hreg:=GetIntRegister(list,OS_INT);
-            a_load_ref_reg(list,OS_32,OS_32,src,hreg);
-            a_load_reg_ref(list,OS_32,OS_32,hreg,dst);
-            inc(src.offset,4);
-            inc(dst.offset,4);
-          end;
-        { copy the leftovers }
-        if (len and 2) <> 0 then
-          begin
-            hreg:=GetIntRegister(list,OS_INT);
-            a_load_ref_reg(list,OS_16,OS_16,src,hreg);
-            a_load_reg_ref(list,OS_16,OS_16,hreg,dst);
-            inc(src.offset,2);
-            inc(dst.offset,2);
-          end;
-        if (len and 1) <> 0 then
-          begin
-            hreg:=GetIntRegister(list,OS_INT);
-            a_load_ref_reg(list,OS_8,OS_8,src,hreg);
-            a_load_reg_ref(list,OS_8,OS_8,hreg,dst);
-          end;
-      end;
-
-
-    procedure tcgsparc.g_concatcopy_unaligned(list : taasmoutput;const source,dest : treference;len : aint);
+    procedure tcgsparc.g_concatcopy_move(list : taasmoutput;const source,dest : treference;len : aint);
       var
         paraloc1,paraloc2,paraloc3 : TCGPara;
       begin
@@ -1091,6 +1005,162 @@ implementation
         paraloc1.done;
       end;
 
+
+    procedure TCgSparc.g_concatcopy(list:taasmoutput;const source,dest:treference;len:aint);
+      var
+        tmpreg1,
+        hreg,
+        countreg: TRegister;
+        src, dst: TReference;
+        lab: tasmlabel;
+        count, count2: aint;
+      begin
+        if len>high(longint) then
+          internalerror(2002072704);
+        { anybody wants to determine a good value here :)? }
+        if len>100 then
+          g_concatcopy_move(list,source,dest,len)
+        else
+          begin
+            reference_reset(src);
+            reference_reset(dst);
+            { load the address of source into src.base }
+            src.base:=GetAddressRegister(list);
+            a_loadaddr_ref_reg(list,source,src.base);
+            { load the address of dest into dst.base }
+            dst.base:=GetAddressRegister(list);
+            a_loadaddr_ref_reg(list,dest,dst.base);
+            { generate a loop }
+            count:=len div 4;
+            if count>4 then
+              begin
+                { the offsets are zero after the a_loadaddress_ref_reg and just }
+                { have to be set to 8. I put an Inc there so debugging may be   }
+                { easier (should offset be different from zero here, it will be }
+                { easy to notice in the generated assembler                     }
+                countreg:=GetIntRegister(list,OS_INT);
+                tmpreg1:=GetIntRegister(list,OS_INT);
+                a_load_const_reg(list,OS_INT,count,countreg);
+                { explicitely allocate R_O0 since it can be used safely here }
+                { (for holding date that's being copied)                    }
+                objectlibrary.getlabel(lab);
+                a_label(list, lab);
+                list.concat(taicpu.op_ref_reg(A_LD,src,tmpreg1));
+                list.concat(taicpu.op_reg_ref(A_ST,tmpreg1,dst));
+                list.concat(taicpu.op_reg_const_reg(A_ADD,src.base,4,src.base));
+                list.concat(taicpu.op_reg_const_reg(A_ADD,dst.base,4,dst.base));
+                list.concat(taicpu.op_reg_const_reg(A_SUBcc,countreg,1,countreg));
+                a_jmp_cond(list,OC_NE,lab);
+                list.concat(taicpu.op_none(A_NOP));
+                { keep the registers alive }
+                list.concat(taicpu.op_reg_reg(A_MOV,countreg,countreg));
+                list.concat(taicpu.op_reg_reg(A_MOV,src.base,src.base));
+                list.concat(taicpu.op_reg_reg(A_MOV,dst.base,dst.base));
+                len := len mod 4;
+              end;
+            { unrolled loop }
+            count:=len div 4;
+            if count>0 then
+              begin
+                tmpreg1:=GetIntRegister(list,OS_INT);
+                for count2 := 1 to count do
+                  begin
+                    list.concat(taicpu.op_ref_reg(A_LD,src,tmpreg1));
+                    list.concat(taicpu.op_reg_ref(A_ST,tmpreg1,dst));
+                    inc(src.offset,4);
+                    inc(dst.offset,4);
+                  end;
+                len := len mod 4;
+              end;
+            if (len and 4) <> 0 then
+              begin
+                hreg:=GetIntRegister(list,OS_INT);
+                a_load_ref_reg(list,OS_32,OS_32,src,hreg);
+                a_load_reg_ref(list,OS_32,OS_32,hreg,dst);
+                inc(src.offset,4);
+                inc(dst.offset,4);
+              end;
+            { copy the leftovers }
+            if (len and 2) <> 0 then
+              begin
+                hreg:=GetIntRegister(list,OS_INT);
+                a_load_ref_reg(list,OS_16,OS_16,src,hreg);
+                a_load_reg_ref(list,OS_16,OS_16,hreg,dst);
+                inc(src.offset,2);
+                inc(dst.offset,2);
+              end;
+            if (len and 1) <> 0 then
+              begin
+                hreg:=GetIntRegister(list,OS_INT);
+                a_load_ref_reg(list,OS_8,OS_8,src,hreg);
+                a_load_reg_ref(list,OS_8,OS_8,hreg,dst);
+              end;
+          end;
+      end;
+
+
+    procedure tcgsparc.g_concatcopy_unaligned(list : taasmoutput;const source,dest : treference;len : aint);
+      var
+        src, dst: TReference;
+        tmpreg1,
+        countreg: TRegister;
+        i : aint;
+        lab: tasmlabel;
+      begin
+        if len>31 then
+          g_concatcopy_move(list,source,dest,len)
+        else
+          begin
+            reference_reset(src);
+            reference_reset(dst);
+            { load the address of source into src.base }
+            src.base:=GetAddressRegister(list);
+            a_loadaddr_ref_reg(list,source,src.base);
+            { load the address of dest into dst.base }
+            dst.base:=GetAddressRegister(list);
+            a_loadaddr_ref_reg(list,dest,dst.base);
+            { generate a loop }
+            if len>4 then
+              begin
+                { the offsets are zero after the a_loadaddress_ref_reg and just }
+                { have to be set to 8. I put an Inc there so debugging may be   }
+                { easier (should offset be different from zero here, it will be }
+                { easy to notice in the generated assembler                     }
+                countreg:=GetIntRegister(list,OS_INT);
+                tmpreg1:=GetIntRegister(list,OS_INT);
+                a_load_const_reg(list,OS_INT,len,countreg);
+                { explicitely allocate R_O0 since it can be used safely here }
+                { (for holding date that's being copied)                    }
+                objectlibrary.getlabel(lab);
+                a_label(list, lab);
+                list.concat(taicpu.op_ref_reg(A_LDUB,src,tmpreg1));
+                list.concat(taicpu.op_reg_ref(A_STB,tmpreg1,dst));
+                list.concat(taicpu.op_reg_const_reg(A_ADD,src.base,1,src.base));
+                list.concat(taicpu.op_reg_const_reg(A_ADD,dst.base,1,dst.base));
+                list.concat(taicpu.op_reg_const_reg(A_SUBcc,countreg,1,countreg));
+                a_jmp_cond(list,OC_NE,lab);
+                list.concat(taicpu.op_none(A_NOP));
+                { keep the registers alive }
+                list.concat(taicpu.op_reg_reg(A_MOV,countreg,countreg));
+                list.concat(taicpu.op_reg_reg(A_MOV,src.base,src.base));
+                list.concat(taicpu.op_reg_reg(A_MOV,dst.base,dst.base));
+              end
+            else
+              begin
+                { unrolled loop }
+                tmpreg1:=GetIntRegister(list,OS_INT);
+                for i:=1 to len do
+                  begin
+                    list.concat(taicpu.op_ref_reg(A_LDUB,src,tmpreg1));
+                    list.concat(taicpu.op_reg_ref(A_STB,tmpreg1,dst));
+                    inc(src.offset);
+                    inc(dst.offset);
+                  end;
+              end;
+          end;
+      end;
+
+
 {****************************************************************************
                                TCG64Sparc
 ****************************************************************************}
@@ -1245,7 +1315,10 @@ begin
 end.
 {
   $Log$
-  Revision 1.98  2004-10-31 21:45:03  peter
+  Revision 1.99  2004-12-18 15:48:06  florian
+    * fixed some alignment trouble
+
+  Revision 1.98  2004/10/31 21:45:03  peter
     * generic tlocation
     * move tlocation to cgutils