target/arm: Gate "miscellaneous FP" insns by ID register field
There is a set of VFP instructions which we implement in disas_vfp_v8_insn() and gate on the ARM_FEATURE_V8 bit. These were all first introduced in v8 for A-profile, but in M-profile they appeared in v7M. Gate them on the MVFR2 FPMisc field instead, and rename the function appropriately. Signed-off-by: Peter Maydell <peter.maydell@linaro.org> Reviewed-by: Richard Henderson <richard.henderson@linaro.org> Message-id: 20190222170936.13268-3-peter.maydell@linaro.org
This commit is contained in:
parent
602f6e42cf
commit
c0c760afe8
@ -3328,6 +3328,26 @@ static inline bool isar_feature_aa32_fp16_dpconv(const ARMISARegisters *id)
|
||||
return FIELD_EX64(id->mvfr1, MVFR1, FPHP) > 1;
|
||||
}
|
||||
|
||||
static inline bool isar_feature_aa32_vsel(const ARMISARegisters *id)
|
||||
{
|
||||
return FIELD_EX64(id->mvfr2, MVFR2, FPMISC) >= 1;
|
||||
}
|
||||
|
||||
static inline bool isar_feature_aa32_vcvt_dr(const ARMISARegisters *id)
|
||||
{
|
||||
return FIELD_EX64(id->mvfr2, MVFR2, FPMISC) >= 2;
|
||||
}
|
||||
|
||||
static inline bool isar_feature_aa32_vrint(const ARMISARegisters *id)
|
||||
{
|
||||
return FIELD_EX64(id->mvfr2, MVFR2, FPMISC) >= 3;
|
||||
}
|
||||
|
||||
static inline bool isar_feature_aa32_vminmaxnm(const ARMISARegisters *id)
|
||||
{
|
||||
return FIELD_EX64(id->mvfr2, MVFR2, FPMISC) >= 4;
|
||||
}
|
||||
|
||||
/*
|
||||
* 64-bit feature tests via id registers.
|
||||
*/
|
||||
|
@ -3357,14 +3357,10 @@ static const uint8_t fp_decode_rm[] = {
|
||||
FPROUNDING_NEGINF,
|
||||
};
|
||||
|
||||
static int disas_vfp_v8_insn(DisasContext *s, uint32_t insn)
|
||||
static int disas_vfp_misc_insn(DisasContext *s, uint32_t insn)
|
||||
{
|
||||
uint32_t rd, rn, rm, dp = extract32(insn, 8, 1);
|
||||
|
||||
if (!arm_dc_feature(s, ARM_FEATURE_V8)) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (dp) {
|
||||
VFP_DREG_D(rd, insn);
|
||||
VFP_DREG_N(rn, insn);
|
||||
@ -3375,15 +3371,18 @@ static int disas_vfp_v8_insn(DisasContext *s, uint32_t insn)
|
||||
rm = VFP_SREG_M(insn);
|
||||
}
|
||||
|
||||
if ((insn & 0x0f800e50) == 0x0e000a00) {
|
||||
if ((insn & 0x0f800e50) == 0x0e000a00 && dc_isar_feature(aa32_vsel, s)) {
|
||||
return handle_vsel(insn, rd, rn, rm, dp);
|
||||
} else if ((insn & 0x0fb00e10) == 0x0e800a00) {
|
||||
} else if ((insn & 0x0fb00e10) == 0x0e800a00 &&
|
||||
dc_isar_feature(aa32_vminmaxnm, s)) {
|
||||
return handle_vminmaxnm(insn, rd, rn, rm, dp);
|
||||
} else if ((insn & 0x0fbc0ed0) == 0x0eb80a40) {
|
||||
} else if ((insn & 0x0fbc0ed0) == 0x0eb80a40 &&
|
||||
dc_isar_feature(aa32_vrint, s)) {
|
||||
/* VRINTA, VRINTN, VRINTP, VRINTM */
|
||||
int rounding = fp_decode_rm[extract32(insn, 16, 2)];
|
||||
return handle_vrint(insn, rd, rm, dp, rounding);
|
||||
} else if ((insn & 0x0fbc0e50) == 0x0ebc0a40) {
|
||||
} else if ((insn & 0x0fbc0e50) == 0x0ebc0a40 &&
|
||||
dc_isar_feature(aa32_vcvt_dr, s)) {
|
||||
/* VCVTA, VCVTN, VCVTP, VCVTM */
|
||||
int rounding = fp_decode_rm[extract32(insn, 16, 2)];
|
||||
return handle_vcvt(insn, rd, rm, dp, rounding);
|
||||
@ -3427,10 +3426,12 @@ static int disas_vfp_insn(DisasContext *s, uint32_t insn)
|
||||
}
|
||||
|
||||
if (extract32(insn, 28, 4) == 0xf) {
|
||||
/* Encodings with T=1 (Thumb) or unconditional (ARM):
|
||||
* only used in v8 and above.
|
||||
/*
|
||||
* Encodings with T=1 (Thumb) or unconditional (ARM):
|
||||
* only used for the "miscellaneous VFP features" added in v8A
|
||||
* and v7M (and gated on the MVFR2.FPMisc field).
|
||||
*/
|
||||
return disas_vfp_v8_insn(s, insn);
|
||||
return disas_vfp_misc_insn(s, insn);
|
||||
}
|
||||
|
||||
dp = ((insn & 0xf00) == 0xb00);
|
||||
|
Loading…
Reference in New Issue
Block a user