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
This commit is contained in:
Richard Henderson 2019-05-16 16:24:21 -04:00 committed by Lioncash
parent 18b3df6e4e
commit 6d1730048d
No known key found for this signature in database
GPG key ID: 4E3C3CC1031BA9C7
19 changed files with 58 additions and 13 deletions

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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',

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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;

View file

@ -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)

View file

@ -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

View file

@ -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