Browse Source

+ generate faster, branchless code for abs(int64) on i8086

git-svn-id: trunk@37172 -
nickysn 8 years ago
parent
commit
4e489f2b33
2 changed files with 21 additions and 3 deletions
  1. 19 1
      compiler/i8086/n8086inl.pas
  2. 2 2
      compiler/options.pas

+ 19 - 1
compiler/i8086/n8086inl.pas

@@ -256,7 +256,25 @@ implementation
          opsize: TCgSize;
          opsize: TCgSize;
        begin
        begin
          opsize:=def_cgsize(left.resultdef);
          opsize:=def_cgsize(left.resultdef);
-         if opsize in [OS_32,OS_S32] then
+         if opsize in [OS_64,OS_S64] 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_16,15,GetNextReg(left.location.register64.reghi));
+            cg.a_op_reg_reg(current_asmdata.CurrAsmList,OP_XOR,OS_16,GetNextReg(left.location.register64.reghi),location.register64.reglo);
+            cg.a_op_reg_reg(current_asmdata.CurrAsmList,OP_XOR,OS_16,GetNextReg(left.location.register64.reghi),GetNextReg(location.register64.reglo));
+            cg.a_op_reg_reg(current_asmdata.CurrAsmList,OP_XOR,OS_16,GetNextReg(left.location.register64.reghi),location.register64.reghi);
+            cg.a_op_reg_reg(current_asmdata.CurrAsmList,OP_XOR,OS_16,GetNextReg(left.location.register64.reghi),GetNextReg(location.register64.reghi));
+            emit_reg_reg(A_SUB,S_W,GetNextReg(left.location.register64.reghi),location.register64.reglo);
+            emit_reg_reg(A_SBB,S_W,GetNextReg(left.location.register64.reghi),GetNextReg(location.register64.reglo));
+            emit_reg_reg(A_SBB,S_W,GetNextReg(left.location.register64.reghi),location.register64.reghi);
+            emit_reg_reg(A_SBB,S_W,GetNextReg(left.location.register64.reghi),GetNextReg(location.register64.reghi));
+           end
+         else if opsize in [OS_32,OS_S32] then
            begin
            begin
             secondpass(left);
             secondpass(left);
             hlcg.location_force_reg(current_asmdata.CurrAsmList,left.location,left.resultdef,left.resultdef,false);
             hlcg.location_force_reg(current_asmdata.CurrAsmList,left.location,left.resultdef,left.resultdef,false);

+ 2 - 2
compiler/options.pas

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