@samitouri / QOSamiQemu / commits / 380b959618

target/i386: decode opcode extensions group 3 /1 as TEST

According to Table A-6 in Volume 3 of AMD64 Architecture Programmer's Manual, opcodes F6 and F7 (opcode extensions group 3) with ModRM's reg field values of 0 and 1 can be used to encode a TEST instruction. Although Intel 64 and IA-32 Architectures Software Developer's Manual leaves the cell 1 of opcode extensions group 3 blank in the opcode table (Table A-6, Volume 2D), the instruction in a group 3 with reg field of ModRM byte set to 1 actually behaves like TEST instruction on Intel CPUs. Currently, QEMU decodes group 3 instruction as TEST only if reg field of ModRM byte is 0. When the reg field is 1, QEMU raises a #UD exception. This behavior does not match real Intel and AMD hardware. This patch fixes this issue by duplicating the existing [0x00] and [0x08] X86_OP_ENTRYrr(AND, ...) entries into slots [0x01] and [0x09] in the opcodes_grp3 table. Fixes: d7c41a60d0c5 ("target/i386: move C0-FF opcodes to new decoder (except for x87)") Resolves: https://gitlab.com/qemu-project/qemu/-/work_items/3580 Signed-off-by: Andrey Polivoda <apolivodaa433@gmail.com> Cc: qemu-devel@nongnu.org Cc: Paolo Bonzini <pbonzini@redhat.com> Cc: Richard Henderson <richard.henderson@linaro.org> Reviewed-by: Richard Henderson <richard.henderson@linaro.org> Link: https://lore.kernel.org/r/20260621032524.1138213-1-apolivodaa433@gmail.com Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>

Andrey Polivoda committed Jun 21, 2026 at 13:25 UTC 380b9596181760f371713604ea3472c56c19deb9
1 file changed +2
target/i386/tcg/decode-new.c.inc
+2
@@ -1624,6 +1624,7 @@ static void decode_group3(DisasContext *s, CPUX86State *env, X86OpEntry *entry,
1624 static const X86OpEntry opcodes_grp3[16] = {
1625 /* 0xf6 */
1626 [0x00] = X86_OP_ENTRYrr(AND, E,b, I,b),
1627 + [0x01] = X86_OP_ENTRYrr(AND, E,b, I,b),
1628 [0x02] = X86_OP_ENTRY1(NOT, E,b, lock),
1629 [0x03] = X86_OP_ENTRY1(NEG, E,b, lock),
1630 [0x04] = X86_OP_ENTRYrr(MUL, E,b, 0,b, zextT0),
@@ -1633,6 +1634,7 @@ static void decode_group3(DisasContext *s, CPUX86State *env, X86OpEntry *entry,
1634
1635 /* 0xf7 */
1636 [0x08] = X86_OP_ENTRYrr(AND, E,v, I,z),
1637 + [0x09] = X86_OP_ENTRYrr(AND, E,v, I,z),
1638 [0x0a] = X86_OP_ENTRY1(NOT, E,v, lock),
1639 [0x0b] = X86_OP_ENTRY1(NEG, E,v, lock),
1640 [0x0c] = X86_OP_ENTRYrr(MUL, E,v, 0,v, zextT0),