Browse Source

Optimized support for 32x32 => 64bit multiplications on ARM

This code uses UMULL and SMULL to perform the multiplications, which
take two 32bit source registers and two 32bit destination registers.

git-svn-id: trunk@26346 -
masta 11 years ago
parent
commit
cec633e86e
1 changed files with 28 additions and 0 deletions
  1. 28 0
      compiler/arm/narmadd.pas

+ 28 - 0
compiler/arm/narmadd.pas

@@ -34,8 +34,10 @@ interface
           function  GetResFlags(unsigned:Boolean):TResFlags;
           function  GetResFlags(unsigned:Boolean):TResFlags;
        public
        public
           function pass_1 : tnode;override;
           function pass_1 : tnode;override;
+          function use_generic_mul32to64: boolean; override;
        protected
        protected
           function first_addfloat: tnode; override;
           function first_addfloat: tnode; override;
+          procedure second_addordinal;override;
           procedure second_addfloat;override;
           procedure second_addfloat;override;
           procedure second_cmpfloat;override;
           procedure second_cmpfloat;override;
           procedure second_cmpordinal;override;
           procedure second_cmpordinal;override;
@@ -644,6 +646,32 @@ interface
         location.resflags:=getresflags(unsigned);
         location.resflags:=getresflags(unsigned);
       end;
       end;
 
 
+    const
+      multops: array[boolean] of TAsmOp = (A_SMULL, A_UMULL);
+
+    procedure tarmaddnode.second_addordinal;
+      var
+        unsigned: boolean;
+      begin
+        if (nodetype=muln) and is_64bit(resultdef) then
+          begin
+            pass_left_right;
+            force_reg_left_right(true, false);
+            set_result_location_reg;
+            unsigned:=not(is_signed(left.resultdef)) or
+                      not(is_signed(right.resultdef));
+            current_asmdata.CurrAsmList.Concat(
+              taicpu.op_reg_reg_reg_reg(multops[unsigned], location.register64.reglo, location.register64.reghi,
+                                        left.location.register,right.location.register));
+          end
+        else
+          inherited second_addordinal;
+      end;
+
+    function tarmaddnode.use_generic_mul32to64: boolean;
+      begin
+        result:=false;
+      end;
 begin
 begin
   caddnode:=tarmaddnode;
   caddnode:=tarmaddnode;
 end.
 end.