Commit f4c828b633 for qemu.org
commit f4c828b6330934aa887ad721de8501ac704cefc3
Author: Paolo Bonzini <pbonzini@redhat.com>
Date: Sat Oct 17 09:53:54 2026 +0200
target/i386/tcg: remove X and Y operand types
Since the Intel SDM is moving away from operand types, remove more of
the implicit types; X and Y are meant for string instructions but the
DS:SI and ES:DI addressing modes are handled entirely in the generator
functions; the operands were just placeholders to distinguish byte
string operations from s->dflag string operations.
Note that this moves the port for INS and OUTS from s->T1 to s->T0.
This frees up some operand letters that could be useful in the future,
for example to allocate K/X/Y to mask registers in the same guise as
H/V/W for AVX.
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
diff --git a/target/i386/tcg/decode-new.c.inc b/target/i386/tcg/decode-new.c.inc
index 65fd402c17..7e5ece380a 100644
--- a/target/i386/tcg/decode-new.c.inc
+++ b/target/i386/tcg/decode-new.c.inc
@@ -1810,10 +1810,10 @@ static const X86OpEntry opcodes_root[256] = {
[0xA1] = X86_OP_ENTRY3(MOV, 0,v, O,v, None, None), /* rAX, Ov */
[0xA2] = X86_OP_ENTRY3(MOV, O,b, 0,b, None, None), /* Ob, AL */
[0xA3] = X86_OP_ENTRY3(MOV, O,v, 0,v, None, None), /* Ov, rAX */
- [0xA4] = X86_OP_ENTRYrr(MOVS, Y,b, X,b),
- [0xA5] = X86_OP_ENTRYrr(MOVS, Y,v, X,v),
- [0xA6] = X86_OP_ENTRYrr(CMPS, Y,b, X,b),
- [0xA7] = X86_OP_ENTRYrr(CMPS, Y,v, X,v),
+ [0xA4] = X86_OP_ENTRY0(MOVS),
+ [0xA5] = X86_OP_ENTRY0(MOVS),
+ [0xA6] = X86_OP_ENTRY0(CMPS),
+ [0xA7] = X86_OP_ENTRY0(CMPS),
[0xB0] = X86_OP_ENTRY3(MOV, LoBits,b, I,b, None, None),
[0xB1] = X86_OP_ENTRY3(MOV, LoBits,b, I,b, None, None),
@@ -1916,10 +1916,10 @@ static const X86OpEntry opcodes_root[256] = {
[0x69] = X86_OP_ENTRY3(IMUL3, G,v, E,v, I,z, sextT0),
[0x6A] = X86_OP_ENTRYr(PUSH, I,b),
[0x6B] = X86_OP_ENTRY3(IMUL3, G,v, E,v, I,b, sextT0),
- [0x6C] = X86_OP_ENTRYrr(INS, Y,b, 2,w), /* DX */
- [0x6D] = X86_OP_ENTRYrr(INS, Y,z, 2,w), /* DX */
- [0x6E] = X86_OP_ENTRYrr(OUTS, X,b, 2,w), /* DX */
- [0x6F] = X86_OP_ENTRYrr(OUTS, X,z, 2,w), /* DX */
+ [0x6C] = X86_OP_ENTRYr(INS, 2,w), /* DX */
+ [0x6D] = X86_OP_ENTRYr(INS, 2,w), /* DX */
+ [0x6E] = X86_OP_ENTRYr(OUTS, 2,w), /* DX */
+ [0x6F] = X86_OP_ENTRYr(OUTS, 2,w), /* DX */
[0x78] = X86_OP_ENTRYr(Jcc, J,b),
[0x79] = X86_OP_ENTRYr(Jcc, J,b),
@@ -1951,13 +1951,13 @@ static const X86OpEntry opcodes_root[256] = {
[0xA8] = X86_OP_ENTRYrr(TEST, 0,b, I,b), /* AL, Ib */
[0xA9] = X86_OP_ENTRYrr(TEST, 0,v, I,z), /* rAX, Iz */
- [0xAA] = X86_OP_ENTRYwr(STOS, Y,b, 0,b),
- [0xAB] = X86_OP_ENTRYwr(STOS, Y,v, 0,v),
+ [0xAA] = X86_OP_ENTRYr(STOS, 0,b),
+ [0xAB] = X86_OP_ENTRYr(STOS, 0,v),
/* Manual writeback because REP LODS (!) has to write EAX/RAX after every LODS. */
- [0xAC] = X86_OP_ENTRYr(LODS, X,b),
- [0xAD] = X86_OP_ENTRYr(LODS, X,v),
- [0xAE] = X86_OP_ENTRYrr(SCAS, 0,b, Y,b),
- [0xAF] = X86_OP_ENTRYrr(SCAS, 0,v, Y,v),
+ [0xAC] = X86_OP_ENTRY0(LODS),
+ [0xAD] = X86_OP_ENTRY0(LODS),
+ [0xAE] = X86_OP_ENTRYr(SCAS, 0,b),
+ [0xAF] = X86_OP_ENTRYr(SCAS, 0,v),
[0xB8] = X86_OP_ENTRYwr(MOV, LoBits,v, I,v),
[0xB9] = X86_OP_ENTRYwr(MOV, LoBits,v, I,v),
@@ -2552,8 +2552,6 @@ static bool decode_op(DisasContext *s, CPUX86State *env, X86DecodedInsn *decode,
switch (type) {
case X86_TYPE_None: /* Implicit or absent */
case X86_TYPE_F: /* EFLAGS/RFLAGS */
- case X86_TYPE_X: /* string source */
- case X86_TYPE_Y: /* string destination */
break;
case X86_TYPE_B: /* VEX.vvvv selects a GPR, else use modrm */
diff --git a/target/i386/tcg/decode-new.h b/target/i386/tcg/decode-new.h
index a823143bbd..2218a4eda3 100644
--- a/target/i386/tcg/decode-new.h
+++ b/target/i386/tcg/decode-new.h
@@ -41,8 +41,6 @@ typedef enum X86OpType {
X86_TYPE_U, /* R/M in the modrm byte selects an XMM/YMM register */
X86_TYPE_V, /* reg in the modrm byte selects an XMM/YMM register */
X86_TYPE_W, /* XMM/YMM modrm operand */
- X86_TYPE_X, /* string source */
- X86_TYPE_Y, /* string destination */
/* Custom */
X86_TYPE_EM, /* modrm byte selects an ALU memory operand */
diff --git a/target/i386/tcg/emit.c.inc b/target/i386/tcg/emit.c.inc
index a1ae582174..5754f3dcc8 100644
--- a/target/i386/tcg/emit.c.inc
+++ b/target/i386/tcg/emit.c.inc
@@ -1923,7 +1923,7 @@ static void gen_CMPccXADD(DisasContext *s, X86DecodedInsn *decode)
static void gen_CMPS(DisasContext *s, X86DecodedInsn *decode)
{
- MemOp ot = decode->op[2].ot;
+ MemOp ot = decode->b & 1 ? s->dflag : MO_8;
gen_repz_nz(s, ot, gen_cmps);
}
@@ -2388,10 +2388,10 @@ static void gen_INC(DisasContext *s, X86DecodedInsn *decode)
static void gen_INS(DisasContext *s, X86DecodedInsn *decode)
{
- MemOp ot = decode->op[1].ot;
+ MemOp ot = decode->b & 1 ? mo_ins_outs(s) : MO_8;
TCGv_i32 port = tcg_temp_new_i32();
- tcg_gen_trunc_tl_i32(port, s->T1);
+ tcg_gen_trunc_tl_i32(port, s->T0);
tcg_gen_ext16u_i32(port, port);
if (!gen_check_io(s, ot, port,
SVM_IOIO_TYPE_MASK | SVM_IOIO_STR_MASK)) {
@@ -2593,7 +2593,7 @@ static void gen_LGS(DisasContext *s, X86DecodedInsn *decode)
static void gen_LODS(DisasContext *s, X86DecodedInsn *decode)
{
- MemOp ot = decode->op[1].ot;
+ MemOp ot = decode->b & 1 ? s->dflag : MO_8;
gen_repz(s, ot, gen_lods);
}
@@ -2803,7 +2803,7 @@ static void gen_MOVq_dq(DisasContext *s, X86DecodedInsn *decode)
static void gen_MOVS(DisasContext *s, X86DecodedInsn *decode)
{
- MemOp ot = decode->op[2].ot;
+ MemOp ot = decode->b & 1 ? s->dflag : MO_8;
gen_repz(s, ot, gen_movs);
}
@@ -2960,10 +2960,10 @@ static void gen_OUT(DisasContext *s, X86DecodedInsn *decode)
static void gen_OUTS(DisasContext *s, X86DecodedInsn *decode)
{
- MemOp ot = decode->op[1].ot;
+ MemOp ot = decode->b & 1 ? mo_ins_outs(s) : MO_8;
TCGv_i32 port = tcg_temp_new_i32();
- tcg_gen_trunc_tl_i32(port, s->T1);
+ tcg_gen_trunc_tl_i32(port, s->T0);
tcg_gen_ext16u_i32(port, port);
if (!gen_check_io(s, ot, port, SVM_IOIO_STR_MASK)) {
return;
@@ -4128,7 +4128,7 @@ static void gen_SBB(DisasContext *s, X86DecodedInsn *decode)
static void gen_SCAS(DisasContext *s, X86DecodedInsn *decode)
{
- MemOp ot = decode->op[2].ot;
+ MemOp ot = decode->b & 1 ? s->dflag : MO_8;
gen_repz_nz(s, ot, gen_scas);
}
@@ -4332,7 +4332,7 @@ static void gen_STMXCSR(DisasContext *s, X86DecodedInsn *decode)
static void gen_STOS(DisasContext *s, X86DecodedInsn *decode)
{
- MemOp ot = decode->op[1].ot;
+ MemOp ot = decode->b & 1 ? s->dflag : MO_8;
gen_repz(s, ot, gen_stos);
}
diff --git a/target/i386/tcg/translate.c b/target/i386/tcg/translate.c
index 3d542acd97..b715921c37 100644
--- a/target/i386/tcg/translate.c
+++ b/target/i386/tcg/translate.c
@@ -403,6 +403,12 @@ static inline bool byte_reg_is_xH(DisasContext *s, int reg)
return true;
}
+/* Select the size of an INS/OUTS operation ("z" operand size). */
+static inline MemOp mo_ins_outs(DisasContext *s)
+{
+ return s->dflag == MO_16 ? MO_16 : MO_32;
+}
+
/* Select the size of a push/pop operation. */
static inline MemOp mo_pushpop(DisasContext *s, MemOp ot)
{