|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [PATCH v4 23/28] x86emul: support AMX-AVX512 insns with immediate operand
Due to their similarity with the GPR forms the code used there can
simply re-use most of the code there.
Signed-off-by: Jan Beulich <jbeulich@xxxxxxxx>
---
v4: New.
--- a/tools/tests/x86_emulator/predicates.c
+++ b/tools/tests/x86_emulator/predicates.c
@@ -2107,6 +2107,10 @@ static const struct evex {
{ { 0x03 }, 3, T, R, pfx_66, Wn, Ln }, /* valign{d,q} */
{ { 0x04 }, 3, T, R, pfx_66, W0, Ln }, /* vpermilps */
{ { 0x05 }, 3, T, R, pfx_66, W1, Ln }, /* vpermilpd */
+ { { 0x07, 0xc0 }, 3, F, N, pfx_no, W0, L2 }, /* tcvtrowps2phh */
+ { { 0x07, 0xc0 }, 3, F, N, pfx_66, W0, L2 }, /* tilemovrow */
+ { { 0x07, 0xc0 }, 3, F, N, pfx_f3, W0, L2 }, /* tcvtrowd2ps */
+ { { 0x07, 0xc0 }, 3, F, N, pfx_f2, W0, L2 }, /* tcvtrowps2bf16h */
{ { 0x08 }, 3, T, R, pfx_no, W0, Ln }, /* vrndscaleph */
{ { 0x08 }, 3, T, R, pfx_66, W0, Ln }, /* vrndscaleps */
{ { 0x08 }, 3, T, R, pfx_f2, W0, Ln }, /* vrndscalebf16 */
@@ -2170,6 +2174,8 @@ static const struct evex {
{ { 0x71 }, 3, T, R, pfx_66, Wn, Ln }, /* vshld{d,q} */
{ { 0x72 }, 3, T, R, pfx_66, W1, Ln }, /* vshrdw */
{ { 0x73 }, 3, T, R, pfx_66, Wn, Ln }, /* vshrd{d,q} */
+ { { 0x77, 0xc0 }, 3, F, N, pfx_f3, W0, L2 }, /* tcvtrowps2bf16l */
+ { { 0x77, 0xc0 }, 3, F, N, pfx_f2, W0, L2 }, /* tcvtrowps2phl */
{ { 0xc2 }, 3, T, R, pfx_no, W0, Ln }, /* vcmpph */
{ { 0xc2 }, 3, T, R, pfx_f3, W0, LIG }, /* vcmpsh */
{ { 0xc2 }, 3, T, R, pfx_f2, W0, Ln }, /* vcmpbf16 */
--- a/xen/arch/x86/x86_emulate/decode.c
+++ b/xen/arch/x86/x86_emulate/decode.c
@@ -470,6 +470,7 @@ static const struct ext0f3a_table {
[0x03] = { .simd_size = simd_packed_int, .d8s = d8s_vl },
[0x04 ... 0x05] = { .simd_size = simd_packed_fp, .two_op = 1, .d8s =
d8s_vl },
[0x06] = { .simd_size = simd_packed_fp },
+ [0x07] = { .simd_size = simd_other, .two_op = 1 },
[0x08 ... 0x09] = { .simd_size = simd_packed_fp, .two_op = 1, .d8s =
d8s_vl },
[0x0a ... 0x0b] = { .simd_size = simd_scalar_opc, .d8s = d8s_dq },
[0x0c ... 0x0d] = { .simd_size = simd_packed_fp },
@@ -523,6 +524,7 @@ static const struct ext0f3a_table {
[0x6c ... 0x6d] = { .simd_size = simd_packed_fp, .four_op = 1 },
[0x6e ... 0x6f] = { .simd_size = simd_scalar_opc, .four_op = 1 },
[0x70 ... 0x73] = { .simd_size = simd_packed_int, .d8s = d8s_vl },
+ [0x77] = { .simd_size = simd_other, .two_op = 1 },
[0x78 ... 0x79] = { .simd_size = simd_packed_fp, .four_op = 1 },
[0x7a ... 0x7b] = { .simd_size = simd_scalar_opc, .four_op = 1 },
[0x7c ... 0x7d] = { .simd_size = simd_packed_fp, .four_op = 1 },
--- a/xen/arch/x86/x86_emulate/x86_emulate.c
+++ b/xen/arch/x86/x86_emulate/x86_emulate.c
@@ -6977,6 +6977,7 @@ x86_emulate(
(!evex.RX && !(state->xcr0 & X86_XCR0_APX))),
X86_EXC_UD);
+ tilemov:
get_fpu(X86EMUL_FPU_zmm_tile);
sttilecfg(&mmvalp->tilecfg);
@@ -6986,6 +6987,10 @@ x86_emulate(
generate_exception_if(mmvalp->tilecfg.colsb[modrm_rm] & 3,
X86_EXC_UD);
+ /*
+ * Note: For the immediate forms this decodes %rax, but the value isn't
+ * going to be used by the insn below anyway.
+ */
ea.reg = decode_evex_gpr(evex.reg | (evex.RX << 4), &_regs,
&state->egpr, ctxt);
@@ -6995,8 +7000,10 @@ x86_emulate(
evex.reg = 0xf;
evex.RX = 1;
opc[1] = modrm;
- insn_bytes = EVEX_PFX_BYTES + 2;
- place_ret(&opc[2]);
+ opc[2] = imm1;
+ i = ((ctxt->opcode & X86EMUL_OPC_EXT_MASK) == X86EMUL_OPC(0x0f3a, 0));
+ insn_bytes = EVEX_PFX_BYTES + 2 + i;
+ place_ret(&opc[2 + i]);
copy_EVEX(opc, evex);
invoke_stub("", "", "=g" (dummy) : "a" (*ea.reg));
@@ -8288,6 +8295,20 @@ x86_emulate(
fault_suppression = false;
goto avx512f_imm8_no_sae;
+ case X86EMUL_OPC_EVEX (0x0f3a, 0x07): /* tcvtrowps2phh $imm8,tmm,zmm */
+ case X86EMUL_OPC_EVEX_66(0x0f3a, 0x07): /* tilemovrow $imm8,tmm,zmm */
+ case X86EMUL_OPC_EVEX_F3(0x0f3a, 0x07): /* tcvtrowd2ps $imm8,tmm,zmm */
+ case X86EMUL_OPC_EVEX_F2(0x0f3a, 0x07): /* tcvtrowps2bf16h $imm8,tmm,zmm */
+ case X86EMUL_OPC_EVEX_F3(0x0f3a, 0x77): /* tcvtrowps2bf16l $imm8,tmm,zmm */
+ case X86EMUL_OPC_EVEX_F2(0x0f3a, 0x77): /* tcvtrowps2phl $imm8,tmm,zmm */
+ if ( ea.type != OP_REG )
+ goto unrecognized_insn;
+ vcpu_must_have(amx_avx512);
+ generate_exception_if((evex.w || evex.brs || evex.opmsk ||
+ evex.lr != 2 || evex.reg != 0xf || !evex.RX),
+ X86_EXC_UD);
+ goto tilemov;
+
case X86EMUL_OPC_66(0x0f3a, 0x08): /* roundps $imm8,xmm/m128,xmm */
case X86EMUL_OPC_66(0x0f3a, 0x09): /* roundpd $imm8,xmm/m128,xmm */
case X86EMUL_OPC_66(0x0f3a, 0x0a): /* roundss $imm8,xmm/m128,xmm */
--- a/xen/include/public/arch-x86/cpufeatureset.h
+++ b/xen/include/public/arch-x86/cpufeatureset.h
@@ -425,7 +425,7 @@ XEN_CPUFEATURE(AMX__BF16, 21*32
XEN_CPUFEATURE(AMX__COMPLEX, 21*32+ 2) /*a AMX-COMPLEX Instructions */
XEN_CPUFEATURE(AMX__FP16, 21*32+ 3) /*a AMX-FP16 Instructions */
XEN_CPUFEATURE(AMX_FP8, 21*32+ 4) /*a AMX-FP8 Instructions */
-XEN_CPUFEATURE(AMX_AVX512, 21*32+ 7) /* AMX-AVX512 Instructions */
+XEN_CPUFEATURE(AMX_AVX512, 21*32+ 7) /*a AMX-AVX512 Instructions */
XEN_CPUFEATURE(AMX_MOVRS, 21*32+ 8) /*a AMX-MOVRS Instructions */
#endif /* XEN_CPUFEATURE */
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |