From 4e489f2b33830fa052fd5328b409d0f735af5cea Mon Sep 17 00:00:00 2001 From: nickysn Date: Sun, 10 Sep 2017 18:58:45 +0000 Subject: [PATCH] + generate faster, branchless code for abs(int64) on i8086 git-svn-id: trunk@37172 - --- compiler/i8086/n8086inl.pas | 20 +++++++++++++++++++- compiler/options.pas | 4 ++-- 2 files changed, 21 insertions(+), 3 deletions(-) diff --git a/compiler/i8086/n8086inl.pas b/compiler/i8086/n8086inl.pas index 0590e72a52..a52d485a7e 100644 --- a/compiler/i8086/n8086inl.pas +++ b/compiler/i8086/n8086inl.pas @@ -256,7 +256,25 @@ implementation opsize: TCgSize; begin 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 secondpass(left); hlcg.location_force_reg(current_asmdata.CurrAsmList,left.location,left.resultdef,left.resultdef,false); diff --git a/compiler/options.pas b/compiler/options.pas index f8ceae088f..0a21e9698a 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(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'); -{$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_UNICODESTRING');