Преглед изворни кода

* MIPS: removed specific handling of 32-bit shifts, generic code does the job just well.
* Tweak 64-bit shifts to take advantage of 3-address instructions (i.e. don't operate on same register).

git-svn-id: trunk@26142 -

sergei пре 11 година
родитељ
комит
e16e19b170
1 измењених фајлова са 42 додато и 74 уклоњено
  1. 42 74
      compiler/mips/ncpumat.pas

+ 42 - 74
compiler/mips/ncpumat.pas

@@ -35,8 +35,8 @@ type
     procedure pass_generate_code;override;
   end;
 
-  tMIPSELshlshrnode = class(tshlshrnode)
-    procedure pass_generate_code;override;
+  tMIPSELshlshrnode = class(tcgshlshrnode)
+    procedure second_64bit;override;
     { everything will be handled in pass_2 }
     function first_shlshr64bitint: tnode; override;
   end;
@@ -164,96 +164,65 @@ begin
 end;
 
 
-procedure tMIPSELshlshrnode.pass_generate_code;
+procedure tMIPSELshlshrnode.second_64bit;
 var
   hregister, hreg64hi, hreg64lo: tregister;
   op: topcg;
   shiftval: aword;
+const
+  ops: array [boolean] of topcg = (OP_SHR,OP_SHL);
 begin
   { 64bit without constants need a helper, and is
           already replaced in pass1 }
-  if is_64bit(left.resultdef) and
-    (right.nodetype <> ordconstn) then
+  if (right.nodetype <> ordconstn) then
     internalerror(200405301);
 
-  secondpass(left);
-  secondpass(right);
-  if is_64bit(left.resultdef) then
-  begin
-    location_reset(location, LOC_REGISTER, OS_64);
-
-    { load left operator in a register }
-    hlcg.location_force_reg(current_asmdata.CurrAsmList, left.location, left.resultdef, u64inttype, False);
+  location_reset(location, LOC_REGISTER, def_cgsize(resultdef));
 
+  { load left operator in a register }
+  hlcg.location_force_reg(current_asmdata.CurrAsmList, left.location, left.resultdef, resultdef, true);
+  hreg64hi := left.location.register64.reghi;
+  hreg64lo := left.location.register64.reglo;
 
-    hreg64hi := left.location.register64.reghi;
-    hreg64lo := left.location.register64.reglo;
-
-    shiftval := tordconstnode(right).Value.svalue and 63;
-    if shiftval > 31 then
+  shiftval := tordconstnode(right).Value.svalue and 63;
+  op := ops[nodetype=shln];
+  if shiftval > 31 then
+  begin
+    if nodetype = shln then
     begin
-      if nodetype = shln then
-      begin
-        cg.a_load_const_reg(current_asmdata.CurrAsmList, OS_32, 0, hreg64hi);
-        if (shiftval and 31) <> 0 then
-          cg.a_op_const_reg_reg(current_asmdata.CurrAsmList, OP_SHL, OS_32, shiftval and 31, hreg64lo, hreg64lo);
-      end
-      else
-      begin
-        cg.a_load_const_reg(current_asmdata.CurrAsmList, OS_32, 0, hreg64lo);
-        if (shiftval and 31) <> 0 then
-          cg.a_op_const_reg_reg(current_asmdata.CurrAsmList, OP_SHR, OS_32, shiftval and 31, hreg64hi, hreg64hi);
-      end;
-      location.register64.reglo := hreg64hi;
-      location.register64.reghi := hreg64lo;
+      location.register64.reglo:=NR_R0;
+      location.register64.reghi:=cg.GetIntRegister(current_asmdata.CurrAsmList,OS_32);
+      { if shiftval and 31 = 0, it will optimize to MOVE }
+      cg.a_op_const_reg_reg(current_asmdata.CurrAsmList, OP_SHL, OS_32, shiftval and 31, hreg64lo, location.register64.reghi);
     end
     else
     begin
-      if shiftval <> 0 then
-        begin
-          hregister := cg.getintregister(current_asmdata.CurrAsmList, OS_32);
-          if nodetype = shln then
-            begin
-              cg.a_op_const_reg_reg(current_asmdata.CurrAsmList, OP_SHR, OS_32, 32 - shiftval, hreg64lo, hregister);
-              cg.a_op_const_reg_reg(current_asmdata.CurrAsmList, OP_SHL, OS_32, shiftval, hreg64hi, hreg64hi);
-              cg.a_op_reg_reg_reg(current_asmdata.CurrAsmList, OP_OR, OS_32, hregister, hreg64hi, hreg64hi);
-              cg.a_op_const_reg_reg(current_asmdata.CurrAsmList, OP_SHL, OS_32, shiftval, hreg64lo, hreg64lo);
-            end
-          else
-            begin
-              cg.a_op_const_reg_reg(current_asmdata.CurrAsmList, OP_SHL, OS_32, 32 - shiftval, hreg64hi, hregister);
-              cg.a_op_const_reg_reg(current_asmdata.CurrAsmList, OP_SHR, OS_32, shiftval, hreg64lo, hreg64lo);
-              cg.a_op_reg_reg_reg(current_asmdata.CurrAsmList, OP_OR, OS_32, hregister, hreg64lo, hreg64lo);
-              cg.a_op_const_reg_reg(current_asmdata.CurrAsmList, OP_SHR, OS_32, shiftval, hreg64hi, hreg64hi);
-            end;
-        end;
-      location.register64.reghi := hreg64hi;
-      location.register64.reglo := hreg64lo;
+      location.register64.reghi:=NR_R0;
+      location.register64.reglo:=cg.GetIntRegister(current_asmdata.CurrAsmList,OS_32);
+      cg.a_op_const_reg_reg(current_asmdata.CurrAsmList, OP_SHR, OS_32, shiftval and 31, hreg64hi, location.register64.reglo);
     end;
   end
   else
   begin
-    { load left operators in a register }
-    hlcg.location_force_reg(current_asmdata.CurrAsmList, left.location, left.resultdef, left.resultdef, True);
-    location_reset(location,LOC_REGISTER,def_cgsize(resultdef));
-    location.register:=cg.GetIntRegister(current_asmdata.CurrAsmList,OS_INT);
-    { determine operator }
-    if nodetype = shln then
-      op := OP_SHL
-    else
-      op := OP_SHR;
-    { shifting by a constant directly coded: }
-    if (right.nodetype = ordconstn) then
-    begin
-      if tordconstnode(right).Value.svalue and 31 <> 0 then
-        cg.a_op_const_reg_reg(current_asmdata.CurrAsmList, op, OS_32, tordconstnode(right).Value.svalue and 31, left.location.register, location.register);
-    end
-    else
-    begin
-      { load shift count in a register if necessary }
-      hlcg.location_force_reg(current_asmdata.CurrAsmList, right.location, right.resultdef, right.resultdef, True);
-      cg.a_op_reg_reg_reg(current_asmdata.CurrAsmList, op, OS_32, right.location.Register, left.location.register, location.register);
-    end;
+    location.register64.reglo:=cg.GetIntRegister(current_asmdata.CurrAsmList,OS_32);
+    location.register64.reghi:=cg.GetIntRegister(current_asmdata.CurrAsmList,OS_32);
+    hregister := cg.getintregister(current_asmdata.CurrAsmList, OS_32);
+
+    cg.a_op_const_reg_reg(current_asmdata.CurrAsmList, op, OS_32, shiftval, hreg64hi, location.register64.reghi);
+    cg.a_op_const_reg_reg(current_asmdata.CurrAsmList, op, OS_32, shiftval, hreg64lo, location.register64.reglo);
+    if shiftval <> 0 then
+      begin
+        if nodetype = shln then
+          begin
+            cg.a_op_const_reg_reg(current_asmdata.CurrAsmList, OP_SHR, OS_32, 32-shiftval, hreg64lo, hregister);
+            cg.a_op_reg_reg_reg(current_asmdata.CurrAsmList, OP_OR, OS_32, hregister, location.register64.reghi, location.register64.reghi);
+          end
+        else
+          begin
+            cg.a_op_const_reg_reg(current_asmdata.CurrAsmList, OP_SHL, OS_32, 32-shiftval, hreg64hi, hregister);
+            cg.a_op_reg_reg_reg(current_asmdata.CurrAsmList, OP_OR, OS_32, hregister, location.register64.reglo, location.register64.reglo);
+          end;
+      end;
   end;
 end;
 
@@ -266,7 +235,6 @@ procedure tMIPSELnotnode.second_boolean;
 var
   hl: tasmlabel;
   tmpreg : TRegister;
-  r64: TRegister64;
 begin
   { if the location is LOC_JUMP, we do the secondpass after the
           labels are allocated