Explorar o código

* ARM: Implemented floating-point negation and abs() for softfloat using integer instructions. Fixes webtbs/tw4534.pp, and also yields much faster code than existing implementation.
Background: these operations are defined as flipping or clearing the upper bit of number, respectively, and never result in precision loss or raise floating-point exceptions.

git-svn-id: trunk@27411 -

sergei %!s(int64=11) %!d(string=hai) anos
pai
achega
68b97bee5a
Modificáronse 2 ficheiros con 40 adicións e 2 borrados
  1. 18 2
      compiler/arm/narminl.pas
  2. 22 0
      compiler/arm/narmmat.pas

+ 18 - 2
compiler/arm/narminl.pas

@@ -60,7 +60,7 @@ implementation
     uses
       globtype,verbose,globals,
       cpuinfo, defutil,symdef,aasmdata,aasmcpu,
-      cgbase,cgutils,pass_2,
+      cgbase,cgutils,pass_1,pass_2,
       cpubase,ncgutil,cgobj,cgcpu, hlcgobj;
 
 {*****************************************************************************
@@ -96,6 +96,11 @@ implementation
                  location.loc := LOC_MMREGISTER;
                end;
             end;
+          fpu_soft:
+            begin
+              hlcg.location_force_reg(current_asmdata.CurrAsmList,left.location,left.resultdef,left.resultdef,false);
+              location_copy(location,left.location);
+            end
           else
             internalerror(2009111801);
         end;
@@ -106,7 +111,11 @@ implementation
     function tarminlinenode.first_abs_real : tnode;
       begin
         if (cs_fp_emulation in current_settings.moduleswitches) then
-          result:=inherited first_abs_real
+          begin
+            firstpass(left);
+            expectloc:=LOC_REGISTER;
+            first_abs_real:=nil;
+          end
         else
           begin
             case current_settings.fputype of
@@ -245,6 +254,13 @@ implementation
             end;
           fpu_fpv4_s16:
             current_asmdata.CurrAsmList.Concat(setoppostfix(taicpu.op_reg_reg(A_VABS,location.register,left.location.register), PF_F32));
+          fpu_soft:
+            begin
+              if singleprec then
+                cg.a_op_const_reg(current_asmdata.CurrAsmList,OP_AND,OS_32,tcgint($7fffffff),location.register)
+              else
+                cg.a_op_const_reg(current_asmdata.CurrAsmList,OP_AND,OS_32,tcgint($7fffffff),location.registerhi);
+            end
         else
           internalerror(2009111402);
         end;

+ 22 - 0
compiler/arm/narmmat.pas

@@ -356,6 +356,15 @@ implementation
         procname: string[31];
         fdef : tdef;
       begin
+        if (current_settings.fputype=fpu_soft) and
+           (left.resultdef.typ=floatdef) then
+          begin
+            result:=nil;
+            firstpass(left);
+            expectloc:=LOC_REGISTER;
+            exit;
+          end;
+
         if (current_settings.fputype<>fpu_fpv4_s16) or
           (tfloatdef(resultdef).floattype=s32real) then
           exit(inherited pass_1);
@@ -430,6 +439,19 @@ implementation
                 location.register:=cg.getmmregister(current_asmdata.CurrAsmList,location.size);
               current_asmdata.CurrAsmList.concat(setoppostfix(taicpu.op_reg_reg(A_VNEG,
                 location.register,left.location.register), PF_F32));
+            end;
+          fpu_soft:
+            begin
+              hlcg.location_force_reg(current_asmdata.CurrAsmList,left.location,left.resultdef,left.resultdef,false);
+              location:=left.location;
+              case location.size of
+                OS_32:
+                  cg.a_op_const_reg(current_asmdata.CurrAsmList,OP_XOR,OS_32,tcgint($80000000),location.register);
+                OS_64:
+                  cg.a_op_const_reg(current_asmdata.CurrAsmList,OP_XOR,OS_32,tcgint($80000000),location.registerhi);
+              else
+                internalerror(2014033101);
+              end;
             end
           else
             internalerror(2009112602);