]> git.ipfire.org Git - thirdparty/qemu.git/commitdiff
target/i386/tcg: simplify decoding of 0F 38 F0...FF
authorPaolo Bonzini <pbonzini@redhat.com>
Tue, 31 Mar 2026 06:52:37 +0000 (08:52 +0200)
committerPaolo Bonzini <pbonzini@redhat.com>
Thu, 30 Apr 2026 13:50:18 +0000 (15:50 +0200)
These lines are shown in the manual with a weird representation that
confers a special meaning to 0x66 0xF2 prefixes.  In reality, this is
just the CRC32 instruction (chosen by 0xF2) plus a data size override
prefix.  All other instruction in the range that use the 0xF2 prefix
are VEX-encoded and therefore they do not support multiple prefixes.
Because of this, it is possible to handle the four prefixes normally
using decode_by_prefix; the 0x66 0xF2 combination for CRC32 is handled
naturally by the "v" operand size.

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
target/i386/tcg/decode-new.c.inc

index c8b5bd6ad2628cf944d759f7ecf32fa8c2783f64..ac181308ca4bc8a61b78405fcbcf720ef1f3d22a 100644 (file)
@@ -873,8 +873,8 @@ static const X86OpEntry opcodes_0F38_00toEF[240] = {
     [0xef] = X86_OP_ENTRY3(CMPccXADD,   M,y, G,y, B,y,  vex13 xchg chk(o64) cpuid(CMPCCXADD) p_66),
 };
 
-/* five rows for no prefix, 66, F3, F2, 66+F2  */
-static const X86OpEntry opcodes_0F38_F0toFF[16][5] = {
+/* four rows for no prefix, 66, F3, F2 (including 66+F2 operand size override) */
+static const X86OpEntry opcodes_0F38_F0toFF[16][4] = {
     /*
      * MOVBE and CRC32 are incorrectly listed as always doing 32-bit operation
      * without prefix and 16-bit operation with 0x66.
@@ -884,49 +884,42 @@ static const X86OpEntry opcodes_0F38_F0toFF[16][5] = {
         X86_OP_ENTRYwr(MOVBE, G,v, M,v, cpuid(MOVBE)),
         {},
         X86_OP_ENTRY2(CRC32, G,d, E,b, cpuid(SSE42)),
-        X86_OP_ENTRY2(CRC32, G,d, E,b, cpuid(SSE42)),
     },
     [1] = {
         X86_OP_ENTRYwr(MOVBE, M,v, G,v, cpuid(MOVBE)),
         X86_OP_ENTRYwr(MOVBE, M,v, G,v, cpuid(MOVBE)),
         {},
         X86_OP_ENTRY2(CRC32, G,d, E,v, cpuid(SSE42)),
-        X86_OP_ENTRY2(CRC32, G,d, E,v, cpuid(SSE42)),
     },
     [2] = {
         X86_OP_ENTRY3(ANDN, G,y, B,y, E,y, vex13 cpuid(BMI1)),
         {},
         {},
         {},
-        {},
     },
     [3] = {
         X86_OP_GROUP3(group17, B,y, None,None, E,y, vex13 cpuid(BMI1)),
         {},
         {},
         {},
-        {},
     },
     [5] = {
         X86_OP_ENTRY3(BZHI, G,y, E,y, B,y, vex13 cpuid(BMI1)),
         {},
         X86_OP_ENTRY3(PEXT, G,y, B,y, E,y, vex13 zextT0 cpuid(BMI2)),
         X86_OP_ENTRY3(PDEP, G,y, B,y, E,y, vex13 zextT0 cpuid(BMI2)),
-        {},
     },
     [6] = {
         {},
         X86_OP_ENTRY2(ADCX, G,y, E,y, cpuid(ADX)),
         X86_OP_ENTRY2(ADOX, G,y, E,y, cpuid(ADX)),
         X86_OP_ENTRY3(MULX, /* B,y, */ G,y, E,y, 2,y, vex13 cpuid(BMI2)),
-        {},
     },
     [7] = {
         X86_OP_ENTRY3(BEXTR, G,y, E,y, B,y, vex13 zextT0 cpuid(BMI1)),
         X86_OP_ENTRY3(SHLX, G,y, E,y, B,y, vex13 cpuid(BMI1)),
         X86_OP_ENTRY3(SARX, G,y, E,y, B,y, vex13 sextT0 cpuid(BMI1)),
         X86_OP_ENTRY3(SHRX, G,y, E,y, B,y, vex13 zextT0 cpuid(BMI1)),
-        {},
     },
 };
 
@@ -936,15 +929,7 @@ static void decode_0F38(DisasContext *s, CPUX86State *env, X86OpEntry *entry, ui
     if (*b < 0xf0) {
         *entry = opcodes_0F38_00toEF[*b];
     } else {
-        int row = 0;
-        if (s->prefix & PREFIX_REPZ) {
-            /* The REPZ (F3) prefix has priority over 66 */
-            row = 2;
-        } else {
-            row += s->prefix & PREFIX_REPNZ ? 3 : 0;
-            row += s->prefix & PREFIX_DATA ? 1 : 0;
-        }
-        *entry = opcodes_0F38_F0toFF[*b & 15][row];
+        *entry = *decode_by_prefix(s, opcodes_0F38_F0toFF[*b & 15]);
     }
 }