Browse Source

+ Xtensa: make use of muluh/mulsh instructions

git-svn-id: trunk@46544 -
florian 5 years ago
parent
commit
31cb670b20
2 changed files with 45 additions and 2 deletions
  1. 3 2
      compiler/xtensa/cpuinfo.pas
  2. 42 0
      compiler/xtensa/ncpuadd.pas

+ 3 - 2
compiler/xtensa/cpuinfo.pas

@@ -137,7 +137,8 @@ Const
       (
         CPUXTENSA_REGWINDOW,
         CPUXTENSA_HAS_SEXT,
-        CPUXTENSA_HAS_BOOLEAN_OPTION
+        CPUXTENSA_HAS_BOOLEAN_OPTION,
+        CPUXTENSA_HAS_MUL32HIGH
       );
 
    tfpuflags =
@@ -151,7 +152,7 @@ Const
      (
        { cpu_none     } [],
        { cpu_lx106    } [],
-       { cpu_lx6      } [CPUXTENSA_REGWINDOW, CPUXTENSA_HAS_SEXT, CPUXTENSA_HAS_BOOLEAN_OPTION]
+       { cpu_lx6      } [CPUXTENSA_REGWINDOW, CPUXTENSA_HAS_SEXT, CPUXTENSA_HAS_BOOLEAN_OPTION, CPUXTENSA_HAS_MUL32HIGH]
      );
 
    fpu_capabilities : array[tfputype] of set of tfpuflags =

+ 42 - 0
compiler/xtensa/ncpuadd.pas

@@ -35,6 +35,8 @@ interface
        protected
          function pass_1 : tnode;override;
          function first_addfloat: tnode;override;
+         function use_generic_mul32to64: boolean;override;
+         procedure second_addordinal;override;
          procedure second_cmpordinal;override;
          procedure second_cmpsmallset;override;
          procedure second_cmp64bit;override;
@@ -61,6 +63,40 @@ interface
                                TCPUAddNode
 *****************************************************************************}
 
+    procedure TCPUAddNode.second_addordinal;
+      var
+        ophigh: tasmop;
+      begin
+        { this is only true, if the CPU supports 32x32 -> 64 bit MUL, see the relevant method }
+        if (nodetype=muln) and is_64bit(resultdef) then
+          begin
+            if not(is_signed(left.resultdef)) or
+               not(is_signed(right.resultdef)) then
+              ophigh:=A_MULUH
+            else
+              ophigh:=A_MULSH;
+
+            pass_left_right;
+
+            if not(left.location.loc in [LOC_CREGISTER,LOC_REGISTER]) then
+              hlcg.location_force_reg(current_asmdata.CurrAsmList,left.location,left.resultdef,left.resultdef,true);
+            if not(right.location.loc in [LOC_CREGISTER,LOC_REGISTER]) then
+              hlcg.location_force_reg(current_asmdata.CurrAsmList,right.location,right.resultdef,right.resultdef,true);
+
+            { initialize the result }
+            location_reset(location,LOC_REGISTER,def_cgsize(resultdef));
+
+            location.register64.reglo:=cg.getintregister(current_asmdata.CurrAsmList,OS_INT);
+            location.register64.reghi:=cg.getintregister(current_asmdata.CurrAsmList,OS_INT);
+
+            current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg_reg(A_MULL,location.register64.reglo,left.location.register,right.location.register));
+            current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg_reg(ophigh,location.register64.reghi,left.location.register,right.location.register));
+          end
+        else
+          Inherited;
+      end;
+
+
    procedure TCPUAddNode.second_cmpsmallset;
       var
         tmpreg : tregister;
@@ -217,6 +253,12 @@ interface
       end;
 
 
+    function TCPUAddNode.use_generic_mul32to64: boolean;
+      begin
+        result:=not(CPUXTENSA_HAS_MUL32HIGH in cpu_capabilities[current_settings.cputype]) or needoverflowcheck;
+      end;
+
+
     procedure TCPUAddNode.second_addfloat;
       var
         op    : TAsmOp;