From nobody Thu Nov 6 00:34:40 2025 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=linaro.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1538084589080922.2120165260604; Thu, 27 Sep 2018 14:43:09 -0700 (PDT) Received: from localhost ([::1]:39654 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1g5e3w-0007ge-24 for importer@patchew.org; Thu, 27 Sep 2018 17:43:08 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:53958) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1g5dpV-0003oG-KU for qemu-devel@nongnu.org; Thu, 27 Sep 2018 17:28:15 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1g5dbU-0000t9-DD for qemu-devel@nongnu.org; Thu, 27 Sep 2018 17:13:46 -0400 Received: from mail-pg1-x52a.google.com ([2607:f8b0:4864:20::52a]:33196) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1g5dbT-0000o0-Iw for qemu-devel@nongnu.org; Thu, 27 Sep 2018 17:13:44 -0400 Received: by mail-pg1-x52a.google.com with SMTP id y18-v6so2855932pge.0 for ; Thu, 27 Sep 2018 14:13:39 -0700 (PDT) Received: from cloudburst.twiddle.net (97-113-8-179.tukw.qwest.net. [97.113.8.179]) by smtp.gmail.com with ESMTPSA id l26-v6sm5395884pfg.161.2018.09.27.14.13.37 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Thu, 27 Sep 2018 14:13:37 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=l+yshe/I07m2SqY8FXn8ApkFdUsaReHb1sD150NFCbI=; b=aU56NRyAw6Im66/qH9szrq/zzkZ3LZIE7ciEzuc4+nXgsK3NVemm2JmEmWy9IdDUVi DkatCkpWN1Tz6SzKfKd50c/pklyA1rmnB9nzdPUjHn6gWrlvS1W+ZPembRz1ZD9wA/cv vhhVIX9A/r1bCefjBiVnEPHpHlSC2HJpbKtms= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=l+yshe/I07m2SqY8FXn8ApkFdUsaReHb1sD150NFCbI=; b=Y0Jl/zcun6mt2Kzj+k0zPJcJPljPLAYuJpY9NtgV/4P8hrRRbDuyc7vQiWPCpWZ/X6 /drX47VvznPEpg5833KEwPUxjEijRCghAD5l3vcivhNSpgHWOWBpnTT7kYZp8OnVyFzu XiI7oEwNlur3EmVN+9ey8iU9ePpid9J4UaLwqkCZSSjO8pYe9CjPT1RL7q8Kivs1w7El SCBk6qpHst1fvY9HJ2ibPWmQDsHP+SaH4PKyA8IBXDo1WKhqEsxnuoyDftSgKi3erku5 Xl8lkmOnb3IbGlfDY+GRe9k1ZO87vF0DPo8PLmr9BRcX8l3bK6/o027yx6CJ4TWMKBfh ewuA== X-Gm-Message-State: ABuFfoit4FrvhjKoGj5i9jhj2bNuizQ3JiGhsL+2biXy1uLin99E1j3z uJtqfxo0twMLm5fpZGSbiH54Ti+q4j4= X-Google-Smtp-Source: ACcGV62/zc9zhN4kDJ1WYWigiQ8OvW2RlINasPlQScxHo1fXrM9YcLzbmCEOmbhQYvXZdrOsyTzhPA== X-Received: by 2002:a63:5a54:: with SMTP id k20-v6mr12164315pgm.297.1538082818623; Thu, 27 Sep 2018 14:13:38 -0700 (PDT) From: Richard Henderson To: qemu-devel@nongnu.org Date: Thu, 27 Sep 2018 14:13:22 -0700 Message-Id: <20180927211322.16118-10-richard.henderson@linaro.org> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20180927211322.16118-1-richard.henderson@linaro.org> References: <20180927211322.16118-1-richard.henderson@linaro.org> X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2607:f8b0:4864:20::52a Subject: [Qemu-devel] [PATCH v2 9/9] target/arm: Convert v8.2-fp16 from feature bit to pfr0 test X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: peter.maydell@linaro.org Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: fail (Header signature does not verify) X-ZohoMail: RDMRC_1 RDKM_2 RSF_0 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Signed-off-by: Richard Henderson Reviewed-by: Philippe Mathieu-Daud=C3=A9 --- target/arm/cpu.h | 17 +++++++++++++++- target/arm/translate-a64.h | 1 + target/arm/translate.h | 1 + linux-user/elfload.c | 6 +----- target/arm/cpu64.c | 13 ++++++------- target/arm/helper.c | 2 +- target/arm/translate-a64.c | 40 +++++++++++++++++++------------------- target/arm/translate.c | 6 +++--- 8 files changed, 49 insertions(+), 37 deletions(-) diff --git a/target/arm/cpu.h b/target/arm/cpu.h index 152a558a94..bca4ee4281 100644 --- a/target/arm/cpu.h +++ b/target/arm/cpu.h @@ -1566,7 +1566,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 */ }; =20 @@ -3176,6 +3175,16 @@ static inline bool aa32_feature_dp(ARMCPU *cpu) return FIELD_EX32(cpu->id_isar6, ID_ISAR6, DP) !=3D 0; } =20 +static inline bool aa32_feature_fp16_arith(ARMCPU *cpu) +{ + /* + * 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(cpu->id_aa64pfr0, ID_AA64PFR0, FP) =3D=3D 1; +} + /* * 64-bit feature tests via id registers. */ @@ -3244,6 +3253,12 @@ static inline bool aa64_feature_fcma(ARMCPU *cpu) return FIELD_EX64(cpu->id_aa64isar1, ID_AA64ISAR1, FCMA) !=3D 0; } =20 +static inline bool aa64_feature_fp16(ARMCPU *cpu) +{ + /* We always set the AdvSIMD and FP fields identically wrt FP16. */ + return FIELD_EX64(cpu->id_aa64pfr0, ID_AA64PFR0, FP) =3D=3D 1; +} + static inline bool aa64_feature_sve(ARMCPU *cpu) { return FIELD_EX64(cpu->id_aa64pfr0, ID_AA64PFR0, SVE) !=3D 0; diff --git a/target/arm/translate-a64.h b/target/arm/translate-a64.h index 636f3fded3..e122cef242 100644 --- a/target/arm/translate-a64.h +++ b/target/arm/translate-a64.h @@ -140,6 +140,7 @@ FORWARD_FEATURE(sm3) FORWARD_FEATURE(sm4) FORWARD_FEATURE(dp) FORWARD_FEATURE(fcma) +FORWARD_FEATURE(fp16) FORWARD_FEATURE(sve) =20 #undef FORWARD_FEATURE diff --git a/target/arm/translate.h b/target/arm/translate.h index d8eafbe88d..e022d6d4e6 100644 --- a/target/arm/translate.h +++ b/target/arm/translate.h @@ -205,6 +205,7 @@ FORWARD_FEATURE(crc32) FORWARD_FEATURE(rdm) FORWARD_FEATURE(vcma) FORWARD_FEATURE(dp) +FORWARD_FEATURE(fp16_arith) =20 #undef FORWARD_FEATURE =20 diff --git a/linux-user/elfload.c b/linux-user/elfload.c index c4969f163e..bcb2c9928c 100644 --- a/linux-user/elfload.c +++ b/linux-user/elfload.c @@ -573,8 +573,6 @@ static uint32_t get_elf_hwcap(void) hwcaps |=3D ARM_HWCAP_A64_ASIMD; =20 /* probe for the extra features */ -#define GET_FEATURE(feat, hwcap) \ - do { if (arm_feature(&cpu->env, feat)) { hwcaps |=3D hwcap; } } while = (0) #define GET_FEATURE_ID(feat, hwcap) \ do { if (aa64_feature_##feat(cpu)) { hwcaps |=3D hwcap; } } while (0) =20 @@ -587,15 +585,13 @@ static uint32_t get_elf_hwcap(void) GET_FEATURE_ID(sha3, ARM_HWCAP_A64_SHA3); GET_FEATURE_ID(sm3, ARM_HWCAP_A64_SM3); GET_FEATURE_ID(sm4, ARM_HWCAP_A64_SM4); - GET_FEATURE(ARM_FEATURE_V8_FP16, - ARM_HWCAP_A64_FPHP | ARM_HWCAP_A64_ASIMDHP); + GET_FEATURE_ID(fp16, ARM_HWCAP_A64_FPHP | ARM_HWCAP_A64_ASIMDHP); GET_FEATURE_ID(atomics, ARM_HWCAP_A64_ATOMICS); GET_FEATURE_ID(rdm, ARM_HWCAP_A64_ASIMDRDM); GET_FEATURE_ID(dp, ARM_HWCAP_A64_ASIMDDP); GET_FEATURE_ID(fcma, ARM_HWCAP_A64_FCMA); GET_FEATURE_ID(sve, ARM_HWCAP_A64_SVE); =20 -#undef GET_FEATURE #undef GET_FEATURE_ID =20 return hwcaps; diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c index 8f95de677a..c734e2b2cd 100644 --- a/target/arm/cpu64.c +++ b/target/arm/cpu64.c @@ -259,6 +259,8 @@ static void aarch64_max_initfn(Object *obj) FIELD_DP64(cpu->id_aa64isar1, ID_AA64ISAR1, FCMA, 1); =20 FIELD_DP64(cpu->id_aa64pfr0, ID_AA64PFR0, SVE, 1); + FIELD_DP64(cpu->id_aa64pfr0, ID_AA64PFR0, FP, 1); + FIELD_DP64(cpu->id_aa64pfr0, ID_AA64PFR0, ADVSIMD, 1); =20 /* Replicate the same data to the 32-bit id registers. */ FIELD_DP32(cpu->id_isar5, ID_ISAR5, AES, 2); /* AES + PMULL */ @@ -268,15 +270,12 @@ static void aarch64_max_initfn(Object *obj) FIELD_DP32(cpu->id_isar5, ID_ISAR5, RDM, 1); FIELD_DP32(cpu->id_isar5, ID_ISAR5, VCMA, 1); FIELD_DP32(cpu->id_isar6, ID_ISAR6, DP, 1); + /* + * FIXME: ARMv8.2-FP16 is not implemented for aa32, + * so do not set MVFR1.FPHP and MVFR.SIMDHP. + */ =20 #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 AAr= ch32, - * whereas the architecture requires them to be present in both if - * present in either. - */ - set_feature(&cpu->env, ARM_FEATURE_V8_FP16); /* 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. */ diff --git a/target/arm/helper.c b/target/arm/helper.c index dd3a2c0b8b..996af1b0b3 100644 --- a/target/arm/helper.c +++ b/target/arm/helper.c @@ -11528,7 +11528,7 @@ void HELPER(vfp_set_fpscr)(CPUARMState *env, uint32= _t val) uint32_t changed; =20 /* When ARMv8.2-FP16 is not supported, FZ16 is RES0. */ - if (!arm_feature(env, ARM_FEATURE_V8_FP16)) { + if (!aa64_feature_fp16(arm_env_get_cpu(env))) { val &=3D ~FPCR_FZ16; } =20 diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c index 5527ffb203..095d204992 100644 --- a/target/arm/translate-a64.c +++ b/target/arm/translate-a64.c @@ -4801,7 +4801,7 @@ static void disas_fp_compare(DisasContext *s, uint32_= t insn) break; case 3: size =3D MO_16; - if (arm_dc_feature(s, ARM_FEATURE_V8_FP16)) { + if (aa64_dc_feature_fp16(s)) { break; } /* fallthru */ @@ -4852,7 +4852,7 @@ static void disas_fp_ccomp(DisasContext *s, uint32_t = insn) break; case 3: size =3D MO_16; - if (arm_dc_feature(s, ARM_FEATURE_V8_FP16)) { + if (aa64_dc_feature_fp16(s)) { break; } /* fallthru */ @@ -4918,7 +4918,7 @@ static void disas_fp_csel(DisasContext *s, uint32_t i= nsn) break; case 3: sz =3D MO_16; - if (arm_dc_feature(s, ARM_FEATURE_V8_FP16)) { + if (aa64_dc_feature_fp16(s)) { break; } /* fallthru */ @@ -5251,7 +5251,7 @@ static void disas_fp_1src(DisasContext *s, uint32_t i= nsn) handle_fp_1src_double(s, opcode, rd, rn); break; case 3: - if (!arm_dc_feature(s, ARM_FEATURE_V8_FP16)) { + if (!aa64_dc_feature_fp16(s)) { unallocated_encoding(s); return; } @@ -5466,7 +5466,7 @@ static void disas_fp_2src(DisasContext *s, uint32_t i= nsn) handle_fp_2src_double(s, opcode, rd, rn, rm); break; case 3: - if (!arm_dc_feature(s, ARM_FEATURE_V8_FP16)) { + if (!aa64_dc_feature_fp16(s)) { unallocated_encoding(s); return; } @@ -5624,7 +5624,7 @@ static void disas_fp_3src(DisasContext *s, uint32_t i= nsn) handle_fp_3src_double(s, o0, o1, rd, rn, rm, ra); break; case 3: - if (!arm_dc_feature(s, ARM_FEATURE_V8_FP16)) { + if (!aa64_dc_feature_fp16(s)) { unallocated_encoding(s); return; } @@ -5694,7 +5694,7 @@ static void disas_fp_imm(DisasContext *s, uint32_t in= sn) break; case 3: sz =3D MO_16; - if (arm_dc_feature(s, ARM_FEATURE_V8_FP16)) { + if (aa64_dc_feature_fp16(s)) { break; } /* fallthru */ @@ -5919,7 +5919,7 @@ static void disas_fp_fixed_conv(DisasContext *s, uint= 32_t insn) case 1: /* float64 */ break; case 3: /* float16 */ - if (arm_dc_feature(s, ARM_FEATURE_V8_FP16)) { + if (aa64_dc_feature_fp16(s)) { break; } /* fallthru */ @@ -6049,7 +6049,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 (aa64_dc_feature_fp16(s)) { break; } /* fallthru */ @@ -6076,7 +6076,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 (aa64_dc_feature_fp16(s)) { break; } /* fallthru */ @@ -6513,7 +6513,7 @@ static void disas_simd_across_lanes(DisasContext *s, = uint32_t insn) */ is_min =3D extract32(size, 1, 1); is_fp =3D true; - if (!is_u && arm_dc_feature(s, ARM_FEATURE_V8_FP16)) { + if (!is_u && aa64_dc_feature_fp16(s)) { size =3D 1; } else if (!is_u || !is_q || extract32(size, 0, 1)) { unallocated_encoding(s); @@ -6909,7 +6909,7 @@ static void disas_simd_mod_imm(DisasContext *s, uint3= 2_t insn) =20 if (o2 !=3D 0 || ((cmode =3D=3D 0xf) && is_neg && !is_q)) { /* Check for FMOV (vector, immediate) - half-precision */ - if (!(arm_dc_feature(s, ARM_FEATURE_V8_FP16) && o2 && cmode =3D=3D= 0xf)) { + if (!(aa64_dc_feature_fp16(s) && o2 && cmode =3D=3D 0xf)) { unallocated_encoding(s); return; } @@ -7076,7 +7076,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 (!aa64_dc_feature_fp16(s)) { unallocated_encoding(s); return; } else { @@ -7721,7 +7721,7 @@ static void handle_simd_shift_intfp_conv(DisasContext= *s, bool is_scalar, size =3D MO_32; } else if (immh & 2) { size =3D MO_16; - if (!arm_dc_feature(s, ARM_FEATURE_V8_FP16)) { + if (!aa64_dc_feature_fp16(s)) { unallocated_encoding(s); return; } @@ -7766,7 +7766,7 @@ static void handle_simd_shift_fpint_conv(DisasContext= *s, bool is_scalar, size =3D MO_32; } else if (immh & 0x2) { size =3D MO_16; - if (!arm_dc_feature(s, ARM_FEATURE_V8_FP16)) { + if (!aa64_dc_feature_fp16(s)) { unallocated_encoding(s); return; } @@ -8530,7 +8530,7 @@ static void disas_simd_scalar_three_reg_same_fp16(Dis= asContext *s, return; } =20 - if (!arm_dc_feature(s, ARM_FEATURE_V8_FP16)) { + if (!aa64_dc_feature_fp16(s)) { unallocated_encoding(s); } =20 @@ -11211,7 +11211,7 @@ static void disas_simd_three_reg_same_fp16(DisasCon= text *s, uint32_t insn) TCGv_ptr fpst; bool pairwise =3D false; =20 - if (!arm_dc_feature(s, ARM_FEATURE_V8_FP16)) { + if (!aa64_dc_feature_fp16(s)) { unallocated_encoding(s); return; } @@ -11426,7 +11426,7 @@ static void disas_simd_three_reg_same_extra(DisasCo= ntext *s, uint32_t insn) case 0x1c: /* FCADD, #90 */ case 0x1e: /* FCADD, #270 */ if (size =3D=3D 0 - || (size =3D=3D 1 && !arm_dc_feature(s, ARM_FEATURE_V8_FP16)) + || (size =3D=3D 1 && !aa64_dc_feature_fp16(s)) || (size =3D=3D 3 && !is_q)) { unallocated_encoding(s); return; @@ -12306,7 +12306,7 @@ static void disas_simd_two_reg_misc_fp16(DisasConte= xt *s, uint32_t insn) bool need_fpst =3D true; int rmode; =20 - if (!arm_dc_feature(s, ARM_FEATURE_V8_FP16)) { + if (!aa64_dc_feature_fp16(s)) { unallocated_encoding(s); return; } @@ -12723,7 +12723,7 @@ static void disas_simd_indexed(DisasContext *s, uin= t32_t insn) } break; } - if (is_fp16 && !arm_dc_feature(s, ARM_FEATURE_V8_FP16)) { + if (is_fp16 && !aa64_dc_feature_fp16(s)) { unallocated_encoding(s); return; } diff --git a/target/arm/translate.c b/target/arm/translate.c index 4036be6828..3dac413c82 100644 --- a/target/arm/translate.c +++ b/target/arm/translate.c @@ -7783,7 +7783,7 @@ static int disas_neon_insn_3same_ext(DisasContext *s,= uint32_t insn) int size =3D extract32(insn, 20, 1); data =3D extract32(insn, 23, 2); /* rot */ if (!aa32_dc_feature_vcma(s) - || (!size && !arm_dc_feature(s, ARM_FEATURE_V8_FP16))) { + || (!size && !aa32_dc_feature_fp16_arith(s))) { return 1; } fn_gvec_ptr =3D size ? gen_helper_gvec_fcmlas : gen_helper_gvec_fc= mlah; @@ -7792,7 +7792,7 @@ static int disas_neon_insn_3same_ext(DisasContext *s,= uint32_t insn) int size =3D extract32(insn, 20, 1); data =3D extract32(insn, 24, 1); /* rot */ if (!aa32_dc_feature_vcma(s) - || (!size && !arm_dc_feature(s, ARM_FEATURE_V8_FP16))) { + || (!size && !aa32_dc_feature_fp16_arith(s))) { return 1; } fn_gvec_ptr =3D size ? gen_helper_gvec_fcadds : gen_helper_gvec_fc= addh; @@ -7865,7 +7865,7 @@ static int disas_neon_insn_2reg_scalar_ext(DisasConte= xt *s, uint32_t insn) return 1; } if (size =3D=3D 0) { - if (!arm_dc_feature(s, ARM_FEATURE_V8_FP16)) { + if (!aa32_dc_feature_fp16_arith(s)) { return 1; } /* For fp16, rm is just Vm, and index is M. */ --=20 2.17.1