target/arm: Convert SUQADD, USQADD to decodetree
These are faux 2-operand instructions, reading from rd.
Sort them next to the other three-operand same insns for clarity.
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Message-id: 20240528203044.612851-9-richard.henderson@linaro.org
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
diff --git a/target/arm/tcg/a64.decode b/target/arm/tcg/a64.decode
index 19010af..7c350ba 100644
--- a/target/arm/tcg/a64.decode
+++ b/target/arm/tcg/a64.decode
@@ -45,6 +45,7 @@
@rrr_sd ........ ... rm:5 ...... rn:5 rd:5 &rrr_e esz=%esz_sd
@rrr_hsd ........ ... rm:5 ...... rn:5 rd:5 &rrr_e esz=%esz_hsd
@rrr_e ........ esz:2 . rm:5 ...... rn:5 rd:5 &rrr_e
+@r2r_e ........ esz:2 . ..... ...... rm:5 rd:5 &rrr_e rn=%rd
@rrx_h ........ .. .. rm:4 .... . . rn:5 rd:5 &rrx_e esz=1 idx=%hlm
@rrx_s ........ .. . rm:5 .... . . rn:5 rd:5 &rrx_e esz=2 idx=%hl
@@ -60,6 +61,7 @@
@qrrr_h . q:1 ...... ... rm:5 ...... rn:5 rd:5 &qrrr_e esz=1
@qrrr_sd . q:1 ...... ... rm:5 ...... rn:5 rd:5 &qrrr_e esz=%esz_sd
@qrrr_e . q:1 ...... esz:2 . rm:5 ...... rn:5 rd:5 &qrrr_e
+@qr2r_e . q:1 ...... esz:2 . ..... ...... rm:5 rd:5 &qrrr_e rn=%rd
@qrrx_h . q:1 .. .... .. .. rm:4 .... . . rn:5 rd:5 \
&qrrx_e esz=1 idx=%hlm
@@ -750,6 +752,9 @@
SQSUB_s 0101 1110 ..1 ..... 00101 1 ..... ..... @rrr_e
UQSUB_s 0111 1110 ..1 ..... 00101 1 ..... ..... @rrr_e
+SUQADD_s 0101 1110 ..1 00000 00111 0 ..... ..... @r2r_e
+USQADD_s 0111 1110 ..1 00000 00111 0 ..... ..... @r2r_e
+
### Advanced SIMD scalar pairwise
FADDP_s 0101 1110 0011 0000 1101 10 ..... ..... @rr_h
@@ -868,6 +873,9 @@
SQSUB_v 0.00 1110 ..1 ..... 00101 1 ..... ..... @qrrr_e
UQSUB_v 0.10 1110 ..1 ..... 00101 1 ..... ..... @qrrr_e
+SUQADD_v 0.00 1110 ..1 00000 00111 0 ..... ..... @qr2r_e
+USQADD_v 0.10 1110 ..1 00000 00111 0 ..... ..... @qr2r_e
+
### Advanced SIMD scalar x indexed element
FMUL_si 0101 1111 00 .. .... 1001 . 0 ..... ..... @rrx_h
diff --git a/target/arm/tcg/translate-a64.c b/target/arm/tcg/translate-a64.c
index 3956c41..c0637bd 100644
--- a/target/arm/tcg/translate-a64.c
+++ b/target/arm/tcg/translate-a64.c
@@ -5096,6 +5096,8 @@
TRANS(SQSUB_s, do_satacc_s, a, MO_SIGN, MO_SIGN, gen_sqsub_bhs, gen_sqsub_d)
TRANS(UQADD_s, do_satacc_s, a, 0, 0, gen_uqadd_bhs, gen_uqadd_d)
TRANS(UQSUB_s, do_satacc_s, a, 0, 0, gen_uqsub_bhs, gen_uqsub_d)
+TRANS(SUQADD_s, do_satacc_s, a, MO_SIGN, 0, gen_suqadd_bhs, gen_suqadd_d)
+TRANS(USQADD_s, do_satacc_s, a, 0, MO_SIGN, gen_usqadd_bhs, gen_usqadd_d)
static bool do_fp3_vector(DisasContext *s, arg_qrrr_e *a,
gen_helper_gvec_3_ptr * const fns[3])
@@ -5339,6 +5341,8 @@
TRANS(UQADD_v, do_gvec_fn3, a, gen_gvec_uqadd_qc)
TRANS(SQSUB_v, do_gvec_fn3, a, gen_gvec_sqsub_qc)
TRANS(UQSUB_v, do_gvec_fn3, a, gen_gvec_uqsub_qc)
+TRANS(SUQADD_v, do_gvec_fn3, a, gen_gvec_suqadd_qc)
+TRANS(USQADD_v, do_gvec_fn3, a, gen_gvec_usqadd_qc)
/*
* Advanced SIMD scalar/vector x indexed element
@@ -10009,48 +10013,6 @@
clear_vec_high(s, is_q, rd);
}
-/* Remaining saturating accumulating ops */
-static void handle_2misc_satacc(DisasContext *s, bool is_scalar, bool is_u,
- bool is_q, unsigned size, int rn, int rd)
-{
- TCGv_i64 res, qc, a, b;
-
- if (!is_scalar) {
- gen_gvec_fn3(s, is_q, rd, rd, rn,
- is_u ? gen_gvec_usqadd_qc : gen_gvec_suqadd_qc, size);
- return;
- }
-
- res = tcg_temp_new_i64();
- qc = tcg_temp_new_i64();
- a = tcg_temp_new_i64();
- b = tcg_temp_new_i64();
-
- /* Read and extend scalar inputs to 64-bits. */
- read_vec_element(s, a, rd, 0, size | (is_u ? 0 : MO_SIGN));
- read_vec_element(s, b, rn, 0, size | (is_u ? MO_SIGN : 0));
- tcg_gen_ld_i64(qc, tcg_env, offsetof(CPUARMState, vfp.qc));
-
- if (size == MO_64) {
- if (is_u) {
- gen_usqadd_d(res, qc, a, b);
- } else {
- gen_suqadd_d(res, qc, a, b);
- }
- } else {
- if (is_u) {
- gen_usqadd_bhs(res, qc, a, b, size);
- } else {
- gen_suqadd_bhs(res, qc, a, b, size);
- /* Truncate signed 64-bit result for writeback. */
- tcg_gen_ext_i64(res, res, size);
- }
- }
-
- write_fp_dreg(s, rd, res);
- tcg_gen_st_i64(qc, tcg_env, offsetof(CPUARMState, vfp.qc));
-}
-
/* AdvSIMD scalar two reg misc
* 31 30 29 28 24 23 22 21 17 16 12 11 10 9 5 4 0
* +-----+---+-----------+------+-----------+--------+-----+------+------+
@@ -10070,12 +10032,6 @@
TCGv_ptr tcg_fpstatus;
switch (opcode) {
- case 0x3: /* USQADD / SUQADD*/
- if (!fp_access_check(s)) {
- return;
- }
- handle_2misc_satacc(s, true, u, false, size, rn, rd);
- return;
case 0x7: /* SQABS / SQNEG */
break;
case 0xa: /* CMLT */
@@ -10175,6 +10131,7 @@
}
break;
default:
+ case 0x3: /* USQADD / SUQADD */
unallocated_encoding(s);
return;
}
@@ -11662,16 +11619,6 @@
return;
}
break;
- case 0x3: /* SUQADD, USQADD */
- if (size == 3 && !is_q) {
- unallocated_encoding(s);
- return;
- }
- if (!fp_access_check(s)) {
- return;
- }
- handle_2misc_satacc(s, false, u, is_q, size, rn, rd);
- return;
case 0x7: /* SQABS, SQNEG */
if (size == 3 && !is_q) {
unallocated_encoding(s);
@@ -11846,6 +11793,7 @@
break;
}
default:
+ case 0x3: /* SUQADD, USQADD */
unallocated_encoding(s);
return;
}