[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[PATCH v4 26/28] x86emul: enable tile data movement insns for ACE


  • To: "xen-devel@xxxxxxxxxxxxxxxxxxxx" <xen-devel@xxxxxxxxxxxxxxxxxxxx>
  • From: Jan Beulich <jbeulich@xxxxxxxx>
  • Date: Wed, 11 Nov 2026 16:18:59 +0100
  • Authentication-results: eu.smtp.expurgate.cloud; dkim=pass header.s=google header.d=suse.com header.i="@suse.com" header.h="Content-Transfer-Encoding:Content-Type:In-Reply-To:Autocrypt:Content-Language:References:Cc:To:From:Subject:User-Agent:MIME-Version:Date:Message-ID"
  • Autocrypt: addr=jbeulich@xxxxxxxx; keydata= xsDiBFk3nEQRBADAEaSw6zC/EJkiwGPXbWtPxl2xCdSoeepS07jW8UgcHNurfHvUzogEq5xk hu507c3BarVjyWCJOylMNR98Yd8VqD9UfmX0Hb8/BrA+Hl6/DB/eqGptrf4BSRwcZQM32aZK 7Pj2XbGWIUrZrd70x1eAP9QE3P79Y2oLrsCgbZJfEwCgvz9JjGmQqQkRiTVzlZVCJYcyGGsD /0tbFCzD2h20ahe8rC1gbb3K3qk+LpBtvjBu1RY9drYk0NymiGbJWZgab6t1jM7sk2vuf0Py O9Hf9XBmK0uE9IgMaiCpc32XV9oASz6UJebwkX+zF2jG5I1BfnO9g7KlotcA/v5ClMjgo6Gl MDY4HxoSRu3i1cqqSDtVlt+AOVBJBACrZcnHAUSuCXBPy0jOlBhxPqRWv6ND4c9PH1xjQ3NP nxJuMBS8rnNg22uyfAgmBKNLpLgAGVRMZGaGoJObGf72s6TeIqKJo/LtggAS9qAUiuKVnygo 3wjfkS9A3DRO+SpU7JqWdsveeIQyeyEJ/8PTowmSQLakF+3fote9ybzd880fSmFuIEJldWxp Y2ggPGpiZXVsaWNoQHN1c2UuY29tPsJgBBMRAgAgBQJZN5xEAhsDBgsJCAcDAgQVAggDBBYC AwECHgECF4AACgkQoDSui/t3IH4J+wCfQ5jHdEjCRHj23O/5ttg9r9OIruwAn3103WUITZee e7Sbg12UgcQ5lv7SzsFNBFk3nEQQCACCuTjCjFOUdi5Nm244F+78kLghRcin/awv+IrTcIWF hUpSs1Y91iQQ7KItirz5uwCPlwejSJDQJLIS+QtJHaXDXeV6NI0Uef1hP20+y8qydDiVkv6l IreXjTb7DvksRgJNvCkWtYnlS3mYvQ9NzS9PhyALWbXnH6sIJd2O9lKS1Mrfq+y0IXCP10eS FFGg+Av3IQeFatkJAyju0PPthyTqxSI4lZYuJVPknzgaeuJv/2NccrPvmeDg6Coe7ZIeQ8Yj t0ARxu2xytAkkLCel1Lz1WLmwLstV30g80nkgZf/wr+/BXJW/oIvRlonUkxv+IbBM3dX2OV8 AmRv1ySWPTP7AAMFB/9PQK/VtlNUJvg8GXj9ootzrteGfVZVVT4XBJkfwBcpC/XcPzldjv+3 HYudvpdNK3lLujXeA5fLOH+Z/G9WBc5pFVSMocI71I8bT8lIAzreg0WvkWg5V2WZsUMlnDL9 mpwIGFhlbM3gfDMs7MPMu8YQRFVdUvtSpaAs8OFfGQ0ia3LGZcjA6Ik2+xcqscEJzNH+qh8V m5jjp28yZgaqTaRbg3M/+MTbMpicpZuqF4rnB0AQD12/3BNWDR6bmh+EkYSMcEIpQmBM51qM EKYTQGybRCjpnKHGOxG0rfFY1085mBDZCH5Kx0cl0HVJuQKC+dV2ZY5AqjcKwAxpE75MLFkr wkkEGBECAAkFAlk3nEQCGwwACgkQoDSui/t3IH7nnwCfcJWUDUFKdCsBH/E5d+0ZnMQi+G0A nAuWpQkjM1ASeQwSHEeAWPgskBQL
  • Cc: Andrew Cooper <andrew.cooper3@xxxxxxxxxx>, Teddy Astie <teddy.astie@xxxxxxxxxx>, Roger Pau Monné <roger@xxxxxxxxxxxxxx>
  • Delivery-date: Wed, 11 Nov 2026 15:19:03 +0000
  • List-id: Xen developer discussion <xen-devel.lists.xenproject.org>

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;
 




 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.