From aefa3174742fa630c3fa7003c4e8aaf3821a1bc0 Mon Sep 17 00:00:00 2001 From: nickysn Date: Sun, 10 Sep 2017 17:25:47 +0000 Subject: [PATCH] + fast and branchless implementation of abs(int64) for i386 git-svn-id: trunk@37169 - --- compiler/i386/n386inl.pas | 22 ++++++++++++++++++++++ compiler/options.pas | 4 ++-- 2 files changed, 24 insertions(+), 2 deletions(-) diff --git a/compiler/i386/n386inl.pas b/compiler/i386/n386inl.pas index 8320bcf9fc..e8782ce26a 100644 --- a/compiler/i386/n386inl.pas +++ b/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. diff --git a/compiler/options.pas b/compiler/options.pas index 0bf3da72e2..f8ceae088f 100644 --- a/compiler/options.pas +++ b/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');