|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [PATCH v4 03/16] x86emul: support AVX10.1
This requires relaxing various pre-existing AVX512* checks, as AVX10.1
covers all AVX512* except PF, ER, 4FMAPS, 4VNNIW (support for all of
which was removed meanwhile anyway), and VP2INTERSECT. At the same time
all vector widths are always supported.
Note that visa_check(), replacing host_and_vcpu_must_have() uses, checks
only the guest capability: We wouldn't expose AVX512* (nor AVX10)
without the hardware supporting it. Similarly in avx512_vlen_check() the
original host_and_vcpu_must_have() is reduced just vcpu_must_have().
This also simplifies (resulting) code in the test and fuzzing harnesses,
as there the XCR0 checks that are part of cpu_has_avx512* are only
needed in local code, not in the emulator itself (where respective
checking occurs elsewhere anyway, utilizing emul_test_read_xcr()).
While in most cases the changes to x86_emulate() are entirely
mechanical, for opmask insns earlier unconditional AVX512F checks are
converted into "else" clauses to existing if/else-if ones.
To be certain that no uses remain, also drop respective cpu_has_avx512*
(except in the test harness) and vcpu_has_avx512*().
Signed-off-by: Jan Beulich <jbeulich@xxxxxxxx>
---
Probably avx512_vlen_check() should have the avx512_ prefix dropped, now
that it also covers AVX10. But if so that wants to be either a prereq or
a follow-on patch.
visa_check() won't cover AVX10.2 and higher, but probably we will want
independent checking logic for that anyway.
Spec version 2 still leaves unclear what the xstate components are which
would need enabling for AVX10/256. x86emul_get_fpu() is therefore
untouched for now.
Since it'll be reducing code size, we may want to further convert
host_and_vcpu_must_have() to just vcpu_must_have() where appropriate
(should be [almost?] everywhere).
---
v4: Switch to using fallthrough pseudo-keyword. Drop new _vlen_check()
helper again. Re-base.
v3: Add ChangeLog entry.
v2: Drop use of vsz128 field. Re-base, in particular over dropping of
Xeon Phi support.
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -16,6 +16,7 @@ The format is based on [Keep a Changelog
mitigate (by rate-limiting) the system wide impact of an HVM guest
misusing atomic instructions.
- Support for CPIO microcode in discrete multiboot modules.
+ - Support for AVX10.1. (Experimental)
- On Arm:
- Support for guest suspend and resume to/from RAM via vPSCI.
--- a/xen/arch/x86/include/asm/cpufeature.h
+++ b/xen/arch/x86/include/asm/cpufeature.h
@@ -200,29 +200,18 @@ static inline bool boot_cpu_has(unsigned
#define cpu_has_pqe boot_cpu_has(X86_FEATURE_PQE)
#define cpu_has_fpu_sel (!boot_cpu_has(X86_FEATURE_NO_FPU_SEL))
#define cpu_has_mpx boot_cpu_has(X86_FEATURE_MPX)
-#define cpu_has_avx512f boot_cpu_has(X86_FEATURE_AVX512F)
-#define cpu_has_avx512dq boot_cpu_has(X86_FEATURE_AVX512DQ)
#define cpu_has_rdseed boot_cpu_has(X86_FEATURE_RDSEED)
#define cpu_has_smap boot_cpu_has(X86_FEATURE_SMAP)
-#define cpu_has_avx512_ifma boot_cpu_has(X86_FEATURE_AVX512_IFMA)
#define cpu_has_clflushopt boot_cpu_has(X86_FEATURE_CLFLUSHOPT)
#define cpu_has_clwb boot_cpu_has(X86_FEATURE_CLWB)
-#define cpu_has_avx512cd boot_cpu_has(X86_FEATURE_AVX512CD)
#define cpu_has_proc_trace boot_cpu_has(X86_FEATURE_PROC_TRACE)
#define cpu_has_sha boot_cpu_has(X86_FEATURE_SHA)
-#define cpu_has_avx512bw boot_cpu_has(X86_FEATURE_AVX512BW)
-#define cpu_has_avx512vl boot_cpu_has(X86_FEATURE_AVX512VL)
/* CPUID level 0x00000007:0.ecx */
-#define cpu_has_avx512_vbmi boot_cpu_has(X86_FEATURE_AVX512_VBMI)
#define cpu_has_pku boot_cpu_has(X86_FEATURE_PKU)
-#define cpu_has_avx512_vbmi2 boot_cpu_has(X86_FEATURE_AVX512_VBMI2)
#define cpu_has_gfni boot_cpu_has(X86_FEATURE_GFNI)
#define cpu_has_vaes boot_cpu_has(X86_FEATURE_VAES)
#define cpu_has_vpclmulqdq boot_cpu_has(X86_FEATURE_VPCLMULQDQ)
-#define cpu_has_avx512_vnni boot_cpu_has(X86_FEATURE_AVX512_VNNI)
-#define cpu_has_avx512_bitalg boot_cpu_has(X86_FEATURE_AVX512_BITALG)
-#define cpu_has_avx512_vpopcntdq boot_cpu_has(X86_FEATURE_AVX512_VPOPCNTDQ)
#define cpu_has_rdpid boot_cpu_has(X86_FEATURE_RDPID)
#define cpu_has_movdiri boot_cpu_has(X86_FEATURE_MOVDIRI)
#define cpu_has_movdir64b boot_cpu_has(X86_FEATURE_MOVDIR64B)
@@ -248,7 +237,6 @@ static inline bool boot_cpu_has(unsigned
#define cpu_has_tsx_force_abort boot_cpu_has(X86_FEATURE_TSX_FORCE_ABORT)
#define cpu_has_serialize boot_cpu_has(X86_FEATURE_SERIALIZE)
#define cpu_has_hybrid boot_cpu_has(X86_FEATURE_HYBRID)
-#define cpu_has_avx512_fp16 boot_cpu_has(X86_FEATURE_AVX512_FP16)
#define cpu_has_arch_caps boot_cpu_has(X86_FEATURE_ARCH_CAPS)
/* CPUID level 0x00000007:1.eax */
@@ -256,7 +244,6 @@ static inline bool boot_cpu_has(unsigned
#define cpu_has_sm3 boot_cpu_has(X86_FEATURE_SM3)
#define cpu_has_sm4 boot_cpu_has(X86_FEATURE_SM4)
#define cpu_has_avx_vnni boot_cpu_has(X86_FEATURE_AVX_VNNI)
-#define cpu_has_avx512_bf16 boot_cpu_has(X86_FEATURE_AVX512_BF16)
#define cpu_has_cmpccxadd boot_cpu_has(X86_FEATURE_CMPCCXADD)
#define cpu_has_fred boot_cpu_has(X86_FEATURE_FRED)
#define cpu_has_lkgs boot_cpu_has(X86_FEATURE_LKGS)
--- a/xen/arch/x86/x86_emulate/private.h
+++ b/xen/arch/x86/x86_emulate/private.h
@@ -577,26 +577,15 @@ amd_like(const struct x86_emulate_ctxt *
#define vcpu_has_invpcid() (ctxt->cpuid->feat.invpcid)
#define vcpu_has_rtm() (ctxt->cpuid->feat.rtm)
#define vcpu_has_mpx() (ctxt->cpuid->feat.mpx)
-#define vcpu_has_avx512f() (ctxt->cpuid->feat.avx512f)
-#define vcpu_has_avx512dq() (ctxt->cpuid->feat.avx512dq)
#define vcpu_has_rdseed() (ctxt->cpuid->feat.rdseed)
#define vcpu_has_adx() (ctxt->cpuid->feat.adx)
#define vcpu_has_smap() (ctxt->cpuid->feat.smap)
-#define vcpu_has_avx512_ifma() (ctxt->cpuid->feat.avx512_ifma)
#define vcpu_has_clflushopt() (ctxt->cpuid->feat.clflushopt)
#define vcpu_has_clwb() (ctxt->cpuid->feat.clwb)
-#define vcpu_has_avx512cd() (ctxt->cpuid->feat.avx512cd)
#define vcpu_has_sha() (ctxt->cpuid->feat.sha)
-#define vcpu_has_avx512bw() (ctxt->cpuid->feat.avx512bw)
-#define vcpu_has_avx512vl() (ctxt->cpuid->feat.avx512vl)
-#define vcpu_has_avx512_vbmi() (ctxt->cpuid->feat.avx512_vbmi)
-#define vcpu_has_avx512_vbmi2() (ctxt->cpuid->feat.avx512_vbmi2)
#define vcpu_has_gfni() (ctxt->cpuid->feat.gfni)
#define vcpu_has_vaes() (ctxt->cpuid->feat.vaes)
#define vcpu_has_vpclmulqdq() (ctxt->cpuid->feat.vpclmulqdq)
-#define vcpu_has_avx512_vnni() (ctxt->cpuid->feat.avx512_vnni)
-#define vcpu_has_avx512_bitalg() (ctxt->cpuid->feat.avx512_bitalg)
-#define vcpu_has_avx512_vpopcntdq() (ctxt->cpuid->feat.avx512_vpopcntdq)
#define vcpu_has_rdpid() (ctxt->cpuid->feat.rdpid)
#define vcpu_has_movdiri() (ctxt->cpuid->feat.movdiri)
#define vcpu_has_movdir64b() (ctxt->cpuid->feat.movdir64b)
@@ -604,12 +593,10 @@ amd_like(const struct x86_emulate_ctxt *
#define vcpu_has_avx512_vp2intersect() (ctxt->cpuid->feat.avx512_vp2intersect)
#define vcpu_has_serialize() (ctxt->cpuid->feat.serialize)
#define vcpu_has_tsxldtrk() (ctxt->cpuid->feat.tsxldtrk)
-#define vcpu_has_avx512_fp16() (ctxt->cpuid->feat.avx512_fp16)
#define vcpu_has_sha512() (ctxt->cpuid->feat.sha512)
#define vcpu_has_sm3() (ctxt->cpuid->feat.sm3)
#define vcpu_has_sm4() (ctxt->cpuid->feat.sm4)
#define vcpu_has_avx_vnni() (ctxt->cpuid->feat.avx_vnni)
-#define vcpu_has_avx512_bf16() (ctxt->cpuid->feat.avx512_bf16)
#define vcpu_has_cmpccxadd() (ctxt->cpuid->feat.cmpccxadd)
#define vcpu_has_lkgs() (ctxt->cpuid->feat.lkgs)
#define vcpu_has_wrmsrns() (ctxt->cpuid->feat.wrmsrns)
--- a/xen/arch/x86/x86_emulate/x86_emulate.c
+++ b/xen/arch/x86/x86_emulate/x86_emulate.c
@@ -1152,6 +1152,10 @@ static unsigned long *decode_vex_gpr(
return decode_gpr(regs, ~vex_reg & (mode_64bit() ? 0xf : 7));
}
+#define visa_check(subfeat) \
+ generate_exception_if(!cp->feat.avx512 ## subfeat && !cp->feat.avx10, \
+ X86_EXC_UD)
+
#define avx512_vlen_check(lig) do { \
switch ( evex.lr ) \
{ \
@@ -1161,7 +1165,7 @@ static unsigned long *decode_vex_gpr(
break; \
case 0: case 1: \
if ( !(lig) ) \
- host_and_vcpu_must_have(avx512vl); \
+ visa_check(vl); \
break; \
} \
} while ( false )
@@ -1396,7 +1400,9 @@ x86_emulate(
/* KMOV{W,Q} %k<n>, (%rax) */
stb[0] = 0xc4;
stb[1] = 0xe1;
- stb[2] = cpu_has_avx512bw ? 0xf8 : 0x78;
+ stb[2] = cp->feat.avx512bw || cp->feat.avx10
+ ? 0xf8 /* L0.NP.W1 - kmovq */
+ : 0x78 /* L0.NP.W0 - kmovw */;
stb[3] = 0x91;
stb[4] = evex.opmsk << 3;
insn_bytes = 5;
@@ -3423,7 +3429,7 @@ x86_emulate(
(ea.type != OP_REG && evex.brs &&
(evex.pfx & VEX_PREFIX_SCALAR_MASK))),
X86_EXC_UD);
- host_and_vcpu_must_have(avx512f);
+ visa_check(f);
if ( ea.type != OP_REG || !evex.brs )
avx512_vlen_check(evex.pfx & VEX_PREFIX_SCALAR_MASK);
simd_zmm:
@@ -3479,7 +3485,7 @@ x86_emulate(
generate_exception_if((evex.lr || evex.opmsk || evex.brs ||
evex.w != (evex.pfx & VEX_PREFIX_DOUBLE_MASK)),
X86_EXC_UD);
- host_and_vcpu_must_have(avx512f);
+ visa_check(f);
if ( (d & DstMask) != DstMem )
d &= ~TwoOp;
op_bytes = 8;
@@ -3506,7 +3512,7 @@ x86_emulate(
generate_exception_if((evex.brs ||
evex.w != (evex.pfx & VEX_PREFIX_DOUBLE_MASK)),
X86_EXC_UD);
- host_and_vcpu_must_have(avx512f);
+ visa_check(f);
avx512_vlen_check(false);
d |= TwoOp;
op_bytes = !(evex.pfx & VEX_PREFIX_DOUBLE_MASK) || evex.lr
@@ -3543,7 +3549,7 @@ x86_emulate(
case X86EMUL_OPC_EVEX_66(0x0f38, 0x64): /* vpblendm{d,q}
[xyz]mm/mem,[xyz]mm,[xyz]mm{k} */
case X86EMUL_OPC_EVEX_66(0x0f38, 0x65): /* vblendmp{s,d}
[xyz]mm/mem,[xyz]mm,[xyz]mm{k} */
avx512f_no_sae:
- host_and_vcpu_must_have(avx512f);
+ visa_check(f);
generate_exception_if(ea.type != OP_MEM && evex.brs, X86_EXC_UD);
avx512_vlen_check(false);
goto simd_zmm;
@@ -3623,13 +3629,13 @@ x86_emulate(
case X86EMUL_OPC_EVEX_F3(5, 0x2a): /* vcvtsi2sh r/m,xmm,xmm */
case X86EMUL_OPC_EVEX_F3(5, 0x7b): /* vcvtusi2sh r/m,xmm,xmm */
- host_and_vcpu_must_have(avx512_fp16);
+ visa_check(_fp16);
/* fall through */
CASE_SIMD_SCALAR_FP(_EVEX, 0x0f, 0x2a): /* vcvtsi2s{s,d} r/m,xmm,xmm */
CASE_SIMD_SCALAR_FP(_EVEX, 0x0f, 0x7b): /* vcvtusi2s{s,d} r/m,xmm,xmm */
generate_exception_if(evex.opmsk || (ea.type != OP_REG && evex.brs),
X86_EXC_UD);
- host_and_vcpu_must_have(avx512f);
+ visa_check(f);
if ( !evex.brs )
avx512_vlen_check(true);
get_fpu(X86EMUL_FPU_zmm);
@@ -3742,7 +3748,7 @@ x86_emulate(
case X86EMUL_OPC_EVEX_F3(5, 0x2d): /* vcvtsh2si xmm/mem,reg */
case X86EMUL_OPC_EVEX_F3(5, 0x78): /* vcvttsh2usi xmm/mem,reg */
case X86EMUL_OPC_EVEX_F3(5, 0x79): /* vcvtsh2usi xmm/mem,reg */
- host_and_vcpu_must_have(avx512_fp16);
+ visa_check(_fp16);
/* fall through */
CASE_SIMD_SCALAR_FP(_EVEX, 0x0f, 0x2c): /* vcvtts{s,d}2si xmm/mem,reg */
CASE_SIMD_SCALAR_FP(_EVEX, 0x0f, 0x2d): /* vcvts{s,d}2si xmm/mem,reg */
@@ -3752,7 +3758,7 @@ x86_emulate(
evex.opmsk ||
(ea.type != OP_REG && evex.brs)),
X86_EXC_UD);
- host_and_vcpu_must_have(avx512f);
+ visa_check(f);
if ( !evex.brs )
avx512_vlen_check(true);
get_fpu(X86EMUL_FPU_zmm);
@@ -3818,7 +3824,7 @@ x86_emulate(
case X86EMUL_OPC_EVEX(5, 0x2e): /* vucomish xmm/m16,xmm */
case X86EMUL_OPC_EVEX(5, 0x2f): /* vcomish xmm/m16,xmm */
- host_and_vcpu_must_have(avx512_fp16);
+ visa_check(_fp16);
generate_exception_if(evex.w, X86_EXC_UD);
/* fall through */
CASE_SIMD_PACKED_FP(_EVEX, 0x0f, 0x2e): /* vucomis{s,d} xmm/mem,xmm */
@@ -3827,7 +3833,7 @@ x86_emulate(
(ea.type != OP_REG && evex.brs) ||
evex.w != evex.pfx),
X86_EXC_UD);
- host_and_vcpu_must_have(avx512f);
+ visa_check(f);
if ( !evex.brs )
avx512_vlen_check(true);
get_fpu(X86EMUL_FPU_zmm);
@@ -3971,7 +3977,7 @@ x86_emulate(
case X86EMUL_OPC_VEX(0x0f, 0x4a): /* kadd{w,q} k,k,k */
if ( !vex.w )
- host_and_vcpu_must_have(avx512dq);
+ visa_check(dq);
/* fall through */
case X86EMUL_OPC_VEX(0x0f, 0x41): /* kand{w,q} k,k,k */
case X86EMUL_OPC_VEX_66(0x0f, 0x41): /* kand{b,d} k,k,k */
@@ -3987,11 +3993,12 @@ x86_emulate(
generate_exception_if(!vex.l, X86_EXC_UD);
opmask_basic:
if ( vex.w )
- host_and_vcpu_must_have(avx512bw);
+ visa_check(bw);
else if ( vex.pfx )
- host_and_vcpu_must_have(avx512dq);
+ visa_check(dq);
+ else
+ visa_check(f);
opmask_common:
- host_and_vcpu_must_have(avx512f);
generate_exception_if(!vex.r || (mode_64bit() && !(vex.reg & 8)) ||
ea.type != OP_REG, X86_EXC_UD);
@@ -4014,13 +4021,14 @@ x86_emulate(
generate_exception_if(vex.l || vex.reg != 0xf, X86_EXC_UD);
goto opmask_basic;
- case X86EMUL_OPC_VEX(0x0f, 0x4b): /* kunpck{w,d}{d,q} k,k,k */
+ case X86EMUL_OPC_VEX(0x0f, 0x4b): /* kunpck{wd,dq} k,k,k */
generate_exception_if(!vex.l, X86_EXC_UD);
- host_and_vcpu_must_have(avx512bw);
+ visa_check(bw);
goto opmask_common;
case X86EMUL_OPC_VEX_66(0x0f, 0x4b): /* kunpckbw k,k,k */
generate_exception_if(!vex.l || vex.w, X86_EXC_UD);
+ visa_check(f);
goto opmask_common;
#endif /* X86EMUL_NO_SIMD */
@@ -4088,7 +4096,7 @@ x86_emulate(
generate_exception_if((evex.w != (evex.pfx & VEX_PREFIX_DOUBLE_MASK) ||
(ea.type != OP_MEM && evex.brs)),
X86_EXC_UD);
- host_and_vcpu_must_have(avx512dq);
+ visa_check(dq);
avx512_vlen_check(false);
goto simd_zmm;
@@ -4127,12 +4135,12 @@ x86_emulate(
case X86EMUL_OPC_EVEX_F2(0x0f, 0x7a): /* vcvtudq2ps [xyz]mm/mem,[xyz]mm{k}
*/
/* vcvtuqq2ps [xyz]mm/mem,{x,y}mm{k}
*/
if ( evex.w )
- host_and_vcpu_must_have(avx512dq);
+ visa_check(dq);
else
{
case X86EMUL_OPC_EVEX(0x0f, 0x78): /* vcvttp{s,d}2udq
[xyz]mm/mem,[xyz]mm{k} */
case X86EMUL_OPC_EVEX(0x0f, 0x79): /* vcvtp{s,d}2udq
[xyz]mm/mem,[xyz]mm{k} */
- host_and_vcpu_must_have(avx512f);
+ visa_check(f);
}
if ( ea.type != OP_REG || !evex.brs )
avx512_vlen_check(false);
@@ -4349,7 +4357,7 @@ x86_emulate(
case X86EMUL_OPC_EVEX_66(0x0f38, 0x0b): /* vpmulhrsw
[xyz]mm/mem,[xyz]mm,[xyz]mm{k} */
case X86EMUL_OPC_EVEX_66(0x0f38, 0x1c): /* vpabsb [xyz]mm/mem,[xyz]mm{k} */
case X86EMUL_OPC_EVEX_66(0x0f38, 0x1d): /* vpabsw [xyz]mm/mem,[xyz]mm{k} */
- host_and_vcpu_must_have(avx512bw);
+ visa_check(bw);
generate_exception_if(evex.brs, X86_EXC_UD);
elem_bytes = 1 << (b & 1);
goto avx512f_no_sae;
@@ -4381,7 +4389,7 @@ x86_emulate(
generate_exception_if(b != 0x27 && evex.w != (b & 1), X86_EXC_UD);
goto avx512f_no_sae;
}
- host_and_vcpu_must_have(avx512bw);
+ visa_check(bw);
generate_exception_if(evex.brs, X86_EXC_UD);
elem_bytes = 1 << (ext == ext_0f ? b & 1 : evex.w);
avx512_vlen_check(false);
@@ -4454,7 +4462,7 @@ x86_emulate(
dst.bytes = 2;
/* fall through */
case X86EMUL_OPC_EVEX_66(5, 0x6e): /* vmovw r/m16,xmm */
- host_and_vcpu_must_have(avx512_fp16);
+ visa_check(_fp16);
generate_exception_if(evex.w, X86_EXC_UD);
/* fall through */
case X86EMUL_OPC_EVEX_66(0x0f, 0x6e): /* vmov{d,q} r/m,xmm */
@@ -4462,7 +4470,7 @@ x86_emulate(
generate_exception_if((evex.lr || evex.opmsk || evex.brs ||
evex.reg != 0xf || !evex.RX),
X86_EXC_UD);
- host_and_vcpu_must_have(avx512f);
+ visa_check(f);
get_fpu(X86EMUL_FPU_zmm);
opc = init_evex(stub);
@@ -4520,7 +4528,7 @@ x86_emulate(
case X86EMUL_OPC_EVEX_F2(0x0f, 0x6f): /* vmovdqu{8,16}
[xyz]mm/mem,[xyz]mm{k} */
case X86EMUL_OPC_EVEX_F2(0x0f, 0x7f): /* vmovdqu{8,16}
[xyz]mm,[xyz]mm/mem{k} */
- host_and_vcpu_must_have(avx512bw);
+ visa_check(bw);
elem_bytes = 1 << evex.w;
goto vmovdqa;
@@ -4613,7 +4621,7 @@ x86_emulate(
generate_exception_if(evex.w, X86_EXC_UD);
else
{
- host_and_vcpu_must_have(avx512bw);
+ visa_check(bw);
generate_exception_if(evex.brs, X86_EXC_UD);
}
d = (d & ~SrcMask) | SrcMem | TwoOp;
@@ -4861,7 +4869,7 @@ x86_emulate(
case X86EMUL_OPC_EVEX_F3(0x0f, 0xe6): /* vcvtdq2pd
{x,y}mm/mem,[xyz]mm{k} */
/* vcvtqq2pd
[xyz]mm/mem,[xyz]mm{k} */
if ( evex.pfx != vex_f3 )
- host_and_vcpu_must_have(avx512f);
+ visa_check(f);
else if ( evex.w )
{
case X86EMUL_OPC_EVEX_66(0x0f, 0x78): /* vcvttps2uqq
{x,y}mm/mem,[xyz]mm{k} */
@@ -4872,11 +4880,11 @@ x86_emulate(
/* vcvttpd2qq
[xyz]mm/mem,[xyz]mm{k} */
case X86EMUL_OPC_EVEX_66(0x0f, 0x7b): /* vcvtps2qq
{x,y}mm/mem,[xyz]mm{k} */
/* vcvtpd2qq
[xyz]mm/mem,[xyz]mm{k} */
- host_and_vcpu_must_have(avx512dq);
+ visa_check(dq);
}
else
{
- host_and_vcpu_must_have(avx512f);
+ visa_check(f);
/*
* While SDM version 085 has explicit wording towards embedded
* rounding being ignored, it's still not entirely unambiguous with
@@ -4923,7 +4931,7 @@ x86_emulate(
case X86EMUL_OPC_EVEX_66(0x0f, 0xd6): /* vmovq xmm,xmm/m64 */
generate_exception_if(evex.lr || !evex.w || evex.opmsk || evex.brs,
X86_EXC_UD);
- host_and_vcpu_must_have(avx512f);
+ visa_check(f);
d |= TwoOp;
op_bytes = 8;
goto simd_zmm;
@@ -4949,19 +4957,21 @@ x86_emulate(
case X86EMUL_OPC_VEX(0x0f, 0x90): /* kmov{w,q} k/mem,k */
case X86EMUL_OPC_VEX_66(0x0f, 0x90): /* kmov{b,d} k/mem,k */
generate_exception_if(vex.l || !vex.r, X86_EXC_UD);
- host_and_vcpu_must_have(avx512f);
if ( vex.w )
{
- host_and_vcpu_must_have(avx512bw);
+ visa_check(bw);
op_bytes = 4 << !vex.pfx;
}
else if ( vex.pfx )
{
- host_and_vcpu_must_have(avx512dq);
+ visa_check(dq);
op_bytes = 1;
}
else
+ {
+ visa_check(f);
op_bytes = 2;
+ }
get_fpu(X86EMUL_FPU_opmask);
@@ -4983,14 +4993,15 @@ x86_emulate(
generate_exception_if(vex.l || !vex.r || vex.reg != 0xf ||
ea.type != OP_REG, X86_EXC_UD);
- host_and_vcpu_must_have(avx512f);
if ( vex.pfx == vex_f2 )
- host_and_vcpu_must_have(avx512bw);
+ visa_check(bw);
else
{
generate_exception_if(vex.w, X86_EXC_UD);
if ( vex.pfx )
- host_and_vcpu_must_have(avx512dq);
+ visa_check(dq);
+ else
+ visa_check(f);
}
get_fpu(X86EMUL_FPU_opmask);
@@ -5022,10 +5033,9 @@ x86_emulate(
dst = ea;
dst.reg = decode_gpr(&_regs, modrm_reg);
- host_and_vcpu_must_have(avx512f);
if ( vex.pfx == vex_f2 )
{
- host_and_vcpu_must_have(avx512bw);
+ visa_check(bw);
dst.bytes = 4 << (mode_64bit() && vex.w);
}
else
@@ -5033,7 +5043,9 @@ x86_emulate(
generate_exception_if(vex.w, X86_EXC_UD);
dst.bytes = 4;
if ( vex.pfx )
- host_and_vcpu_must_have(avx512dq);
+ visa_check(dq);
+ else
+ visa_check(f);
}
get_fpu(X86EMUL_FPU_opmask);
@@ -5055,20 +5067,18 @@ x86_emulate(
ASSERT(!state->simd_size);
break;
- case X86EMUL_OPC_VEX(0x0f, 0x99): /* ktest{w,q} k,k */
- if ( !vex.w )
- host_and_vcpu_must_have(avx512dq);
- /* fall through */
case X86EMUL_OPC_VEX(0x0f, 0x98): /* kortest{w,q} k,k */
case X86EMUL_OPC_VEX_66(0x0f, 0x98): /* kortest{b,d} k,k */
+ case X86EMUL_OPC_VEX(0x0f, 0x99): /* ktest{w,q} k,k */
case X86EMUL_OPC_VEX_66(0x0f, 0x99): /* ktest{b,d} k,k */
generate_exception_if(vex.l || !vex.r || vex.reg != 0xf ||
ea.type != OP_REG, X86_EXC_UD);
- host_and_vcpu_must_have(avx512f);
if ( vex.w )
- host_and_vcpu_must_have(avx512bw);
- else if ( vex.pfx )
- host_and_vcpu_must_have(avx512dq);
+ visa_check(bw);
+ else if ( vex.pfx || (b & 1) )
+ visa_check(dq);
+ else
+ visa_check(f);
get_fpu(X86EMUL_FPU_opmask);
@@ -5355,7 +5365,7 @@ x86_emulate(
(evex.pfx & VEX_PREFIX_SCALAR_MASK)) ||
!evex.r || !evex.R || evex.z),
X86_EXC_UD);
- host_and_vcpu_must_have(avx512f);
+ visa_check(f);
if ( ea.type != OP_REG || !evex.brs )
avx512_vlen_check(evex.pfx & VEX_PREFIX_SCALAR_MASK);
simd_imm8_zmm:
@@ -5399,9 +5409,9 @@ x86_emulate(
case X86EMUL_OPC_EVEX_66(0x0f3a, 0x22): /* vpinsr{d,q} $imm8,r/m,xmm,xmm */
generate_exception_if(evex.lr || evex.opmsk || evex.brs, X86_EXC_UD);
if ( b & 2 )
- host_and_vcpu_must_have(avx512dq);
+ visa_check(dq);
else
- host_and_vcpu_must_have(avx512bw);
+ visa_check(bw);
if ( !mode_64bit() )
evex.w = 0;
memcpy(mmvalp, &src.val, src.bytes);
@@ -5438,7 +5448,7 @@ x86_emulate(
/* fall through */
case X86EMUL_OPC_EVEX_66(0x0f3a, 0x25): /* vpternlog{d,q}
$imm8,[xyz]mm/mem,[xyz]mm,[xyz]mm{k} */
avx512f_imm8_no_sae:
- host_and_vcpu_must_have(avx512f);
+ visa_check(f);
generate_exception_if(ea.type != OP_MEM && evex.brs, X86_EXC_UD);
avx512_vlen_check(false);
goto simd_imm8_zmm;
@@ -5537,7 +5547,7 @@ x86_emulate(
case X86EMUL_OPC_EVEX_66(0x0f, 0xe4): /* vpmulhuw
[xyz]mm/mem,[xyz]mm,[xyz]mm{k} */
case X86EMUL_OPC_EVEX_66(0x0f, 0xea): /* vpminsw
[xyz]mm/mem,[xyz]mm,[xyz]mm{k} */
case X86EMUL_OPC_EVEX_66(0x0f, 0xee): /* vpmaxsw
[xyz]mm/mem,[xyz]mm,[xyz]mm{k} */
- host_and_vcpu_must_have(avx512bw);
+ visa_check(bw);
generate_exception_if(evex.brs, X86_EXC_UD);
elem_bytes = b & 0x10 ? 1 : 2;
goto avx512f_no_sae;
@@ -5762,7 +5772,7 @@ x86_emulate(
case X86EMUL_OPC_EVEX_66(0x0f38, 0x10): /* vpsrlvw
[xyz]mm/mem,[xyz]mm,[xyz]mm{k} */
case X86EMUL_OPC_EVEX_66(0x0f38, 0x11): /* vpsravw
[xyz]mm/mem,[xyz]mm,[xyz]mm{k} */
case X86EMUL_OPC_EVEX_66(0x0f38, 0x12): /* vpsllvw
[xyz]mm/mem,[xyz]mm,[xyz]mm{k} */
- host_and_vcpu_must_have(avx512bw);
+ visa_check(bw);
generate_exception_if(!evex.w || evex.brs, X86_EXC_UD);
elem_bytes = 2;
goto avx512f_no_sae;
@@ -5772,7 +5782,7 @@ x86_emulate(
case X86EMUL_OPC_EVEX_F3(0x0f38, 0x20): /* vpmovswb [xyz]mm,{x,y}mm/mem{k}
*/
case X86EMUL_OPC_EVEX_66(0x0f38, 0x30): /* vpmovzxbw
{x,y}mm/mem,[xyz]mm{k} */
case X86EMUL_OPC_EVEX_F3(0x0f38, 0x30): /* vpmovwb [xyz]mm,{x,y}mm/mem{k}
*/
- host_and_vcpu_must_have(avx512bw);
+ visa_check(bw);
if ( evex.pfx != vex_f3 )
{
case X86EMUL_OPC_EVEX_66(0x0f38, 0x21): /* vpmovsxbd xmm/mem,[xyz]mm{k} */
@@ -5820,7 +5830,7 @@ x86_emulate(
case X86EMUL_OPC_EVEX_66(0x0f38, 0x13): /* vcvtph2ps
{x,y}mm/mem,[xyz]mm{k} */
generate_exception_if(evex.w || (ea.type != OP_REG && evex.brs),
X86_EXC_UD);
- host_and_vcpu_must_have(avx512f);
+ visa_check(f);
if ( !evex.brs )
avx512_vlen_check(false);
op_bytes = 8 << evex.lr;
@@ -5874,7 +5884,7 @@ x86_emulate(
op_bytes = 8;
generate_exception_if(evex.brs, X86_EXC_UD);
if ( !evex.w )
- host_and_vcpu_must_have(avx512dq);
+ visa_check(dq);
goto avx512_broadcast;
case X86EMUL_OPC_EVEX_66(0x0f38, 0x1a): /* vbroadcastf32x4 m128,{y,z}mm{k}
*/
@@ -5884,7 +5894,7 @@ x86_emulate(
generate_exception_if(ea.type != OP_MEM || !evex.lr || evex.brs,
X86_EXC_UD);
if ( evex.w )
- host_and_vcpu_must_have(avx512dq);
+ visa_check(dq);
goto avx512_broadcast;
case X86EMUL_OPC_VEX_66(0x0f38, 0x20): /* vpmovsxbw xmm/mem,{x,y}mm */
@@ -5909,9 +5919,9 @@ x86_emulate(
case X86EMUL_OPC_EVEX_F3(0x0f38, 0x28): /* vpmovm2{b,w} k,[xyz]mm */
case X86EMUL_OPC_EVEX_F3(0x0f38, 0x38): /* vpmovm2{d,q} k,[xyz]mm */
if ( b & 0x10 )
- host_and_vcpu_must_have(avx512dq);
+ visa_check(dq);
else
- host_and_vcpu_must_have(avx512bw);
+ visa_check(bw);
generate_exception_if(evex.opmsk || ea.type != OP_REG, X86_EXC_UD);
d |= TwoOp;
op_bytes = 16 << evex.lr;
@@ -5954,7 +5964,7 @@ x86_emulate(
fault_suppression = false;
/* fall through */
case X86EMUL_OPC_EVEX_66(0x0f38, 0x44): /* vplzcnt{d,q}
[xyz]mm/mem,[xyz]mm{k} */
- host_and_vcpu_must_have(avx512cd);
+ visa_check(cd);
goto avx512f_no_sae;
case X86EMUL_OPC_VEX_66(0x0f38, 0x2c): /* vmaskmovps mem,{x,y}mm,{x,y}mm */
@@ -6030,7 +6040,7 @@ x86_emulate(
case X86EMUL_OPC_EVEX_66(0x0f38, 0xba): /* vfmsub231p{s,d}
[xyz]mm/mem,[xyz]mm,[xyz]mm{k} */
case X86EMUL_OPC_EVEX_66(0x0f38, 0xbc): /* vfnmadd231p{s,d}
[xyz]mm/mem,[xyz]mm,[xyz]mm{k} */
case X86EMUL_OPC_EVEX_66(0x0f38, 0xbe): /* vfnmsub231p{s,d}
[xyz]mm/mem,[xyz]mm,[xyz]mm{k} */
- host_and_vcpu_must_have(avx512f);
+ visa_check(f);
if ( ea.type != OP_REG || !evex.brs )
avx512_vlen_check(false);
goto simd_zmm;
@@ -6049,7 +6059,7 @@ x86_emulate(
case X86EMUL_OPC_EVEX_66(0x0f38, 0xbb): /* vfmsub231s{s,d}
xmm/mem,xmm,xmm{k} */
case X86EMUL_OPC_EVEX_66(0x0f38, 0xbd): /* vfnmadd231s{s,d}
xmm/mem,xmm,xmm{k} */
case X86EMUL_OPC_EVEX_66(0x0f38, 0xbf): /* vfnmsub231s{s,d}
xmm/mem,xmm,xmm{k} */
- host_and_vcpu_must_have(avx512f);
+ visa_check(f);
generate_exception_if(ea.type != OP_REG && evex.brs, X86_EXC_UD);
if ( !evex.brs )
avx512_vlen_check(true);
@@ -6063,14 +6073,14 @@ x86_emulate(
case X86EMUL_OPC_EVEX_66(0x0f38, 0x3a): /* vpminuw
[xyz]mm/mem,[xyz]mm,[xyz]mm{k} */
case X86EMUL_OPC_EVEX_66(0x0f38, 0x3c): /* vpmaxsb
[xyz]mm/mem,[xyz]mm,[xyz]mm{k} */
case X86EMUL_OPC_EVEX_66(0x0f38, 0x3e): /* vpmaxuw
[xyz]mm/mem,[xyz]mm,[xyz]mm{k} */
- host_and_vcpu_must_have(avx512bw);
+ visa_check(bw);
generate_exception_if(evex.brs, X86_EXC_UD);
elem_bytes = b & 2 ?: 1;
goto avx512f_no_sae;
case X86EMUL_OPC_EVEX_66(0x0f38, 0x40): /* vpmull{d,q}
[xyz]mm/mem,[xyz]mm,[xyz]mm{k} */
if ( evex.w )
- host_and_vcpu_must_have(avx512dq);
+ visa_check(dq);
goto avx512f_no_sae;
case X86EMUL_OPC_66(0x0f38, 0xdb): /* aesimc xmm/m128,xmm */
@@ -6110,7 +6120,7 @@ x86_emulate(
case X86EMUL_OPC_EVEX_66(0x0f38, 0x51): /* vpdpbusds
[xyz]mm/mem,[xyz]mm,[xyz]mm{k} */
case X86EMUL_OPC_EVEX_66(0x0f38, 0x52): /* vpdpwssd
[xyz]mm/mem,[xyz]mm,[xyz]mm{k} */
case X86EMUL_OPC_EVEX_66(0x0f38, 0x53): /* vpdpwssds
[xyz]mm/mem,[xyz]mm,[xyz]mm{k} */
- host_and_vcpu_must_have(avx512_vnni);
+ visa_check(_vnni);
generate_exception_if(evex.w, X86_EXC_UD);
goto avx512f_no_sae;
@@ -6122,7 +6132,7 @@ x86_emulate(
d |= TwoOp;
/* fall through */
case X86EMUL_OPC_EVEX_F3(0x0f38, 0x52): /* vdpbf16ps
[xyz]mm/mem,[xyz]mm,[xyz]mm{k} */
- host_and_vcpu_must_have(avx512_bf16);
+ visa_check(_bf16);
generate_exception_if(evex.w, X86_EXC_UD);
op_bytes = 16 << evex.lr;
goto avx512f_no_sae;
@@ -6139,7 +6149,7 @@ x86_emulate(
case X86EMUL_OPC_EVEX_66(0x0f38, 0x4d): /* vrcp14s{s,d} xmm/mem,xmm,xmm{k}
*/
case X86EMUL_OPC_EVEX_66(0x0f38, 0x4f): /* vrsqrt14s{s,d}
xmm/mem,xmm,xmm{k} */
- host_and_vcpu_must_have(avx512f);
+ visa_check(f);
generate_exception_if(evex.brs, X86_EXC_UD);
avx512_vlen_check(true);
goto simd_zmm;
@@ -6148,16 +6158,16 @@ x86_emulate(
generate_exception_if(evex.w || !evex.r || !evex.R || evex.z,
X86_EXC_UD);
/* fall through */
case X86EMUL_OPC_EVEX_66(0x0f38, 0x54): /* vpopcnt{b,w}
[xyz]mm/mem,[xyz]mm{k} */
- host_and_vcpu_must_have(avx512_bitalg);
+ visa_check(_bitalg);
/* fall through */
case X86EMUL_OPC_EVEX_66(0x0f38, 0x66): /* vpblendm{b,w}
[xyz]mm/mem,[xyz]mm,[xyz]mm{k} */
- host_and_vcpu_must_have(avx512bw);
+ visa_check(bw);
generate_exception_if(evex.brs, X86_EXC_UD);
elem_bytes = 1 << evex.w;
goto avx512f_no_sae;
case X86EMUL_OPC_EVEX_66(0x0f38, 0x55): /* vpopcnt{d,q}
[xyz]mm/mem,[xyz]mm{k} */
- host_and_vcpu_must_have(avx512_vpopcntdq);
+ visa_check(_vpopcntdq);
goto avx512f_no_sae;
case X86EMUL_OPC_VEX_66(0x0f38, 0x5a): /* vbroadcasti128 m128,ymm */
@@ -6166,14 +6176,14 @@ x86_emulate(
case X86EMUL_OPC_EVEX_66(0x0f38, 0x62): /* vpexpand{b,w}
[xyz]mm/mem,[xyz]mm{k} */
case X86EMUL_OPC_EVEX_66(0x0f38, 0x63): /* vpcompress{b,w}
[xyz]mm,[xyz]mm/mem{k} */
- host_and_vcpu_must_have(avx512_vbmi2);
+ visa_check(_vbmi2);
elem_bytes = 1 << evex.w;
/* fall through */
case X86EMUL_OPC_EVEX_66(0x0f38, 0x88): /* vexpandp{s,d}
[xyz]mm/mem,[xyz]mm{k} */
case X86EMUL_OPC_EVEX_66(0x0f38, 0x89): /* vpexpand{d,q}
[xyz]mm/mem,[xyz]mm{k} */
case X86EMUL_OPC_EVEX_66(0x0f38, 0x8a): /* vcompressp{s,d}
[xyz]mm,[xyz]mm/mem{k} */
case X86EMUL_OPC_EVEX_66(0x0f38, 0x8b): /* vpcompress{d,q}
[xyz]mm,[xyz]mm/mem{k} */
- host_and_vcpu_must_have(avx512f);
+ visa_check(f);
generate_exception_if(evex.brs, X86_EXC_UD);
avx512_vlen_check(false);
/*
@@ -6207,7 +6217,7 @@ x86_emulate(
/* fall through */
case X86EMUL_OPC_EVEX_66(0x0f38, 0x71): /* vpshldv{d,q}
[xyz]mm/mem,[xyz]mm,[xyz]mm{k} */
case X86EMUL_OPC_EVEX_66(0x0f38, 0x73): /* vpshrdv{d,q}
[xyz]mm/mem,[xyz]mm,[xyz]mm{k} */
- host_and_vcpu_must_have(avx512_vbmi2);
+ visa_check(_vbmi2);
goto avx512f_no_sae;
case X86EMUL_OPC_VEX (0x0f38, 0xb0): /* vcvtneoph2ps mem,[xy]mm */
@@ -6227,16 +6237,16 @@ x86_emulate(
case X86EMUL_OPC_EVEX_66(0x0f38, 0x7d): /* vpermt2{b,w}
[xyz]mm/mem,[xyz]mm,[xyz]mm{k} */
case X86EMUL_OPC_EVEX_66(0x0f38, 0x8d): /* vperm{b,w}
[xyz]mm/mem,[xyz]mm,[xyz]mm{k} */
if ( !evex.w )
- host_and_vcpu_must_have(avx512_vbmi);
+ visa_check(_vbmi);
else
- host_and_vcpu_must_have(avx512bw);
+ visa_check(bw);
generate_exception_if(evex.brs, X86_EXC_UD);
fault_suppression = false;
goto avx512f_no_sae;
case X86EMUL_OPC_EVEX_66(0x0f38, 0x78): /* vpbroadcastb xmm/m8,[xyz]mm{k}
*/
case X86EMUL_OPC_EVEX_66(0x0f38, 0x79): /* vpbroadcastw xmm/m16,[xyz]mm{k}
*/
- host_and_vcpu_must_have(avx512bw);
+ visa_check(bw);
generate_exception_if(evex.w || evex.brs, X86_EXC_UD);
op_bytes = elem_bytes = 1 << (b & 1);
/* See the comment at the avx512_broadcast label. */
@@ -6245,14 +6255,14 @@ x86_emulate(
case X86EMUL_OPC_EVEX_66(0x0f38, 0x7a): /* vpbroadcastb r32,[xyz]mm{k} */
case X86EMUL_OPC_EVEX_66(0x0f38, 0x7b): /* vpbroadcastw r32,[xyz]mm{k} */
- host_and_vcpu_must_have(avx512bw);
+ visa_check(bw);
generate_exception_if(evex.w, X86_EXC_UD);
/* fall through */
case X86EMUL_OPC_EVEX_66(0x0f38, 0x7c): /* vpbroadcast{d,q} reg,[xyz]mm{k}
*/
generate_exception_if((ea.type != OP_REG || evex.brs ||
evex.reg != 0xf || !evex.RX),
X86_EXC_UD);
- host_and_vcpu_must_have(avx512f);
+ visa_check(f);
avx512_vlen_check(false);
get_fpu(X86EMUL_FPU_zmm);
@@ -6321,7 +6331,7 @@ x86_emulate(
case X86EMUL_OPC_EVEX_66(0x0f38, 0x83): /* vpmultishiftqb
[xyz]mm/mem,[xyz]mm,[xyz]mm{k} */
generate_exception_if(!evex.w, X86_EXC_UD);
- host_and_vcpu_must_have(avx512_vbmi);
+ visa_check(_vbmi);
fault_suppression = false;
goto avx512f_no_sae;
@@ -6479,8 +6489,8 @@ x86_emulate(
evex.reg != 0xf ||
modrm_reg == state->sib_index),
X86_EXC_UD);
+ visa_check(f);
avx512_vlen_check(false);
- host_and_vcpu_must_have(avx512f);
get_fpu(X86EMUL_FPU_zmm);
/* Read destination and index registers. */
@@ -6641,8 +6651,8 @@ x86_emulate(
evex.reg != 0xf ||
modrm_reg == state->sib_index),
X86_EXC_UD);
+ visa_check(f);
avx512_vlen_check(false);
- host_and_vcpu_must_have(avx512f);
get_fpu(X86EMUL_FPU_zmm);
/* Read source and index registers. */
@@ -6758,7 +6768,7 @@ x86_emulate(
case X86EMUL_OPC_EVEX_66(0x0f38, 0xb4): /* vpmadd52luq
[xyz]mm/mem,[xyz]mm,[xyz]mm{k} */
case X86EMUL_OPC_EVEX_66(0x0f38, 0xb5): /* vpmadd52huq
[xyz]mm/mem,[xyz]mm,[xyz]mm{k} */
- host_and_vcpu_must_have(avx512_ifma);
+ visa_check(_ifma);
generate_exception_if(!evex.w, X86_EXC_UD);
goto avx512f_no_sae;
@@ -7238,7 +7248,7 @@ x86_emulate(
/* fall through */
case X86EMUL_OPC_EVEX_66(0x0f3a, 0x08): /* vrndscaleps
$imm8,[xyz]mm/mem,[xyz]mm{k} */
case X86EMUL_OPC_EVEX_66(0x0f3a, 0x09): /* vrndscalepd
$imm8,[xyz]mm/mem,[xyz]mm{k} */
- host_and_vcpu_must_have(avx512f);
+ visa_check(f);
generate_exception_if(evex.w != (b & 1), X86_EXC_UD);
avx512_vlen_check(b & 2);
goto simd_imm8_zmm;
@@ -7247,7 +7257,7 @@ x86_emulate(
generate_exception_if(ea.type != OP_REG && evex.brs, X86_EXC_UD);
/* fall through */
case X86EMUL_OPC_EVEX(0x0f3a, 0x08): /* vrndscaleph
$imm8,[xyz]mm/mem,[xyz]mm{k} */
- host_and_vcpu_must_have(avx512_fp16);
+ visa_check(_fp16);
generate_exception_if(evex.w, X86_EXC_UD);
avx512_vlen_check(b & 2);
goto simd_imm8_zmm;
@@ -7360,11 +7370,11 @@ x86_emulate(
evex.opmsk || evex.brs),
X86_EXC_UD);
if ( !(b & 2) )
- host_and_vcpu_must_have(avx512bw);
+ visa_check(bw);
else if ( !(b & 1) )
- host_and_vcpu_must_have(avx512dq);
+ visa_check(dq);
else
- host_and_vcpu_must_have(avx512f);
+ visa_check(f);
get_fpu(X86EMUL_FPU_zmm);
opc = init_evex(stub);
goto pextr;
@@ -7378,7 +7388,7 @@ x86_emulate(
case X86EMUL_OPC_EVEX_66(0x0f3a, 0x39): /* vextracti32x4
$imm8,{y,z}mm,xmm/m128{k} */
/* vextracti64x2
$imm8,{y,z}mm,xmm/m128{k} */
if ( evex.w )
- host_and_vcpu_must_have(avx512dq);
+ visa_check(dq);
generate_exception_if(evex.brs, X86_EXC_UD);
/* fall through */
case X86EMUL_OPC_EVEX_66(0x0f3a, 0x23): /* vshuff32x4
$imm8,{y,z}mm/mem,{y,z}mm,{y,z}mm{k} */
@@ -7398,7 +7408,7 @@ x86_emulate(
case X86EMUL_OPC_EVEX_66(0x0f3a, 0x3b): /* vextracti32x8
$imm8,zmm,ymm/m256{k} */
/* vextracti64x4
$imm8,zmm,ymm/m256{k} */
if ( !evex.w )
- host_and_vcpu_must_have(avx512dq);
+ visa_check(dq);
generate_exception_if(evex.lr != 2 || evex.brs, X86_EXC_UD);
fault_suppression = false;
goto avx512f_imm8_no_sae;
@@ -7414,7 +7424,7 @@ x86_emulate(
generate_exception_if((evex.w || evex.reg != 0xf || !evex.RX ||
(ea.type != OP_REG && (evex.z ||
evex.brs))),
X86_EXC_UD);
- host_and_vcpu_must_have(avx512f);
+ visa_check(f);
avx512_vlen_check(false);
opc = init_evex(stub);
}
@@ -7506,7 +7516,7 @@ x86_emulate(
if ( !(b & 0x20) )
goto avx512f_imm8_no_sae;
avx512bw_imm:
- host_and_vcpu_must_have(avx512bw);
+ visa_check(bw);
generate_exception_if(evex.brs, X86_EXC_UD);
elem_bytes = 1 << evex.w;
avx512_vlen_check(false);
@@ -7545,7 +7555,7 @@ x86_emulate(
goto simd_0f_imm8_avx;
case X86EMUL_OPC_EVEX_66(0x0f3a, 0x21): /* vinsertps $imm8,xmm/m32,xmm,xmm
*/
- host_and_vcpu_must_have(avx512f);
+ visa_check(f);
generate_exception_if(evex.lr || evex.w || evex.opmsk || evex.brs,
X86_EXC_UD);
op_bytes = 4;
@@ -7553,18 +7563,18 @@ x86_emulate(
case X86EMUL_OPC_EVEX_66(0x0f3a, 0x50): /* vrangep{s,d}
$imm8,[xyz]mm/mem,[xyz]mm,[xyz]mm{k} */
case X86EMUL_OPC_EVEX_66(0x0f3a, 0x56): /* vreducep{s,d}
$imm8,[xyz]mm/mem,[xyz]mm{k} */
- host_and_vcpu_must_have(avx512dq);
+ visa_check(dq);
/* fall through */
case X86EMUL_OPC_EVEX_66(0x0f3a, 0x26): /* vgetmantp{s,d}
$imm8,[xyz]mm/mem,[xyz]mm{k} */
case X86EMUL_OPC_EVEX_66(0x0f3a, 0x54): /* vfixupimmp{s,d}
$imm8,[xyz]mm/mem,[xyz]mm,[xyz]mm{k} */
- host_and_vcpu_must_have(avx512f);
+ visa_check(f);
if ( ea.type != OP_REG || !evex.brs )
avx512_vlen_check(false);
goto simd_imm8_zmm;
case X86EMUL_OPC_EVEX(0x0f3a, 0x26): /* vgetmantph
$imm8,[xyz]mm/mem,[xyz]mm{k} */
case X86EMUL_OPC_EVEX(0x0f3a, 0x56): /* vreduceph
$imm8,[xyz]mm/mem,[xyz]mm{k} */
- host_and_vcpu_must_have(avx512_fp16);
+ visa_check(_fp16);
generate_exception_if(evex.w, X86_EXC_UD);
if ( ea.type != OP_REG || !evex.brs )
avx512_vlen_check(false);
@@ -7572,11 +7582,11 @@ x86_emulate(
case X86EMUL_OPC_EVEX_66(0x0f3a, 0x51): /* vranges{s,d}
$imm8,xmm/mem,xmm,xmm{k} */
case X86EMUL_OPC_EVEX_66(0x0f3a, 0x57): /* vreduces{s,d}
$imm8,xmm/mem,xmm,xmm{k} */
- host_and_vcpu_must_have(avx512dq);
+ visa_check(dq);
/* fall through */
case X86EMUL_OPC_EVEX_66(0x0f3a, 0x27): /* vgetmants{s,d}
$imm8,xmm/mem,xmm,xmm{k} */
case X86EMUL_OPC_EVEX_66(0x0f3a, 0x55): /* vfixupimms{s,d}
$imm8,xmm/mem,xmm,xmm{k} */
- host_and_vcpu_must_have(avx512f);
+ visa_check(f);
generate_exception_if(ea.type != OP_REG && evex.brs, X86_EXC_UD);
if ( !evex.brs )
avx512_vlen_check(true);
@@ -7584,7 +7594,7 @@ x86_emulate(
case X86EMUL_OPC_EVEX(0x0f3a, 0x27): /* vgetmantsh
$imm8,xmm/mem,xmm,xmm{k} */
case X86EMUL_OPC_EVEX(0x0f3a, 0x57): /* vreducesh $imm8,xmm/mem,xmm,xmm{k}
*/
- host_and_vcpu_must_have(avx512_fp16);
+ visa_check(_fp16);
generate_exception_if(evex.w, X86_EXC_UD);
if ( !evex.brs )
avx512_vlen_check(true);
@@ -7595,18 +7605,19 @@ x86_emulate(
case X86EMUL_OPC_VEX_66(0x0f3a, 0x30): /* kshiftr{b,w} $imm8,k,k */
case X86EMUL_OPC_VEX_66(0x0f3a, 0x32): /* kshiftl{b,w} $imm8,k,k */
if ( !vex.w )
- host_and_vcpu_must_have(avx512dq);
+ visa_check(dq);
+ else
+ visa_check(f);
opmask_shift_imm:
generate_exception_if(vex.l || !vex.r || vex.reg != 0xf ||
ea.type != OP_REG, X86_EXC_UD);
- host_and_vcpu_must_have(avx512f);
get_fpu(X86EMUL_FPU_opmask);
op_bytes = 1; /* Any non-zero value will do. */
goto simd_0f_imm8;
case X86EMUL_OPC_VEX_66(0x0f3a, 0x31): /* kshiftr{d,q} $imm8,k,k */
case X86EMUL_OPC_VEX_66(0x0f3a, 0x33): /* kshiftl{d,q} $imm8,k,k */
- host_and_vcpu_must_have(avx512bw);
+ visa_check(bw);
goto opmask_shift_imm;
case X86EMUL_OPC_66(0x0f3a, 0x44): /* pclmulqdq $imm8,xmm/m128,xmm */
@@ -7747,7 +7758,7 @@ x86_emulate(
case X86EMUL_OPC_EVEX_66(0x0f3a, 0x66): /* vfpclassp{s,d}
$imm8,[xyz]mm/mem,k{k} */
case X86EMUL_OPC_EVEX_66(0x0f3a, 0x67): /* vfpclasss{s,d}
$imm8,xmm/mem,k{k} */
- host_and_vcpu_must_have(avx512dq);
+ visa_check(dq);
generate_exception_if(!evex.r || !evex.R || evex.z, X86_EXC_UD);
if ( !(b & 1) )
goto avx512f_imm8_no_sae;
@@ -7757,7 +7768,7 @@ x86_emulate(
case X86EMUL_OPC_EVEX(0x0f3a, 0x66): /* vfpclassph $imm8,[xyz]mm/mem,k{k}
*/
case X86EMUL_OPC_EVEX(0x0f3a, 0x67): /* vfpclasssh $imm8,xmm/mem,k{k} */
- host_and_vcpu_must_have(avx512_fp16);
+ visa_check(_fp16);
generate_exception_if(evex.w || !evex.r || !evex.R || evex.z,
X86_EXC_UD);
if ( !(b & 1) )
goto avx512f_imm8_no_sae;
@@ -7772,14 +7783,14 @@ x86_emulate(
/* fall through */
case X86EMUL_OPC_EVEX_66(0x0f3a, 0x71): /* vpshld{d,q}
$imm8,[xyz]mm/mem,[xyz]mm,[xyz]mm{k} */
case X86EMUL_OPC_EVEX_66(0x0f3a, 0x73): /* vpshrd{d,q}
$imm8,[xyz]mm/mem,[xyz]mm,[xyz]mm{k} */
- host_and_vcpu_must_have(avx512_vbmi2);
+ visa_check(_vbmi2);
goto avx512f_imm8_no_sae;
case X86EMUL_OPC_EVEX_F3(0x0f3a, 0xc2): /* vcmpsh $imm8,xmm/mem,xmm,k{k} */
generate_exception_if(ea.type != OP_REG && evex.brs, X86_EXC_UD);
/* fall through */
case X86EMUL_OPC_EVEX(0x0f3a, 0xc2): /* vcmpph
$imm8,[xyz]mm/mem,[xyz]mm,k{k} */
- host_and_vcpu_must_have(avx512_fp16);
+ visa_check(_fp16);
generate_exception_if(evex.w || !evex.r || !evex.R || evex.z,
X86_EXC_UD);
if ( ea.type != OP_REG || !evex.brs )
avx512_vlen_check(evex.pfx & VEX_PREFIX_SCALAR_MASK);
@@ -7855,13 +7866,13 @@ x86_emulate(
CASE_SIMD_SINGLE_FP(_EVEX, 5, 0x5d): /* vmin{p,s}h
[xyz]mm/mem,[xyz]mm,[xyz]mm{k} */
CASE_SIMD_SINGLE_FP(_EVEX, 5, 0x5e): /* vdiv{p,s}h
[xyz]mm/mem,[xyz]mm,[xyz]mm{k} */
CASE_SIMD_SINGLE_FP(_EVEX, 5, 0x5f): /* vmax{p,s}h
[xyz]mm/mem,[xyz]mm,[xyz]mm{k} */
- host_and_vcpu_must_have(avx512_fp16);
+ visa_check(_fp16);
generate_exception_if(evex.w, X86_EXC_UD);
goto avx512f_all_fp;
CASE_SIMD_ALL_FP(_EVEX, 5, 0x5a): /* vcvtp{h,d}2p{h,d}
[xyz]mm/mem,[xyz]mm{k} */
/* vcvts{h,d}2s{h,d} xmm/mem,xmm,xmm{k}
*/
- host_and_vcpu_must_have(avx512_fp16);
+ visa_check(_fp16);
if ( vex.pfx & VEX_PREFIX_SCALAR_MASK )
d &= ~TwoOp;
op_bytes = 2 << (((evex.pfx & VEX_PREFIX_SCALAR_MASK) ? 0 : 1 +
evex.lr) +
@@ -7872,7 +7883,7 @@ x86_emulate(
/* vcvtqq2ph [xyz]mm/mem,xmm{k} */
case X86EMUL_OPC_EVEX_F2(5, 0x7a): /* vcvtudq2ph [xyz]mm/mem,[xy]mm{k} */
/* vcvtuqq2ph [xyz]mm/mem,xmm{k} */
- host_and_vcpu_must_have(avx512_fp16);
+ visa_check(_fp16);
if ( ea.type != OP_REG || !evex.brs )
avx512_vlen_check(false);
op_bytes = 16 << evex.lr;
@@ -7882,7 +7893,7 @@ x86_emulate(
case X86EMUL_OPC_EVEX_F3(5, 0x5b): /* vcvttph2dq [xy]mm/mem,[xyz]mm{k} */
case X86EMUL_OPC_EVEX (5, 0x78): /* vcvttph2udq [xy]mm/mem,[xyz]mm{k} */
case X86EMUL_OPC_EVEX (5, 0x79): /* vcvtph2udq [xy]mm/mem,[xyz]mm{k} */
- host_and_vcpu_must_have(avx512_fp16);
+ visa_check(_fp16);
generate_exception_if(evex.w, X86_EXC_UD);
if ( ea.type != OP_REG || !evex.brs )
avx512_vlen_check(false);
@@ -7904,7 +7915,7 @@ x86_emulate(
case X86EMUL_OPC_EVEX_66(5, 0x79): /* vcvtph2uqq xmm/mem,[xyz]mm{k} */
case X86EMUL_OPC_EVEX_66(5, 0x7a): /* vcvttph2qq xmm/mem,[xyz]mm{k} */
case X86EMUL_OPC_EVEX_66(5, 0x7b): /* vcvtph2qq xmm/mem,[xyz]mm{k} */
- host_and_vcpu_must_have(avx512_fp16);
+ visa_check(_fp16);
generate_exception_if(evex.w, X86_EXC_UD);
if ( ea.type != OP_REG || !evex.brs )
avx512_vlen_check(false);
@@ -7941,7 +7952,7 @@ x86_emulate(
case X86EMUL_OPC_EVEX_66(6, 0xba): /* vfmsub231ph
[xyz]mm/mem,[xyz]mm,[xyz]mm{k} */
case X86EMUL_OPC_EVEX_66(6, 0xbc): /* vfnmadd231ph
[xyz]mm/mem,[xyz]mm,[xyz]mm{k} */
case X86EMUL_OPC_EVEX_66(6, 0xbe): /* vfnmsub231ph
[xyz]mm/mem,[xyz]mm,[xyz]mm{k} */
- host_and_vcpu_must_have(avx512_fp16);
+ visa_check(_fp16);
generate_exception_if(evex.w, X86_EXC_UD);
if ( ea.type != OP_REG || !evex.brs )
avx512_vlen_check(false);
@@ -7963,7 +7974,7 @@ x86_emulate(
case X86EMUL_OPC_EVEX_66(6, 0xbb): /* vfmsub231sh xmm/m16,xmm,xmm{k} */
case X86EMUL_OPC_EVEX_66(6, 0xbd): /* vfnmadd231sh xmm/m16,xmm,xmm{k} */
case X86EMUL_OPC_EVEX_66(6, 0xbf): /* vfnmsub231sh xmm/m16,xmm,xmm{k} */
- host_and_vcpu_must_have(avx512_fp16);
+ visa_check(_fp16);
generate_exception_if(evex.w || (ea.type != OP_REG && evex.brs),
X86_EXC_UD);
if ( !evex.brs )
@@ -7972,13 +7983,13 @@ x86_emulate(
case X86EMUL_OPC_EVEX_66(6, 0x4c): /* vrcpph [xyz]mm/mem,[xyz]mm{k} */
case X86EMUL_OPC_EVEX_66(6, 0x4e): /* vrsqrtph [xyz]mm/mem,[xyz]mm{k} */
- host_and_vcpu_must_have(avx512_fp16);
+ visa_check(_fp16);
generate_exception_if(evex.w, X86_EXC_UD);
goto avx512f_no_sae;
case X86EMUL_OPC_EVEX_66(6, 0x4d): /* vrcpsh xmm/m16,xmm,xmm{k} */
case X86EMUL_OPC_EVEX_66(6, 0x4f): /* vrsqrtsh xmm/m16,xmm,xmm{k} */
- host_and_vcpu_must_have(avx512_fp16);
+ visa_check(_fp16);
generate_exception_if(evex.w || evex.brs, X86_EXC_UD);
avx512_vlen_check(true);
goto simd_zmm;
@@ -7996,7 +8007,7 @@ x86_emulate(
{
unsigned int src1 = ~evex.reg;
- host_and_vcpu_must_have(avx512_fp16);
+ visa_check(_fp16);
generate_exception_if(evex.w || ((b & 1) && ea.type != OP_REG &&
evex.brs),
X86_EXC_UD);
if ( mode_64bit() )
--- a/xen/arch/x86/xstate.c
+++ b/xen/arch/x86/xstate.c
@@ -814,7 +814,7 @@ static void __init noinline xstate_check
if ( cpu_has_mpx )
check_new_xstate(&s, X86_XCR0_BNDCSR | X86_XCR0_BNDREGS);
- if ( cpu_has_avx512f )
+ if ( boot_cpu_has(X86_FEATURE_AVX512F) || boot_cpu_has(X86_FEATURE_AVX10) )
check_new_xstate(&s, X86_XCR0_HI_ZMM | X86_XCR0_ZMM | X86_XCR0_OPMASK);
/*
--- a/xen/include/public/arch-x86/cpufeatureset.h
+++ b/xen/include/public/arch-x86/cpufeatureset.h
@@ -366,7 +366,7 @@ XEN_CPUFEATURE(PREFETCHI, 15*32
XEN_CPUFEATURE(USER_MSR, 15*32+15) /*s U{RD,WR}MSR Instructions */
XEN_CPUFEATURE(UIRET_UIF, 15*32+17) /* UIRET updates UIF */
XEN_CPUFEATURE(CET_SSS, 15*32+18) /* CET Supervisor Shadow Stacks
safe to use */
-XEN_CPUFEATURE(AVX10, 15*32+19) /* AVX10 Converged Vector ISA */
+XEN_CPUFEATURE(AVX10, 15*32+19) /*a AVX10 Converged Vector ISA */
XEN_CPUFEATURE(SLSM, 15*32+24) /* Static Lockstep Mode */
/* Intel-defined CPU features, MSR_ARCH_CAPS 0x10a.eax, word 16 */
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |