target/arm: Convert FCVT* (vector, integer) to decodetree

Remove handle_2misc_64 as these were the last insns decoded
by that function.  Remove helper_advsimd_f16to[su]inth as unused;
we now always go through helper_vfp_to[su]hh or a specialized
vector function instead.

Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Message-id: 20241211163036.2297116-65-richard.henderson@linaro.org
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
Richard Henderson 2024-12-11 10:30:31 -06:00 committed by Peter Maydell
parent 9a93223c86
commit 475dbea47d
6 changed files with 102 additions and 188 deletions

View file

@ -665,6 +665,8 @@ DEF_HELPER_FLAGS_4(gvec_vcvt_ud, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
DEF_HELPER_FLAGS_4(gvec_vcvt_rz_ds, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32) DEF_HELPER_FLAGS_4(gvec_vcvt_rz_ds, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
DEF_HELPER_FLAGS_4(gvec_vcvt_rz_du, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32) DEF_HELPER_FLAGS_4(gvec_vcvt_rz_du, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
DEF_HELPER_FLAGS_4(gvec_vcvt_rm_sd, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
DEF_HELPER_FLAGS_4(gvec_vcvt_rm_ud, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
DEF_HELPER_FLAGS_4(gvec_vcvt_rm_ss, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32) DEF_HELPER_FLAGS_4(gvec_vcvt_rm_ss, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
DEF_HELPER_FLAGS_4(gvec_vcvt_rm_us, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32) DEF_HELPER_FLAGS_4(gvec_vcvt_rm_us, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
DEF_HELPER_FLAGS_4(gvec_vcvt_rm_sh, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32) DEF_HELPER_FLAGS_4(gvec_vcvt_rm_sh, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)

View file

@ -1793,6 +1793,31 @@ SCVTF_vi 0.00 1110 0.1 00001 11011 0 ..... ..... @qrr_sd
UCVTF_vi 0.10 1110 011 11001 11011 0 ..... ..... @qrr_h UCVTF_vi 0.10 1110 011 11001 11011 0 ..... ..... @qrr_h
UCVTF_vi 0.10 1110 0.1 00001 11011 0 ..... ..... @qrr_sd UCVTF_vi 0.10 1110 0.1 00001 11011 0 ..... ..... @qrr_sd
FCVTNS_vi 0.00 1110 011 11001 10101 0 ..... ..... @qrr_h
FCVTNS_vi 0.00 1110 0.1 00001 10101 0 ..... ..... @qrr_sd
FCVTNU_vi 0.10 1110 011 11001 10101 0 ..... ..... @qrr_h
FCVTNU_vi 0.10 1110 0.1 00001 10101 0 ..... ..... @qrr_sd
FCVTPS_vi 0.00 1110 111 11001 10101 0 ..... ..... @qrr_h
FCVTPS_vi 0.00 1110 1.1 00001 10101 0 ..... ..... @qrr_sd
FCVTPU_vi 0.10 1110 111 11001 10101 0 ..... ..... @qrr_h
FCVTPU_vi 0.10 1110 1.1 00001 10101 0 ..... ..... @qrr_sd
FCVTMS_vi 0.00 1110 011 11001 10111 0 ..... ..... @qrr_h
FCVTMS_vi 0.00 1110 0.1 00001 10111 0 ..... ..... @qrr_sd
FCVTMU_vi 0.10 1110 011 11001 10111 0 ..... ..... @qrr_h
FCVTMU_vi 0.10 1110 0.1 00001 10111 0 ..... ..... @qrr_sd
FCVTZS_vi 0.00 1110 111 11001 10111 0 ..... ..... @qrr_h
FCVTZS_vi 0.00 1110 1.1 00001 10111 0 ..... ..... @qrr_sd
FCVTZU_vi 0.10 1110 111 11001 10111 0 ..... ..... @qrr_h
FCVTZU_vi 0.10 1110 1.1 00001 10111 0 ..... ..... @qrr_sd
FCVTAS_vi 0.00 1110 011 11001 11001 0 ..... ..... @qrr_h
FCVTAS_vi 0.00 1110 0.1 00001 11001 0 ..... ..... @qrr_sd
FCVTAU_vi 0.10 1110 011 11001 11001 0 ..... ..... @qrr_h
FCVTAU_vi 0.10 1110 0.1 00001 11001 0 ..... ..... @qrr_sd
&fcvt_q rd rn esz q shift &fcvt_q rd rn esz q shift
@fcvtq_h . q:1 . ...... 001 .... ...... rn:5 rd:5 \ @fcvtq_h . q:1 . ...... 001 .... ...... rn:5 rd:5 \
&fcvt_q esz=1 shift=%fcvt_f_sh_h &fcvt_q esz=1 shift=%fcvt_f_sh_h

View file

@ -618,38 +618,6 @@ uint32_t HELPER(advsimd_rinth)(uint32_t x, void *fp_status)
return ret; return ret;
} }
/*
* Half-precision floating point conversion functions
*
* There are a multitude of conversion functions with various
* different rounding modes. This is dealt with by the calling code
* setting the mode appropriately before calling the helper.
*/
uint32_t HELPER(advsimd_f16tosinth)(uint32_t a, void *fpstp)
{
float_status *fpst = fpstp;
/* Invalid if we are passed a NaN */
if (float16_is_any_nan(a)) {
float_raise(float_flag_invalid, fpst);
return 0;
}
return float16_to_int16(a, fpst);
}
uint32_t HELPER(advsimd_f16touinth)(uint32_t a, void *fpstp)
{
float_status *fpst = fpstp;
/* Invalid if we are passed a NaN */
if (float16_is_any_nan(a)) {
float_raise(float_flag_invalid, fpst);
return 0;
}
return float16_to_uint16(a, fpst);
}
static int el_from_spsr(uint32_t spsr) static int el_from_spsr(uint32_t spsr)
{ {
/* Return the exception level that this SPSR is requesting a return to, /* Return the exception level that this SPSR is requesting a return to,

View file

@ -74,8 +74,6 @@ DEF_HELPER_3(advsimd_mulx2h, i32, i32, i32, ptr)
DEF_HELPER_4(advsimd_muladd2h, i32, i32, i32, i32, ptr) DEF_HELPER_4(advsimd_muladd2h, i32, i32, i32, i32, ptr)
DEF_HELPER_2(advsimd_rinth_exact, f16, f16, ptr) DEF_HELPER_2(advsimd_rinth_exact, f16, f16, ptr)
DEF_HELPER_2(advsimd_rinth, f16, f16, ptr) DEF_HELPER_2(advsimd_rinth, f16, f16, ptr)
DEF_HELPER_2(advsimd_f16tosinth, i32, f16, ptr)
DEF_HELPER_2(advsimd_f16touinth, i32, f16, ptr)
DEF_HELPER_2(exception_return, void, env, i64) DEF_HELPER_2(exception_return, void, env, i64)
DEF_HELPER_FLAGS_2(dc_zva, TCG_CALL_NO_WG, void, env, i64) DEF_HELPER_FLAGS_2(dc_zva, TCG_CALL_NO_WG, void, env, i64)

View file

@ -9348,56 +9348,38 @@ static gen_helper_gvec_2_ptr * const f_fcvtzu_vf[] = {
TRANS(FCVTZU_vf, do_gvec_op2_fpst, TRANS(FCVTZU_vf, do_gvec_op2_fpst,
a->esz, a->q, a->rd, a->rn, a->shift, f_fcvtzu_vf) a->esz, a->q, a->rd, a->rn, a->shift, f_fcvtzu_vf)
static void handle_2misc_64(DisasContext *s, int opcode, bool u, static gen_helper_gvec_2_ptr * const f_fcvt_s_vi[] = {
TCGv_i64 tcg_rd, TCGv_i64 tcg_rn, gen_helper_gvec_vcvt_rm_sh,
TCGv_i32 tcg_rmode, TCGv_ptr tcg_fpstatus) gen_helper_gvec_vcvt_rm_ss,
{ gen_helper_gvec_vcvt_rm_sd,
/* Handle 64->64 opcodes which are shared between the scalar and };
* vector 2-reg-misc groups. We cover every integer opcode where size == 3
* is valid in either group and also the double-precision fp ops. static gen_helper_gvec_2_ptr * const f_fcvt_u_vi[] = {
* The caller only need provide tcg_rmode and tcg_fpstatus if the op gen_helper_gvec_vcvt_rm_uh,
* requires them. gen_helper_gvec_vcvt_rm_us,
*/ gen_helper_gvec_vcvt_rm_ud,
switch (opcode) { };
case 0x1a: /* FCVTNS */
case 0x1b: /* FCVTMS */ TRANS(FCVTNS_vi, do_gvec_op2_fpst,
case 0x1c: /* FCVTAS */ a->esz, a->q, a->rd, a->rn, float_round_nearest_even, f_fcvt_s_vi)
case 0x3a: /* FCVTPS */ TRANS(FCVTNU_vi, do_gvec_op2_fpst,
case 0x3b: /* FCVTZS */ a->esz, a->q, a->rd, a->rn, float_round_nearest_even, f_fcvt_u_vi)
gen_helper_vfp_tosqd(tcg_rd, tcg_rn, tcg_constant_i32(0), tcg_fpstatus); TRANS(FCVTPS_vi, do_gvec_op2_fpst,
break; a->esz, a->q, a->rd, a->rn, float_round_up, f_fcvt_s_vi)
case 0x5a: /* FCVTNU */ TRANS(FCVTPU_vi, do_gvec_op2_fpst,
case 0x5b: /* FCVTMU */ a->esz, a->q, a->rd, a->rn, float_round_up, f_fcvt_u_vi)
case 0x5c: /* FCVTAU */ TRANS(FCVTMS_vi, do_gvec_op2_fpst,
case 0x7a: /* FCVTPU */ a->esz, a->q, a->rd, a->rn, float_round_down, f_fcvt_s_vi)
case 0x7b: /* FCVTZU */ TRANS(FCVTMU_vi, do_gvec_op2_fpst,
gen_helper_vfp_touqd(tcg_rd, tcg_rn, tcg_constant_i32(0), tcg_fpstatus); a->esz, a->q, a->rd, a->rn, float_round_down, f_fcvt_u_vi)
break; TRANS(FCVTZS_vi, do_gvec_op2_fpst,
default: a->esz, a->q, a->rd, a->rn, float_round_to_zero, f_fcvt_s_vi)
case 0x4: /* CLS, CLZ */ TRANS(FCVTZU_vi, do_gvec_op2_fpst,
case 0x5: /* NOT */ a->esz, a->q, a->rd, a->rn, float_round_to_zero, f_fcvt_u_vi)
case 0x7: /* SQABS, SQNEG */ TRANS(FCVTAS_vi, do_gvec_op2_fpst,
case 0x8: /* CMGT, CMGE */ a->esz, a->q, a->rd, a->rn, float_round_ties_away, f_fcvt_s_vi)
case 0x9: /* CMEQ, CMLE */ TRANS(FCVTAU_vi, do_gvec_op2_fpst,
case 0xa: /* CMLT */ a->esz, a->q, a->rd, a->rn, float_round_ties_away, f_fcvt_u_vi)
case 0xb: /* ABS, NEG */
case 0x2f: /* FABS */
case 0x6f: /* FNEG */
case 0x7f: /* FSQRT */
case 0x18: /* FRINTN */
case 0x19: /* FRINTM */
case 0x38: /* FRINTP */
case 0x39: /* FRINTZ */
case 0x58: /* FRINTA */
case 0x79: /* FRINTI */
case 0x59: /* FRINTX */
case 0x1e: /* FRINT32Z */
case 0x5e: /* FRINT32X */
case 0x1f: /* FRINT64Z */
case 0x5f: /* FRINT64X */
g_assert_not_reached();
}
}
static void handle_2misc_fcmp_zero(DisasContext *s, int opcode, static void handle_2misc_fcmp_zero(DisasContext *s, int opcode,
bool is_scalar, bool is_u, bool is_q, bool is_scalar, bool is_u, bool is_q,
@ -9758,30 +9740,6 @@ static void disas_simd_two_reg_misc(DisasContext *s, uint32_t insn)
} }
handle_2misc_fcmp_zero(s, opcode, false, u, is_q, size, rn, rd); handle_2misc_fcmp_zero(s, opcode, false, u, is_q, size, rn, rd);
return; return;
case 0x1a: /* FCVTNS */
case 0x1b: /* FCVTMS */
case 0x3a: /* FCVTPS */
case 0x3b: /* FCVTZS */
case 0x5a: /* FCVTNU */
case 0x5b: /* FCVTMU */
case 0x7a: /* FCVTPU */
case 0x7b: /* FCVTZU */
need_fpstatus = true;
rmode = extract32(opcode, 5, 1) | (extract32(opcode, 0, 1) << 1);
if (size == 3 && !is_q) {
unallocated_encoding(s);
return;
}
break;
case 0x5c: /* FCVTAU */
case 0x1c: /* FCVTAS */
need_fpstatus = true;
rmode = FPROUNDING_TIEAWAY;
if (size == 3 && !is_q) {
unallocated_encoding(s);
return;
}
break;
case 0x3c: /* URECPE */ case 0x3c: /* URECPE */
if (size == 3) { if (size == 3) {
unallocated_encoding(s); unallocated_encoding(s);
@ -9831,6 +9789,16 @@ static void disas_simd_two_reg_misc(DisasContext *s, uint32_t insn)
case 0x5f: /* FRINT64X */ case 0x5f: /* FRINT64X */
case 0x1d: /* SCVTF */ case 0x1d: /* SCVTF */
case 0x5d: /* UCVTF */ case 0x5d: /* UCVTF */
case 0x1a: /* FCVTNS */
case 0x1b: /* FCVTMS */
case 0x3a: /* FCVTPS */
case 0x3b: /* FCVTZS */
case 0x5a: /* FCVTNU */
case 0x5b: /* FCVTMU */
case 0x7a: /* FCVTPU */
case 0x7b: /* FCVTZU */
case 0x5c: /* FCVTAU */
case 0x1c: /* FCVTAS */
unallocated_encoding(s); unallocated_encoding(s);
return; return;
} }
@ -9871,26 +9839,7 @@ static void disas_simd_two_reg_misc(DisasContext *s, uint32_t insn)
tcg_rmode = NULL; tcg_rmode = NULL;
} }
if (size == 3) { {
/* All 64-bit element operations can be shared with scalar 2misc */
int pass;
/* Coverity claims (size == 3 && !is_q) has been eliminated
* from all paths leading to here.
*/
tcg_debug_assert(is_q);
for (pass = 0; pass < 2; pass++) {
TCGv_i64 tcg_op = tcg_temp_new_i64();
TCGv_i64 tcg_res = tcg_temp_new_i64();
read_vec_element(s, tcg_op, rn, pass, MO_64);
handle_2misc_64(s, opcode, u, tcg_res, tcg_op,
tcg_rmode, tcg_fpstatus);
write_vec_element(s, tcg_res, rd, pass, MO_64);
}
} else {
int pass; int pass;
assert(size == 2); assert(size == 2);
@ -9903,22 +9852,6 @@ static void disas_simd_two_reg_misc(DisasContext *s, uint32_t insn)
{ {
/* Special cases for 32 bit elements */ /* Special cases for 32 bit elements */
switch (opcode) { switch (opcode) {
case 0x1a: /* FCVTNS */
case 0x1b: /* FCVTMS */
case 0x1c: /* FCVTAS */
case 0x3a: /* FCVTPS */
case 0x3b: /* FCVTZS */
gen_helper_vfp_tosls(tcg_res, tcg_op,
tcg_constant_i32(0), tcg_fpstatus);
break;
case 0x5a: /* FCVTNU */
case 0x5b: /* FCVTMU */
case 0x5c: /* FCVTAU */
case 0x7a: /* FCVTPU */
case 0x7b: /* FCVTZU */
gen_helper_vfp_touls(tcg_res, tcg_op,
tcg_constant_i32(0), tcg_fpstatus);
break;
case 0x7c: /* URSQRTE */ case 0x7c: /* URSQRTE */
gen_helper_rsqrte_u32(tcg_res, tcg_op); gen_helper_rsqrte_u32(tcg_res, tcg_op);
break; break;
@ -9938,6 +9871,16 @@ static void disas_simd_two_reg_misc(DisasContext *s, uint32_t insn)
case 0x5e: /* FRINT32X */ case 0x5e: /* FRINT32X */
case 0x1f: /* FRINT64Z */ case 0x1f: /* FRINT64Z */
case 0x5f: /* FRINT64X */ case 0x5f: /* FRINT64X */
case 0x1a: /* FCVTNS */
case 0x1b: /* FCVTMS */
case 0x1c: /* FCVTAS */
case 0x3a: /* FCVTPS */
case 0x3b: /* FCVTZS */
case 0x5a: /* FCVTNU */
case 0x5b: /* FCVTMU */
case 0x5c: /* FCVTAU */
case 0x7a: /* FCVTPU */
case 0x7b: /* FCVTZU */
g_assert_not_reached(); g_assert_not_reached();
} }
} }
@ -10006,36 +9949,6 @@ static void disas_simd_two_reg_misc_fp16(DisasContext *s, uint32_t insn)
case 0x3d: /* FRECPE */ case 0x3d: /* FRECPE */
case 0x3f: /* FRECPX */ case 0x3f: /* FRECPX */
break; break;
case 0x1a: /* FCVTNS */
rmode = FPROUNDING_TIEEVEN;
break;
case 0x1b: /* FCVTMS */
rmode = FPROUNDING_NEGINF;
break;
case 0x1c: /* FCVTAS */
rmode = FPROUNDING_TIEAWAY;
break;
case 0x3a: /* FCVTPS */
rmode = FPROUNDING_POSINF;
break;
case 0x3b: /* FCVTZS */
rmode = FPROUNDING_ZERO;
break;
case 0x5a: /* FCVTNU */
rmode = FPROUNDING_TIEEVEN;
break;
case 0x5b: /* FCVTMU */
rmode = FPROUNDING_NEGINF;
break;
case 0x5c: /* FCVTAU */
rmode = FPROUNDING_TIEAWAY;
break;
case 0x7a: /* FCVTPU */
rmode = FPROUNDING_POSINF;
break;
case 0x7b: /* FCVTZU */
rmode = FPROUNDING_ZERO;
break;
case 0x7d: /* FRSQRTE */ case 0x7d: /* FRSQRTE */
break; break;
default: default:
@ -10051,6 +9964,16 @@ static void disas_simd_two_reg_misc_fp16(DisasContext *s, uint32_t insn)
case 0x79: /* FRINTI */ case 0x79: /* FRINTI */
case 0x1d: /* SCVTF */ case 0x1d: /* SCVTF */
case 0x5d: /* UCVTF */ case 0x5d: /* UCVTF */
case 0x1a: /* FCVTNS */
case 0x1b: /* FCVTMS */
case 0x1c: /* FCVTAS */
case 0x3a: /* FCVTPS */
case 0x3b: /* FCVTZS */
case 0x5a: /* FCVTNU */
case 0x5b: /* FCVTMU */
case 0x5c: /* FCVTAU */
case 0x7a: /* FCVTPU */
case 0x7b: /* FCVTZU */
unallocated_encoding(s); unallocated_encoding(s);
return; return;
} }
@ -10115,23 +10038,9 @@ static void disas_simd_two_reg_misc_fp16(DisasContext *s, uint32_t insn)
read_vec_element_i32(s, tcg_op, rn, pass, MO_16); read_vec_element_i32(s, tcg_op, rn, pass, MO_16);
switch (fpop) { switch (fpop) {
case 0x1a: /* FCVTNS */
case 0x1b: /* FCVTMS */
case 0x1c: /* FCVTAS */
case 0x3a: /* FCVTPS */
case 0x3b: /* FCVTZS */
gen_helper_advsimd_f16tosinth(tcg_res, tcg_op, tcg_fpstatus);
break;
case 0x3d: /* FRECPE */ case 0x3d: /* FRECPE */
gen_helper_recpe_f16(tcg_res, tcg_op, tcg_fpstatus); gen_helper_recpe_f16(tcg_res, tcg_op, tcg_fpstatus);
break; break;
case 0x5a: /* FCVTNU */
case 0x5b: /* FCVTMU */
case 0x5c: /* FCVTAU */
case 0x7a: /* FCVTPU */
case 0x7b: /* FCVTZU */
gen_helper_advsimd_f16touinth(tcg_res, tcg_op, tcg_fpstatus);
break;
case 0x7d: /* FRSQRTE */ case 0x7d: /* FRSQRTE */
gen_helper_rsqrte_f16(tcg_res, tcg_op, tcg_fpstatus); gen_helper_rsqrte_f16(tcg_res, tcg_op, tcg_fpstatus);
break; break;
@ -10146,6 +10055,16 @@ static void disas_simd_two_reg_misc_fp16(DisasContext *s, uint32_t insn)
case 0x58: /* FRINTA */ case 0x58: /* FRINTA */
case 0x79: /* FRINTI */ case 0x79: /* FRINTI */
case 0x59: /* FRINTX */ case 0x59: /* FRINTX */
case 0x1a: /* FCVTNS */
case 0x1b: /* FCVTMS */
case 0x1c: /* FCVTAS */
case 0x3a: /* FCVTPS */
case 0x3b: /* FCVTZS */
case 0x5a: /* FCVTNU */
case 0x5b: /* FCVTMU */
case 0x5c: /* FCVTAU */
case 0x7a: /* FCVTPU */
case 0x7b: /* FCVTZU */
g_assert_not_reached(); g_assert_not_reached();
} }

View file

@ -2537,6 +2537,8 @@ DO_VCVT_FIXED(gvec_vcvt_rz_hu, helper_vfp_touhh_round_to_zero, uint16_t)
clear_tail(d, oprsz, simd_maxsz(desc)); \ clear_tail(d, oprsz, simd_maxsz(desc)); \
} }
DO_VCVT_RMODE(gvec_vcvt_rm_sd, helper_vfp_tosqd, uint64_t)
DO_VCVT_RMODE(gvec_vcvt_rm_ud, helper_vfp_touqd, uint64_t)
DO_VCVT_RMODE(gvec_vcvt_rm_ss, helper_vfp_tosls, uint32_t) DO_VCVT_RMODE(gvec_vcvt_rm_ss, helper_vfp_tosls, uint32_t)
DO_VCVT_RMODE(gvec_vcvt_rm_us, helper_vfp_touls, uint32_t) DO_VCVT_RMODE(gvec_vcvt_rm_us, helper_vfp_touls, uint32_t)
DO_VCVT_RMODE(gvec_vcvt_rm_sh, helper_vfp_toshh, uint16_t) DO_VCVT_RMODE(gvec_vcvt_rm_sh, helper_vfp_toshh, uint16_t)