소스 검색

Better Code generation for SAR/ROR/ROL inline nodes

The old code forced dst and src to be the same, which is highly x86
specific and creates bad register utilization on other architectures
like arm.

The new version will use more imaginary registers, allowing the register
allocator to do a better job.

I've merged second_sar and second_rox into a single procedure
second_rox_sar because they were very similar.

git-svn-id: trunk@21809 -
masta 13 년 전
부모
커밋
bba75a079c
1개의 변경된 파일28개의 추가작업 그리고 60개의 파일을 삭제
  1. 28 60
      compiler/ncginl.pas

+ 28 - 60
compiler/ncginl.pas

@@ -54,8 +54,7 @@ interface
           procedure second_round_real; virtual;
           procedure second_round_real; virtual;
           procedure second_trunc_real; virtual;
           procedure second_trunc_real; virtual;
           procedure second_abs_long; virtual;
           procedure second_abs_long; virtual;
-          procedure second_rox; virtual;
-          procedure second_sar; virtual;
+          procedure second_rox_sar; virtual;
           procedure second_bsfbsr; virtual;
           procedure second_bsfbsr; virtual;
           procedure second_new; virtual;
           procedure second_new; virtual;
           procedure second_setlength; virtual; abstract;
           procedure second_setlength; virtual; abstract;
@@ -168,11 +167,10 @@ implementation
             in_rol_x,
             in_rol_x,
             in_rol_x_y,
             in_rol_x_y,
             in_ror_x,
             in_ror_x,
-            in_ror_x_y:
-              second_rox;
+            in_ror_x_y,
             in_sar_x,
             in_sar_x,
             in_sar_x_y:
             in_sar_x_y:
-              second_sar;
+              second_rox_sar;
             in_bsf_x,
             in_bsf_x,
             in_bsr_x:
             in_bsr_x:
                second_BsfBsr;
                second_BsfBsr;
@@ -721,10 +719,9 @@ implementation
       end;
       end;
 
 
 
 
-    procedure tcginlinenode.second_rox;
+    procedure tcginlinenode.second_rox_sar;
       var
       var
         op : topcg;
         op : topcg;
-        {hcountreg : tregister;}
         op1,op2 : tnode;
         op1,op2 : tnode;
       begin
       begin
         { one or two parameters? }
         { one or two parameters? }
@@ -733,13 +730,15 @@ implementation
           begin
           begin
             op1:=tcallparanode(tcallparanode(left).right).left;
             op1:=tcallparanode(tcallparanode(left).right).left;
             op2:=tcallparanode(left).left;
             op2:=tcallparanode(left).left;
+            secondpass(op2);
           end
           end
         else
         else
-          op1:=left;
+          begin
+            op1:=left;
+            op2:=nil;
+          end;
 
 
         secondpass(op1);
         secondpass(op1);
-        { load left operator in a register }
-        location_copy(location,op1.location);
         case inlinenumber of
         case inlinenumber of
           in_ror_x,
           in_ror_x,
           in_ror_x_y:
           in_ror_x_y:
@@ -747,66 +746,35 @@ implementation
           in_rol_x,
           in_rol_x,
           in_rol_x_y:
           in_rol_x_y:
             op:=OP_ROL;
             op:=OP_ROL;
+          in_sar_x,
+          in_sar_x_y:
+            op:=OP_SAR;
         end;
         end;
-        hlcg.location_force_reg(current_asmdata.CurrAsmList,location,op1.resultdef,resultdef,false);
 
 
-        if (left.nodetype=callparan) and
-           assigned(tcallparanode(left).right) then
+        hlcg.location_force_reg(current_asmdata.CurrAsmList,op1.location,op1.resultdef,resultdef,true);
+
+        location_reset(location,LOC_REGISTER,def_cgsize(resultdef));
+        location.register:=hlcg.getintregister(current_asmdata.CurrAsmList,resultdef);
+
+        if assigned(op2) then
           begin
           begin
-             secondpass(op2);
              { rotating by a constant directly coded: }
              { rotating by a constant directly coded: }
              if op2.nodetype=ordconstn then
              if op2.nodetype=ordconstn then
-               cg.a_op_const_reg(current_asmdata.CurrAsmList,op,location.size,
-                 tordconstnode(op2).value.uvalue and (resultdef.size*8-1),location.register)
+               hlcg.a_op_const_reg_reg(current_asmdata.CurrAsmList,op,resultdef,
+                 tordconstnode(op2).value.uvalue and (resultdef.size*8-1),
+                 op1.location.register, location.register)
              else
              else
                begin
                begin
-                 hlcg.location_force_reg(current_asmdata.CurrAsmList,op2.location,op2.resultdef,resultdef,false);
-                 { do modulo 2 operation }
-                 cg.a_op_reg_reg(current_asmdata.CurrAsmList,op,location.size,op2.location.register,location.register);
+                 hlcg.location_force_reg(current_asmdata.CurrAsmList,op2.location,
+                                         op2.resultdef,resultdef,true);
+                 hlcg.a_op_reg_reg_reg(current_asmdata.CurrAsmList,op,resultdef,
+                                       op2.location.register,op1.location.register,
+                                       location.register);
                end;
                end;
           end
           end
         else
         else
-          cg.a_op_const_reg(current_asmdata.CurrAsmList,op,location.size,1,location.register);
-      end;
-
-
-    procedure tcginlinenode.second_sar;
-      var
-        {hcountreg : tregister;}
-        op1,op2 : tnode;
-      begin
-        if (left.nodetype=callparan) and
-           assigned(tcallparanode(left).right) then
-          begin
-            op1:=tcallparanode(tcallparanode(left).right).left;
-            op2:=tcallparanode(left).left;
-          end
-        else
-          begin
-            op1:=left;
-            op2:=nil;
-          end;
-        secondpass(op1);
-        { load left operator in a register }
-        location_copy(location,op1.location);
-
-        hlcg.location_force_reg(current_asmdata.CurrAsmList,location,op1.resultdef,resultdef,false);
-
-        if not(assigned(op2)) then
-          hlcg.a_op_const_reg(current_asmdata.CurrAsmList,OP_SAR,resultdef,1,location.register)
-        else
-          begin
-            secondpass(op2);
-            { shifting by a constant directly coded: }
-            if op2.nodetype=ordconstn then
-              hlcg.a_op_const_reg(current_asmdata.CurrAsmList,OP_SAR,resultdef,
-                                  tordconstnode(op2).value.uvalue and (resultdef.size*8-1),location.register)
-            else
-              begin
-                hlcg.location_force_reg(current_asmdata.CurrAsmList,op2.location,op2.resultdef,resultdef,false);
-                hlcg.a_op_reg_reg(current_asmdata.CurrAsmList,OP_SAR,resultdef,op2.location.register,location.register);
-             end;
-          end;
+          hlcg.a_op_const_reg_reg(current_asmdata.CurrAsmList,op,resultdef,1,
+                                  op1.location.register,location.register);
       end;
       end;