Ver código fonte

+ fast and branchless implementation of abs(int64) for i386

git-svn-id: trunk@37169 -
nickysn 8 anos atrás
pai
commit
aefa317474
2 arquivos alterados com 24 adições e 2 exclusões
  1. 22 0
      compiler/i386/n386inl.pas
  2. 2 2
      compiler/options.pas

+ 22 - 0
compiler/i386/n386inl.pas

@@ -33,6 +33,7 @@ interface
        public
          function first_sar: tnode; override;
          procedure second_rox_sar; override;
+         procedure second_abs_long; override;
        end;
 
 implementation
@@ -121,6 +122,27 @@ implementation
     end;
 
 
+  procedure ti386inlinenode.second_abs_long;
+    begin
+      if is_64bitint(left.resultdef) then
+        begin
+          secondpass(left);
+          hlcg.location_force_reg(current_asmdata.CurrAsmList,left.location,left.resultdef,left.resultdef,false);
+          location:=left.location;
+          location.register64.reglo:=cg.getintregister(current_asmdata.CurrAsmList,OS_32);
+          location.register64.reghi:=cg.getintregister(current_asmdata.CurrAsmList,OS_32);
+          cg64.a_load64_reg_reg(current_asmdata.CurrAsmList,left.location.register64,location.register64);
+          cg.a_op_const_reg(current_asmdata.CurrAsmList,OP_SAR,OS_32,31,left.location.register64.reghi);
+          cg.a_op_reg_reg(current_asmdata.CurrAsmList,OP_XOR,OS_32,left.location.register64.reghi,location.register64.reglo);
+          cg.a_op_reg_reg(current_asmdata.CurrAsmList,OP_XOR,OS_32,left.location.register64.reghi,location.register64.reghi);
+          emit_reg_reg(A_SUB,S_L,left.location.register64.reghi,location.register64.reglo);
+          emit_reg_reg(A_SBB,S_L,left.location.register64.reghi,location.register64.reghi);
+        end
+      else
+        inherited second_abs_long;
+    end;
+
+
 begin
    cinlinenode:=ti386inlinenode;
 end.

+ 2 - 2
compiler/options.pas

@@ -3401,9 +3401,9 @@ begin
 {$endif i8086 or avr}
 { abs(long) is handled internally on all CPUs }
   def_system_macro('FPC_HAS_INTERNAL_ABS_LONG');
-{$if defined(x86_64) or defined(powerpc64) or defined(cpuaarch64)}
+{$if defined(i386) or defined(x86_64) or defined(powerpc64) or defined(cpuaarch64)}
   def_system_macro('FPC_HAS_INTERNAL_ABS_INT64');
-{$endif x86_64 or powerpc64 or aarch64}
+{$endif i386 or x86_64 or powerpc64 or aarch64}
 
   def_system_macro('FPC_HAS_MANAGEMENT_OPERATORS');
   def_system_macro('FPC_HAS_UNICODESTRING');