mirror of https://github.com/xemu-project/xemu.git
target/arm: Convert FNMUL to decodetree
This is the last instruction within disas_fp_2src, so remove that and its subroutines. Reviewed-by: Peter Maydell <peter.maydell@linaro.org> Signed-off-by: Richard Henderson <richard.henderson@linaro.org> Message-id: 20240524232121.284515-24-richard.henderson@linaro.org Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
parent
21e885aff4
commit
69cefabcac
|
@ -703,6 +703,7 @@ FADD_s 0001 1110 ..1 ..... 0010 10 ..... ..... @rrr_hsd
|
|||
FSUB_s 0001 1110 ..1 ..... 0011 10 ..... ..... @rrr_hsd
|
||||
FDIV_s 0001 1110 ..1 ..... 0001 10 ..... ..... @rrr_hsd
|
||||
FMUL_s 0001 1110 ..1 ..... 0000 10 ..... ..... @rrr_hsd
|
||||
FNMUL_s 0001 1110 ..1 ..... 1000 10 ..... ..... @rrr_hsd
|
||||
|
||||
FMAX_s 0001 1110 ..1 ..... 0100 10 ..... ..... @rrr_hsd
|
||||
FMIN_s 0001 1110 ..1 ..... 0101 10 ..... ..... @rrr_hsd
|
||||
|
|
|
@ -4950,6 +4950,31 @@ static const FPScalar f_scalar_fmulx = {
|
|||
};
|
||||
TRANS(FMULX_s, do_fp3_scalar, a, &f_scalar_fmulx)
|
||||
|
||||
static void gen_fnmul_h(TCGv_i32 d, TCGv_i32 n, TCGv_i32 m, TCGv_ptr s)
|
||||
{
|
||||
gen_helper_vfp_mulh(d, n, m, s);
|
||||
gen_vfp_negh(d, d);
|
||||
}
|
||||
|
||||
static void gen_fnmul_s(TCGv_i32 d, TCGv_i32 n, TCGv_i32 m, TCGv_ptr s)
|
||||
{
|
||||
gen_helper_vfp_muls(d, n, m, s);
|
||||
gen_vfp_negs(d, d);
|
||||
}
|
||||
|
||||
static void gen_fnmul_d(TCGv_i64 d, TCGv_i64 n, TCGv_i64 m, TCGv_ptr s)
|
||||
{
|
||||
gen_helper_vfp_muld(d, n, m, s);
|
||||
gen_vfp_negd(d, d);
|
||||
}
|
||||
|
||||
static const FPScalar f_scalar_fnmul = {
|
||||
gen_fnmul_h,
|
||||
gen_fnmul_s,
|
||||
gen_fnmul_d,
|
||||
};
|
||||
TRANS(FNMUL_s, do_fp3_scalar, a, &f_scalar_fnmul)
|
||||
|
||||
static bool do_fp3_vector(DisasContext *s, arg_qrrr_e *a,
|
||||
gen_helper_gvec_3_ptr * const fns[3])
|
||||
{
|
||||
|
@ -6932,156 +6957,6 @@ static void disas_fp_1src(DisasContext *s, uint32_t insn)
|
|||
}
|
||||
}
|
||||
|
||||
/* Floating-point data-processing (2 source) - single precision */
|
||||
static void handle_fp_2src_single(DisasContext *s, int opcode,
|
||||
int rd, int rn, int rm)
|
||||
{
|
||||
TCGv_i32 tcg_op1;
|
||||
TCGv_i32 tcg_op2;
|
||||
TCGv_i32 tcg_res;
|
||||
TCGv_ptr fpst;
|
||||
|
||||
tcg_res = tcg_temp_new_i32();
|
||||
fpst = fpstatus_ptr(FPST_FPCR);
|
||||
tcg_op1 = read_fp_sreg(s, rn);
|
||||
tcg_op2 = read_fp_sreg(s, rm);
|
||||
|
||||
switch (opcode) {
|
||||
case 0x8: /* FNMUL */
|
||||
gen_helper_vfp_muls(tcg_res, tcg_op1, tcg_op2, fpst);
|
||||
gen_vfp_negs(tcg_res, tcg_res);
|
||||
break;
|
||||
default:
|
||||
case 0x0: /* FMUL */
|
||||
case 0x1: /* FDIV */
|
||||
case 0x2: /* FADD */
|
||||
case 0x3: /* FSUB */
|
||||
case 0x4: /* FMAX */
|
||||
case 0x5: /* FMIN */
|
||||
case 0x6: /* FMAXNM */
|
||||
case 0x7: /* FMINNM */
|
||||
g_assert_not_reached();
|
||||
}
|
||||
|
||||
write_fp_sreg(s, rd, tcg_res);
|
||||
}
|
||||
|
||||
/* Floating-point data-processing (2 source) - double precision */
|
||||
static void handle_fp_2src_double(DisasContext *s, int opcode,
|
||||
int rd, int rn, int rm)
|
||||
{
|
||||
TCGv_i64 tcg_op1;
|
||||
TCGv_i64 tcg_op2;
|
||||
TCGv_i64 tcg_res;
|
||||
TCGv_ptr fpst;
|
||||
|
||||
tcg_res = tcg_temp_new_i64();
|
||||
fpst = fpstatus_ptr(FPST_FPCR);
|
||||
tcg_op1 = read_fp_dreg(s, rn);
|
||||
tcg_op2 = read_fp_dreg(s, rm);
|
||||
|
||||
switch (opcode) {
|
||||
case 0x8: /* FNMUL */
|
||||
gen_helper_vfp_muld(tcg_res, tcg_op1, tcg_op2, fpst);
|
||||
gen_vfp_negd(tcg_res, tcg_res);
|
||||
break;
|
||||
default:
|
||||
case 0x0: /* FMUL */
|
||||
case 0x1: /* FDIV */
|
||||
case 0x2: /* FADD */
|
||||
case 0x3: /* FSUB */
|
||||
case 0x4: /* FMAX */
|
||||
case 0x5: /* FMIN */
|
||||
case 0x6: /* FMAXNM */
|
||||
case 0x7: /* FMINNM */
|
||||
g_assert_not_reached();
|
||||
}
|
||||
|
||||
write_fp_dreg(s, rd, tcg_res);
|
||||
}
|
||||
|
||||
/* Floating-point data-processing (2 source) - half precision */
|
||||
static void handle_fp_2src_half(DisasContext *s, int opcode,
|
||||
int rd, int rn, int rm)
|
||||
{
|
||||
TCGv_i32 tcg_op1;
|
||||
TCGv_i32 tcg_op2;
|
||||
TCGv_i32 tcg_res;
|
||||
TCGv_ptr fpst;
|
||||
|
||||
tcg_res = tcg_temp_new_i32();
|
||||
fpst = fpstatus_ptr(FPST_FPCR_F16);
|
||||
tcg_op1 = read_fp_hreg(s, rn);
|
||||
tcg_op2 = read_fp_hreg(s, rm);
|
||||
|
||||
switch (opcode) {
|
||||
case 0x8: /* FNMUL */
|
||||
gen_helper_advsimd_mulh(tcg_res, tcg_op1, tcg_op2, fpst);
|
||||
gen_vfp_negh(tcg_res, tcg_res);
|
||||
break;
|
||||
default:
|
||||
case 0x0: /* FMUL */
|
||||
case 0x1: /* FDIV */
|
||||
case 0x2: /* FADD */
|
||||
case 0x3: /* FSUB */
|
||||
case 0x4: /* FMAX */
|
||||
case 0x5: /* FMIN */
|
||||
case 0x6: /* FMAXNM */
|
||||
case 0x7: /* FMINNM */
|
||||
g_assert_not_reached();
|
||||
}
|
||||
|
||||
write_fp_sreg(s, rd, tcg_res);
|
||||
}
|
||||
|
||||
/* Floating point data-processing (2 source)
|
||||
* 31 30 29 28 24 23 22 21 20 16 15 12 11 10 9 5 4 0
|
||||
* +---+---+---+-----------+------+---+------+--------+-----+------+------+
|
||||
* | M | 0 | S | 1 1 1 1 0 | type | 1 | Rm | opcode | 1 0 | Rn | Rd |
|
||||
* +---+---+---+-----------+------+---+------+--------+-----+------+------+
|
||||
*/
|
||||
static void disas_fp_2src(DisasContext *s, uint32_t insn)
|
||||
{
|
||||
int mos = extract32(insn, 29, 3);
|
||||
int type = extract32(insn, 22, 2);
|
||||
int rd = extract32(insn, 0, 5);
|
||||
int rn = extract32(insn, 5, 5);
|
||||
int rm = extract32(insn, 16, 5);
|
||||
int opcode = extract32(insn, 12, 4);
|
||||
|
||||
if (opcode > 8 || mos) {
|
||||
unallocated_encoding(s);
|
||||
return;
|
||||
}
|
||||
|
||||
switch (type) {
|
||||
case 0:
|
||||
if (!fp_access_check(s)) {
|
||||
return;
|
||||
}
|
||||
handle_fp_2src_single(s, opcode, rd, rn, rm);
|
||||
break;
|
||||
case 1:
|
||||
if (!fp_access_check(s)) {
|
||||
return;
|
||||
}
|
||||
handle_fp_2src_double(s, opcode, rd, rn, rm);
|
||||
break;
|
||||
case 3:
|
||||
if (!dc_isar_feature(aa64_fp16, s)) {
|
||||
unallocated_encoding(s);
|
||||
return;
|
||||
}
|
||||
if (!fp_access_check(s)) {
|
||||
return;
|
||||
}
|
||||
handle_fp_2src_half(s, opcode, rd, rn, rm);
|
||||
break;
|
||||
default:
|
||||
unallocated_encoding(s);
|
||||
}
|
||||
}
|
||||
|
||||
/* Floating-point data-processing (3 source) - single precision */
|
||||
static void handle_fp_3src_single(DisasContext *s, bool o0, bool o1,
|
||||
int rd, int rn, int rm, int ra)
|
||||
|
@ -7685,7 +7560,7 @@ static void disas_data_proc_fp(DisasContext *s, uint32_t insn)
|
|||
break;
|
||||
case 2:
|
||||
/* Floating point data-processing (2 source) */
|
||||
disas_fp_2src(s, insn);
|
||||
unallocated_encoding(s); /* in decodetree */
|
||||
break;
|
||||
case 3:
|
||||
/* Floating point conditional select */
|
||||
|
|
Loading…
Reference in New Issue