diff mbox series

[2/2] target/arm: Gate "miscellaneous FP" insns by ID register field

Message ID 20190222170936.13268-3-peter.maydell@linaro.org
State Superseded
Headers show
Series target/arm: Use MVFR feature bits to gate some insns | expand

Commit Message

Peter Maydell Feb. 22, 2019, 5:09 p.m. UTC
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>

---
 target/arm/cpu.h       | 20 ++++++++++++++++++++
 target/arm/translate.c | 21 +++++++++++++--------
 2 files changed, 33 insertions(+), 8 deletions(-)

-- 
2.20.1

Comments

Peter Maydell Feb. 22, 2019, 5:36 p.m. UTC | #1
On Fri, 22 Feb 2019 at 17:09, Peter Maydell <peter.maydell@linaro.org> wrote:
>

> 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.


> diff --git a/target/arm/translate.c b/target/arm/translate.c

> index b7702fb49f7..af8f9e669b8 100644

> --- a/target/arm/translate.c

> +++ b/target/arm/translate.c

> @@ -3357,7 +3357,7 @@ 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);

>


Oops, I forgot to commit this part of the change:

@@ -3361,10 +3361,6 @@ 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);

thanks
-- PMM
Richard Henderson Feb. 22, 2019, 9:59 p.m. UTC | #2
On 2/22/19 9:36 AM, Peter Maydell wrote:
> On Fri, 22 Feb 2019 at 17:09, Peter Maydell <peter.maydell@linaro.org> wrote:

>>

>> 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.

> 

>> diff --git a/target/arm/translate.c b/target/arm/translate.c

>> index b7702fb49f7..af8f9e669b8 100644

>> --- a/target/arm/translate.c

>> +++ b/target/arm/translate.c

>> @@ -3357,7 +3357,7 @@ 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);

>>

> 

> Oops, I forgot to commit this part of the change:

> 

> @@ -3361,10 +3361,6 @@ 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);


With the addition,
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>



r~
diff mbox series

Patch

diff --git a/target/arm/cpu.h b/target/arm/cpu.h
index 36ea3b58567..ff9ba387b42 100644
--- a/target/arm/cpu.h
+++ b/target/arm/cpu.h
@@ -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.
  */
diff --git a/target/arm/translate.c b/target/arm/translate.c
index b7702fb49f7..af8f9e669b8 100644
--- a/target/arm/translate.c
+++ b/target/arm/translate.c
@@ -3357,7 +3357,7 @@  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);
 
@@ -3375,15 +3375,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 +3430,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);