|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [PATCH v4 26/28] x86emul: enable tile data movement insns for ACE
Most of these are being re-used from AMX, only TILEMOVCOL and TILEMOVROW
moving to tile are new.
Signed-off-by: Jan Beulich <jbeulich@xxxxxxxx>
---
SDE: ???
---
While all ACE-E<n> right now merely say "#UD if TILES_CONFIGURED == 0",
that's reportedly be incorrect. A requirement for the new insns (enabled
here and/or by later patches) is that the selected palette be palette 2.
By implication for the original AMX insns this then also means that they
need to have palette 1 in use. Except for the few which are available with
either palette.
---
v4: New.
--- a/tools/tests/x86_emulator/predicates.c
+++ b/tools/tests/x86_emulator/predicates.c
@@ -1948,11 +1948,12 @@ static const struct evex {
{ { 0x49, 0x00 }, 2, F, W, pfx_66, W0, L0 }, /* sttilecfg */
{ { 0x4a, VSIB(0) }, 3, F, R, pfx_66, W0, L0 }, /* tileloaddrst1 */
{ { 0x4a, VSIB(0) }, 3, F, R, pfx_f2, W0, L0 }, /* tileloaddrs */
- { { 0x4a, 0xc0 }, 2, F, N, pfx_66, W0, L2 }, /* tilemovrow */
+ { { 0x4a, 0xc0 }, 2, F, N, pfx_66, Wn, L2 }, /* tilemovrow */
{ { 0x4a, 0xc0 }, 2, F, N, pfx_f3, W0, L2 }, /* tcvtrowd2ps */
{ { 0x4b, VSIB(0) }, 3, F, R, pfx_66, W0, L0 }, /* tileloaddt1 */
{ { 0x4b, VSIB(0) }, 3, F, W, pfx_f3, W0, L0 }, /* tilestored */
{ { 0x4b, VSIB(0) }, 3, F, R, pfx_f2, W0, L0 }, /* tileloadd */
+ { { 0x4b, 0xc0 }, 2, F, N, pfx_66, W1, L2 }, /* tilemovcol */
{ { 0x4c }, 2, T, R, pfx_66, Wn, Ln }, /* vrcp14p{s,d} */
{ { 0x4d }, 2, T, R, pfx_66, Wn, LIG }, /* vrcp14s{s,d} */
{ { 0x4e }, 2, T, R, pfx_66, Wn, Ln }, /* vrsqrt14p{s,d} */
@@ -2108,7 +2109,7 @@ static const struct evex {
{ { 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_66, Wn, 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 */
@@ -2140,6 +2141,7 @@ static const struct evex {
{ { 0x26 }, 3, T, R, pfx_f2, W0, Ln }, /* vgetmantbf16 */
{ { 0x27 }, 3, T, R, pfx_no, W0, LIG }, /* vgetmantsh */
{ { 0x27 }, 3, T, R, pfx_66, Wn, LIG }, /* vgetmants{s,d} */
+ { { 0x2f, 0xc0 }, 3, F, N, pfx_66, W1, L2 }, /* tilemovcol */
{ { 0x38 }, 3, T, R, pfx_66, Wn, L1|L2 }, /* vinserti{32x4,64x2} */
{ { 0x39 }, 3, T, W, pfx_66, Wn, L1|L2 }, /* vextracti{32x4,64x2} */
{ { 0x3a }, 3, T, R, pfx_66, Wn, L2 }, /* vinserti{32x8,64x4} */
--- a/xen/arch/x86/x86_emulate/decode.c
+++ b/xen/arch/x86/x86_emulate/decode.c
@@ -493,6 +493,7 @@ static const struct ext0f3a_table {
[0x25] = { .simd_size = simd_packed_int, .d8s = d8s_vl },
[0x26] = { .simd_size = simd_packed_fp, .two_op = 1, .d8s = d8s_vl },
[0x27] = { .simd_size = simd_scalar_vexw, .d8s = d8s_dq },
+ [0x2f] = { .simd_size = simd_other, .two_op = 1 },
[0x30 ... 0x33] = { .simd_size = simd_other, .two_op = 1 },
[0x38] = { .simd_size = simd_128, .d8s = 4 },
[0x3a] = { .simd_size = simd_256, .d8s = d8s_vl_by_2 },
@@ -1315,6 +1316,7 @@ decode_0f38(struct x86_emulate_state *s,
break;
case X86EMUL_OPC_EVEX_66(0, 0x4a): /* tileloaddrst1 / tilemovrow */
+ case X86EMUL_OPC_EVEX_66(0, 0x4b): /* tileloaddt1 / tilemovcol */
if ( s->modrm_mod == 3 )
{
case X86EMUL_OPC_EVEX_F3(0, 0x4a): /* tcvtrowd2ps */
@@ -1324,7 +1326,6 @@ decode_0f38(struct x86_emulate_state *s,
fallthrough;
case X86EMUL_OPC_EVEX(0, 0x49): /* ldtilecfg */
case X86EMUL_OPC_EVEX_F2(0, 0x4a): /* tileloaddrs */
- case X86EMUL_OPC_EVEX_66(0, 0x4b): /* tileloaddt1 */
case X86EMUL_OPC_EVEX_F2(0, 0x4b): /* tileloadd */
case X86EMUL_OPC_EVEX_66(0, 0xe0) ...
X86EMUL_OPC_EVEX_66(0, 0xef): /* cmp<cc>xadd */
@@ -2112,7 +2113,7 @@ int x86emul_decode(struct x86_emulate_st
generate_exception_if(evex_encoded() && !s->evex.u,
X86_EXC_UD);
- if ( b != 0x4a || s->modrm_mod != 3 )
+ if ( (b | 1) != 0x4b || s->modrm_mod != 3 )
d |= vSIB;
}
s->simd_size = ext0f38_table[b].simd_size;
--- a/xen/arch/x86/x86_emulate/x86_emulate.c
+++ b/xen/arch/x86/x86_emulate/x86_emulate.c
@@ -6818,7 +6818,13 @@ x86_emulate(
case X86EMUL_OPC_EVEX_66(0x0f38, 0x4a): /* tileloaddrst1 mem,tmm */
if ( ea.type != OP_MEM )
- goto tilemovrow;
+ {
+ if ( evex.w )
+ vcpu_must_have(ace);
+ else if ( !vcpu_has_ace() )
+ vcpu_must_have(amx_avx512);
+ goto tilemov_gpr;
+ }
fallthrough;
case X86EMUL_OPC_EVEX_F2(0x0f38, 0x4a): /* tileloaddrs mem,tmm */
generate_exception_if((evex.lr || evex.brs || evex.opmsk || !evex.RX),
@@ -6830,6 +6836,13 @@ x86_emulate(
goto tile_load_store;
case X86EMUL_OPC_EVEX_66(0x0f38, 0x4b): /* tileloaddt1 mem,tmm */
+ if ( ea.type != OP_MEM )
+ {
+ generate_exception_if(!evex.w, X86_EXC_UD);
+ vcpu_must_have(ace);
+ goto tilemov_gpr;
+ }
+ fallthrough;
case X86EMUL_OPC_EVEX_F3(0x0f38, 0x4b): /* tilestored tmm,mem */
case X86EMUL_OPC_EVEX_F2(0x0f38, 0x4b): /* tileloadd mem,tmm */
generate_exception_if(evex.lr || evex.brs || evex.opmsk || !evex.RX,
@@ -6999,7 +7012,6 @@ x86_emulate(
generate_exception_if(vex.w, X86_EXC_UD);
goto simd_0f_avx2;
- tilemovrow: /* tilemovrow r32,tmm,zmm */
case X86EMUL_OPC_EVEX_F3(0x0f38, 0x4a): /* tcvtrowd2ps r32,tmm,zmm */
case X86EMUL_OPC_EVEX (0x0f38, 0x6d): /* tcvtrowps2phh r32,tmm,zmm */
case X86EMUL_OPC_EVEX_66(0x0f38, 0x6d): /* tcvtrowps2phl r32,tmm,zmm */
@@ -7008,20 +7020,36 @@ x86_emulate(
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 ||
+ generate_exception_if(evex.w, X86_EXC_UD);
+ tilemov_gpr: /* tilemovrow r32,tmm,zmm */
+ /* tilemovrow r32,zmm,tmm */
+ /* tilemovcol r32,zmm,tmm */
+ generate_exception_if((evex.brs || evex.opmsk || evex.lr != 2 ||
(!evex.RX && !(state->xcr0 & X86_XCR0_APX))),
X86_EXC_UD);
tilemov:
- get_fpu(X86EMUL_FPU_zmm_tile);
+ get_fpu(X86EMUL_FPU_tilecfg);
sttilecfg(&mmvalp->tilecfg);
+ put_fpu(X86EMUL_FPU_tilecfg, false, state, ctxt, ops);
+ fpu_type = X86EMUL_FPU_none;
- generate_exception_if(!tile_valid(modrm_rm, &mmvalp->tilecfg,
- PALETTE(AMX)),
- X86_EXC_UD);
- generate_exception_if(mmvalp->tilecfg.colsb[modrm_rm] & 3,
- X86_EXC_UD);
+ if ( evex.w )
+ generate_exception_if(!tile_valid(modrm_reg, &mmvalp->tilecfg,
+ PALETTE(ACE)),
+ X86_EXC_UD);
+ else
+ {
+ generate_exception_if(!tile_valid(modrm_rm, &mmvalp->tilecfg,
+ PALETTE(AMX, ACE)),
+ X86_EXC_UD);
+ generate_exception_if((mmvalp->tilecfg.palette == PALETTE_AMX &&
+ (mmvalp->tilecfg.colsb[modrm_rm] & 3)),
+ X86_EXC_UD);
+ }
+
+ get_fpu(mmvalp->tilecfg.palette == PALETTE_AMX ? X86EMUL_FPU_zmm_tile
+ : X86EMUL_FPU_zmm_ace);
/*
* Note: For the immediate forms this decodes %rax, but the value isn't
@@ -8331,8 +8359,26 @@ 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, 0x2f): /* tilemovcol $imm8,zmm,tmm */
+ if ( ea.type != OP_REG )
+ goto unrecognized_insn;
+ generate_exception_if(!evex.w, X86_EXC_UD);
+ vcpu_must_have(ace);
+ goto tilemov_imm;
+
case X86EMUL_OPC_EVEX_66(0x0f3a, 0x07): /* tilemovrow $imm8,tmm,zmm */
+ /* tilemovrow $imm8,zmm,tmm */
+ if ( ea.type == OP_REG )
+ {
+ if ( evex.w )
+ vcpu_must_have(ace);
+ else if ( !vcpu_has_ace() )
+ vcpu_must_have(amx_avx512);
+ goto tilemov_imm;
+ }
+ goto unrecognized_insn;
+
+ case X86EMUL_OPC_EVEX (0x0f3a, 0x07): /* tcvtrowps2phh $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 */
@@ -8340,8 +8386,10 @@ x86_emulate(
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),
+ generate_exception_if(evex.w, X86_EXC_UD);
+ tilemov_imm:
+ generate_exception_if((evex.brs || evex.opmsk || evex.lr != 2 ||
+ evex.reg != 0xf || !evex.RX),
X86_EXC_UD);
goto tilemov;
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |