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

[PATCH v4 17/28] x86emul: support APX forms of TILE{LOADD{,T1},STORED}


  • To: "xen-devel@xxxxxxxxxxxxxxxxxxxx" <xen-devel@xxxxxxxxxxxxxxxxxxxx>
  • From: Jan Beulich <jbeulich@xxxxxxxx>
  • Date: Wed, 11 Nov 2026 16:14:06 +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:14:10 +0000
  • List-id: Xen developer discussion <xen-devel.lists.xenproject.org>

While, like elsewhere, pre-existing code can largely be re-used, EVEX
Disp8 testing requires some special care: .

Note that the calculation of ->sib_index can be left as is, as long as
all SIBMEM insns don't use EVEX.vvvv (and hence EVEX.V4 is required to
be set).

Signed-off-by: Jan Beulich <jbeulich@xxxxxxxx>
---
TBD: How to reasonably test AMX+APX isn't entirely clear yet. Simply
     re-compiling matrix.c with -mapfx is unlikely to produce good uses
     of eGPR-s. Yet fiddling with intermediate assembly isn't quite
     nice either, and even then there's no guarantee that we'd end up
     with any useful uses of eGPR-s.
---
v4: New.

--- a/tools/tests/x86_emulator/evex-disp8.c
+++ b/tools/tests/x86_emulator/evex-disp8.c
@@ -1196,6 +1196,10 @@ static const struct test amx_tile[] = {
     /* Element size is set arbitrarily here. See test_one(). */
     INSN(ldtilecfg,     , 0f38, 49, el, b, no),
     INSN(sttilecfg,   66, 0f38, 49, el, b, no),
+    /* Element size assumes a 1x1 matrix here. See test_one(). */
+    INSN(tileloadd,   f2, 0f38, 4b, el, d, no),
+    INSN(tileloaddt1, 66, 0f38, 4b, el, d, no),
+    INSN(tilestored,  f3, 0f38, 4b, el, d, no),
 };
 
 static const unsigned char vl_all[] = { VL_512, VL_128, VL_256 };
@@ -1316,6 +1320,7 @@ static void test_one(const struct test *
     int rc;
     bool sg = strstr(test->mnemonic, "gather") ||
               strstr(test->mnemonic, "scatter");
+    bool tile = false;
     unsigned int imm = test->spc == SPC_0f3a ||
                        (test->spc == SPC_0f &&
                         (imm0f[test->opc >> 4] & (1 << (test->opc & 0xf))));
@@ -1437,8 +1442,8 @@ static void test_one(const struct test *
     }
 
     /*
-     * Note: SIB addressing is used here, such that S/G insns can be handled
-     * without extra conditionals.
+     * Note: SIB addressing is used here, such that S/G and SIBMEM insns can
+     * be handled without extra conditionals.
      */
     instr[0] = 0x62;
  again:
@@ -1465,6 +1470,24 @@ static void test_one(const struct test *
          */
         if ( test->spc == SPC_0f38 && test->opc == 0x49 )
             vsz = 64;
+
+        /*
+         * Tile loads/stores require a valid tile configuration. Set up a 1x1
+         * tile for %tmm0.
+         */
+        if ( test->spc == SPC_0f38 && test->opc == 0x4b )
+        {
+            static const struct x86_tilecfg tilecfg = {
+                .palette = 1,
+                .colsb[0] = 4,
+                .rows[0] = 1,
+            };
+
+            /* ldtilecfg (%rax) */
+            asm volatile ( ".byte 0xc4, 0xe2, 0x78, 0x49, 0x00"
+                           :: "a" (&tilecfg), "m" (tilecfg) );
+            tile = true;
+        }
     }
     else
     {
@@ -1554,7 +1577,12 @@ static void test_one(const struct test *
          */
         if ( test->spc != SPC_map4 || (test->opc | 0xf) != 0x4f ||
              test->pfx > PFX_66 || (evex.bcst && evex.opmsk) )
+        {
+            /* Issue TILERELEASE if we fiddled with tiles. */
+            if ( tile )
+                asm volatile ( ".byte 0xc4, 0xe2, 0x78, 0x49, 0xc0" );
             return;
+        }
 
         evex.bcst = !evex.bcst;
         if ( !evex.bcst )
--- a/tools/tests/x86_emulator/predicates.c
+++ b/tools/tests/x86_emulator/predicates.c
@@ -1939,6 +1939,9 @@ static const struct evex {
     { { 0x47 }, 2, T, R, pfx_66, Wn, Ln }, /* vpsllv{d,q} */
     { { 0x49, 0x00 }, 2, F, R, pfx_no, W0, L0 }, /* ldtilecfg */
     { { 0x49, 0x00 }, 2, F, W, pfx_66, W0, L0 }, /* sttilecfg */
+    { { 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 */
     { { 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} */
--- a/xen/arch/x86/x86_emulate/decode.c
+++ b/xen/arch/x86/x86_emulate/decode.c
@@ -1272,6 +1272,7 @@ decode_0f38(struct x86_emulate_state *s,
         break;
 
     case X86EMUL_OPC_EVEX_66(0, 0x49): /* sttilecfg */
+    case X86EMUL_OPC_EVEX_F3(0, 0x4b): /* tilestored */
         s->promoted_evex = true;
         fallthrough;
     case X86EMUL_OPC_VEX_66(0, 0x49): /* sttilecfg */
@@ -1312,6 +1313,8 @@ decode_0f38(struct x86_emulate_state *s,
         break;
 
     case X86EMUL_OPC_EVEX(0, 0x49):    /* ldtilecfg */
+    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 */
     case X86EMUL_OPC_EVEX(0, 0xf2):    /* andn */
--- a/xen/arch/x86/x86_emulate/x86_emulate.c
+++ b/xen/arch/x86/x86_emulate/x86_emulate.c
@@ -6771,6 +6771,12 @@ x86_emulate(
         }
         goto unrecognized_insn;
 
+    case X86EMUL_OPC_EVEX_66(0x0f38, 0x4b): /* tileloaddt1 mem,tmm */
+    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,
+                              X86_EXC_UD);
+        fallthrough;
     case X86EMUL_OPC_VEX_66(0x0f38, 0x4b): /* tileloaddt1 mem,tmm */
     case X86EMUL_OPC_VEX_F3(0x0f38, 0x4b): /* tilestored tmm,mem */
     case X86EMUL_OPC_VEX_F2(0x0f38, 0x4b): /* tileloadd mem,tmm */
@@ -6795,7 +6801,7 @@ x86_emulate(
 
         /* Calculate stride. */
         if ( state->sib_index != 4 )
-            ea.val = truncate_ea(*decode_gpr(ctxt->regs, NULL,
+            ea.val = truncate_ea(*decode_gpr(ctxt->regs, &state->egpr,
                                              state->sib_index) <<
                                  state->sib_scale);
 
@@ -6847,7 +6853,7 @@ x86_emulate(
         opc[1] = modrm & 0x3f;
         opc[2] = 0x20;
         place_ret(&opc[3]);
-        copy_VEX(opc, vex, false);
+        copy_VEX(opc, vex, state->promoted_evex);
 
         do {
             if ( row >= n )




 


Rackspace

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