From 6d1730048dafc5fccb671459de9a7eecaf6cd286 Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Thu, 16 May 2019 16:24:21 -0400 Subject: [PATCH] tcg: Add support for integer absolute value Remove a function of the same name from target/arm/. Use a branchless implementation of abs gleaned from gcc. Backports commit ff1f11f7f8710a768f9313f24bd7f509d3db27e5 from qemu --- qemu/aarch64.h | 2 ++ qemu/aarch64eb.h | 2 ++ qemu/arm.h | 2 ++ qemu/armeb.h | 2 ++ qemu/header_gen.py | 2 ++ qemu/m68k.h | 2 ++ qemu/mips.h | 2 ++ qemu/mips64.h | 2 ++ qemu/mips64el.h | 2 ++ qemu/mipsel.h | 2 ++ qemu/powerpc.h | 2 ++ qemu/riscv32.h | 2 ++ qemu/riscv64.h | 2 ++ qemu/sparc.h | 2 ++ qemu/sparc64.h | 2 ++ qemu/target/arm/translate.c | 13 +------------ qemu/tcg/tcg-op.c | 20 ++++++++++++++++++++ qemu/tcg/tcg-op.h | 6 +++++- qemu/x86_64.h | 2 ++ 19 files changed, 58 insertions(+), 13 deletions(-) diff --git a/qemu/aarch64.h b/qemu/aarch64.h index 41eb06f6..f4286c66 100644 --- a/qemu/aarch64.h +++ b/qemu/aarch64.h @@ -2731,6 +2731,8 @@ #define tcg_flush_softmmu_tlb tcg_flush_softmmu_tlb_aarch64 #define tcg_func_start tcg_func_start_aarch64 #define tcg_gen_abs_i32 tcg_gen_abs_i32_aarch64 +#define tcg_gen_abs_i64 tcg_gen_abs_i64_aarch64 +#define tcg_gen_abs_vec tcg_gen_abs_vec_aarch64 #define tcg_gen_add2_i32 tcg_gen_add2_i32_aarch64 #define tcg_gen_add2_i64 tcg_gen_add2_i64_aarch64 #define tcg_gen_add_i32 tcg_gen_add_i32_aarch64 diff --git a/qemu/aarch64eb.h b/qemu/aarch64eb.h index 2b06d3d4..cebc3411 100644 --- a/qemu/aarch64eb.h +++ b/qemu/aarch64eb.h @@ -2731,6 +2731,8 @@ #define tcg_flush_softmmu_tlb tcg_flush_softmmu_tlb_aarch64eb #define tcg_func_start tcg_func_start_aarch64eb #define tcg_gen_abs_i32 tcg_gen_abs_i32_aarch64eb +#define tcg_gen_abs_i64 tcg_gen_abs_i64_aarch64eb +#define tcg_gen_abs_vec tcg_gen_abs_vec_aarch64eb #define tcg_gen_add2_i32 tcg_gen_add2_i32_aarch64eb #define tcg_gen_add2_i64 tcg_gen_add2_i64_aarch64eb #define tcg_gen_add_i32 tcg_gen_add_i32_aarch64eb diff --git a/qemu/arm.h b/qemu/arm.h index 1629f8d5..1f677522 100644 --- a/qemu/arm.h +++ b/qemu/arm.h @@ -2731,6 +2731,8 @@ #define tcg_flush_softmmu_tlb tcg_flush_softmmu_tlb_arm #define tcg_func_start tcg_func_start_arm #define tcg_gen_abs_i32 tcg_gen_abs_i32_arm +#define tcg_gen_abs_i64 tcg_gen_abs_i64_arm +#define tcg_gen_abs_vec tcg_gen_abs_vec_arm #define tcg_gen_add2_i32 tcg_gen_add2_i32_arm #define tcg_gen_add2_i64 tcg_gen_add2_i64_arm #define tcg_gen_add_i32 tcg_gen_add_i32_arm diff --git a/qemu/armeb.h b/qemu/armeb.h index 4757cce8..64abcefd 100644 --- a/qemu/armeb.h +++ b/qemu/armeb.h @@ -2731,6 +2731,8 @@ #define tcg_flush_softmmu_tlb tcg_flush_softmmu_tlb_armeb #define tcg_func_start tcg_func_start_armeb #define tcg_gen_abs_i32 tcg_gen_abs_i32_armeb +#define tcg_gen_abs_i64 tcg_gen_abs_i64_armeb +#define tcg_gen_abs_vec tcg_gen_abs_vec_armeb #define tcg_gen_add2_i32 tcg_gen_add2_i32_armeb #define tcg_gen_add2_i64 tcg_gen_add2_i64_armeb #define tcg_gen_add_i32 tcg_gen_add_i32_armeb diff --git a/qemu/header_gen.py b/qemu/header_gen.py index d1dbbe47..166f10d9 100644 --- a/qemu/header_gen.py +++ b/qemu/header_gen.py @@ -2737,6 +2737,8 @@ symbols = ( 'tcg_flush_softmmu_tlb', 'tcg_func_start', 'tcg_gen_abs_i32', + 'tcg_gen_abs_i64', + 'tcg_gen_abs_vec', 'tcg_gen_add2_i32', 'tcg_gen_add2_i64', 'tcg_gen_add_i32', diff --git a/qemu/m68k.h b/qemu/m68k.h index 8cec72b2..38c9e788 100644 --- a/qemu/m68k.h +++ b/qemu/m68k.h @@ -2731,6 +2731,8 @@ #define tcg_flush_softmmu_tlb tcg_flush_softmmu_tlb_m68k #define tcg_func_start tcg_func_start_m68k #define tcg_gen_abs_i32 tcg_gen_abs_i32_m68k +#define tcg_gen_abs_i64 tcg_gen_abs_i64_m68k +#define tcg_gen_abs_vec tcg_gen_abs_vec_m68k #define tcg_gen_add2_i32 tcg_gen_add2_i32_m68k #define tcg_gen_add2_i64 tcg_gen_add2_i64_m68k #define tcg_gen_add_i32 tcg_gen_add_i32_m68k diff --git a/qemu/mips.h b/qemu/mips.h index a042c708..5253fc56 100644 --- a/qemu/mips.h +++ b/qemu/mips.h @@ -2731,6 +2731,8 @@ #define tcg_flush_softmmu_tlb tcg_flush_softmmu_tlb_mips #define tcg_func_start tcg_func_start_mips #define tcg_gen_abs_i32 tcg_gen_abs_i32_mips +#define tcg_gen_abs_i64 tcg_gen_abs_i64_mips +#define tcg_gen_abs_vec tcg_gen_abs_vec_mips #define tcg_gen_add2_i32 tcg_gen_add2_i32_mips #define tcg_gen_add2_i64 tcg_gen_add2_i64_mips #define tcg_gen_add_i32 tcg_gen_add_i32_mips diff --git a/qemu/mips64.h b/qemu/mips64.h index 7aed95e1..e3c7c6f0 100644 --- a/qemu/mips64.h +++ b/qemu/mips64.h @@ -2731,6 +2731,8 @@ #define tcg_flush_softmmu_tlb tcg_flush_softmmu_tlb_mips64 #define tcg_func_start tcg_func_start_mips64 #define tcg_gen_abs_i32 tcg_gen_abs_i32_mips64 +#define tcg_gen_abs_i64 tcg_gen_abs_i64_mips64 +#define tcg_gen_abs_vec tcg_gen_abs_vec_mips64 #define tcg_gen_add2_i32 tcg_gen_add2_i32_mips64 #define tcg_gen_add2_i64 tcg_gen_add2_i64_mips64 #define tcg_gen_add_i32 tcg_gen_add_i32_mips64 diff --git a/qemu/mips64el.h b/qemu/mips64el.h index b43851f3..17831fa0 100644 --- a/qemu/mips64el.h +++ b/qemu/mips64el.h @@ -2731,6 +2731,8 @@ #define tcg_flush_softmmu_tlb tcg_flush_softmmu_tlb_mips64el #define tcg_func_start tcg_func_start_mips64el #define tcg_gen_abs_i32 tcg_gen_abs_i32_mips64el +#define tcg_gen_abs_i64 tcg_gen_abs_i64_mips64el +#define tcg_gen_abs_vec tcg_gen_abs_vec_mips64el #define tcg_gen_add2_i32 tcg_gen_add2_i32_mips64el #define tcg_gen_add2_i64 tcg_gen_add2_i64_mips64el #define tcg_gen_add_i32 tcg_gen_add_i32_mips64el diff --git a/qemu/mipsel.h b/qemu/mipsel.h index d2fc46bf..5abeea76 100644 --- a/qemu/mipsel.h +++ b/qemu/mipsel.h @@ -2731,6 +2731,8 @@ #define tcg_flush_softmmu_tlb tcg_flush_softmmu_tlb_mipsel #define tcg_func_start tcg_func_start_mipsel #define tcg_gen_abs_i32 tcg_gen_abs_i32_mipsel +#define tcg_gen_abs_i64 tcg_gen_abs_i64_mipsel +#define tcg_gen_abs_vec tcg_gen_abs_vec_mipsel #define tcg_gen_add2_i32 tcg_gen_add2_i32_mipsel #define tcg_gen_add2_i64 tcg_gen_add2_i64_mipsel #define tcg_gen_add_i32 tcg_gen_add_i32_mipsel diff --git a/qemu/powerpc.h b/qemu/powerpc.h index 0baedefb..36bf76c5 100644 --- a/qemu/powerpc.h +++ b/qemu/powerpc.h @@ -2731,6 +2731,8 @@ #define tcg_flush_softmmu_tlb tcg_flush_softmmu_tlb_powerpc #define tcg_func_start tcg_func_start_powerpc #define tcg_gen_abs_i32 tcg_gen_abs_i32_powerpc +#define tcg_gen_abs_i64 tcg_gen_abs_i64_powerpc +#define tcg_gen_abs_vec tcg_gen_abs_vec_powerpc #define tcg_gen_add2_i32 tcg_gen_add2_i32_powerpc #define tcg_gen_add2_i64 tcg_gen_add2_i64_powerpc #define tcg_gen_add_i32 tcg_gen_add_i32_powerpc diff --git a/qemu/riscv32.h b/qemu/riscv32.h index 5a5d78bd..7069cc0f 100644 --- a/qemu/riscv32.h +++ b/qemu/riscv32.h @@ -2731,6 +2731,8 @@ #define tcg_flush_softmmu_tlb tcg_flush_softmmu_tlb_riscv32 #define tcg_func_start tcg_func_start_riscv32 #define tcg_gen_abs_i32 tcg_gen_abs_i32_riscv32 +#define tcg_gen_abs_i64 tcg_gen_abs_i64_riscv32 +#define tcg_gen_abs_vec tcg_gen_abs_vec_riscv32 #define tcg_gen_add2_i32 tcg_gen_add2_i32_riscv32 #define tcg_gen_add2_i64 tcg_gen_add2_i64_riscv32 #define tcg_gen_add_i32 tcg_gen_add_i32_riscv32 diff --git a/qemu/riscv64.h b/qemu/riscv64.h index a0855934..08c8d239 100644 --- a/qemu/riscv64.h +++ b/qemu/riscv64.h @@ -2731,6 +2731,8 @@ #define tcg_flush_softmmu_tlb tcg_flush_softmmu_tlb_riscv64 #define tcg_func_start tcg_func_start_riscv64 #define tcg_gen_abs_i32 tcg_gen_abs_i32_riscv64 +#define tcg_gen_abs_i64 tcg_gen_abs_i64_riscv64 +#define tcg_gen_abs_vec tcg_gen_abs_vec_riscv64 #define tcg_gen_add2_i32 tcg_gen_add2_i32_riscv64 #define tcg_gen_add2_i64 tcg_gen_add2_i64_riscv64 #define tcg_gen_add_i32 tcg_gen_add_i32_riscv64 diff --git a/qemu/sparc.h b/qemu/sparc.h index b98d7958..49d8ec57 100644 --- a/qemu/sparc.h +++ b/qemu/sparc.h @@ -2731,6 +2731,8 @@ #define tcg_flush_softmmu_tlb tcg_flush_softmmu_tlb_sparc #define tcg_func_start tcg_func_start_sparc #define tcg_gen_abs_i32 tcg_gen_abs_i32_sparc +#define tcg_gen_abs_i64 tcg_gen_abs_i64_sparc +#define tcg_gen_abs_vec tcg_gen_abs_vec_sparc #define tcg_gen_add2_i32 tcg_gen_add2_i32_sparc #define tcg_gen_add2_i64 tcg_gen_add2_i64_sparc #define tcg_gen_add_i32 tcg_gen_add_i32_sparc diff --git a/qemu/sparc64.h b/qemu/sparc64.h index c73154c9..b140ed02 100644 --- a/qemu/sparc64.h +++ b/qemu/sparc64.h @@ -2731,6 +2731,8 @@ #define tcg_flush_softmmu_tlb tcg_flush_softmmu_tlb_sparc64 #define tcg_func_start tcg_func_start_sparc64 #define tcg_gen_abs_i32 tcg_gen_abs_i32_sparc64 +#define tcg_gen_abs_i64 tcg_gen_abs_i64_sparc64 +#define tcg_gen_abs_vec tcg_gen_abs_vec_sparc64 #define tcg_gen_add2_i32 tcg_gen_add2_i32_sparc64 #define tcg_gen_add2_i64 tcg_gen_add2_i64_sparc64 #define tcg_gen_add_i32 tcg_gen_add_i32_sparc64 diff --git a/qemu/target/arm/translate.c b/qemu/target/arm/translate.c index a5570f6e..1ce750a3 100644 --- a/qemu/target/arm/translate.c +++ b/qemu/target/arm/translate.c @@ -624,17 +624,6 @@ static void gen_sar(DisasContext *s, TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1) tcg_temp_free_i32(tcg_ctx, tmp1); } -static void tcg_gen_abs_i32(DisasContext *s, TCGv_i32 dest, TCGv_i32 src) -{ - TCGContext *tcg_ctx = s->uc->tcg_ctx; - TCGv_i32 c0 = tcg_const_i32(tcg_ctx, 0); - TCGv_i32 tmp = tcg_temp_new_i32(tcg_ctx); - tcg_gen_neg_i32(tcg_ctx, tmp, src); - tcg_gen_movcond_i32(tcg_ctx, TCG_COND_GT, dest, src, c0, src, tmp); - tcg_temp_free_i32(tcg_ctx, c0); - tcg_temp_free_i32(tcg_ctx, tmp); -} - static void shifter_out_im(DisasContext *s, TCGv_i32 var, int shift) { TCGContext *tcg_ctx = s->uc->tcg_ctx; @@ -8395,7 +8384,7 @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn) switch(size) { case 0: gen_helper_neon_abs_s8(tcg_ctx, tmp, tmp); break; case 1: gen_helper_neon_abs_s16(tcg_ctx, tmp, tmp); break; - case 2: tcg_gen_abs_i32(s, tmp, tmp); break; + case 2: tcg_gen_abs_i32(tcg_ctx, tmp, tmp); break; default: abort(); } break; diff --git a/qemu/tcg/tcg-op.c b/qemu/tcg/tcg-op.c index 12b13b07..2b5c68a9 100644 --- a/qemu/tcg/tcg-op.c +++ b/qemu/tcg/tcg-op.c @@ -1099,6 +1099,16 @@ void tcg_gen_umax_i32(TCGContext *s, TCGv_i32 ret, TCGv_i32 a, TCGv_i32 b) tcg_gen_movcond_i32(s, TCG_COND_LTU, ret, a, b, b, a); } +void tcg_gen_abs_i32(TCGContext *s, TCGv_i32 ret, TCGv_i32 a) +{ + TCGv_i32 t = tcg_temp_new_i32(s); + + tcg_gen_sari_i32(s, t, a, 31); + tcg_gen_xor_i32(s, ret, a, t); + tcg_gen_sub_i32(s, ret, ret, t); + tcg_temp_free_i32(s, t); +} + /* 64-bit ops */ #if TCG_TARGET_REG_BITS == 32 @@ -2565,6 +2575,16 @@ void tcg_gen_umax_i64(TCGContext *s, TCGv_i64 ret, TCGv_i64 a, TCGv_i64 b) tcg_gen_movcond_i64(s, TCG_COND_LTU, ret, a, b, b, a); } +void tcg_gen_abs_i64(TCGContext *s, TCGv_i64 ret, TCGv_i64 a) +{ + TCGv_i64 t = tcg_temp_new_i64(s); + + tcg_gen_sari_i64(s, t, a, 63); + tcg_gen_xor_i64(s, ret, a, t); + tcg_gen_sub_i64(s, ret, ret, t); + tcg_temp_free_i64(s, t); +} + /* Size changing operations. */ void tcg_gen_extrl_i64_i32(TCGContext *s, TCGv_i32 ret, TCGv_i64 arg) diff --git a/qemu/tcg/tcg-op.h b/qemu/tcg/tcg-op.h index d2e09e21..2fd44755 100644 --- a/qemu/tcg/tcg-op.h +++ b/qemu/tcg/tcg-op.h @@ -353,6 +353,7 @@ void tcg_gen_smin_i32(TCGContext *s, TCGv_i32, TCGv_i32 arg1, TCGv_i32 arg2); void tcg_gen_smax_i32(TCGContext *s, TCGv_i32, TCGv_i32 arg1, TCGv_i32 arg2); void tcg_gen_umin_i32(TCGContext *s, TCGv_i32, TCGv_i32 arg1, TCGv_i32 arg2); void tcg_gen_umax_i32(TCGContext *s, TCGv_i32, TCGv_i32 arg1, TCGv_i32 arg2); +void tcg_gen_abs_i32(TCGContext *s, TCGv_i32, TCGv_i32); static inline void tcg_gen_discard_i32(TCGContext *s, TCGv_i32 arg) { @@ -544,7 +545,7 @@ void tcg_gen_smin_i64(TCGContext *s, TCGv_i64, TCGv_i64 arg1, TCGv_i64 arg2); void tcg_gen_smax_i64(TCGContext *s, TCGv_i64, TCGv_i64 arg1, TCGv_i64 arg2); void tcg_gen_umin_i64(TCGContext *s, TCGv_i64, TCGv_i64 arg1, TCGv_i64 arg2); void tcg_gen_umax_i64(TCGContext *s, TCGv_i64, TCGv_i64 arg1, TCGv_i64 arg2); - +void tcg_gen_abs_i64(TCGContext *s, TCGv_i64, TCGv_i64); #if TCG_TARGET_REG_BITS == 64 static inline void tcg_gen_discard_i64(TCGContext *s, TCGv_i64 arg) @@ -986,6 +987,7 @@ void tcg_gen_nor_vec(TCGContext *, unsigned vece, TCGv_vec r, TCGv_vec a, TCGv_v void tcg_gen_eqv_vec(TCGContext *, unsigned vece, TCGv_vec r, TCGv_vec a, TCGv_vec b); void tcg_gen_not_vec(TCGContext *, unsigned vece, TCGv_vec r, TCGv_vec a); void tcg_gen_neg_vec(TCGContext *, unsigned vece, TCGv_vec r, TCGv_vec a); +void tcg_gen_abs_vec(TCGContext *, unsigned vece, TCGv_vec r, TCGv_vec a); void tcg_gen_ssadd_vec(TCGContext *, unsigned vece, TCGv_vec r, TCGv_vec a, TCGv_vec b); void tcg_gen_usadd_vec(TCGContext *, unsigned vece, TCGv_vec r, TCGv_vec a, TCGv_vec b); void tcg_gen_sssub_vec(TCGContext *, unsigned vece, TCGv_vec r, TCGv_vec a, TCGv_vec b); @@ -1033,6 +1035,7 @@ void tcg_gen_stl_vec(TCGContext *, TCGv_vec r, TCGv_ptr base, TCGArg offset, TCG #define tcg_gen_addi_tl tcg_gen_addi_i64 #define tcg_gen_sub_tl tcg_gen_sub_i64 #define tcg_gen_neg_tl tcg_gen_neg_i64 +#define tcg_gen_abs_tl tcg_gen_abs_i64 #define tcg_gen_subfi_tl tcg_gen_subfi_i64 #define tcg_gen_subi_tl tcg_gen_subi_i64 #define tcg_gen_and_tl tcg_gen_and_i64 @@ -1145,6 +1148,7 @@ void tcg_gen_stl_vec(TCGContext *, TCGv_vec r, TCGv_ptr base, TCGArg offset, TCG #define tcg_gen_addi_tl tcg_gen_addi_i32 #define tcg_gen_sub_tl tcg_gen_sub_i32 #define tcg_gen_neg_tl tcg_gen_neg_i32 +#define tcg_gen_abs_tl tcg_gen_abs_i32 #define tcg_gen_subfi_tl tcg_gen_subfi_i32 #define tcg_gen_subi_tl tcg_gen_subi_i32 #define tcg_gen_and_tl tcg_gen_and_i32 diff --git a/qemu/x86_64.h b/qemu/x86_64.h index 2429888c..da754870 100644 --- a/qemu/x86_64.h +++ b/qemu/x86_64.h @@ -2731,6 +2731,8 @@ #define tcg_flush_softmmu_tlb tcg_flush_softmmu_tlb_x86_64 #define tcg_func_start tcg_func_start_x86_64 #define tcg_gen_abs_i32 tcg_gen_abs_i32_x86_64 +#define tcg_gen_abs_i64 tcg_gen_abs_i64_x86_64 +#define tcg_gen_abs_vec tcg_gen_abs_vec_x86_64 #define tcg_gen_add2_i32 tcg_gen_add2_i32_x86_64 #define tcg_gen_add2_i64 tcg_gen_add2_i64_x86_64 #define tcg_gen_add_i32 tcg_gen_add_i32_x86_64