target/arm: Convert FCVT (scalar) to decodetree

Remove handle_fp_fcvt and disas_fp_1src as these were
the last insns decoded by those functions.

Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Message-id: 20241211163036.2297116-32-richard.henderson@linaro.org
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
Richard Henderson 2024-12-11 10:29:58 -06:00 committed by Peter Maydell
parent 9982ccec41
commit 7b0f8dc1ec
2 changed files with 74 additions and 105 deletions

View File

@ -1345,6 +1345,13 @@ FRINT32X_s 00011110 0. 1 010001 10000 ..... ..... @rr_sd
FRINT64Z_s 00011110 0. 1 010010 10000 ..... ..... @rr_sd
FRINT64X_s 00011110 0. 1 010011 10000 ..... ..... @rr_sd
FCVT_s_ds 00011110 00 1 000101 10000 ..... ..... @rr
FCVT_s_hs 00011110 00 1 000111 10000 ..... ..... @rr
FCVT_s_sd 00011110 01 1 000100 10000 ..... ..... @rr
FCVT_s_hd 00011110 01 1 000111 10000 ..... ..... @rr
FCVT_s_sh 00011110 11 1 000100 10000 ..... ..... @rr
FCVT_s_dh 00011110 11 1 000101 10000 ..... ..... @rr
# Floating-point Immediate
FMOVI_s 0001 1110 .. 1 imm:8 100 00000 rd:5 esz=%esz_hsd

View File

@ -8443,123 +8443,85 @@ TRANS_FEAT(FRINT64Z_s, aa64_frint, do_fp1_scalar, a,
&f_scalar_frint64, FPROUNDING_ZERO)
TRANS_FEAT(FRINT64X_s, aa64_frint, do_fp1_scalar, a, &f_scalar_frint64, -1)
static void handle_fp_fcvt(DisasContext *s, int opcode,
int rd, int rn, int dtype, int ntype)
static bool trans_FCVT_s_ds(DisasContext *s, arg_rr *a)
{
switch (ntype) {
case 0x0:
{
TCGv_i32 tcg_rn = read_fp_sreg(s, rn);
if (dtype == 1) {
/* Single to double */
if (fp_access_check(s)) {
TCGv_i32 tcg_rn = read_fp_sreg(s, a->rn);
TCGv_i64 tcg_rd = tcg_temp_new_i64();
gen_helper_vfp_fcvtds(tcg_rd, tcg_rn, tcg_env);
write_fp_dreg(s, rd, tcg_rd);
} else {
/* Single to half */
TCGv_i32 tcg_rd = tcg_temp_new_i32();
TCGv_i32 ahp = get_ahp_flag();
TCGv_ptr fpst = fpstatus_ptr(FPST_FPCR);
gen_helper_vfp_fcvt_f32_to_f16(tcg_rd, tcg_rn, fpst, ahp);
/* write_fp_sreg is OK here because top half of tcg_rd is zero */
write_fp_sreg(s, rd, tcg_rd);
}
break;
}
case 0x1:
{
TCGv_i64 tcg_rn = read_fp_dreg(s, rn);
TCGv_i32 tcg_rd = tcg_temp_new_i32();
if (dtype == 0) {
/* Double to single */
gen_helper_vfp_fcvtsd(tcg_rd, tcg_rn, tcg_env);
} else {
TCGv_ptr fpst = fpstatus_ptr(FPST_FPCR);
TCGv_i32 ahp = get_ahp_flag();
/* Double to half */
gen_helper_vfp_fcvt_f64_to_f16(tcg_rd, tcg_rn, fpst, ahp);
/* write_fp_sreg is OK here because top half of tcg_rd is zero */
}
write_fp_sreg(s, rd, tcg_rd);
break;
}
case 0x3:
{
TCGv_i32 tcg_rn = read_fp_sreg(s, rn);
TCGv_ptr tcg_fpst = fpstatus_ptr(FPST_FPCR);
TCGv_i32 tcg_ahp = get_ahp_flag();
tcg_gen_ext16u_i32(tcg_rn, tcg_rn);
if (dtype == 0) {
/* Half to single */
TCGv_i32 tcg_rd = tcg_temp_new_i32();
gen_helper_vfp_fcvt_f16_to_f32(tcg_rd, tcg_rn, tcg_fpst, tcg_ahp);
write_fp_sreg(s, rd, tcg_rd);
} else {
/* Half to double */
TCGv_i64 tcg_rd = tcg_temp_new_i64();
gen_helper_vfp_fcvt_f16_to_f64(tcg_rd, tcg_rn, tcg_fpst, tcg_ahp);
write_fp_dreg(s, rd, tcg_rd);
}
break;
}
default:
g_assert_not_reached();
gen_helper_vfp_fcvtds(tcg_rd, tcg_rn, tcg_env);
write_fp_dreg(s, a->rd, tcg_rd);
}
return true;
}
/* Floating point data-processing (1 source)
* 31 30 29 28 24 23 22 21 20 15 14 10 9 5 4 0
* +---+---+---+-----------+------+---+--------+-----------+------+------+
* | M | 0 | S | 1 1 1 1 0 | type | 1 | opcode | 1 0 0 0 0 | Rn | Rd |
* +---+---+---+-----------+------+---+--------+-----------+------+------+
*/
static void disas_fp_1src(DisasContext *s, uint32_t insn)
static bool trans_FCVT_s_hs(DisasContext *s, arg_rr *a)
{
int mos = extract32(insn, 29, 3);
int type = extract32(insn, 22, 2);
int opcode = extract32(insn, 15, 6);
int rn = extract32(insn, 5, 5);
int rd = extract32(insn, 0, 5);
if (fp_access_check(s)) {
TCGv_i32 tmp = read_fp_sreg(s, a->rn);
TCGv_i32 ahp = get_ahp_flag();
TCGv_ptr fpst = fpstatus_ptr(FPST_FPCR);
if (mos) {
goto do_unallocated;
gen_helper_vfp_fcvt_f32_to_f16(tmp, tmp, fpst, ahp);
/* write_fp_sreg is OK here because top half of result is zero */
write_fp_sreg(s, a->rd, tmp);
}
return true;
}
switch (opcode) {
case 0x4: case 0x5: case 0x7:
{
/* FCVT between half, single and double precision */
int dtype = extract32(opcode, 0, 2);
if (type == 2 || dtype == type) {
goto do_unallocated;
}
if (!fp_access_check(s)) {
return;
}
static bool trans_FCVT_s_sd(DisasContext *s, arg_rr *a)
{
if (fp_access_check(s)) {
TCGv_i64 tcg_rn = read_fp_dreg(s, a->rn);
TCGv_i32 tcg_rd = tcg_temp_new_i32();
handle_fp_fcvt(s, opcode, rd, rn, dtype, type);
break;
gen_helper_vfp_fcvtsd(tcg_rd, tcg_rn, tcg_env);
write_fp_sreg(s, a->rd, tcg_rd);
}
return true;
}
default:
do_unallocated:
case 0x0: /* FMOV */
case 0x1: /* FABS */
case 0x2: /* FNEG */
case 0x3: /* FSQRT */
case 0x6: /* BFCVT */
case 0x8: /* FRINTN */
case 0x9: /* FRINTP */
case 0xa: /* FRINTM */
case 0xb: /* FRINTZ */
case 0xc: /* FRINTA */
case 0xe: /* FRINTX */
case 0xf: /* FRINTI */
case 0x10 ... 0x13: /* FRINT{32,64}{X,Z} */
unallocated_encoding(s);
break;
static bool trans_FCVT_s_hd(DisasContext *s, arg_rr *a)
{
if (fp_access_check(s)) {
TCGv_i64 tcg_rn = read_fp_dreg(s, a->rn);
TCGv_i32 tcg_rd = tcg_temp_new_i32();
TCGv_i32 ahp = get_ahp_flag();
TCGv_ptr fpst = fpstatus_ptr(FPST_FPCR);
gen_helper_vfp_fcvt_f64_to_f16(tcg_rd, tcg_rn, fpst, ahp);
/* write_fp_sreg is OK here because top half of tcg_rd is zero */
write_fp_sreg(s, a->rd, tcg_rd);
}
return true;
}
static bool trans_FCVT_s_sh(DisasContext *s, arg_rr *a)
{
if (fp_access_check(s)) {
TCGv_i32 tcg_rn = read_fp_hreg(s, a->rn);
TCGv_i32 tcg_rd = tcg_temp_new_i32();
TCGv_ptr tcg_fpst = fpstatus_ptr(FPST_FPCR);
TCGv_i32 tcg_ahp = get_ahp_flag();
gen_helper_vfp_fcvt_f16_to_f32(tcg_rd, tcg_rn, tcg_fpst, tcg_ahp);
write_fp_sreg(s, a->rd, tcg_rd);
}
return true;
}
static bool trans_FCVT_s_dh(DisasContext *s, arg_rr *a)
{
if (fp_access_check(s)) {
TCGv_i32 tcg_rn = read_fp_hreg(s, a->rn);
TCGv_i64 tcg_rd = tcg_temp_new_i64();
TCGv_ptr tcg_fpst = fpstatus_ptr(FPST_FPCR);
TCGv_i32 tcg_ahp = get_ahp_flag();
gen_helper_vfp_fcvt_f16_to_f64(tcg_rd, tcg_rn, tcg_fpst, tcg_ahp);
write_fp_dreg(s, a->rd, tcg_rd);
}
return true;
}
/* Handle floating point <=> fixed point conversions. Note that we can
@ -8982,7 +8944,7 @@ static void disas_data_proc_fp(DisasContext *s, uint32_t insn)
break;
case 2: /* [15:12] == x100 */
/* Floating point data-processing (1 source) */
disas_fp_1src(s, insn);
unallocated_encoding(s); /* in decodetree */
break;
case 3: /* [15:12] == 1000 */
unallocated_encoding(s);