aboutsummaryrefslogtreecommitdiff
path: root/target/arm/tcg/translate-a64.c
diff options
context:
space:
mode:
authorRichard Henderson <richard.henderson@linaro.org>2024-05-28 13:30:17 -0700
committerPeter Maydell <peter.maydell@linaro.org>2024-05-30 15:24:39 +0100
commitf4fa83d6148f9d9bbd543c776e6cdc919c43c8e3 (patch)
tree2dba80d126021dc99a2da9af9ab5de885f1dd925 /target/arm/tcg/translate-a64.c
parent1217edace8a5f1f8c4eb7f0648ff47eccd08bc8e (diff)
target/arm: Inline scalar SQADD, UQADD, SQSUB, UQSUB
This eliminates the last uses of these neon helpers. Incorporate the MO_64 expanders as an option to the vector expander. Reviewed-by: Peter Maydell <peter.maydell@linaro.org> Signed-off-by: Richard Henderson <richard.henderson@linaro.org> Message-id: 20240528203044.612851-7-richard.henderson@linaro.org Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to 'target/arm/tcg/translate-a64.c')
-rw-r--r--target/arm/tcg/translate-a64.c67
1 files changed, 38 insertions, 29 deletions
diff --git a/target/arm/tcg/translate-a64.c b/target/arm/tcg/translate-a64.c
index 781b224972..ca7ba6b1e8 100644
--- a/target/arm/tcg/translate-a64.c
+++ b/target/arm/tcg/translate-a64.c
@@ -9291,21 +9291,28 @@ static void handle_3same_64(DisasContext *s, int opcode, bool u,
* or scalar-three-reg-same groups.
*/
TCGCond cond;
+ TCGv_i64 qc;
switch (opcode) {
case 0x1: /* SQADD */
+ qc = tcg_temp_new_i64();
+ tcg_gen_ld_i64(qc, tcg_env, offsetof(CPUARMState, vfp.qc));
if (u) {
- gen_helper_neon_qadd_u64(tcg_rd, tcg_env, tcg_rn, tcg_rm);
+ gen_uqadd_d(tcg_rd, qc, tcg_rn, tcg_rm);
} else {
- gen_helper_neon_qadd_s64(tcg_rd, tcg_env, tcg_rn, tcg_rm);
+ gen_sqadd_d(tcg_rd, qc, tcg_rn, tcg_rm);
}
+ tcg_gen_st_i64(qc, tcg_env, offsetof(CPUARMState, vfp.qc));
break;
case 0x5: /* SQSUB */
+ qc = tcg_temp_new_i64();
+ tcg_gen_ld_i64(qc, tcg_env, offsetof(CPUARMState, vfp.qc));
if (u) {
- gen_helper_neon_qsub_u64(tcg_rd, tcg_env, tcg_rn, tcg_rm);
+ gen_uqsub_d(tcg_rd, qc, tcg_rn, tcg_rm);
} else {
- gen_helper_neon_qsub_s64(tcg_rd, tcg_env, tcg_rn, tcg_rm);
+ gen_sqsub_d(tcg_rd, qc, tcg_rn, tcg_rm);
}
+ tcg_gen_st_i64(qc, tcg_env, offsetof(CPUARMState, vfp.qc));
break;
case 0x6: /* CMGT, CMHI */
cond = u ? TCG_COND_GTU : TCG_COND_GT;
@@ -9425,35 +9432,16 @@ static void disas_simd_scalar_three_reg_same(DisasContext *s, uint32_t insn)
* OPTME: special-purpose helpers would avoid doing some
* unnecessary work in the helper for the 8 and 16 bit cases.
*/
- NeonGenTwoOpEnvFn *genenvfn;
- TCGv_i32 tcg_rn = tcg_temp_new_i32();
- TCGv_i32 tcg_rm = tcg_temp_new_i32();
- TCGv_i32 tcg_rd32 = tcg_temp_new_i32();
-
- read_vec_element_i32(s, tcg_rn, rn, 0, size);
- read_vec_element_i32(s, tcg_rm, rm, 0, size);
+ NeonGenTwoOpEnvFn *genenvfn = NULL;
+ void (*genfn)(TCGv_i64, TCGv_i64, TCGv_i64, TCGv_i64, MemOp) = NULL;
switch (opcode) {
case 0x1: /* SQADD, UQADD */
- {
- static NeonGenTwoOpEnvFn * const fns[3][2] = {
- { gen_helper_neon_qadd_s8, gen_helper_neon_qadd_u8 },
- { gen_helper_neon_qadd_s16, gen_helper_neon_qadd_u16 },
- { gen_helper_neon_qadd_s32, gen_helper_neon_qadd_u32 },
- };
- genenvfn = fns[size][u];
+ genfn = u ? gen_uqadd_bhs : gen_sqadd_bhs;
break;
- }
case 0x5: /* SQSUB, UQSUB */
- {
- static NeonGenTwoOpEnvFn * const fns[3][2] = {
- { gen_helper_neon_qsub_s8, gen_helper_neon_qsub_u8 },
- { gen_helper_neon_qsub_s16, gen_helper_neon_qsub_u16 },
- { gen_helper_neon_qsub_s32, gen_helper_neon_qsub_u32 },
- };
- genenvfn = fns[size][u];
+ genfn = u ? gen_uqsub_bhs : gen_sqsub_bhs;
break;
- }
case 0x9: /* SQSHL, UQSHL */
{
static NeonGenTwoOpEnvFn * const fns[3][2] = {
@@ -9488,8 +9476,29 @@ static void disas_simd_scalar_three_reg_same(DisasContext *s, uint32_t insn)
g_assert_not_reached();
}
- genenvfn(tcg_rd32, tcg_env, tcg_rn, tcg_rm);
- tcg_gen_extu_i32_i64(tcg_rd, tcg_rd32);
+ if (genenvfn) {
+ TCGv_i32 tcg_rn = tcg_temp_new_i32();
+ TCGv_i32 tcg_rm = tcg_temp_new_i32();
+
+ read_vec_element_i32(s, tcg_rn, rn, 0, size);
+ read_vec_element_i32(s, tcg_rm, rm, 0, size);
+ genenvfn(tcg_rn, tcg_env, tcg_rn, tcg_rm);
+ tcg_gen_extu_i32_i64(tcg_rd, tcg_rn);
+ } else {
+ TCGv_i64 tcg_rn = tcg_temp_new_i64();
+ TCGv_i64 tcg_rm = tcg_temp_new_i64();
+ TCGv_i64 qc = tcg_temp_new_i64();
+
+ read_vec_element(s, tcg_rn, rn, 0, size | (u ? 0 : MO_SIGN));
+ read_vec_element(s, tcg_rm, rm, 0, size | (u ? 0 : MO_SIGN));
+ tcg_gen_ld_i64(qc, tcg_env, offsetof(CPUARMState, vfp.qc));
+ genfn(tcg_rd, qc, tcg_rn, tcg_rm, size);
+ tcg_gen_st_i64(qc, tcg_env, offsetof(CPUARMState, vfp.qc));
+ if (!u) {
+ /* Truncate signed 64-bit result for writeback. */
+ tcg_gen_ext_i64(tcg_rd, tcg_rd, size);
+ }
+ }
}
write_fp_dreg(s, rd, tcg_rd);