Bladeren bron

Signed modulus by 2 on ARM with no division is optimized to a series of instructions instead of calling fpc_mod_longint.
An ASR is removed from signed division by 2.

git-svn-id: trunk@24778 -

Jeppe Johansen 12 jaren geleden
bovenliggende
commit
570b40faed
1 gewijzigde bestanden met toevoegingen van 16 en 2 verwijderingen
  1. 16 2
      compiler/arm/narmmat.pas

+ 16 - 2
compiler/arm/narmmat.pas

@@ -58,7 +58,7 @@ implementation
       symtype,symconst,symtable,
       cgbase,cgobj,hlcgobj,cgutils,
       pass_2,procinfo,
-      ncon,ncnv,ncal,
+      ncon,ncnv,ncal,ninl,
       cpubase,cpuinfo,
       ncgutil,
       nadd,pass_1,symdef;
@@ -99,6 +99,17 @@ implementation
               end;
             left:=nil;
           end
+        else if (nodetype=modn) and
+          (is_signed(left.resultdef)) and
+          (right.nodetype=ordconstn) and
+          (tordconstnode(right).value=2) then
+          begin
+            // result:=(0-(left and 1)) and (1+(sarlongint(left,31) shl 1))
+            result:=caddnode.create(andn,caddnode.create(subn,cordconstnode.create(0,sinttype,false),caddnode.create(andn,left,cordconstnode.create(1,sinttype,false))),
+                                         caddnode.create(addn,cordconstnode.create(1,sinttype,false),
+                                                              cshlshrnode.create(shln,cinlinenode.create(in_sar_x_y,false,ccallparanode.create(cordconstnode.create(31,sinttype,false),ccallparanode.Create(left.getcopy,nil))),cordconstnode.create(1,sinttype,false))));
+            left:=nil;
+          end
         else
           result:=inherited first_moddivint;
       end;
@@ -135,7 +146,10 @@ implementation
                  begin
                     helper1:=cg.getintregister(current_asmdata.CurrAsmList,OS_INT);
                     helper2:=cg.getintregister(current_asmdata.CurrAsmList,OS_INT);
-                    cg.a_op_const_reg_reg(current_asmdata.CurrAsmList,OP_SAR,OS_INT,31,numerator,helper1);
+                    if power = 1 then
+                      cg.a_load_reg_reg(current_asmdata.CurrAsmList,OS_INT,OS_INT,numerator,helper1)
+                    else
+                      cg.a_op_const_reg_reg(current_asmdata.CurrAsmList,OP_SAR,OS_INT,31,numerator,helper1);
                     if current_settings.cputype in cpu_thumb then
                       begin
                         cg.a_op_const_reg(current_asmdata.CurrAsmList,OP_SAR,OS_INT,32-power,helper1);