aboutsummaryrefslogtreecommitdiff
path: root/target
diff options
context:
space:
mode:
authorPeter Maydell <peter.maydell@linaro.org>2019-05-14 10:08:47 +0100
committerPeter Maydell <peter.maydell@linaro.org>2019-05-14 10:08:47 +0100
commite329ad2ab72c43b56df88b34954c2c7d839bb373 (patch)
tree69180a9f32bc7cfa7b9645e7d18ba3ff32a37975 /target
parente24f44dbeab8e54c72bdaedbd35453fb2a6c38da (diff)
parenta7b6d286cfb5205b9f5330aefc5727269b3d810f (diff)
downloadqemu-e329ad2ab72c43b56df88b34954c2c7d839bb373.zip
qemu-e329ad2ab72c43b56df88b34954c2c7d839bb373.tar.gz
qemu-e329ad2ab72c43b56df88b34954c2c7d839bb373.tar.bz2
Merge remote-tracking branch 'remotes/rth/tags/pull-tcg-20190513' into staging
Improve code generation for vector duplication. Add vector expansions for shifts by non-constant scalar. Add vector expansions for shifts by vector. Add integer and vector expansions for absolute value. Several patches in preparation for Altivec. Bug fix for tcg/aarch64 vs min/max. # gpg: Signature made Tue 14 May 2019 00:58:02 BST # gpg: using RSA key 7A481E78868B4DB6A85A05C064DF38E8AF7E215F # gpg: issuer "richard.henderson@linaro.org" # gpg: Good signature from "Richard Henderson <richard.henderson@linaro.org>" [full] # Primary key fingerprint: 7A48 1E78 868B 4DB6 A85A 05C0 64DF 38E8 AF7E 215F * remotes/rth/tags/pull-tcg-20190513: (31 commits) tcg/aarch64: Do not advertise minmax for MO_64 target/xtensa: Use tcg_gen_abs_i32 target/tricore: Use tcg_gen_abs_tl target/s390x: Use tcg_gen_abs_i64 target/ppc: Use tcg_gen_abs_tl target/ppc: Use tcg_gen_abs_i32 target/cris: Use tcg_gen_abs_tl target/arm: Use tcg_gen_abs_i64 and tcg_gen_gvec_abs tcg/aarch64: Support vector absolute value tcg/i386: Support vector absolute value tcg: Add support for vector absolute value tcg: Add support for integer absolute value tcg/i386: Support vector scalar shift opcodes tcg: Add gvec expanders for vector shift by scalar tcg/aarch64: Support vector variable shift opcodes tcg/i386: Support vector variable shift opcodes tcg: Add gvec expanders for variable shift tcg: Add INDEX_op_dupm_vec tcg/aarch64: Implement tcg_out_dupm_vec tcg/i386: Implement tcg_out_dupm_vec ... Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to 'target')
-rw-r--r--target/arm/helper.h2
-rw-r--r--target/arm/neon_helper.c5
-rw-r--r--target/arm/translate-a64.c41
-rw-r--r--target/arm/translate-sve.c9
-rw-r--r--target/arm/translate.c144
-rw-r--r--target/cris/translate.c9
-rw-r--r--target/ppc/translate.c68
-rw-r--r--target/ppc/translate/spe-impl.inc.c14
-rw-r--r--target/ppc/translate/vmx-impl.inc.c7
-rw-r--r--target/s390x/translate.c8
-rw-r--r--target/tricore/translate.c27
-rw-r--r--target/xtensa/translate.c9
12 files changed, 135 insertions, 208 deletions
diff --git a/target/arm/helper.h b/target/arm/helper.h
index 50cb036..132aa16 100644
--- a/target/arm/helper.h
+++ b/target/arm/helper.h
@@ -352,8 +352,6 @@ DEF_HELPER_2(neon_ceq_u8, i32, i32, i32)
DEF_HELPER_2(neon_ceq_u16, i32, i32, i32)
DEF_HELPER_2(neon_ceq_u32, i32, i32, i32)
-DEF_HELPER_1(neon_abs_s8, i32, i32)
-DEF_HELPER_1(neon_abs_s16, i32, i32)
DEF_HELPER_1(neon_clz_u8, i32, i32)
DEF_HELPER_1(neon_clz_u16, i32, i32)
DEF_HELPER_1(neon_cls_s8, i32, i32)
diff --git a/target/arm/neon_helper.c b/target/arm/neon_helper.c
index ed1c6fc..4259056 100644
--- a/target/arm/neon_helper.c
+++ b/target/arm/neon_helper.c
@@ -1228,11 +1228,6 @@ NEON_VOP(ceq_u16, neon_u16, 2)
NEON_VOP(ceq_u32, neon_u32, 1)
#undef NEON_FN
-#define NEON_FN(dest, src, dummy) dest = (src < 0) ? -src : src
-NEON_VOP1(abs_s8, neon_s8, 4)
-NEON_VOP1(abs_s16, neon_s16, 2)
-#undef NEON_FN
-
/* Count Leading Sign/Zero Bits. */
static inline int do_clz8(uint8_t x)
{
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
index 9dcc5ff..b7c5a92 100644
--- a/target/arm/translate-a64.c
+++ b/target/arm/translate-a64.c
@@ -9468,11 +9468,7 @@ static void handle_2misc_64(DisasContext *s, int opcode, bool u,
if (u) {
tcg_gen_neg_i64(tcg_rd, tcg_rn);
} else {
- TCGv_i64 tcg_zero = tcg_const_i64(0);
- tcg_gen_neg_i64(tcg_rd, tcg_rn);
- tcg_gen_movcond_i64(TCG_COND_GT, tcg_rd, tcg_rn, tcg_zero,
- tcg_rn, tcg_rd);
- tcg_temp_free_i64(tcg_zero);
+ tcg_gen_abs_i64(tcg_rd, tcg_rn);
}
break;
case 0x2f: /* FABS */
@@ -12366,11 +12362,12 @@ static void disas_simd_two_reg_misc(DisasContext *s, uint32_t insn)
}
break;
case 0xb:
- if (u) { /* NEG */
+ if (u) { /* ABS, NEG */
gen_gvec_fn2(s, is_q, rd, rn, tcg_gen_gvec_neg, size);
- return;
+ } else {
+ gen_gvec_fn2(s, is_q, rd, rn, tcg_gen_gvec_abs, size);
}
- break;
+ return;
}
if (size == 3) {
@@ -12438,17 +12435,6 @@ static void disas_simd_two_reg_misc(DisasContext *s, uint32_t insn)
gen_helper_neon_qabs_s32(tcg_res, cpu_env, tcg_op);
}
break;
- case 0xb: /* ABS, NEG */
- if (u) {
- tcg_gen_neg_i32(tcg_res, tcg_op);
- } else {
- TCGv_i32 tcg_zero = tcg_const_i32(0);
- tcg_gen_neg_i32(tcg_res, tcg_op);
- tcg_gen_movcond_i32(TCG_COND_GT, tcg_res, tcg_op,
- tcg_zero, tcg_op, tcg_res);
- tcg_temp_free_i32(tcg_zero);
- }
- break;
case 0x2f: /* FABS */
gen_helper_vfp_abss(tcg_res, tcg_op);
break;
@@ -12561,23 +12547,6 @@ static void disas_simd_two_reg_misc(DisasContext *s, uint32_t insn)
tcg_temp_free_i32(tcg_zero);
break;
}
- case 0xb: /* ABS, NEG */
- if (u) {
- TCGv_i32 tcg_zero = tcg_const_i32(0);
- if (size) {
- gen_helper_neon_sub_u16(tcg_res, tcg_zero, tcg_op);
- } else {
- gen_helper_neon_sub_u8(tcg_res, tcg_zero, tcg_op);
- }
- tcg_temp_free_i32(tcg_zero);
- } else {
- if (size) {
- gen_helper_neon_abs_s16(tcg_res, tcg_op);
- } else {
- gen_helper_neon_abs_s8(tcg_res, tcg_op);
- }
- }
- break;
case 0x4: /* CLS, CLZ */
if (u) {
if (size == 0) {
diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
index 80645db..fa068b0 100644
--- a/target/arm/translate-sve.c
+++ b/target/arm/translate-sve.c
@@ -3302,29 +3302,30 @@ static bool trans_SUB_zzi(DisasContext *s, arg_rri_esz *a)
static bool trans_SUBR_zzi(DisasContext *s, arg_rri_esz *a)
{
+ static const TCGOpcode vecop_list[] = { INDEX_op_sub_vec, 0 };
static const GVecGen2s op[4] = {
{ .fni8 = tcg_gen_vec_sub8_i64,
.fniv = tcg_gen_sub_vec,
.fno = gen_helper_sve_subri_b,
- .opc = INDEX_op_sub_vec,
+ .opt_opc = vecop_list,
.vece = MO_8,
.scalar_first = true },
{ .fni8 = tcg_gen_vec_sub16_i64,
.fniv = tcg_gen_sub_vec,
.fno = gen_helper_sve_subri_h,
- .opc = INDEX_op_sub_vec,
+ .opt_opc = vecop_list,
.vece = MO_16,
.scalar_first = true },
{ .fni4 = tcg_gen_sub_i32,
.fniv = tcg_gen_sub_vec,
.fno = gen_helper_sve_subri_s,
- .opc = INDEX_op_sub_vec,
+ .opt_opc = vecop_list,
.vece = MO_32,
.scalar_first = true },
{ .fni8 = tcg_gen_sub_i64,
.fniv = tcg_gen_sub_vec,
.fno = gen_helper_sve_subri_d,
- .opc = INDEX_op_sub_vec,
+ .opt_opc = vecop_list,
.prefer_i64 = TCG_TARGET_REG_BITS == 64,
.vece = MO_64,
.scalar_first = true }
diff --git a/target/arm/translate.c b/target/arm/translate.c
index 10bc53f..dd053c8 100644
--- a/target/arm/translate.c
+++ b/target/arm/translate.c
@@ -604,16 +604,6 @@ static void gen_sar(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
tcg_temp_free_i32(tmp1);
}
-static void tcg_gen_abs_i32(TCGv_i32 dest, TCGv_i32 src)
-{
- TCGv_i32 c0 = tcg_const_i32(0);
- TCGv_i32 tmp = tcg_temp_new_i32();
- tcg_gen_neg_i32(tmp, src);
- tcg_gen_movcond_i32(TCG_COND_GT, dest, src, c0, src, tmp);
- tcg_temp_free_i32(c0);
- tcg_temp_free_i32(tmp);
-}
-
static void shifter_out_im(TCGv_i32 var, int shift)
{
if (shift == 0) {
@@ -5861,27 +5851,31 @@ static void gen_ssra_vec(unsigned vece, TCGv_vec d, TCGv_vec a, int64_t sh)
tcg_gen_add_vec(vece, d, d, a);
}
+static const TCGOpcode vecop_list_ssra[] = {
+ INDEX_op_sari_vec, INDEX_op_add_vec, 0
+};
+
const GVecGen2i ssra_op[4] = {
{ .fni8 = gen_ssra8_i64,
.fniv = gen_ssra_vec,
.load_dest = true,
- .opc = INDEX_op_sari_vec,
+ .opt_opc = vecop_list_ssra,
.vece = MO_8 },
{ .fni8 = gen_ssra16_i64,
.fniv = gen_ssra_vec,
.load_dest = true,
- .opc = INDEX_op_sari_vec,
+ .opt_opc = vecop_list_ssra,
.vece = MO_16 },
{ .fni4 = gen_ssra32_i32,
.fniv = gen_ssra_vec,
.load_dest = true,
- .opc = INDEX_op_sari_vec,
+ .opt_opc = vecop_list_ssra,
.vece = MO_32 },
{ .fni8 = gen_ssra64_i64,
.fniv = gen_ssra_vec,
.prefer_i64 = TCG_TARGET_REG_BITS == 64,
+ .opt_opc = vecop_list_ssra,
.load_dest = true,
- .opc = INDEX_op_sari_vec,
.vece = MO_64 },
};
@@ -5915,27 +5909,31 @@ static void gen_usra_vec(unsigned vece, TCGv_vec d, TCGv_vec a, int64_t sh)
tcg_gen_add_vec(vece, d, d, a);
}
+static const TCGOpcode vecop_list_usra[] = {
+ INDEX_op_shri_vec, INDEX_op_add_vec, 0
+};
+
const GVecGen2i usra_op[4] = {
{ .fni8 = gen_usra8_i64,
.fniv = gen_usra_vec,
.load_dest = true,
- .opc = INDEX_op_shri_vec,
+ .opt_opc = vecop_list_usra,
.vece = MO_8, },
{ .fni8 = gen_usra16_i64,
.fniv = gen_usra_vec,
.load_dest = true,
- .opc = INDEX_op_shri_vec,
+ .opt_opc = vecop_list_usra,
.vece = MO_16, },
{ .fni4 = gen_usra32_i32,
.fniv = gen_usra_vec,
.load_dest = true,
- .opc = INDEX_op_shri_vec,
+ .opt_opc = vecop_list_usra,
.vece = MO_32, },
{ .fni8 = gen_usra64_i64,
.fniv = gen_usra_vec,
.prefer_i64 = TCG_TARGET_REG_BITS == 64,
.load_dest = true,
- .opc = INDEX_op_shri_vec,
+ .opt_opc = vecop_list_usra,
.vece = MO_64, },
};
@@ -5993,27 +5991,29 @@ static void gen_shr_ins_vec(unsigned vece, TCGv_vec d, TCGv_vec a, int64_t sh)
}
}
+static const TCGOpcode vecop_list_sri[] = { INDEX_op_shri_vec, 0 };
+
const GVecGen2i sri_op[4] = {
{ .fni8 = gen_shr8_ins_i64,
.fniv = gen_shr_ins_vec,
.load_dest = true,
- .opc = INDEX_op_shri_vec,
+ .opt_opc = vecop_list_sri,
.vece = MO_8 },
{ .fni8 = gen_shr16_ins_i64,
.fniv = gen_shr_ins_vec,
.load_dest = true,
- .opc = INDEX_op_shri_vec,
+ .opt_opc = vecop_list_sri,
.vece = MO_16 },
{ .fni4 = gen_shr32_ins_i32,
.fniv = gen_shr_ins_vec,
.load_dest = true,
- .opc = INDEX_op_shri_vec,
+ .opt_opc = vecop_list_sri,
.vece = MO_32 },
{ .fni8 = gen_shr64_ins_i64,
.fniv = gen_shr_ins_vec,
.prefer_i64 = TCG_TARGET_REG_BITS == 64,
.load_dest = true,
- .opc = INDEX_op_shri_vec,
+ .opt_opc = vecop_list_sri,
.vece = MO_64 },
};
@@ -6069,27 +6069,29 @@ static void gen_shl_ins_vec(unsigned vece, TCGv_vec d, TCGv_vec a, int64_t sh)
}
}
+static const TCGOpcode vecop_list_sli[] = { INDEX_op_shli_vec, 0 };
+
const GVecGen2i sli_op[4] = {
{ .fni8 = gen_shl8_ins_i64,
.fniv = gen_shl_ins_vec,
.load_dest = true,
- .opc = INDEX_op_shli_vec,
+ .opt_opc = vecop_list_sli,
.vece = MO_8 },
{ .fni8 = gen_shl16_ins_i64,
.fniv = gen_shl_ins_vec,
.load_dest = true,
- .opc = INDEX_op_shli_vec,
+ .opt_opc = vecop_list_sli,
.vece = MO_16 },
{ .fni4 = gen_shl32_ins_i32,
.fniv = gen_shl_ins_vec,
.load_dest = true,
- .opc = INDEX_op_shli_vec,
+ .opt_opc = vecop_list_sli,
.vece = MO_32 },
{ .fni8 = gen_shl64_ins_i64,
.fniv = gen_shl_ins_vec,
.prefer_i64 = TCG_TARGET_REG_BITS == 64,
.load_dest = true,
- .opc = INDEX_op_shli_vec,
+ .opt_opc = vecop_list_sli,
.vece = MO_64 },
};
@@ -6156,51 +6158,60 @@ static void gen_mls_vec(unsigned vece, TCGv_vec d, TCGv_vec a, TCGv_vec b)
/* Note that while NEON does not support VMLA and VMLS as 64-bit ops,
* these tables are shared with AArch64 which does support them.
*/
+
+static const TCGOpcode vecop_list_mla[] = {
+ INDEX_op_mul_vec, INDEX_op_add_vec, 0
+};
+
+static const TCGOpcode vecop_list_mls[] = {
+ INDEX_op_mul_vec, INDEX_op_sub_vec, 0
+};
+
const GVecGen3 mla_op[4] = {
{ .fni4 = gen_mla8_i32,
.fniv = gen_mla_vec,
- .opc = INDEX_op_mul_vec,
.load_dest = true,
+ .opt_opc = vecop_list_mla,
.vece = MO_8 },
{ .fni4 = gen_mla16_i32,
.fniv = gen_mla_vec,
- .opc = INDEX_op_mul_vec,
.load_dest = true,
+ .opt_opc = vecop_list_mla,
.vece = MO_16 },
{ .fni4 = gen_mla32_i32,
.fniv = gen_mla_vec,
- .opc = INDEX_op_mul_vec,
.load_dest = true,
+ .opt_opc = vecop_list_mla,
.vece = MO_32 },
{ .fni8 = gen_mla64_i64,
.fniv = gen_mla_vec,
- .opc = INDEX_op_mul_vec,
.prefer_i64 = TCG_TARGET_REG_BITS == 64,
.load_dest = true,
+ .opt_opc = vecop_list_mla,
.vece = MO_64 },
};
const GVecGen3 mls_op[4] = {
{ .fni4 = gen_mls8_i32,
.fniv = gen_mls_vec,
- .opc = INDEX_op_mul_vec,
.load_dest = true,
+ .opt_opc = vecop_list_mls,
.vece = MO_8 },
{ .fni4 = gen_mls16_i32,
.fniv = gen_mls_vec,
- .opc = INDEX_op_mul_vec,
.load_dest = true,
+ .opt_opc = vecop_list_mls,
.vece = MO_16 },
{ .fni4 = gen_mls32_i32,
.fniv = gen_mls_vec,
- .opc = INDEX_op_mul_vec,
.load_dest = true,
+ .opt_opc = vecop_list_mls,
.vece = MO_32 },
{ .fni8 = gen_mls64_i64,
.fniv = gen_mls_vec,
- .opc = INDEX_op_mul_vec,
.prefer_i64 = TCG_TARGET_REG_BITS == 64,
.load_dest = true,
+ .opt_opc = vecop_list_mls,
.vece = MO_64 },
};
@@ -6226,19 +6237,25 @@ static void gen_cmtst_vec(unsigned vece, TCGv_vec d, TCGv_vec a, TCGv_vec b)
tcg_gen_cmp_vec(TCG_COND_NE, vece, d, d, a);
}
+static const TCGOpcode vecop_list_cmtst[] = { INDEX_op_cmp_vec, 0 };
+
const GVecGen3 cmtst_op[4] = {
{ .fni4 = gen_helper_neon_tst_u8,
.fniv = gen_cmtst_vec,
+ .opt_opc = vecop_list_cmtst,
.vece = MO_8 },
{ .fni4 = gen_helper_neon_tst_u16,
.fniv = gen_cmtst_vec,
+ .opt_opc = vecop_list_cmtst,
.vece = MO_16 },
{ .fni4 = gen_cmtst_i32,
.fniv = gen_cmtst_vec,
+ .opt_opc = vecop_list_cmtst,
.vece = MO_32 },
{ .fni8 = gen_cmtst_i64,
.fniv = gen_cmtst_vec,
.prefer_i64 = TCG_TARGET_REG_BITS == 64,
+ .opt_opc = vecop_list_cmtst,
.vece = MO_64 },
};
@@ -6253,26 +6270,30 @@ static void gen_uqadd_vec(unsigned vece, TCGv_vec t, TCGv_vec sat,
tcg_temp_free_vec(x);
}
+static const TCGOpcode vecop_list_uqadd[] = {
+ INDEX_op_usadd_vec, INDEX_op_cmp_vec, INDEX_op_add_vec, 0
+};
+
const GVecGen4 uqadd_op[4] = {
{ .fniv = gen_uqadd_vec,
.fno = gen_helper_gvec_uqadd_b,
- .opc = INDEX_op_usadd_vec,
.write_aofs = true,
+ .opt_opc = vecop_list_uqadd,
.vece = MO_8 },
{ .fniv = gen_uqadd_vec,
.fno = gen_helper_gvec_uqadd_h,
- .opc = INDEX_op_usadd_vec,
.write_aofs = true,
+ .opt_opc = vecop_list_uqadd,
.vece = MO_16 },
{ .fniv = gen_uqadd_vec,
.fno = gen_helper_gvec_uqadd_s,
- .opc = INDEX_op_usadd_vec,
.write_aofs = true,
+ .opt_opc = vecop_list_uqadd,
.vece = MO_32 },
{ .fniv = gen_uqadd_vec,
.fno = gen_helper_gvec_uqadd_d,
- .opc = INDEX_op_usadd_vec,
.write_aofs = true,
+ .opt_opc = vecop_list_uqadd,
.vece = MO_64 },
};
@@ -6287,25 +6308,29 @@ static void gen_sqadd_vec(unsigned vece, TCGv_vec t, TCGv_vec sat,
tcg_temp_free_vec(x);
}
+static const TCGOpcode vecop_list_sqadd[] = {
+ INDEX_op_ssadd_vec, INDEX_op_cmp_vec, INDEX_op_add_vec, 0
+};
+
const GVecGen4 sqadd_op[4] = {
{ .fniv = gen_sqadd_vec,
.fno = gen_helper_gvec_sqadd_b,
- .opc = INDEX_op_ssadd_vec,
+ .opt_opc = vecop_list_sqadd,
.write_aofs = true,
.vece = MO_8 },
{ .fniv = gen_sqadd_vec,
.fno = gen_helper_gvec_sqadd_h,
- .opc = INDEX_op_ssadd_vec,
+ .opt_opc = vecop_list_sqadd,
.write_aofs = true,
.vece = MO_16 },
{ .fniv = gen_sqadd_vec,
.fno = gen_helper_gvec_sqadd_s,
- .opc = INDEX_op_ssadd_vec,
+ .opt_opc = vecop_list_sqadd,
.write_aofs = true,
.vece = MO_32 },
{ .fniv = gen_sqadd_vec,
.fno = gen_helper_gvec_sqadd_d,
- .opc = INDEX_op_ssadd_vec,
+ .opt_opc = vecop_list_sqadd,
.write_aofs = true,
.vece = MO_64 },
};
@@ -6321,25 +6346,29 @@ static void gen_uqsub_vec(unsigned vece, TCGv_vec t, TCGv_vec sat,
tcg_temp_free_vec(x);
}
+static const TCGOpcode vecop_list_uqsub[] = {
+ INDEX_op_ussub_vec, INDEX_op_cmp_vec, INDEX_op_sub_vec, 0
+};
+
const GVecGen4 uqsub_op[4] = {
{ .fniv = gen_uqsub_vec,
.fno = gen_helper_gvec_uqsub_b,
- .opc = INDEX_op_ussub_vec,
+ .opt_opc = vecop_list_uqsub,
.write_aofs = true,
.vece = MO_8 },
{ .fniv = gen_uqsub_vec,
.fno = gen_helper_gvec_uqsub_h,
- .opc = INDEX_op_ussub_vec,
+ .opt_opc = vecop_list_uqsub,
.write_aofs = true,
.vece = MO_16 },
{ .fniv = gen_uqsub_vec,
.fno = gen_helper_gvec_uqsub_s,
- .opc = INDEX_op_ussub_vec,
+ .opt_opc = vecop_list_uqsub,
.write_aofs = true,
.vece = MO_32 },
{ .fniv = gen_uqsub_vec,
.fno = gen_helper_gvec_uqsub_d,
- .opc = INDEX_op_ussub_vec,
+ .opt_opc = vecop_list_uqsub,
.write_aofs = true,
.vece = MO_64 },
};
@@ -6355,25 +6384,29 @@ static void gen_sqsub_vec(unsigned vece, TCGv_vec t, TCGv_vec sat,
tcg_temp_free_vec(x);
}
+static const TCGOpcode vecop_list_sqsub[] = {
+ INDEX_op_sssub_vec, INDEX_op_cmp_vec, INDEX_op_sub_vec, 0
+};
+
const GVecGen4 sqsub_op[4] = {
{ .fniv = gen_sqsub_vec,
.fno = gen_helper_gvec_sqsub_b,
- .opc = INDEX_op_sssub_vec,
+ .opt_opc = vecop_list_sqsub,
.write_aofs = true,
.vece = MO_8 },
{ .fniv = gen_sqsub_vec,
.fno = gen_helper_gvec_sqsub_h,
- .opc = INDEX_op_sssub_vec,
+ .opt_opc = vecop_list_sqsub,
.write_aofs = true,
.vece = MO_16 },
{ .fniv = gen_sqsub_vec,
.fno = gen_helper_gvec_sqsub_s,
- .opc = INDEX_op_sssub_vec,
+ .opt_opc = vecop_list_sqsub,
.write_aofs = true,
.vece = MO_32 },
{ .fniv = gen_sqsub_vec,
.fno = gen_helper_gvec_sqsub_d,
- .opc = INDEX_op_sssub_vec,
+ .opt_opc = vecop_list_sqsub,
.write_aofs = true,
.vece = MO_64 },
};
@@ -8087,6 +8120,9 @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
case NEON_2RM_VNEG:
tcg_gen_gvec_neg(size, rd_ofs, rm_ofs, vec_size, vec_size);
break;
+ case NEON_2RM_VABS:
+ tcg_gen_gvec_abs(size, rd_ofs, rm_ofs, vec_size, vec_size);
+ break;
default:
elementwise:
@@ -8192,14 +8228,6 @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
}
tcg_temp_free_i32(tmp2);
break;
- case NEON_2RM_VABS:
- switch(size) {
- case 0: gen_helper_neon_abs_s8(tmp, tmp); break;
- case 1: gen_helper_neon_abs_s16(tmp, tmp); break;
- case 2: tcg_gen_abs_i32(tmp, tmp); break;
- default: abort();
- }
- break;
case NEON_2RM_VCGT0_F:
{
TCGv_ptr fpstatus = get_fpstatus_ptr(1);
diff --git a/target/cris/translate.c b/target/cris/translate.c
index b005a5c..31b40a5 100644
--- a/target/cris/translate.c
+++ b/target/cris/translate.c
@@ -1686,18 +1686,11 @@ static int dec_cmp_r(CPUCRISState *env, DisasContext *dc)
static int dec_abs_r(CPUCRISState *env, DisasContext *dc)
{
- TCGv t0;
-
LOG_DIS("abs $r%u, $r%u\n",
dc->op1, dc->op2);
cris_cc_mask(dc, CC_MASK_NZ);
- t0 = tcg_temp_new();
- tcg_gen_sari_tl(t0, cpu_R[dc->op1], 31);
- tcg_gen_xor_tl(cpu_R[dc->op2], cpu_R[dc->op1], t0);
- tcg_gen_sub_tl(cpu_R[dc->op2], cpu_R[dc->op2], t0);
- tcg_temp_free(t0);
-
+ tcg_gen_abs_tl(cpu_R[dc->op2], cpu_R[dc->op1]);
cris_alu(dc, CC_OP_MOVE,
cpu_R[dc->op2], cpu_R[dc->op2], cpu_R[dc->op2], 4);
return 2;
diff --git a/target/ppc/translate.c b/target/ppc/translate.c
index 8d08625..b5217f6 100644
--- a/target/ppc/translate.c
+++ b/target/ppc/translate.c
@@ -5075,40 +5075,26 @@ static void gen_ecowx(DisasContext *ctx)
/* abs - abs. */
static void gen_abs(DisasContext *ctx)
{
- TCGLabel *l1 = gen_new_label();
- TCGLabel *l2 = gen_new_label();
- tcg_gen_brcondi_tl(TCG_COND_GE, cpu_gpr[rA(ctx->opcode)], 0, l1);
- tcg_gen_neg_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
- tcg_gen_br(l2);
- gen_set_label(l1);
- tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
- gen_set_label(l2);
+ TCGv d = cpu_gpr[rD(ctx->opcode)];
+ TCGv a = cpu_gpr[rA(ctx->opcode)];
+
+ tcg_gen_abs_tl(d, a);
if (unlikely(Rc(ctx->opcode) != 0)) {
- gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]);
+ gen_set_Rc0(ctx, d);
}
}
/* abso - abso. */
static void gen_abso(DisasContext *ctx)
{
- TCGLabel *l1 = gen_new_label();
- TCGLabel *l2 = gen_new_label();
- TCGLabel *l3 = gen_new_label();
- /* Start with XER OV disabled, the most likely case */
- tcg_gen_movi_tl(cpu_ov, 0);
- tcg_gen_brcondi_tl(TCG_COND_GE, cpu_gpr[rA(ctx->opcode)], 0, l2);
- tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[rA(ctx->opcode)], 0x80000000, l1);
- tcg_gen_movi_tl(cpu_ov, 1);
- tcg_gen_movi_tl(cpu_so, 1);
- tcg_gen_br(l2);
- gen_set_label(l1);
- tcg_gen_neg_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
- tcg_gen_br(l3);
- gen_set_label(l2);
- tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
- gen_set_label(l3);
+ TCGv d = cpu_gpr[rD(ctx->opcode)];
+ TCGv a = cpu_gpr[rA(ctx->opcode)];
+
+ tcg_gen_setcondi_tl(TCG_COND_EQ, cpu_ov, a, 0x80000000);
+ tcg_gen_abs_tl(d, a);
+ tcg_gen_or_tl(cpu_so, cpu_so, cpu_ov);
if (unlikely(Rc(ctx->opcode) != 0)) {
- gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]);
+ gen_set_Rc0(ctx, d);
}
}
@@ -5344,34 +5330,28 @@ static void gen_mulo(DisasContext *ctx)
/* nabs - nabs. */
static void gen_nabs(DisasContext *ctx)
{
- TCGLabel *l1 = gen_new_label();
- TCGLabel *l2 = gen_new_label();
- tcg_gen_brcondi_tl(TCG_COND_GT, cpu_gpr[rA(ctx->opcode)], 0, l1);
- tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
- tcg_gen_br(l2);
- gen_set_label(l1);
- tcg_gen_neg_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
- gen_set_label(l2);
+ TCGv d = cpu_gpr[rD(ctx->opcode)];
+ TCGv a = cpu_gpr[rA(ctx->opcode)];
+
+ tcg_gen_abs_tl(d, a);
+ tcg_gen_neg_tl(d, d);
if (unlikely(Rc(ctx->opcode) != 0)) {
- gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]);
+ gen_set_Rc0(ctx, d);
}
}
/* nabso - nabso. */
static void gen_nabso(DisasContext *ctx)
{
- TCGLabel *l1 = gen_new_label();
- TCGLabel *l2 = gen_new_label();
- tcg_gen_brcondi_tl(TCG_COND_GT, cpu_gpr[rA(ctx->opcode)], 0, l1);
- tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
- tcg_gen_br(l2);
- gen_set_label(l1);
- tcg_gen_neg_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
- gen_set_label(l2);
+ TCGv d = cpu_gpr[rD(ctx->opcode)];
+ TCGv a = cpu_gpr[rA(ctx->opcode)];
+
+ tcg_gen_abs_tl(d, a);
+ tcg_gen_neg_tl(d, d);
/* nabs never overflows */
tcg_gen_movi_tl(cpu_ov, 0);
if (unlikely(Rc(ctx->opcode) != 0)) {
- gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]);
+ gen_set_Rc0(ctx, d);
}
}
diff --git a/target/ppc/translate/spe-impl.inc.c b/target/ppc/translate/spe-impl.inc.c
index 7ab0a29..36b4d56 100644
--- a/target/ppc/translate/spe-impl.inc.c
+++ b/target/ppc/translate/spe-impl.inc.c
@@ -126,19 +126,7 @@ static inline void gen_##name(DisasContext *ctx) \
tcg_temp_free_i32(t0); \
}
-static inline void gen_op_evabs(TCGv_i32 ret, TCGv_i32 arg1)
-{
- TCGLabel *l1 = gen_new_label();
- TCGLabel *l2 = gen_new_label();
-
- tcg_gen_brcondi_i32(TCG_COND_GE, arg1, 0, l1);
- tcg_gen_neg_i32(ret, arg1);
- tcg_gen_br(l2);
- gen_set_label(l1);
- tcg_gen_mov_i32(ret, arg1);
- gen_set_label(l2);
-}
-GEN_SPEOP_ARITH1(evabs, gen_op_evabs);
+GEN_SPEOP_ARITH1(evabs, tcg_gen_abs_i32);
GEN_SPEOP_ARITH1(evneg, tcg_gen_neg_i32);
GEN_SPEOP_ARITH1(evextsb, tcg_gen_ext8s_i32);
GEN_SPEOP_ARITH1(evextsh, tcg_gen_ext16s_i32);
diff --git a/target/ppc/translate/vmx-impl.inc.c b/target/ppc/translate/vmx-impl.inc.c
index bd3ff40..6861f4c 100644
--- a/target/ppc/translate/vmx-impl.inc.c
+++ b/target/ppc/translate/vmx-impl.inc.c
@@ -566,10 +566,15 @@ static void glue(glue(gen_, NAME), _vec)(unsigned vece, TCGv_vec t, \
} \
static void glue(gen_, NAME)(DisasContext *ctx) \
{ \
+ static const TCGOpcode vecop_list[] = { \
+ glue(glue(INDEX_op_, NORM), _vec), \
+ glue(glue(INDEX_op_, SAT), _vec), \
+ INDEX_op_cmp_vec, 0 \
+ }; \
static const GVecGen4 g = { \
.fniv = glue(glue(gen_, NAME), _vec), \
.fno = glue(gen_helper_, NAME), \
- .opc = glue(glue(INDEX_op_, SAT), _vec), \
+ .opt_opc = vecop_list, \
.write_aofs = true, \
.vece = VECE, \
}; \
diff --git a/target/s390x/translate.c b/target/s390x/translate.c
index d495183..e8e8a79 100644
--- a/target/s390x/translate.c
+++ b/target/s390x/translate.c
@@ -1407,13 +1407,7 @@ static DisasJumpType help_branch(DisasContext *s, DisasCompare *c,
static DisasJumpType op_abs(DisasContext *s, DisasOps *o)
{
- TCGv_i64 z, n;
- z = tcg_const_i64(0);
- n = tcg_temp_new_i64();
- tcg_gen_neg_i64(n, o->in2);
- tcg_gen_movcond_i64(TCG_COND_LT, o->out, o->in2, z, n, o->in2);
- tcg_temp_free_i64(n);
- tcg_temp_free_i64(z);
+ tcg_gen_abs_i64(o->out, o->in2);
return DISAS_NEXT;
}
diff --git a/target/tricore/translate.c b/target/tricore/translate.c
index 8f64161..06c4485 100644
--- a/target/tricore/translate.c
+++ b/target/tricore/translate.c
@@ -2415,11 +2415,7 @@ gen_msubadr32s_h(TCGv ret, TCGv r1, TCGv r2, TCGv r3, uint32_t n, uint32_t mode)
static inline void gen_abs(TCGv ret, TCGv r1)
{
- TCGv temp = tcg_temp_new();
- TCGv t0 = tcg_const_i32(0);
-
- tcg_gen_neg_tl(temp, r1);
- tcg_gen_movcond_tl(TCG_COND_GE, ret, r1, t0, r1, temp);
+ tcg_gen_abs_tl(ret, r1);
/* overflow can only happen, if r1 = 0x80000000 */
tcg_gen_setcondi_tl(TCG_COND_EQ, cpu_PSW_V, r1, 0x80000000);
tcg_gen_shli_tl(cpu_PSW_V, cpu_PSW_V, 31);
@@ -2430,9 +2426,6 @@ static inline void gen_abs(TCGv ret, TCGv r1)
tcg_gen_xor_tl(cpu_PSW_AV, ret, cpu_PSW_AV);
/* calc SAV bit */
tcg_gen_or_tl(cpu_PSW_SAV, cpu_PSW_SAV, cpu_PSW_AV);
-
- tcg_temp_free(temp);
- tcg_temp_free(t0);
}
static inline void gen_absdif(TCGv ret, TCGv r1, TCGv r2)
@@ -6617,13 +6610,8 @@ static void decode_rr_divide(CPUTriCoreState *env, DisasContext *ctx)
tcg_gen_movi_tl(cpu_PSW_AV, 0);
if (!tricore_feature(env, TRICORE_FEATURE_131)) {
/* overflow = (abs(D[r3+1]) >= abs(D[r2])) */
- tcg_gen_neg_tl(temp, temp3);
- /* use cpu_PSW_AV to compare against 0 */
- tcg_gen_movcond_tl(TCG_COND_LT, temp, temp3, cpu_PSW_AV,
- temp, temp3);
- tcg_gen_neg_tl(temp2, cpu_gpr_d[r2]);
- tcg_gen_movcond_tl(TCG_COND_LT, temp2, cpu_gpr_d[r2], cpu_PSW_AV,
- temp2, cpu_gpr_d[r2]);
+ tcg_gen_abs_tl(temp, temp3);
+ tcg_gen_abs_tl(temp2, cpu_gpr_d[r2]);
tcg_gen_setcond_tl(TCG_COND_GE, cpu_PSW_V, temp, temp2);
} else {
/* overflow = (D[b] == 0) */
@@ -6655,13 +6643,8 @@ static void decode_rr_divide(CPUTriCoreState *env, DisasContext *ctx)
tcg_gen_movi_tl(cpu_PSW_AV, 0);
if (!tricore_feature(env, TRICORE_FEATURE_131)) {
/* overflow = (abs(D[r3+1]) >= abs(D[r2])) */
- tcg_gen_neg_tl(temp, temp3);
- /* use cpu_PSW_AV to compare against 0 */
- tcg_gen_movcond_tl(TCG_COND_LT, temp, temp3, cpu_PSW_AV,
- temp, temp3);
- tcg_gen_neg_tl(temp2, cpu_gpr_d[r2]);
- tcg_gen_movcond_tl(TCG_COND_LT, temp2, cpu_gpr_d[r2], cpu_PSW_AV,
- temp2, cpu_gpr_d[r2]);
+ tcg_gen_abs_tl(temp, temp3);
+ tcg_gen_abs_tl(temp2, cpu_gpr_d[r2]);
tcg_gen_setcond_tl(TCG_COND_GE, cpu_PSW_V, temp, temp2);
} else {
/* overflow = (D[b] == 0) */
diff --git a/target/xtensa/translate.c b/target/xtensa/translate.c
index 301c8e3..b063fa8 100644
--- a/target/xtensa/translate.c
+++ b/target/xtensa/translate.c
@@ -1709,14 +1709,7 @@ void restore_state_to_opc(CPUXtensaState *env, TranslationBlock *tb,
static void translate_abs(DisasContext *dc, const OpcodeArg arg[],
const uint32_t par[])
{
- TCGv_i32 zero = tcg_const_i32(0);
- TCGv_i32 neg = tcg_temp_new_i32();
-
- tcg_gen_neg_i32(neg, arg[1].in);
- tcg_gen_movcond_i32(TCG_COND_GE, arg[0].out,
- arg[1].in, zero, arg[1].in, neg);
- tcg_temp_free(neg);
- tcg_temp_free(zero);
+ tcg_gen_abs_i32(arg[0].out, arg[1].in);
}
static void translate_add(DisasContext *dc, const OpcodeArg arg[],