[09/10] x86: replace adhoc ambiguous operand checking for MOVSX/MOVZX

Message ID 7716e107-cc06-a66e-9446-75d3c3a2bbbe@suse.com
State Superseded
Headers show
Series
  • x86: operand size handling improvements
Related show

Commit Message

Jan Beulich Aug. 6, 2019, 2:28 p.m.
For these to get treatment consistent with other operand size checking
the special logic shouldn't live in md_assemble(), but process_suffix().
And there's more logic involved than simply zapping the suffix, in
particular to enforce the general "suffix trumps register size" rule in
AT&T mode. The cases where behavior is being corrected can be seen from
the testcase adjustments (as mentioned in the commit introducing these
tests some cases had wrong expectations at that point, but it seemed
better to separate testcase introduction from actual code changes).

Note however that MOVS* and MOVZ* still aren't fully consistent, due to
the objection to fold MOVS* templates just like was done for MOVZ* in
c07315e0c6 ("x86: allow suffix-less movzw and 64-bit movzb").

gas/
2019-08-XX  Jan Beulich  <jbeulich@suse.com>

	* config/tc-i386.c (md_assemble): Move movsx/movzx special
	casing ...
	(process_suffix): ... here. Consider just the first operand
	initially.
	* testsuite/gas/i386/movx16.l, testsuite/gas/i386/movx32.l,
	testsuite/gas/i386/movx64.l, testsuite/gas/i386/noreg16.l,
	testsuite/gas/i386/noreg32.l, testsuite/gas/i386/noreg64.l:
	Adjust expectations.

opcodes/
2019-08-XX  Jan Beulich  <jbeulich@suse.com>

	* i386-opc.tbl (movsx): Fold patterns. Also allow Reg32 as
	destination for Cpu64-only variant.
	(movsxd): Fold patterns. Also allow Reg32 as destination.
	(movzx): Fold patterns.
	* i386-tbl.h: Re-generate.

Patch

--- a/gas/config/tc-i386.c
+++ b/gas/config/tc-i386.c
@@ -4324,22 +4324,6 @@  md_assemble (char *line)
         : as_bad) (_("SSE instruction `%s' is used"), i.tm.name);
      }
  
-  /* Zap movzx and movsx suffix.  The suffix has been set from
-     "word ptr" or "byte ptr" on the source operand in Intel syntax
-     or extracted from mnemonic in AT&T syntax.  But we'll use
-     the destination register to choose the suffix for encoding.  */
-  if ((i.tm.base_opcode & ~9) == 0x0fb6)
-    {
-      /* In Intel syntax, there must be a suffix.  In AT&T syntax, if
-	 there is no suffix, the default will be byte extension.  */
-      if (i.reg_operands != 2
-	  && !i.suffix
-	  && intel_syntax)
-	as_bad (_("ambiguous operand size for `%s'"), i.tm.name);
-
-      i.suffix = 0;
-    }
-
    if (i.tm.opcode_modifier.fwait)
      if (!add_prefix (FWAIT_OPCODE))
        return;
@@ -6236,6 +6220,16 @@  process_suffix (void)
      i.suffix = QWORD_MNEM_SUFFIX;
    else if (i.reg_operands)
      {
+      unsigned int numop = i.operands;
+
+      /* movsx/movzx want only their source operand considered here, for the
+	 ambiguity checking below.  The suffix will be replaced afterwards
+	 to represent the destination (register).  */
+      if (((i.tm.base_opcode | 8) == 0xfbe && i.tm.opcode_modifier.w)
+	  || (i.tm.base_opcode == 0x63 && i.tm.cpu_flags.bitfield.cpu64
+	      && !i.tm.opcode_modifier.rex64))
+	--i.operands;
+
        /* If there's no instruction mnemonic suffix we try to invent one
  	 based on register operands.  */
        if (!i.suffix)
@@ -6264,6 +6258,13 @@  process_suffix (void)
  		  continue;
  		break;
  	      }
+
+	  /* As an exception, movsx/movzx with a word register destination
+	     silently default to a byte source in AT&T mode, as their word
+	     memory source case isn't really useful.  */
+	  if ((i.tm.base_opcode | 8) == 0xfbe && i.tm.opcode_modifier.w
+	      && !i.suffix && !intel_syntax && i.types[1].bitfield.word)
+	    i.suffix = BYTE_MNEM_SUFFIX;
  	}
        else if (i.suffix == BYTE_MNEM_SUFFIX)
  	{
@@ -6310,6 +6311,9 @@  process_suffix (void)
  	;
        else
  	abort ();
+
+      /* Undo the movsx/movzx change done above.  */
+      i.operands = numop;
      }
    else if (i.tm.opcode_modifier.defaultsize
  	   && !i.suffix
@@ -6403,6 +6407,8 @@  process_suffix (void)
  
  	  if (i.tm.opcode_modifier.floatmf)
  	    i.suffix = SHORT_MNEM_SUFFIX;
+	  else if ((i.tm.base_opcode | 8) == 0xfbe || i.tm.base_opcode == 0x63)
+	    /* handled below */;
  	  else if (flag_code == CODE_16BIT)
  	    i.suffix = WORD_MNEM_SUFFIX;
  	  else if (!i.tm.opcode_modifier.no_lsuf)
@@ -6412,6 +6418,31 @@  process_suffix (void)
  	}
      }
  
+  if ((i.tm.base_opcode | 8) == 0xfbe || i.tm.base_opcode == 0x63)
+    {
+      /* In Intel syntax, movsx/movzx must have a "suffix" (checked above).
+	 In AT&T syntax, if there is no suffix (warned about above), the default
+	 will be byte extension.  */
+      if (i.tm.opcode_modifier.w && i.suffix && i.suffix != BYTE_MNEM_SUFFIX)
+	i.tm.base_opcode |= 1;
+
+      /* For further processing, the suffix should represent the destination
+	 (register).  This is already the case when one was used with
+	 mov[sz][bw]*, but we need to replace it for mov[sz]x, or if there was
+	 no suffix to begin with.  */
+      if (i.tm.opcode_modifier.w || i.tm.base_opcode == 0x63 || !i.suffix)
+	{
+	  if (i.types[1].bitfield.word)
+	    i.suffix = WORD_MNEM_SUFFIX;
+	  else if (i.types[1].bitfield.qword)
+	    i.suffix = QWORD_MNEM_SUFFIX;
+	  else
+	    i.suffix = LONG_MNEM_SUFFIX;
+
+	  i.tm.opcode_modifier.w = 0;
+	}
+    }
+
    /* Change the opcode based on the operand size given by i.suffix.  */
    switch (i.suffix)
      {
--- a/gas/testsuite/gas/i386/movx16.l
+++ b/gas/testsuite/gas/i386/movx16.l
@@ -6,7 +6,7 @@ 
  [ 	]*[1-9][0-9]*[ 	]+movsx	%eax, %cl
  [ 	]*[1-9][0-9]*[ 	]*
  [ 	]*[1-9][0-9]* \?\?\?\? 0FBEC8[ 	]+movsx	%al, %cx
-[ 	]*[1-9][0-9]*[ 	]+movsx	%ax, %cx
+[ 	]*[1-9][0-9]* \?\?\?\? 0FBFC8[ 	]+movsx	%ax, %cx
  [ 	]*[1-9][0-9]*[ 	]+movsx	%eax, %cx
  [ 	]*[1-9][0-9]*[ 	]*
  [ 	]*[1-9][0-9]* \?\?\?\? 660FBEC8[ 	]+movsx	%al, %ecx
@@ -18,11 +18,13 @@ 
  [ 	]*[1-9][0-9]*[ 	]+movsxb	%eax, %cl
  [ 	]*[1-9][0-9]*[ 	]*
  [ 	]*[1-9][0-9]* \?\?\?\? 0FBEC8[ 	]+movsxb	%al, %cx
-[ 	]*[1-9][0-9]*[ 	]+movsxb	%ax, %cx
+[ 	]*[1-9][0-9]* \?\?\?\? 0FBEC8[ 	]+movsxb	%ax, %cx
+.* Warning: using `%al' instead of `%ax' due to `b' suffix
  [ 	]*[1-9][0-9]*[ 	]+movsxb	%eax, %cx
  [ 	]*[1-9][0-9]*[ 	]*
  [ 	]*[1-9][0-9]* \?\?\?\? 660FBEC8[ 	]+movsxb	%al, %ecx
-[ 	]*[1-9][0-9]*[ 	]+movsxb	%ax, %ecx
+[ 	]*[1-9][0-9]* \?\?\?\? 660FBEC8[ 	]+movsxb	%ax, %ecx
+.* Warning: using `%al' instead of `%ax' due to `b' suffix
  [ 	]*[1-9][0-9]*[ 	]+movsxb	%eax, %ecx
  [ 	]*[1-9][0-9]*[ 	]*
  [ 	]*[1-9][0-9]*[ 	]+movsxw	%al, %cl
@@ -30,7 +32,7 @@ 
  [ 	]*[1-9][0-9]*[ 	]+movsxw	%eax, %cl
  [ 	]*[1-9][0-9]*[ 	]*
  [ 	]*[1-9][0-9]*[ 	]+movsxw	%al, %cx
-[ 	]*[1-9][0-9]*[ 	]+movsxw	%ax, %cx
+[ 	]*[1-9][0-9]* \?\?\?\? 0FBFC8[ 	]+movsxw	%ax, %cx
  [ 	]*[1-9][0-9]*[ 	]+movsxw	%eax, %cx
  [ 	]*[1-9][0-9]*[ 	]*
  [ 	]*[1-9][0-9]*[ 	]+movsxw	%al, %ecx
@@ -103,7 +105,7 @@ 
  [ 	]*[1-9][0-9]*[ 	]+movzx	%eax, %cl
  [ 	]*[1-9][0-9]*[ 	]*
  [ 	]*[1-9][0-9]* \?\?\?\? 0FB6C8[ 	]+movzx	%al, %cx
-[ 	]*[1-9][0-9]*[ 	]+movzx	%ax, %cx
+[ 	]*[1-9][0-9]* \?\?\?\? 0FB7C8[ 	]+movzx	%ax, %cx
  [ 	]*[1-9][0-9]*[ 	]+movzx	%eax, %cx
  [ 	]*[1-9][0-9]*[ 	]*
  [ 	]*[1-9][0-9]* \?\?\?\? 660FB6C8[ 	]+movzx	%al, %ecx
@@ -115,11 +117,13 @@ 
  [ 	]*[1-9][0-9]*[ 	]+movzxb	%eax, %cl
  [ 	]*[1-9][0-9]*[ 	]*
  [ 	]*[1-9][0-9]* \?\?\?\? 0FB6C8[ 	]+movzxb	%al, %cx
-[ 	]*[1-9][0-9]*[ 	]+movzxb	%ax, %cx
+[ 	]*[1-9][0-9]* \?\?\?\? 0FB6C8[ 	]+movzxb	%ax, %cx
+.* Warning: using `%al' instead of `%ax' due to `b' suffix
  [ 	]*[1-9][0-9]*[ 	]+movzxb	%eax, %cx
  [ 	]*[1-9][0-9]*[ 	]*
  [ 	]*[1-9][0-9]* \?\?\?\? 660FB6C8[ 	]+movzxb	%al, %ecx
-[ 	]*[1-9][0-9]*[ 	]+movzxb	%ax, %ecx
+[ 	]*[1-9][0-9]* \?\?\?\? 660FB6C8[ 	]+movzxb	%ax, %ecx
+.* Warning: using `%al' instead of `%ax' due to `b' suffix
  [ 	]*[1-9][0-9]*[ 	]+movzxb	%eax, %ecx
  [ 	]*[1-9][0-9]*[ 	]*
  [ 	]*[1-9][0-9]*[ 	]+movzxw	%al, %cl
@@ -127,7 +131,7 @@ 
  [ 	]*[1-9][0-9]*[ 	]+movzxw	%eax, %cl
  [ 	]*[1-9][0-9]*[ 	]*
  [ 	]*[1-9][0-9]*[ 	]+movzxw	%al, %cx
-[ 	]*[1-9][0-9]*[ 	]+movzxw	%ax, %cx
+[ 	]*[1-9][0-9]* \?\?\?\? 0FB7C8[ 	]+movzxw	%ax, %cx
  [ 	]*[1-9][0-9]*[ 	]+movzxw	%eax, %cx
  [ 	]*[1-9][0-9]*[ 	]*
  [ 	]*[1-9][0-9]*[ 	]+movzxw	%al, %ecx
@@ -154,7 +158,8 @@ 
  [ 	]*[1-9][0-9]*[ 	]+movzbw	%ax, %cx
  [ 	]*[1-9][0-9]*[ 	]+movzbw	%eax, %cx
  [ 	]*[1-9][0-9]*[ 	]*
-[ 	]*[1-9][0-9]* \?\?\?\? 660FB6C8[ 	]+movzbw	%al, %ecx
+[ 	]*[1-9][0-9]* \?\?\?\? 0FB6C8[ 	]+movzbw	%al, %ecx
+.* Warning: using `%cx' instead of `%ecx' due to `w' suffix
  [ 	]*[1-9][0-9]*[ 	]+movzbw	%ax, %ecx
  [ 	]*[1-9][0-9]*[ 	]+movzbw	%eax, %ecx
  [ 	]*[1-9][0-9]*[ 	]*
@@ -162,7 +167,8 @@ 
  [ 	]*[1-9][0-9]*[ 	]+movzbl	%ax, %cl
  [ 	]*[1-9][0-9]*[ 	]+movzbl	%eax, %cl
  [ 	]*[1-9][0-9]*[ 	]*
-[ 	]*[1-9][0-9]* \?\?\?\? 0FB6C8[ 	]+movzbl	%al, %cx
+[ 	]*[1-9][0-9]* \?\?\?\? 660FB6C8[ 	]+movzbl	%al, %cx
+.* Warning: using `%ecx' instead of `%cx' due to `l' suffix
  [ 	]*[1-9][0-9]*[ 	]+movzbl	%ax, %cx
  [ 	]*[1-9][0-9]*[ 	]+movzbl	%eax, %cx
  [ 	]*[1-9][0-9]*[ 	]*
--- a/gas/testsuite/gas/i386/movx32.l
+++ b/gas/testsuite/gas/i386/movx32.l
@@ -6,7 +6,7 @@ 
  [ 	]*[1-9][0-9]*[ 	]+movsx	%eax, %cl
  [ 	]*[1-9][0-9]*[ 	]*
  [ 	]*[1-9][0-9]* \?\?\?\? 660FBEC8[ 	]+movsx	%al, %cx
-[ 	]*[1-9][0-9]*[ 	]+movsx	%ax, %cx
+[ 	]*[1-9][0-9]* \?\?\?\? 660FBFC8[ 	]+movsx	%ax, %cx
  [ 	]*[1-9][0-9]*[ 	]+movsx	%eax, %cx
  [ 	]*[1-9][0-9]*[ 	]*
  [ 	]*[1-9][0-9]* \?\?\?\? 0FBEC8[ 	]+movsx	%al, %ecx
@@ -18,11 +18,13 @@ 
  [ 	]*[1-9][0-9]*[ 	]+movsxb	%eax, %cl
  [ 	]*[1-9][0-9]*[ 	]*
  [ 	]*[1-9][0-9]* \?\?\?\? 660FBEC8[ 	]+movsxb	%al, %cx
-[ 	]*[1-9][0-9]*[ 	]+movsxb	%ax, %cx
+[ 	]*[1-9][0-9]* \?\?\?\? 660FBEC8[ 	]+movsxb	%ax, %cx
+.* Warning: using `%al' instead of `%ax' due to `b' suffix
  [ 	]*[1-9][0-9]*[ 	]+movsxb	%eax, %cx
  [ 	]*[1-9][0-9]*[ 	]*
  [ 	]*[1-9][0-9]* \?\?\?\? 0FBEC8[ 	]+movsxb	%al, %ecx
-[ 	]*[1-9][0-9]*[ 	]+movsxb	%ax, %ecx
+[ 	]*[1-9][0-9]* \?\?\?\? 0FBEC8[ 	]+movsxb	%ax, %ecx
+.* Warning: using `%al' instead of `%ax' due to `b' suffix
  [ 	]*[1-9][0-9]*[ 	]+movsxb	%eax, %ecx
  [ 	]*[1-9][0-9]*[ 	]*
  [ 	]*[1-9][0-9]*[ 	]+movsxw	%al, %cl
@@ -30,7 +32,7 @@ 
  [ 	]*[1-9][0-9]*[ 	]+movsxw	%eax, %cl
  [ 	]*[1-9][0-9]*[ 	]*
  [ 	]*[1-9][0-9]*[ 	]+movsxw	%al, %cx
-[ 	]*[1-9][0-9]*[ 	]+movsxw	%ax, %cx
+[ 	]*[1-9][0-9]* \?\?\?\? 660FBFC8[ 	]+movsxw	%ax, %cx
  [ 	]*[1-9][0-9]*[ 	]+movsxw	%eax, %cx
  [ 	]*[1-9][0-9]*[ 	]*
  [ 	]*[1-9][0-9]*[ 	]+movsxw	%al, %ecx
@@ -103,7 +105,7 @@ 
  [ 	]*[1-9][0-9]*[ 	]+movzx	%eax, %cl
  [ 	]*[1-9][0-9]*[ 	]*
  [ 	]*[1-9][0-9]* \?\?\?\? 660FB6C8[ 	]+movzx	%al, %cx
-[ 	]*[1-9][0-9]*[ 	]+movzx	%ax, %cx
+[ 	]*[1-9][0-9]* \?\?\?\? 660FB7C8[ 	]+movzx	%ax, %cx
  [ 	]*[1-9][0-9]*[ 	]+movzx	%eax, %cx
  [ 	]*[1-9][0-9]*[ 	]*
  [ 	]*[1-9][0-9]* \?\?\?\? 0FB6C8[ 	]+movzx	%al, %ecx
@@ -115,11 +117,13 @@ 
  [ 	]*[1-9][0-9]*[ 	]+movzxb	%eax, %cl
  [ 	]*[1-9][0-9]*[ 	]*
  [ 	]*[1-9][0-9]* \?\?\?\? 660FB6C8[ 	]+movzxb	%al, %cx
-[ 	]*[1-9][0-9]*[ 	]+movzxb	%ax, %cx
+[ 	]*[1-9][0-9]* \?\?\?\? 660FB6C8[ 	]+movzxb	%ax, %cx
+.* Warning: using `%al' instead of `%ax' due to `b' suffix
  [ 	]*[1-9][0-9]*[ 	]+movzxb	%eax, %cx
  [ 	]*[1-9][0-9]*[ 	]*
  [ 	]*[1-9][0-9]* \?\?\?\? 0FB6C8[ 	]+movzxb	%al, %ecx
-[ 	]*[1-9][0-9]*[ 	]+movzxb	%ax, %ecx
+[ 	]*[1-9][0-9]* \?\?\?\? 0FB6C8[ 	]+movzxb	%ax, %ecx
+.* Warning: using `%al' instead of `%ax' due to `b' suffix
  [ 	]*[1-9][0-9]*[ 	]+movzxb	%eax, %ecx
  [ 	]*[1-9][0-9]*[ 	]*
  [ 	]*[1-9][0-9]*[ 	]+movzxw	%al, %cl
@@ -127,7 +131,7 @@ 
  [ 	]*[1-9][0-9]*[ 	]+movzxw	%eax, %cl
  [ 	]*[1-9][0-9]*[ 	]*
  [ 	]*[1-9][0-9]*[ 	]+movzxw	%al, %cx
-[ 	]*[1-9][0-9]*[ 	]+movzxw	%ax, %cx
+[ 	]*[1-9][0-9]* \?\?\?\? 660FB7C8[ 	]+movzxw	%ax, %cx
  [ 	]*[1-9][0-9]*[ 	]+movzxw	%eax, %cx
  [ 	]*[1-9][0-9]*[ 	]*
  [ 	]*[1-9][0-9]*[ 	]+movzxw	%al, %ecx
@@ -154,7 +158,8 @@ 
  [ 	]*[1-9][0-9]*[ 	]+movzbw	%ax, %cx
  [ 	]*[1-9][0-9]*[ 	]+movzbw	%eax, %cx
  [ 	]*[1-9][0-9]*[ 	]*
-[ 	]*[1-9][0-9]* \?\?\?\? 0FB6C8[ 	]+movzbw	%al, %ecx
+[ 	]*[1-9][0-9]* \?\?\?\? 660FB6C8[ 	]+movzbw	%al, %ecx
+.* Warning: using `%cx' instead of `%ecx' due to `w' suffix
  [ 	]*[1-9][0-9]*[ 	]+movzbw	%ax, %ecx
  [ 	]*[1-9][0-9]*[ 	]+movzbw	%eax, %ecx
  [ 	]*[1-9][0-9]*[ 	]*
@@ -162,7 +167,8 @@ 
  [ 	]*[1-9][0-9]*[ 	]+movzbl	%ax, %cl
  [ 	]*[1-9][0-9]*[ 	]+movzbl	%eax, %cl
  [ 	]*[1-9][0-9]*[ 	]*
-[ 	]*[1-9][0-9]* \?\?\?\? 660FB6C8[ 	]+movzbl	%al, %cx
+[ 	]*[1-9][0-9]* \?\?\?\? 0FB6C8[ 	]+movzbl	%al, %cx
+.* Warning: using `%ecx' instead of `%cx' due to `l' suffix
  [ 	]*[1-9][0-9]*[ 	]+movzbl	%ax, %cx
  [ 	]*[1-9][0-9]*[ 	]+movzbl	%eax, %cx
  [ 	]*[1-9][0-9]*[ 	]*
--- a/gas/testsuite/gas/i386/movx64.l
+++ b/gas/testsuite/gas/i386/movx64.l
@@ -7,13 +7,13 @@ 
  [ 	]*[1-9][0-9]*[ 	]+movsx	%rax, %cl
  [ 	]*[1-9][0-9]*[ 	]*
  [ 	]*[1-9][0-9]* \?\?\?\? 660FBEC8[ 	]+movsx	%al, %cx
-[ 	]*[1-9][0-9]*[ 	]+movsx	%ax, %cx
+[ 	]*[1-9][0-9]* \?\?\?\? 660FBFC8[ 	]+movsx	%ax, %cx
  [ 	]*[1-9][0-9]*[ 	]+movsx	%eax, %cx
  [ 	]*[1-9][0-9]*[ 	]+movsx	%rax, %cx
  [ 	]*[1-9][0-9]*[ 	]*
  [ 	]*[1-9][0-9]* \?\?\?\? 0FBEC8[ 	]+movsx	%al, %ecx
  [ 	]*[1-9][0-9]* \?\?\?\? 0FBFC8[ 	]+movsx	%ax, %ecx
-[ 	]*[1-9][0-9]*[ 	]+movsx	%eax, %ecx
+[ 	]*[1-9][0-9]* \?\?\?\? 63C8[ 	]+movsx	%eax, %ecx
  [ 	]*[1-9][0-9]*[ 	]+movsx	%rax, %ecx
  [ 	]*[1-9][0-9]*[ 	]*
  [ 	]*[1-9][0-9]* \?\?\?\? 480FBEC8[ 	]+movsx	%al, %rcx
@@ -47,7 +47,7 @@ 
  [ 	]*[1-9][0-9]*[ 	]+movsxw	%rax, %cl
  [ 	]*[1-9][0-9]*[ 	]*
  [ 	]*[1-9][0-9]*[ 	]+movsxw	%al, %cx
-[ 	]*[1-9][0-9]*[ 	]+movsxw	%ax, %cx
+[ 	]*[1-9][0-9]* \?\?\?\? 660FBFC8[ 	]+movsxw	%ax, %cx
  [ 	]*[1-9][0-9]*[ 	]+movsxw	%eax, %cx
  [ 	]*[1-9][0-9]*[ 	]+movsxw	%rax, %cx
  [ 	]*[1-9][0-9]*[ 	]*
@@ -73,7 +73,7 @@ 
  [ 	]*[1-9][0-9]*[ 	]*
  [ 	]*[1-9][0-9]*[ 	]+movsxl	%al, %ecx
  [ 	]*[1-9][0-9]*[ 	]+movsxl	%ax, %ecx
-[ 	]*[1-9][0-9]*[ 	]+movsxl	%eax, %ecx
+[ 	]*[1-9][0-9]* \?\?\?\? 63C8[ 	]+movsxl	%eax, %ecx
  [ 	]*[1-9][0-9]*[ 	]+movsxl	%rax, %ecx
  [ 	]*[1-9][0-9]*[ 	]*
  [ 	]*[1-9][0-9]*[ 	]+movsxl	%al, %rcx
@@ -93,7 +93,7 @@ 
  [ 	]*[1-9][0-9]*[ 	]*
  [ 	]*[1-9][0-9]*[ 	]+movsxd	%al, %ecx
  [ 	]*[1-9][0-9]*[ 	]+movsxd	%ax, %ecx
-[ 	]*[1-9][0-9]*[ 	]+movsxd	%eax, %ecx
+[ 	]*[1-9][0-9]* \?\?\?\? 63C8[ 	]+movsxd	%eax, %ecx
  [ 	]*[1-9][0-9]*[ 	]+movsxd	%rax, %ecx
  [ 	]*[1-9][0-9]*[ 	]*
  [ 	]*[1-9][0-9]*[ 	]+movsxd	%al, %rcx
@@ -248,7 +248,7 @@ 
  [ 	]*[1-9][0-9]*[ 	]+movzx	%rax, %cl
  [ 	]*[1-9][0-9]*[ 	]*
  [ 	]*[1-9][0-9]* \?\?\?\? 660FB6C8[ 	]+movzx	%al, %cx
-[ 	]*[1-9][0-9]*[ 	]+movzx	%ax, %cx
+[ 	]*[1-9][0-9]* \?\?\?\? 660FB7C8[ 	]+movzx	%ax, %cx
  [ 	]*[1-9][0-9]*[ 	]+movzx	%eax, %cx
  [ 	]*[1-9][0-9]*[ 	]+movzx	%rax, %cx
  [ 	]*[1-9][0-9]*[ 	]*
@@ -288,7 +288,7 @@ 
  [ 	]*[1-9][0-9]*[ 	]+movzxw	%rax, %cl
  [ 	]*[1-9][0-9]*[ 	]*
  [ 	]*[1-9][0-9]*[ 	]+movzxw	%al, %cx
-[ 	]*[1-9][0-9]*[ 	]+movzxw	%ax, %cx
+[ 	]*[1-9][0-9]* \?\?\?\? 660FB7C8[ 	]+movzxw	%ax, %cx
  [ 	]*[1-9][0-9]*[ 	]+movzxw	%eax, %cx
  [ 	]*[1-9][0-9]*[ 	]+movzxw	%rax, %cx
  [ 	]*[1-9][0-9]*[ 	]*
@@ -372,12 +372,12 @@ 
  [ 	]*[1-9][0-9]*[ 	]+movzbw	%eax, %cx
  [ 	]*[1-9][0-9]*[ 	]+movzbw	%rax, %cx
  [ 	]*[1-9][0-9]*[ 	]*
-[ 	]*[1-9][0-9]* \?\?\?\? 0FB6C8[ 	]+movzbw	%al, %ecx
+[ 	]*[1-9][0-9]*[ 	]+movzbw	%al, %ecx
  [ 	]*[1-9][0-9]*[ 	]+movzbw	%ax, %ecx
  [ 	]*[1-9][0-9]*[ 	]+movzbw	%eax, %ecx
  [ 	]*[1-9][0-9]*[ 	]+movzbw	%rax, %ecx
  [ 	]*[1-9][0-9]*[ 	]*
-[ 	]*[1-9][0-9]* \?\?\?\? 480FB6C8[ 	]+movzbw	%al, %rcx
+[ 	]*[1-9][0-9]*[ 	]+movzbw	%al, %rcx
  [ 	]*[1-9][0-9]*[ 	]+movzbw	%ax, %rcx
  [ 	]*[1-9][0-9]*[ 	]+movzbw	%eax, %rcx
  [ 	]*[1-9][0-9]*[ 	]+movzbw	%rax, %rcx
@@ -387,7 +387,7 @@ 
  [ 	]*[1-9][0-9]*[ 	]+movzbl	%eax, %cl
  [ 	]*[1-9][0-9]*[ 	]+movzbl	%rax, %cl
  [ 	]*[1-9][0-9]*[ 	]*
-[ 	]*[1-9][0-9]* \?\?\?\? 660FB6C8[ 	]+movzbl	%al, %cx
+[ 	]*[1-9][0-9]*[ 	]+movzbl	%al, %cx
  [ 	]*[1-9][0-9]*[ 	]+movzbl	%ax, %cx
  [ 	]*[1-9][0-9]*[ 	]+movzbl	%eax, %cx
  [ 	]*[1-9][0-9]*[ 	]+movzbl	%rax, %cx
@@ -397,7 +397,7 @@ 
  [ 	]*[1-9][0-9]*[ 	]+movzbl	%eax, %ecx
  [ 	]*[1-9][0-9]*[ 	]+movzbl	%rax, %ecx
  [ 	]*[1-9][0-9]*[ 	]*
-[ 	]*[1-9][0-9]* \?\?\?\? 480FB6C8[ 	]+movzbl	%al, %rcx
+[ 	]*[1-9][0-9]*[ 	]+movzbl	%al, %rcx
  [ 	]*[1-9][0-9]*[ 	]+movzbl	%ax, %rcx
  [ 	]*[1-9][0-9]*[ 	]+movzbl	%eax, %rcx
  [ 	]*[1-9][0-9]*[ 	]+movzbl	%rax, %rcx
@@ -407,12 +407,12 @@ 
  [ 	]*[1-9][0-9]*[ 	]+movzbq	%eax, %cl
  [ 	]*[1-9][0-9]*[ 	]+movzbq	%rax, %cl
  [ 	]*[1-9][0-9]*[ 	]*
-[ 	]*[1-9][0-9]* \?\?\?\? 660FB6C8[ 	]+movzbq	%al, %cx
+[ 	]*[1-9][0-9]*[ 	]+movzbq	%al, %cx
  [ 	]*[1-9][0-9]*[ 	]+movzbq	%ax, %cx
  [ 	]*[1-9][0-9]*[ 	]+movzbq	%eax, %cx
  [ 	]*[1-9][0-9]*[ 	]+movzbq	%rax, %cx
  [ 	]*[1-9][0-9]*[ 	]*
-[ 	]*[1-9][0-9]* \?\?\?\? 0FB6C8[ 	]+movzbq	%al, %ecx
+[ 	]*[1-9][0-9]*[ 	]+movzbq	%al, %ecx
  [ 	]*[1-9][0-9]*[ 	]+movzbq	%ax, %ecx
  [ 	]*[1-9][0-9]*[ 	]+movzbq	%eax, %ecx
  [ 	]*[1-9][0-9]*[ 	]+movzbq	%rax, %ecx
@@ -458,7 +458,7 @@ 
  [ 	]*[1-9][0-9]*[ 	]+movzwl	%rax, %ecx
  [ 	]*[1-9][0-9]*[ 	]*
  [ 	]*[1-9][0-9]*[ 	]+movzwl	%al, %rcx
-[ 	]*[1-9][0-9]* \?\?\?\? 480FB7C8[ 	]+movzwl	%ax, %rcx
+[ 	]*[1-9][0-9]*[ 	]+movzwl	%ax, %rcx
  [ 	]*[1-9][0-9]*[ 	]+movzwl	%eax, %rcx
  [ 	]*[1-9][0-9]*[ 	]+movzwl	%rax, %rcx
  [ 	]*[1-9][0-9]*[ 	]*
@@ -473,7 +473,7 @@ 
  [ 	]*[1-9][0-9]*[ 	]+movzwq	%rax, %cx
  [ 	]*[1-9][0-9]*[ 	]*
  [ 	]*[1-9][0-9]*[ 	]+movzwq	%al, %ecx
-[ 	]*[1-9][0-9]* \?\?\?\? 0FB7C8[ 	]+movzwq	%ax, %ecx
+[ 	]*[1-9][0-9]*[ 	]+movzwq	%ax, %ecx
  [ 	]*[1-9][0-9]*[ 	]+movzwq	%eax, %ecx
  [ 	]*[1-9][0-9]*[ 	]+movzwq	%rax, %ecx
  [ 	]*[1-9][0-9]*[ 	]*
--- a/gas/testsuite/gas/i386/noreg16.l
+++ b/gas/testsuite/gas/i386/noreg16.l
@@ -54,6 +54,8 @@ 
  .*:[1-9][0-9]*: Warning: .* `mov'
  .*:[1-9][0-9]*: Warning: .* `movs'
  .*:[1-9][0-9]*: Warning: .* `movs'
+.*:[1-9][0-9]*: Warning: .* `movsx'
+.*:[1-9][0-9]*: Warning: .* `movzx'
  .*:[1-9][0-9]*: Warning: .* `mul'
  .*:[1-9][0-9]*: Warning: .* `neg'
  .*:[1-9][0-9]*: Warning: .* `not'
--- a/gas/testsuite/gas/i386/noreg32.l
+++ b/gas/testsuite/gas/i386/noreg32.l
@@ -59,6 +59,8 @@ 
  .*:[1-9][0-9]*: Warning: .* `mov'
  .*:[1-9][0-9]*: Warning: .* `movs'
  .*:[1-9][0-9]*: Warning: .* `movs'
+.*:[1-9][0-9]*: Warning: .* `movsx'
+.*:[1-9][0-9]*: Warning: .* `movzx'
  .*:[1-9][0-9]*: Warning: .* `mul'
  .*:[1-9][0-9]*: Warning: .* `neg'
  .*:[1-9][0-9]*: Warning: .* `not'
--- a/gas/testsuite/gas/i386/noreg64.l
+++ b/gas/testsuite/gas/i386/noreg64.l
@@ -62,6 +62,10 @@ 
  .*:[1-9][0-9]*: Warning: .* `mov'
  .*:[1-9][0-9]*: Warning: .* `movs'
  .*:[1-9][0-9]*: Warning: .* `movs'
+.*:[1-9][0-9]*: Warning: .* `movsx'
+.*:[1-9][0-9]*: Warning: .* `movsx'
+.*:[1-9][0-9]*: Warning: .* `movzx'
+.*:[1-9][0-9]*: Warning: .* `movzx'
  .*:[1-9][0-9]*: Warning: .* `mul'
  .*:[1-9][0-9]*: Warning: .* `neg'
  .*:[1-9][0-9]*: Warning: .* `not'
--- a/opcodes/i386-opc.tbl
+++ b/opcodes/i386-opc.tbl
@@ -93,23 +93,16 @@  movsbq, 2, 0xfbe, None, 2, Cpu64, Modrm|
  movswq, 2, 0xfbf, None, 2, Cpu64, Modrm|No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_qSuf|No_ldSuf|Rex64, { Reg16|Word|Unspecified|BaseIndex, Reg64 }
  movslq, 2, 0x63, None, 1, Cpu64, Modrm|No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_qSuf|No_ldSuf|Rex64, { Reg32|Dword|Unspecified|BaseIndex, Reg64 }
  // Intel Syntax next 3 insns
-movsx, 2, 0xfbe, None, 2, Cpu386, Modrm|No_wSuf|No_lSuf|No_sSuf|No_qSuf|No_ldSuf|ATTSyntax, { Reg8|Unspecified|BaseIndex, Reg16|Reg32|Reg64 }
-movsx, 2, 0xfbf, None, 2, Cpu386, Modrm|No_bSuf|No_lSuf|No_sSuf|No_qSuf|No_ldSuf|ATTSyntax, { Reg16|Unspecified|BaseIndex, Reg32|Reg64 }
-movsx, 2, 0x63, None, 1, Cpu64, Modrm|No_bSuf|No_wSuf|No_sSuf|No_qSuf|No_ldSuf|Rex64|ATTSyntax, { Reg32|Unspecified|BaseIndex, Reg64 }
-movsx, 2, 0xfbe, None, 2, Cpu386, Modrm|No_wSuf|No_lSuf|No_sSuf|No_qSuf|No_ldSuf|IntelSyntax, { Reg8|Byte|BaseIndex, Reg16|Reg32|Reg64 }
-movsx, 2, 0xfbf, None, 2, Cpu386, Modrm|No_bSuf|No_lSuf|No_sSuf|No_qSuf|No_ldSuf|IntelSyntax, { Reg16|Word|BaseIndex, Reg32|Reg64 }
-movsx, 2, 0x63, None, 1, Cpu64, Modrm|No_bSuf|No_wSuf|No_sSuf|No_qSuf|No_ldSuf|Rex64|IntelSyntax, { Reg32|Dword|BaseIndex, Reg64 }
-movsxd, 2, 0x63, None, 1, Cpu64, Modrm|No_bSuf|No_wSuf|No_sSuf|No_qSuf|No_ldSuf|Rex64, { Reg32|Dword|Unspecified|BaseIndex, Reg64 }
+movsx, 2, 0xfbe, None, 2, Cpu386, W|Modrm|No_lSuf|No_sSuf|No_qSuf|No_ldSuf, { Reg8|Reg16|Unspecified|BaseIndex, Reg16|Reg32|Reg64 }
+movsx, 2, 0x63, None, 1, Cpu64, Modrm|No_bSuf|No_wSuf|No_sSuf|No_qSuf|No_ldSuf, { Reg32|Unspecified|BaseIndex, Reg32|Reg64 }
+movsxd, 2, 0x63, None, 1, Cpu64, Modrm|No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_qSuf|No_ldSuf, { Reg32|Dword|Unspecified|BaseIndex, Reg32|Reg64 }
  
  // Move with zero extend.
  movzb, 2, 0xfb6, None, 2, Cpu386, Modrm|No_bSuf|No_sSuf|No_ldSuf, { Reg8|Byte|Unspecified|BaseIndex, Reg16|Reg32|Reg64 }
  movzw, 2, 0xfb7, None, 2, Cpu386, Modrm|No_bSuf|No_wSuf|No_sSuf|No_ldSuf, { Reg16|Word|Unspecified|BaseIndex, Reg32|Reg64 }
-// Intel Syntax next 2 insns (the 64-bit variants are not particulary
+// Intel Syntax next insn (the 64-bit variant is not particulary
  // useful since the zero extend 32->64 is implicit, but we can encode them).
-movzx, 2, 0xfb6, None, 2, Cpu386, Modrm|No_wSuf|No_lSuf|No_sSuf|No_qSuf|No_ldSuf|ATTSyntax, { Reg8|Unspecified|BaseIndex, Reg16|Reg32|Reg64 }
-movzx, 2, 0xfb7, None, 2, Cpu386, Modrm|No_bSuf|No_lSuf|No_sSuf|No_qSuf|No_ldSuf|ATTSyntax, { Reg16|Unspecified|BaseIndex, Reg32|Reg64 }
-movzx, 2, 0xfb6, None, 2, Cpu386, Modrm|No_wSuf|No_lSuf|No_sSuf|No_qSuf|No_ldSuf|IntelSyntax, { Reg8|Byte|BaseIndex, Reg16|Reg32|Reg64 }
-movzx, 2, 0xfb7, None, 2, Cpu386, Modrm|No_bSuf|No_lSuf|No_sSuf|No_qSuf|No_ldSuf|IntelSyntax, { Reg16|Word|BaseIndex, Reg32|Reg64 }
+movzx, 2, 0xfb6, None, 2, Cpu386, W|Modrm|No_lSuf|No_sSuf|No_qSuf|No_ldSuf, { Reg8|Reg16|Unspecified|BaseIndex, Reg16|Reg32|Reg64 }
  
  // Push instructions.
  push, 1, 0x50, None, 1, CpuNo64, ShortForm|DefaultSize|No_bSuf|No_sSuf|No_qSuf|No_ldSuf, { Reg16|Reg32 }