Browse Source

More consolidation of OP_SHL/SHR/ROR/SAR in ARM CodeGen

This removes the duplications in a_op_reg_reg_reg_checkoverflow.
OP_ROL stays seperate because it needs some special treatment again.

The code for OP_ROL was changed, previously it generated:
mov tempreg, #32
sub src1, tempreg, src1
mov dst, src2, ror src1

This would trash src1, which MIGHT be a problem, but i'm not totally
sure. But the mov/sub was replaced with rsb, so the new code looks like
this.

rsb tempreg, src1, #32
mov dst, src2, ror tempreg

If src1 gets freed afterwards the regallocator should be able to change
that into:

rsb src1, src1, #32
mov dst, src2, ror src1

git-svn-id: trunk@21804 -
masta 13 years ago
parent
commit
dbf0404fb0
1 changed files with 20 additions and 39 deletions
  1. 20 39
      compiler/arm/cgcpu.pas

+ 20 - 39
compiler/arm/cgcpu.pas

@@ -635,6 +635,17 @@ unit cgcpu;
         a_op_reg_reg_reg_checkoverflow(list,op,size,src1,src2,dst,false,ovloc);
         a_op_reg_reg_reg_checkoverflow(list,op,size,src1,src2,dst,false,ovloc);
       end;
       end;
 
 
+    function opshift2shiftmode(op: TOpCg): tshiftmode;
+      begin
+        case op of
+          OP_SHL: Result:=SM_LSL;
+          OP_SHR: Result:=SM_LSR;
+          OP_ROR: Result:=SM_ROR;
+          OP_ROL: Result:=SM_ROR;
+          OP_SAR: Result:=SM_ASR;
+          else internalerror(2012070501);
+        end
+      end;
 
 
     procedure tcgarm.a_op_const_reg_reg_checkoverflow(list: TAsmList; op: TOpCg; size: tcgsize; a: tcgint; src, dst: tregister;setflags : boolean;var ovloc : tlocation);
     procedure tcgarm.a_op_const_reg_reg_checkoverflow(list: TAsmList; op: TOpCg; size: tcgsize; a: tcgint; src, dst: tregister;setflags : boolean;var ovloc : tlocation);
       var
       var
@@ -644,17 +655,6 @@ unit cgcpu;
         l1 : longint;
         l1 : longint;
         imm1, imm2: DWord;
         imm1, imm2: DWord;
 
 
-      function opshift2shiftmode(op: TOpCg): tshiftmode;
-        begin
-          case op of
-            OP_SHL: Result:=SM_LSL;
-            OP_SHR: Result:=SM_LSR;
-            OP_ROR: Result:=SM_ROR;
-            OP_ROL: Result:=SM_ROR;
-            OP_SAR: Result:=SM_ASR;
-            else internalerror(2012070501);
-          end
-        end;
 
 
       begin
       begin
         ovloc.loc:=LOC_VOID;
         ovloc.loc:=LOC_VOID;
@@ -794,25 +794,16 @@ unit cgcpu;
           OP_NEG,OP_NOT,
           OP_NEG,OP_NOT,
           OP_DIV,OP_IDIV:
           OP_DIV,OP_IDIV:
             internalerror(200308281);
             internalerror(200308281);
-          OP_SHL:
-            begin
-              shifterop_reset(so);
-              so.rs:=src1;
-              so.shiftmode:=SM_LSL;
-              list.concat(taicpu.op_reg_reg_shifterop(A_MOV,dst,src2,so));
-            end;
-          OP_SHR:
-            begin
-              shifterop_reset(so);
-              so.rs:=src1;
-              so.shiftmode:=SM_LSR;
-              list.concat(taicpu.op_reg_reg_shifterop(A_MOV,dst,src2,so));
-            end;
-          OP_SAR:
+          OP_SHL,
+          OP_SHR,
+          OP_SAR,
+          OP_ROR:
             begin
             begin
+              if (op = OP_ROR) and not(size in [OS_32,OS_S32]) then
+                internalerror(2008072801);
               shifterop_reset(so);
               shifterop_reset(so);
               so.rs:=src1;
               so.rs:=src1;
-              so.shiftmode:=SM_ASR;
+              so.shiftmode:=opshift2shiftmode(op);
               list.concat(taicpu.op_reg_reg_shifterop(A_MOV,dst,src2,so));
               list.concat(taicpu.op_reg_reg_shifterop(A_MOV,dst,src2,so));
             end;
             end;
           OP_ROL:
           OP_ROL:
@@ -821,19 +812,9 @@ unit cgcpu;
                 internalerror(2008072801);
                 internalerror(2008072801);
               { simulate ROL by ror'ing 32-value }
               { simulate ROL by ror'ing 32-value }
               tmpreg:=getintregister(list,OS_32);
               tmpreg:=getintregister(list,OS_32);
-              list.concat(taicpu.op_reg_const(A_MOV,tmpreg,32));
-              list.concat(taicpu.op_reg_reg_reg(A_SUB,src1,tmpreg,src1));
-              shifterop_reset(so);
-              so.rs:=src1;
-              so.shiftmode:=SM_ROR;
-              list.concat(taicpu.op_reg_reg_shifterop(A_MOV,dst,src2,so));
-            end;
-          OP_ROR:
-            begin
-              if not(size in [OS_32,OS_S32]) then
-                internalerror(2008072802);
+              list.concat(taicpu.op_reg_reg_const(A_RSB,tmpreg,src1, 32));
               shifterop_reset(so);
               shifterop_reset(so);
-              so.rs:=src1;
+              so.rs:=tmpreg;
               so.shiftmode:=SM_ROR;
               so.shiftmode:=SM_ROR;
               list.concat(taicpu.op_reg_reg_shifterop(A_MOV,dst,src2,so));
               list.concat(taicpu.op_reg_reg_shifterop(A_MOV,dst,src2,so));
             end;
             end;