target/i386/tcg: simplify decoding of 0F 38 F0...FF
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>
Paolo Bonzini committed
Mar 31, 2026 at 08:52 UTC
e45fd081dbf36fc6abb2fa518a80b9c37f0474a2
1 file changed
+3
-18
target/i386/tcg/decode-new.c.inc
+3
-18
@@ -873,8 +873,8 @@ static const X86OpEntry opcodes_0F38_00toEF[240] = {
873
[0xef] = X86_OP_ENTRY3(CMPccXADD, M,y, G,y, B,y, vex13 xchg chk(o64) cpuid(CMPCCXADD) p_66),
874
};
875
876
-/* five rows for no prefix, 66, F3, F2, 66+F2 */
877
-static const X86OpEntry opcodes_0F38_F0toFF[16][5] = {
876
+/* four rows for no prefix, 66, F3, F2 (including 66+F2 operand size override) */
877
+static const X86OpEntry opcodes_0F38_F0toFF[16][4] = {
878
/*
879
* MOVBE and CRC32 are incorrectly listed as always doing 32-bit operation
880
* without prefix and 16-bit operation with 0x66.
@@ -884,49 +884,42 @@ static const X86OpEntry opcodes_0F38_F0toFF[16][5] = {
884
X86_OP_ENTRYwr(MOVBE, G,v, M,v, cpuid(MOVBE)),
885
{},
886
X86_OP_ENTRY2(CRC32, G,d, E,b, cpuid(SSE42)),
887
- X86_OP_ENTRY2(CRC32, G,d, E,b, cpuid(SSE42)),
887
},
888
[1] = {
889
X86_OP_ENTRYwr(MOVBE, M,v, G,v, cpuid(MOVBE)),
890
X86_OP_ENTRYwr(MOVBE, M,v, G,v, cpuid(MOVBE)),
891
{},
892
X86_OP_ENTRY2(CRC32, G,d, E,v, cpuid(SSE42)),
894
- X86_OP_ENTRY2(CRC32, G,d, E,v, cpuid(SSE42)),
893
},
894
[2] = {
895
X86_OP_ENTRY3(ANDN, G,y, B,y, E,y, vex13 cpuid(BMI1)),
896
{},
897
{},
898
{},
901
- {},
899
},
900
[3] = {
901
X86_OP_GROUP3(group17, B,y, None,None, E,y, vex13 cpuid(BMI1)),
902
{},
903
{},
904
{},
908
- {},
905
},
906
[5] = {
907
X86_OP_ENTRY3(BZHI, G,y, E,y, B,y, vex13 cpuid(BMI1)),
908
{},
909
X86_OP_ENTRY3(PEXT, G,y, B,y, E,y, vex13 zextT0 cpuid(BMI2)),
910
X86_OP_ENTRY3(PDEP, G,y, B,y, E,y, vex13 zextT0 cpuid(BMI2)),
915
- {},
911
},
912
[6] = {
913
{},
914
X86_OP_ENTRY2(ADCX, G,y, E,y, cpuid(ADX)),
915
X86_OP_ENTRY2(ADOX, G,y, E,y, cpuid(ADX)),
916
X86_OP_ENTRY3(MULX, /* B,y, */ G,y, E,y, 2,y, vex13 cpuid(BMI2)),
922
- {},
917
},
918
[7] = {
919
X86_OP_ENTRY3(BEXTR, G,y, E,y, B,y, vex13 zextT0 cpuid(BMI1)),
920
X86_OP_ENTRY3(SHLX, G,y, E,y, B,y, vex13 cpuid(BMI1)),
921
X86_OP_ENTRY3(SARX, G,y, E,y, B,y, vex13 sextT0 cpuid(BMI1)),
922
X86_OP_ENTRY3(SHRX, G,y, E,y, B,y, vex13 zextT0 cpuid(BMI1)),
929
- {},
923
},
924
};
925
@@ -936,15 +929,7 @@ static void decode_0F38(DisasContext *s, CPUX86State *env, X86OpEntry *entry, ui
929
if (*b < 0xf0) {
930
*entry = opcodes_0F38_00toEF[*b];
931
} else {
939
- int row = 0;
940
- if (s->prefix & PREFIX_REPZ) {
941
- /* The REPZ (F3) prefix has priority over 66 */
942
- row = 2;
943
- } else {
944
- row += s->prefix & PREFIX_REPNZ ? 3 : 0;
945
- row += s->prefix & PREFIX_DATA ? 1 : 0;
946
- }
947
- *entry = opcodes_0F38_F0toFF[*b & 15][row];
932
+ *entry = *decode_by_prefix(s, opcodes_0F38_F0toFF[*b & 15]);
933
}
934
}
935