On 6/2/24 12:05, lixinyu...@ict.ac.cn wrote:
From: Xinyu Li <lixi...@loongson.cn>

This commit fixes an issue with MOV instructions (0x8C and 0x8E)
involving segment registers by explicitly setting the memory operand
size to 16 bits. It introduces a new flag X86_SPECIAL_MovSeg to handle
this specification correctly.

Signed-off-by: Xinyu Li <lixinyu...@ict.ac.cn>
---
  target/i386/tcg/decode-new.c.inc | 12 ++++++++++--
  target/i386/tcg/decode-new.h     |  2 ++
  2 files changed, 12 insertions(+), 2 deletions(-)

diff --git a/target/i386/tcg/decode-new.c.inc b/target/i386/tcg/decode-new.c.inc
index 0ec849b003..ab7dbb45f9 100644
--- a/target/i386/tcg/decode-new.c.inc
+++ b/target/i386/tcg/decode-new.c.inc
@@ -202,6 +202,7 @@
  #define avx_movx .special = X86_SPECIAL_AVXExtMov,
  #define sextT0 .special = X86_SPECIAL_SExtT0,
  #define zextT0 .special = X86_SPECIAL_ZExtT0,
+#define movseg .special = X86_SPECIAL_MovSeg,
#define vex1 .vex_class = 1,
  #define vex1_rep3 .vex_class = 1, .vex_special = X86_VEX_REPScalar,
@@ -1576,9 +1577,9 @@ static const X86OpEntry opcodes_root[256] = {
      [0x89] = X86_OP_ENTRY3(MOV, E,v, G,v, None, None),
      [0x8A] = X86_OP_ENTRY3(MOV, G,b, E,b, None, None),
      [0x8B] = X86_OP_ENTRY3(MOV, G,v, E,v, None, None),
-    [0x8C] = X86_OP_ENTRY3(MOV, E,v, S,w, None, None),
+    [0x8C] = X86_OP_ENTRY3(MOV, E,v, S,w, None, None, movseg),

Indeed this was a mistake, thanks!  The manual doesn't list it
in Table A-2, but the description of the instruction mentions
"r16/r32/m16" which is what you are implementing it.

      [0x8D] = X86_OP_ENTRY3(LEA, G,v, M,v, None, None, noseg),
-    [0x8E] = X86_OP_ENTRY3(MOV, S,w, E,v, None, None),
+    [0x8E] = X86_OP_ENTRY3(MOV, S,w, E,v, None, None, movseg),

This is also wrong, but here the manual is correct.  It can be
written as "S,w, E,w" instead without special casing it.

Therefore the new X86InsnSpecial only needs to cover op[0]...

+    /* Memory operand size of Mov to/from Seg is MO_16 */
+    X86_SPECIAL_MovSeg,

... and I would call it Op0_Mw, for consistency with other similar
entries of X86InsnSpecial.

So I queued your patch with a few small changes:

diff --git a/target/i386/tcg/decode-new.h b/target/i386/tcg/decode-new.h
index 51ef0e621b9..d6335597a13 100644
--- a/target/i386/tcg/decode-new.h
+++ b/target/i386/tcg/decode-new.h
@@ -203,6 +203,8 @@ typedef enum X86InsnSpecial {
     /* When loaded into s->T0, register operand 1 is zero/sign extended.  */
     X86_SPECIAL_SExtT0,
     X86_SPECIAL_ZExtT0,
+    /* Memory operand size of MOV from segment register is MO_16 */
+    X86_SPECIAL_Op0_Mw,
 } X86InsnSpecial;
/*
diff --git a/target/i386/tcg/decode-new.c.inc b/target/i386/tcg/decode-new.c.inc
index 0ec849b0035..599047df94a 100644
--- a/target/i386/tcg/decode-new.c.inc
+++ b/target/i386/tcg/decode-new.c.inc
@@ -202,6 +202,7 @@
 #define avx_movx .special = X86_SPECIAL_AVXExtMov,
 #define sextT0 .special = X86_SPECIAL_SExtT0,
 #define zextT0 .special = X86_SPECIAL_ZExtT0,
+#define op0_Mw .special = X86_SPECIAL_Op0_Mw,
#define vex1 .vex_class = 1,
 #define vex1_rep3 .vex_class = 1, .vex_special = X86_VEX_REPScalar,
@@ -1576,9 +1577,9 @@ static const X86OpEntry opcodes_root[256] = {
     [0x89] = X86_OP_ENTRY3(MOV, E,v, G,v, None, None),
     [0x8A] = X86_OP_ENTRY3(MOV, G,b, E,b, None, None),
     [0x8B] = X86_OP_ENTRY3(MOV, G,v, E,v, None, None),
-    [0x8C] = X86_OP_ENTRY3(MOV, E,v, S,w, None, None),
+    [0x8C] = X86_OP_ENTRY3(MOV, E,v, S,w, None, None, op0_Mw),
     [0x8D] = X86_OP_ENTRY3(LEA, G,v, M,v, None, None, noseg),
-    [0x8E] = X86_OP_ENTRY3(MOV, S,w, E,v, None, None),
+    [0x8E] = X86_OP_ENTRY3(MOV, S,w, E,w, None, None),
     [0x8F] = X86_OP_GROUPw(group1A, E,v),
[0x98] = X86_OP_ENTRY1(CBW, 0,v), /* rAX */
@@ -2514,6 +2515,13 @@ static void disas_insn(DisasContext *s,
         s->override = -1;
         break;
+ case X86_SPECIAL_Op0_Mw:
+        assert(decode.op[0].unit == X86_OP_INT);
+        if (decode.op[0].has_ea) {
+            decode.op[0].ot = MO_16;
+        }
+        break;
+
     default:
         break;
     }

Thank you very much!

Paolo


Reply via email to