[PATCH] x86: fix disassembly of 16-bit fixed size mem ops

Jan Beulich jbeulich@novell.com
Fri Dec 1 11:15:00 GMT 2006


As gas doesn't require the 'w' suffix on moves to/from memory that can
only be 16 bits wide, don't print such suffixes in the disassembly either
unless always printing suffixes.
This at once fixes a problem with duplicate w suffixes on some instructions
when always printing suffixes as well as wrong indentation of operands of
the affected instructions.

Built and tested on i686-pc-linux-gnu, x86_64-unknown-linux-gnu, and a few
cross x86 targets.

opcodes/
2006-11-30  Jan Beulich  <jbeulich@novell.com>

	* i386-dis.c (SEG_Fixup): Delete.
	(Sv): Use OP_SEG.
	(putop): New suffix character 'D'.
	(dis386): Use it.
	(grps): Likewise.
	(OP_SEG): Handle bytemode other than w_mode.

gas/testsuite/
2006-11-30  Jan Beulich  <jbeulich@novell.com>

	* gas/i386/intel.d: Adjust.
	* gas/i386/naked.d: Adjust.
	* gas/i386/opcode.d: Adjust.

--- 2006-11-30/gas/testsuite/gas/i386/intel.d	2005-03-31 16:25:51.000000000 +0200
+++ 2006-11-30/gas/testsuite/gas/i386/intel.d	2006-11-21 09:43:13.000000000 +0100
@@ -138,9 +138,9 @@ Disassembly of section .text:
  1a3:	89 90 90 90 90 90 [ 	]*mov    %edx,0x90909090\(%eax\)
  1a9:	8a 90 90 90 90 90 [ 	]*mov    0x90909090\(%eax\),%dl
  1af:	8b 90 90 90 90 90 [ 	]*mov    0x90909090\(%eax\),%edx
- 1b5:	8c 90 90 90 90 90 [ 	]*movw   %ss,0x90909090\(%eax\)
+ 1b5:	8c 90 90 90 90 90 [ 	]*mov    %ss,0x90909090\(%eax\)
  1bb:	8d 90 90 90 90 90 [ 	]*lea    0x90909090\(%eax\),%edx
- 1c1:	8e 90 90 90 90 90 [ 	]*movw   0x90909090\(%eax\),%ss
+ 1c1:	8e 90 90 90 90 90 [ 	]*mov    0x90909090\(%eax\),%ss
  1c7:	8f 80 90 90 90 90 [ 	]*popl   0x90909090\(%eax\)
  1cd:	90 [ 	]*nop    
  1ce:	91 [ 	]*xchg   %eax,%ecx
--- 2006-11-30/gas/testsuite/gas/i386/naked.d	2006-04-21 10:25:37.000000000 +0200
+++ 2006-11-30/gas/testsuite/gas/i386/naked.d	2006-11-21 09:43:00.000000000 +0100
@@ -11,8 +11,8 @@ Disassembly of section .text:
    a:	b2 20 [ 	]*mov    \$0x20,%dl
    c:	bb 00 00 00 00 [ 	]*mov    \$0x0,%ebx	d: (R_386_)?(dir)?32	.text
   11:	d9 c9 [ 	]*fxch   %st\(1\)
-  13:	36 8c a4 81 d2 04 00 00 [ 	]*movw   %fs,%ss:0x4d2\(%ecx,%eax,4\)
-  1b:	8c 2c ed 00 00 00 00 [ 	]*movw   %gs,0x0\(,%ebp,8\)
+  13:	36 8c a4 81 d2 04 00 00 [ 	]*mov    %fs,%ss:0x4d2\(%ecx,%eax,4\)
+  1b:	8c 2c ed 00 00 00 00 [ 	]*mov    %gs,0x0\(,%ebp,8\)
   22:	26 88 25 00 00 00 00 [ 	]*mov    %ah,%es:0x0
   29:	2e 8b 74 14 80 [ 	]*mov    %cs:0xffffff80\(%esp,%edx,1\),%esi
   2e:	f3 65 a5 [ 	]*rep movsl %gs:\(%esi\),%es:\(%edi\)
--- 2006-11-30/gas/testsuite/gas/i386/opcode.d	2006-07-31 15:54:15.000000000 +0200
+++ 2006-11-30/gas/testsuite/gas/i386/opcode.d	2006-11-21 09:42:48.000000000 +0100
@@ -137,9 +137,9 @@ Disassembly of section .text:
  1a3:	89 90 90 90 90 90 [ 	]*mov    %edx,0x90909090\(%eax\)
  1a9:	8a 90 90 90 90 90 [ 	]*mov    0x90909090\(%eax\),%dl
  1af:	8b 90 90 90 90 90 [ 	]*mov    0x90909090\(%eax\),%edx
- 1b5:	8c 90 90 90 90 90 [ 	]*movw   %ss,0x90909090\(%eax\)
+ 1b5:	8c 90 90 90 90 90 [ 	]*mov    %ss,0x90909090\(%eax\)
  1bb:	8d 90 90 90 90 90 [ 	]*lea    0x90909090\(%eax\),%edx
- 1c1:	8e 90 90 90 90 90 [ 	]*movw   0x90909090\(%eax\),%ss
+ 1c1:	8e 90 90 90 90 90 [ 	]*mov    0x90909090\(%eax\),%ss
  1c7:	8f 80 90 90 90 90 [ 	]*popl   0x90909090\(%eax\)
  1cd:	90 [ 	]*nop    
  1ce:	91 [ 	]*xchg   %eax,%ecx
--- 2006-11-30/opcodes/i386-dis.c	2006-11-13 15:22:14.000000000 +0100
+++ 2006-11-30/opcodes/i386-dis.c	2006-11-21 09:43:56.000000000 +0100
@@ -102,7 +102,6 @@ static void PNI_Fixup (int, int);
 static void SVME_Fixup (int, int);
 static void INVLPG_Fixup (int, int);
 static void BadOp (void);
-static void SEG_Fixup (int, int);
 static void VMX_Fixup (int, int);
 static void REP_Fixup (int, int);
 
@@ -241,7 +240,6 @@ fetch_data (struct disassemble_info *inf
 #define Cm OP_C, m_mode
 #define Dm OP_D, m_mode
 #define Td OP_T, d_mode
-#define Sv SEG_Fixup, v_mode
 
 #define RMeAX OP_REG, eAX_reg
 #define RMeBX OP_REG, eBX_reg
@@ -292,6 +290,7 @@ fetch_data (struct disassemble_info *inf
 #define indirDX OP_IMREG, indir_dx_reg
 
 #define Sw OP_SEG, w_mode
+#define Sv OP_SEG, v_mode
 #define Ap OP_DIR, 0
 #define Ob OP_OFF64, b_mode
 #define Ov OP_OFF64, v_mode
@@ -498,6 +497,8 @@ struct dis386 {
    'B' => print 'b' if suffix_always is true
    'C' => print 's' or 'l' ('w' or 'd' in Intel mode) depending on operand
    .      size prefix
+   'D' => print 'w' if no register operands or 'w', 'l' or 'q', if
+   .      suffix_always is true
    'E' => print 'e' if 32-bit form of jcxz
    'F' => print 'w' or 'l' depending on address size prefix (loop insns)
    'H' => print ",pt" or ",pn" branch hint
@@ -689,9 +690,9 @@ static const struct dis386 dis386[] = {
   { "movS",		Ev, Gv, XX, XX },
   { "movB",		Gb, Eb, XX, XX },
   { "movS",		Gv, Ev, XX, XX },
-  { "movQ",		Sv, Sw, XX, XX },
+  { "movD",		Sv, Sw, XX, XX },
   { "leaS",		Gv, M, XX, XX },
-  { "movQ",		Sw, Sv, XX, XX },
+  { "movD",		Sw, Sv, XX, XX },
   { "popU",		stackEv, XX, XX, XX },
   /* 90 */
   { "xchgS",		NOP_Fixup1, eAX_reg, NOP_Fixup2, eAX_reg, XX, XX },
@@ -1594,8 +1595,8 @@ static const struct dis386 grps[][8] = {
   },
   /* GRP6 */
   {
-    { "sldt",	Ev, XX, XX, XX },
-    { "str",	Ev, XX, XX, XX },
+    { "sldtD",	Sv, XX, XX, XX },
+    { "strD",	Sv, XX, XX, XX },
     { "lldt",	Ew, XX, XX, XX },
     { "ltr",	Ew, XX, XX, XX },
     { "verr",	Ew, XX, XX, XX },
@@ -1609,7 +1610,7 @@ static const struct dis386 grps[][8] = {
     { "sidt{Q|IQ||}", PNI_Fixup, 0, XX, XX, XX },
     { "lgdt{Q|Q||}",	 M, XX, XX, XX },
     { "lidt{Q|Q||}",	 SVME_Fixup, 0, XX, XX, XX },
-    { "smsw",	Ev, XX, XX, XX },
+    { "smswD",	Sv, XX, XX, XX },
     { "(bad)",	XX, XX, XX, XX },
     { "lmsw",	Ew, XX, XX, XX },
     { "invlpg",	INVLPG_Fixup, w_mode, XX, XX, XX },
@@ -3742,6 +3743,23 @@ putop (const char *template, int sizefla
 	      used_prefixes |= (prefixes & PREFIX_DATA);
 	    }
 	  break;
+	case 'D':
+	  if (intel_syntax || !(sizeflag & SUFFIX_ALWAYS))
+	    break;
+	  USED_REX (REX_MODE64);
+	  if (mod == 3)
+	    {
+	      if (rex & REX_MODE64)
+		*obufp++ = 'q';
+	      else if (sizeflag & DFLAG)
+		*obufp++ = intel_syntax ? 'd' : 'l';
+	      else
+		*obufp++ = 'w';
+	      used_prefixes |= (prefixes & PREFIX_DATA);
+	    }
+	  else
+	    *obufp++ = 'w';
+	  break;
 	case 'E':		/* For jcxz/jecxz */
 	  if (address_mode == mode_64bit)
 	    {
@@ -4861,9 +4879,12 @@ OP_J (int bytemode, int sizeflag)
 }
 
 static void
-OP_SEG (int dummy ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)
+OP_SEG (int bytemode, int sizeflag)
 {
-  oappend (names_seg[reg]);
+  if (bytemode == w_mode)
+    oappend (names_seg[reg]);
+  else
+    OP_E (mod == 3 ? bytemode : w_mode, sizeflag);
 }
 
 static void
@@ -5581,55 +5602,6 @@ BadOp (void)
 }
 
 static void
-SEG_Fixup (int extrachar, int sizeflag)
-{
-  if (mod == 3)
-    {
-      /* We need to add a proper suffix with
-
-		movw %ds,%ax
-		movl %ds,%eax
-		movq %ds,%rax
-		movw %ax,%ds
-		movl %eax,%ds
-		movq %rax,%ds
-       */
-      const char *suffix;
-
-      if (prefixes & PREFIX_DATA)
-	suffix = "w";
-      else
-	{
-	  USED_REX (REX_MODE64);
-	  if (rex & REX_MODE64)
-	    suffix = "q";
-	  else
-	    suffix = "l";
-	}
-      strcat (obuf, suffix);
-    }
-  else
-    {
-      /* We need to fix the suffix for
-
-		movw %ds,(%eax)
-		movw %ds,(%rax)
-		movw (%eax),%ds
-		movw (%rax),%ds
-
-	 Override "mov[l|q]".  */
-      char *p = obuf + strlen (obuf) - 1;
-
-      /* We might not have a suffix.  */
-      if (*p == 'v')
-	++p;
-      *p = 'w';
-    }
-
-  OP_E (extrachar, sizeflag);
-}
-
-static void
 VMX_Fixup (int extrachar ATTRIBUTE_UNUSED, int sizeflag)
 {
   if (mod == 3 && reg == 0 && rm >=1 && rm <= 4)




More information about the Binutils mailing list