Commit 5763190f authored by Richard Henderson's avatar Richard Henderson Committed by Peter Maydell
Browse files

target/arm: Convert v8.2-fp16 from feature bit to aa64pfr0 test



Reviewed-by: default avatarPhilippe Mathieu-Daudé <philmd@redhat.com>
Signed-off-by: default avatarRichard Henderson <richard.henderson@linaro.org>
Message-id: 20181016223115.24100-9-richard.henderson@linaro.org
Reviewed-by: default avatarPeter Maydell <peter.maydell@linaro.org>
Signed-off-by: default avatarPeter Maydell <peter.maydell@linaro.org>
parent cd208a1c
Loading
Loading
Loading
Loading
+1 −5
Original line number Diff line number Diff line
@@ -573,8 +573,6 @@ static uint32_t get_elf_hwcap(void)
    hwcaps |= ARM_HWCAP_A64_ASIMD;

    /* probe for the extra features */
#define GET_FEATURE(feat, hwcap) \
    do { if (arm_feature(&cpu->env, feat)) { hwcaps |= hwcap; } } while (0)
#define GET_FEATURE_ID(feat, hwcap) \
    do { if (cpu_isar_feature(feat, cpu)) { hwcaps |= hwcap; } } while (0)

@@ -587,15 +585,13 @@ static uint32_t get_elf_hwcap(void)
    GET_FEATURE_ID(aa64_sha3, ARM_HWCAP_A64_SHA3);
    GET_FEATURE_ID(aa64_sm3, ARM_HWCAP_A64_SM3);
    GET_FEATURE_ID(aa64_sm4, ARM_HWCAP_A64_SM4);
    GET_FEATURE(ARM_FEATURE_V8_FP16,
                ARM_HWCAP_A64_FPHP | ARM_HWCAP_A64_ASIMDHP);
    GET_FEATURE_ID(aa64_fp16, ARM_HWCAP_A64_FPHP | ARM_HWCAP_A64_ASIMDHP);
    GET_FEATURE_ID(aa64_atomics, ARM_HWCAP_A64_ATOMICS);
    GET_FEATURE_ID(aa64_rdm, ARM_HWCAP_A64_ASIMDRDM);
    GET_FEATURE_ID(aa64_dp, ARM_HWCAP_A64_ASIMDDP);
    GET_FEATURE_ID(aa64_fcma, ARM_HWCAP_A64_FCMA);
    GET_FEATURE_ID(aa64_sve, ARM_HWCAP_A64_SVE);

#undef GET_FEATURE
#undef GET_FEATURE_ID

    return hwcaps;
+16 −1
Original line number Diff line number Diff line
@@ -1603,7 +1603,6 @@ enum arm_features {
    ARM_FEATURE_PMU, /* has PMU support */
    ARM_FEATURE_VBAR, /* has cp15 VBAR */
    ARM_FEATURE_M_SECURITY, /* M profile Security Extension */
    ARM_FEATURE_V8_FP16, /* implements v8.2 half-precision float */
    ARM_FEATURE_M_MAIN, /* M profile Main Extension */
};

@@ -3213,6 +3212,16 @@ static inline bool isar_feature_aa32_dp(const ARMISARegisters *id)
    return FIELD_EX32(id->id_isar6, ID_ISAR6, DP) != 0;
}

static inline bool isar_feature_aa32_fp16_arith(const ARMISARegisters *id)
{
    /*
     * This is a placeholder for use by VCMA until the rest of
     * the ARMv8.2-FP16 extension is implemented for aa32 mode.
     * At which point we can properly set and check MVFR1.FPHP.
     */
    return FIELD_EX64(id->id_aa64pfr0, ID_AA64PFR0, FP) == 1;
}

/*
 * 64-bit feature tests via id registers.
 */
@@ -3281,6 +3290,12 @@ static inline bool isar_feature_aa64_fcma(const ARMISARegisters *id)
    return FIELD_EX64(id->id_aa64isar1, ID_AA64ISAR1, FCMA) != 0;
}

static inline bool isar_feature_aa64_fp16(const ARMISARegisters *id)
{
    /* We always set the AdvSIMD and FP fields identically wrt FP16.  */
    return FIELD_EX64(id->id_aa64pfr0, ID_AA64PFR0, FP) == 1;
}

static inline bool isar_feature_aa64_sve(const ARMISARegisters *id)
{
    return FIELD_EX64(id->id_aa64pfr0, ID_AA64PFR0, SVE) != 0;
+9 −7
Original line number Diff line number Diff line
@@ -320,6 +320,8 @@ static void aarch64_max_initfn(Object *obj)

        t = cpu->isar.id_aa64pfr0;
        t = FIELD_DP64(t, ID_AA64PFR0, SVE, 1);
        t = FIELD_DP64(t, ID_AA64PFR0, FP, 1);
        t = FIELD_DP64(t, ID_AA64PFR0, ADVSIMD, 1);
        cpu->isar.id_aa64pfr0 = t;

        /* Replicate the same data to the 32-bit id registers.  */
@@ -336,14 +338,14 @@ static void aarch64_max_initfn(Object *obj)
        u = FIELD_DP32(u, ID_ISAR6, DP, 1);
        cpu->isar.id_isar6 = u;

#ifdef CONFIG_USER_ONLY
        /* We don't set these in system emulation mode for the moment,
         * since we don't correctly set the ID registers to advertise them,
         * and in some cases they're only available in AArch64 and not AArch32,
         * whereas the architecture requires them to be present in both if
         * present in either.
        /*
         * FIXME: We do not yet support ARMv8.2-fp16 for AArch32 yet,
         * so do not set MVFR1.FPHP.  Strictly speaking this is not legal,
         * but it is also not legal to enable SVE without support for FP16,
         * and enabling SVE in system mode is more useful in the short term.
         */
        set_feature(&cpu->env, ARM_FEATURE_V8_FP16);

#ifdef CONFIG_USER_ONLY
        /* For usermode -cpu max we can use a larger and more efficient DCZ
         * blocksize since we don't have to follow what the hardware does.
         */
+1 −1
Original line number Diff line number Diff line
@@ -11612,7 +11612,7 @@ void HELPER(vfp_set_fpscr)(CPUARMState *env, uint32_t val)
    uint32_t changed;

    /* When ARMv8.2-FP16 is not supported, FZ16 is RES0.  */
    if (!arm_feature(env, ARM_FEATURE_V8_FP16)) {
    if (!cpu_isar_feature(aa64_fp16, arm_env_get_cpu(env))) {
        val &= ~FPCR_FZ16;
    }

+20 −20
Original line number Diff line number Diff line
@@ -4811,7 +4811,7 @@ static void disas_fp_compare(DisasContext *s, uint32_t insn)
        break;
    case 3:
        size = MO_16;
        if (arm_dc_feature(s, ARM_FEATURE_V8_FP16)) {
        if (dc_isar_feature(aa64_fp16, s)) {
            break;
        }
        /* fallthru */
@@ -4862,7 +4862,7 @@ static void disas_fp_ccomp(DisasContext *s, uint32_t insn)
        break;
    case 3:
        size = MO_16;
        if (arm_dc_feature(s, ARM_FEATURE_V8_FP16)) {
        if (dc_isar_feature(aa64_fp16, s)) {
            break;
        }
        /* fallthru */
@@ -4928,7 +4928,7 @@ static void disas_fp_csel(DisasContext *s, uint32_t insn)
        break;
    case 3:
        sz = MO_16;
        if (arm_dc_feature(s, ARM_FEATURE_V8_FP16)) {
        if (dc_isar_feature(aa64_fp16, s)) {
            break;
        }
        /* fallthru */
@@ -5261,7 +5261,7 @@ static void disas_fp_1src(DisasContext *s, uint32_t insn)
            handle_fp_1src_double(s, opcode, rd, rn);
            break;
        case 3:
            if (!arm_dc_feature(s, ARM_FEATURE_V8_FP16)) {
            if (!dc_isar_feature(aa64_fp16, s)) {
                unallocated_encoding(s);
                return;
            }
@@ -5476,7 +5476,7 @@ static void disas_fp_2src(DisasContext *s, uint32_t insn)
        handle_fp_2src_double(s, opcode, rd, rn, rm);
        break;
    case 3:
        if (!arm_dc_feature(s, ARM_FEATURE_V8_FP16)) {
        if (!dc_isar_feature(aa64_fp16, s)) {
            unallocated_encoding(s);
            return;
        }
@@ -5634,7 +5634,7 @@ static void disas_fp_3src(DisasContext *s, uint32_t insn)
        handle_fp_3src_double(s, o0, o1, rd, rn, rm, ra);
        break;
    case 3:
        if (!arm_dc_feature(s, ARM_FEATURE_V8_FP16)) {
        if (!dc_isar_feature(aa64_fp16, s)) {
            unallocated_encoding(s);
            return;
        }
@@ -5704,7 +5704,7 @@ static void disas_fp_imm(DisasContext *s, uint32_t insn)
        break;
    case 3:
        sz = MO_16;
        if (arm_dc_feature(s, ARM_FEATURE_V8_FP16)) {
        if (dc_isar_feature(aa64_fp16, s)) {
            break;
        }
        /* fallthru */
@@ -5929,7 +5929,7 @@ static void disas_fp_fixed_conv(DisasContext *s, uint32_t insn)
    case 1: /* float64 */
        break;
    case 3: /* float16 */
        if (arm_dc_feature(s, ARM_FEATURE_V8_FP16)) {
        if (dc_isar_feature(aa64_fp16, s)) {
            break;
        }
        /* fallthru */
@@ -6059,7 +6059,7 @@ static void disas_fp_int_conv(DisasContext *s, uint32_t insn)
            break;
        case 0x6: /* 16-bit float, 32-bit int */
        case 0xe: /* 16-bit float, 64-bit int */
            if (arm_dc_feature(s, ARM_FEATURE_V8_FP16)) {
            if (dc_isar_feature(aa64_fp16, s)) {
                break;
            }
            /* fallthru */
@@ -6086,7 +6086,7 @@ static void disas_fp_int_conv(DisasContext *s, uint32_t insn)
        case 1: /* float64 */
            break;
        case 3: /* float16 */
            if (arm_dc_feature(s, ARM_FEATURE_V8_FP16)) {
            if (dc_isar_feature(aa64_fp16, s)) {
                break;
            }
            /* fallthru */
@@ -6523,7 +6523,7 @@ static void disas_simd_across_lanes(DisasContext *s, uint32_t insn)
         */
        is_min = extract32(size, 1, 1);
        is_fp = true;
        if (!is_u && arm_dc_feature(s, ARM_FEATURE_V8_FP16)) {
        if (!is_u && dc_isar_feature(aa64_fp16, s)) {
            size = 1;
        } else if (!is_u || !is_q || extract32(size, 0, 1)) {
            unallocated_encoding(s);
@@ -6919,7 +6919,7 @@ static void disas_simd_mod_imm(DisasContext *s, uint32_t insn)

    if (o2 != 0 || ((cmode == 0xf) && is_neg && !is_q)) {
        /* Check for FMOV (vector, immediate) - half-precision */
        if (!(arm_dc_feature(s, ARM_FEATURE_V8_FP16) && o2 && cmode == 0xf)) {
        if (!(dc_isar_feature(aa64_fp16, s) && o2 && cmode == 0xf)) {
            unallocated_encoding(s);
            return;
        }
@@ -7086,7 +7086,7 @@ static void disas_simd_scalar_pairwise(DisasContext *s, uint32_t insn)
    case 0x2f: /* FMINP */
        /* FP op, size[0] is 32 or 64 bit*/
        if (!u) {
            if (!arm_dc_feature(s, ARM_FEATURE_V8_FP16)) {
            if (!dc_isar_feature(aa64_fp16, s)) {
                unallocated_encoding(s);
                return;
            } else {
@@ -7731,7 +7731,7 @@ static void handle_simd_shift_intfp_conv(DisasContext *s, bool is_scalar,
        size = MO_32;
    } else if (immh & 2) {
        size = MO_16;
        if (!arm_dc_feature(s, ARM_FEATURE_V8_FP16)) {
        if (!dc_isar_feature(aa64_fp16, s)) {
            unallocated_encoding(s);
            return;
        }
@@ -7776,7 +7776,7 @@ static void handle_simd_shift_fpint_conv(DisasContext *s, bool is_scalar,
        size = MO_32;
    } else if (immh & 0x2) {
        size = MO_16;
        if (!arm_dc_feature(s, ARM_FEATURE_V8_FP16)) {
        if (!dc_isar_feature(aa64_fp16, s)) {
            unallocated_encoding(s);
            return;
        }
@@ -8540,7 +8540,7 @@ static void disas_simd_scalar_three_reg_same_fp16(DisasContext *s,
        return;
    }

    if (!arm_dc_feature(s, ARM_FEATURE_V8_FP16)) {
    if (!dc_isar_feature(aa64_fp16, s)) {
        unallocated_encoding(s);
    }

@@ -11221,7 +11221,7 @@ static void disas_simd_three_reg_same_fp16(DisasContext *s, uint32_t insn)
    TCGv_ptr fpst;
    bool pairwise = false;

    if (!arm_dc_feature(s, ARM_FEATURE_V8_FP16)) {
    if (!dc_isar_feature(aa64_fp16, s)) {
        unallocated_encoding(s);
        return;
    }
@@ -11436,7 +11436,7 @@ static void disas_simd_three_reg_same_extra(DisasContext *s, uint32_t insn)
    case 0x1c: /* FCADD, #90 */
    case 0x1e: /* FCADD, #270 */
        if (size == 0
            || (size == 1 && !arm_dc_feature(s, ARM_FEATURE_V8_FP16))
            || (size == 1 && !dc_isar_feature(aa64_fp16, s))
            || (size == 3 && !is_q)) {
            unallocated_encoding(s);
            return;
@@ -12316,7 +12316,7 @@ static void disas_simd_two_reg_misc_fp16(DisasContext *s, uint32_t insn)
    bool need_fpst = true;
    int rmode;

    if (!arm_dc_feature(s, ARM_FEATURE_V8_FP16)) {
    if (!dc_isar_feature(aa64_fp16, s)) {
        unallocated_encoding(s);
        return;
    }
@@ -12733,7 +12733,7 @@ static void disas_simd_indexed(DisasContext *s, uint32_t insn)
        }
        break;
    }
    if (is_fp16 && !arm_dc_feature(s, ARM_FEATURE_V8_FP16)) {
    if (is_fp16 && !dc_isar_feature(aa64_fp16, s)) {
        unallocated_encoding(s);
        return;
    }
Loading