x86: Remove movsx/movzx with 16/32-bit memory operand from AT&T syntax

Message ID 20200212031924.GA2551231@gmail.com
State New
Headers show
Series
  • x86: Remove movsx/movzx with 16/32-bit memory operand from AT&T syntax
Related show

Commit Message

H.J. Lu Feb. 12, 2020, 3:19 a.m.
On Tue, Feb 11, 2020 at 03:51:29PM -0800, H.J. Lu wrote:
> On Tue, Feb 11, 2020 at 3:34 PM H.J. Lu <hjl.tools@gmail.com> wrote:

> >

> > On Tue, Feb 11, 2020 at 12:11 PM H.J. Lu <hjl.tools@gmail.com> wrote:

> > >

> > > On Tue, Feb 11, 2020 at 9:04 AM H.J. Lu <hjl.tools@gmail.com> wrote:

> > > >

> > > > On Tue, Feb 11, 2020 at 8:45 AM Jan Beulich <jbeulich@suse.com> wrote:

> > > > >

> > > > > On 11.02.2020 14:07, H.J. Lu wrote:

> > > > > > On Tue, Feb 11, 2020 at 5:04 AM Jan Beulich <jbeulich@suse.com> wrote:

> > > > > >>

> > > > > >> On 11.02.2020 14:01, H.J. Lu wrote:

> > > > > >>> On Tue, Feb 11, 2020 at 4:58 AM Jan Beulich <jbeulich@suse.com> wrote:

> > > > > >>>>

> > > > > >>>> On 11.02.2020 13:19, H.J. Lu wrote:

> > > > > >>>>> On Tue, Feb 11, 2020 at 3:55 AM Jan Beulich <jbeulich@suse.com> wrote:

> > > > > >>>>>>

> > > > > >>>>>> On 11.02.2020 12:42, H.J. Lu wrote:

> > > > > >>>>>>> On Tue, Feb 11, 2020 at 2:25 AM Jan Beulich <jbeulich@suse.com> wrote:

> > > > > >>>>>>>>

> > > > > >>>>>>>> Some encodings are about to gain a warning - move them from test cases

> > > > > >>>>>>>> not expecting any diagnostics to the new, dedicated ones, to allow

> > > > > >>>>>>>> better focus on the actual changes in the subsequent patch.

> > > > > >>>>>>>>

> > > > > >>>>>>>> The new tests added have some wrong expectations right now, which will

> > > > > >>>>>>>> be corrected by the next patch. The test is being added here to make

> > > > > >>>>>>>> more visible which cases actually were wrong (and hence get changed),

> > > > > >>>>>>>> besides demonstrating that in the vast majority of cases the subsequent

> > > > > >>>>>>>> change doesn't alter generated code.

> > > > > >>>>>>>>

> > > > > >>>>>>>> gas/

> > > > > >>>>>>>> 2020-02-XX  Jan Beulich  <jbeulich@suse.com>

> > > > > >>>>>>>>

> > > > > >>>>>>>>         * testsuite/gas/i386/i386.s, testsuite/gas/i386/iamcu-1.s,

> > > > > >>>>>>>>         testsuite/gas/i386/ilp32/x86-64.s: Move ambiguous operand size

> > > > > >>>>>>>>         tests ...

> > > > > >>>>>>>>         * testsuite/gas/i386/noreg16.s, testsuite/gas/i386/noreg32.s,

> > > > > >>>>>>>>         testsuite/gas/i386/noreg64.s, testsuite/gas/i386/x86_64.s: ...

> > > > > >>>>>>>>         here.

> > > > > >>>>>>>>         * testsuite/gas/i386/i386.d, testsuite/gas/i386/i386-intel.d

> > > > > >>>>>>>>         testsuite/gas/i386/iamcu-1.d, testsuite/gas/i386/ilp32/x86-64.d,

> > > > > >>>>>>>>         testsuite/gas/i386/k1om.d, testsuite/gas/i386/l1om.d,

> > > > > >>>>>>>>         testsuite/gas/i386/noreg16.d, testsuite/gas/i386/noreg32.d,

> > > > > >>>>>>>>         testsuite/gas/i386/noreg64.d, testsuite/gas/i386/x86_64-intel.d,

> > > > > >>>>>>>>         testsuite/gas/i386/x86_64.d: Adjust expectations.

> > > > > >>>>>>>>         * testsuite/gas/i386/movx16.s, testsuite/gas/i386/movx16.l,

> > > > > >>>>>>>>         testsuite/gas/i386/movx32.s, testsuite/gas/i386/movx32.l,

> > > > > >>>>>>>>         testsuite/gas/i386/movx64.s, testsuite/gas/i386/movx64.l: New.

> > > > > >>>>>>>>         * testsuite/gas/i386/i386.exp: Run new tests.

> > > > > >>>>>>>

> > > > > >>>>>>> Please make a separate patch to address MOVSX/MOVZX.

> > > > > >>>>>>

> > > > > >>>>>> I don't understand what you mean here. This patch simply documents the

> > > > > >>>>>> status quo, to make it (much) easier to see what the next patch

> > > > > >>>>>> actually adjusts. It doesn't "address" anything. If, for the purpose

> > > > > >>>>>> of committing, you'd like to see both patches folded - fine by me. But

> > > > > >>>>>> only then, not any earlier.

> > > > > >>>>>>

> > > > > >>>>>>>  MOVSX and MOVZX

> > > > > >>>>>>> should take no suffixes.  AT&T syntax is supported if there is no

> > > > > >>>>>>> ambiguity.  AT&T

> > > > > >>>>>>> syntax also supports movsXY and movzXY.

> > > > > >>>>>>

> > > > > >>>>>> Please could you clarify what specifically you'd like to see changed,

> > > > > >>>>>> at the very least by pointing out one case each where you think I'm

> > > > > >>>>>> moving in the wrong direction (presumably in the next patch really)?

> > > > > >>>>>> I'm afraid your response isn't such that I can derive from it what

> > > > > >>>>>> exactly you want.

> > > > > >>>>>

> > > > > >>>>> We support

> > > > > >>>>>

> > > > > >>>>> movsx %ax, %ecx

> > > > > >>>>> movzx %ax, %ecx

> > > > > >>>>> movswl %ax, %ecx

> > > > > >>>>> movzwl %ax, %ecx

> > > > > >>>>>

> > > > > >>>>> We disallow

> > > > > >>>>>

> > > > > >>>>> movsxw %ax, %ecx

> > > > > >>>>> movzxw %ax, %ecx

> > > > > >>>>

> > > > > >>>> We don't (as this patch demonstrates, along with pre-existing tests,

> > > > > >>>> unless you mean once again to have an inconsistency between insns

> > > > > >>>> with all register operands and similar ones with e memory source),

> > > > > >>>> and if you want it to be this way, then please do so yourself, but

> > > > > >>>

> > > > > >>> I will do it.

> > > > > >>>

> > > > > >>>> please also only on top of my changes, so I won't need to re-base

> > > > > >>>

> > > > > >>> Which changes of yours are you referring to?

> > > > > >>

> > > > > >> This patch and the subsequent one.

> > > > > >>

> > > > > >

> > > > > > Both changes won't be necessary after my changes.

> > > > >

> > > > > I'm confused. What you want to deal with is - afaict - orthogonal to

> > > > > what the next patch in the series here does.

> > > > >

> > > >

> > > > You will see what I mean when I post my patch for review.

> > > >

> > >

> > > AT&T syntax requires suffix to specify memory operand size.  Since

> > > movsx and movzx can have different memory operand sizes with the same

> > > destination register, this patch removes movsx and movzx with memory

> > > operand from AT&T syntax.  Since AT&T syntax uses different mnemonics

> > > for movsx and movzx, this change should have little impact on assembly

> > > sources.  Tested with Linux kernel 5.5.3 for x86-64 and glibc 2.31 for

> > > i686 and x86-64.

> > >

> >

> > Updated patch to add more testcases and allow register operand with

> > mov[sz]x[bwl].

> >

> 

> I found usage of

> 

> movzx 4(%edx), %eax

> 

> We also need to support:

> 

> movsx 4(%edx), %eax

> 

> I will update my patch.

> 

> -- 

> H.J.


Here is the updated patch.

H.J.
---
AT&T syntax requires suffix to specify memory operand size.  Since
movsx and movzx can have different memory operand sizes with the same
destination register, this patch removes movsx and movzx with 16/32-bit
memory operand from AT&T syntax.  Now movzx and movsx with incorrect
suffix and register are error in AT&T syntax.

gas/

	PR gas/25438
	* config/tc-i386.c (md_assemble): Zap i.suffix with movzx and
	movsx only for the 'b' suffix or Intel syntax.
	(check_word_reg): Issue an error, not a warning, for incorrect
	suffix and register for movzx and movsx.
	* doc/c-i386.texi: Document movsx, movsxd and movzx for AT&T
	syntax.
	* testsuite/gas/i386/i386-intel.d: Updated.
	* testsuite/gas/i386/i386.d: Likewise.
	* testsuite/gas/i386/iamcu-1.d: Likewise.
	* testsuite/gas/i386/ilp32/x86-64.d: Likewise.
	* testsuite/gas/i386/k1om.d: Likewise.
	* testsuite/gas/i386/l1om.d: Likewise.
	* testsuite/gas/i386/x86_64-intel.d: Likewise.
	* testsuite/gas/i386/x86_64.d: Likewise.
	* testsuite/gas/i386/i386.exp: Run movszx-inval and
	x86-64-movszx-inval.
	* testsuite/gas/i386/i386.s: Add movsxb, movsxw, movsxl, movzxb,
	and movzxw tests with register operand in AT&T syntax.
	* testsuite/gas/i386/iamcu-1.s: Likewise.
	* testsuite/gas/i386/x86_64.s: Likewise.
	* testsuite/gas/i386/ilp32/x86-64.s: Likewise.
	* testsuite/gas/i386/movszx-inval.l: New file.
	* testsuite/gas/i386/movszx-inval.s: Likewise.
	* testsuite/gas/i386/x86-64-movszx-inval.l: Likewise.
	* testsuite/gas/i386/x86-64-movszx-inval.s: Likewise.

opcodes/

	PR gas/25438
	* i386-opc.tbl: Remove movsx and movzx with 16/32-bit memory
	operand from AT&T syntax.  Don't allow suffix with movsx nor
	movzx, except for 8-bit operand in AT&T syntax.  Add movsxw,
	movsxl, movzxw for AT&T syntax.
	* i386-tbl.h: Regenerated.
---
 gas/config/tc-i386.c                         | 10 ++-
 gas/doc/c-i386.texi                          | 43 ++++++++++
 gas/testsuite/gas/i386/i386-intel.d          |  6 ++
 gas/testsuite/gas/i386/i386.d                |  6 ++
 gas/testsuite/gas/i386/i386.exp              |  2 +
 gas/testsuite/gas/i386/i386.s                |  6 ++
 gas/testsuite/gas/i386/iamcu-1.d             |  6 ++
 gas/testsuite/gas/i386/iamcu-1.s             |  6 ++
 gas/testsuite/gas/i386/ilp32/x86-64.d        | 11 +++
 gas/testsuite/gas/i386/ilp32/x86-64.s        | 11 +++
 gas/testsuite/gas/i386/k1om.d                | 11 +++
 gas/testsuite/gas/i386/l1om.d                | 11 +++
 gas/testsuite/gas/i386/movszx-inval.l        | 66 +++++++++++++++
 gas/testsuite/gas/i386/movszx-inval.s        | 33 ++++++++
 gas/testsuite/gas/i386/x86-64-movszx-inval.l | 86 ++++++++++++++++++++
 gas/testsuite/gas/i386/x86-64-movszx-inval.s | 43 ++++++++++
 gas/testsuite/gas/i386/x86_64-intel.d        | 11 +++
 gas/testsuite/gas/i386/x86_64.d              | 11 +++
 gas/testsuite/gas/i386/x86_64.s              | 11 +++
 opcodes/i386-opc.tbl                         | 23 +++---
 opcodes/i386-tbl.h                           | 72 ++++++++++++----
 21 files changed, 457 insertions(+), 28 deletions(-)
 create mode 100644 gas/testsuite/gas/i386/movszx-inval.l
 create mode 100644 gas/testsuite/gas/i386/movszx-inval.s
 create mode 100644 gas/testsuite/gas/i386/x86-64-movszx-inval.l
 create mode 100644 gas/testsuite/gas/i386/x86-64-movszx-inval.s

Comments

Jan Beulich Feb. 12, 2020, 9:19 a.m. | #1
On 12.02.2020 04:19, H.J. Lu wrote:
> AT&T syntax requires suffix to specify memory operand size.  Since

> movsx and movzx can have different memory operand sizes with the same

> destination register, this patch removes movsx and movzx with 16/32-bit

> memory operand from AT&T syntax.  Now movzx and movsx with incorrect

> suffix and register are error in AT&T syntax.


Before we discuss this patch in detail, I think we need to come
to an agreement what is and what is not meant to be permitted.
My position of this is shown by the final shape of the new
tests that the series at the root of this thread first adds and
then adjusts. It was for this very reason why I had asked that
you please point out specifically against the two patches you
put under question what you think is wrong once those patches
would be in place.

What you say above makes no sense to me at all: Why would you
remove support for something that's supposed to work?

You know my underlying thinking - things should be as
consistent as possible. What you do here moves us farther
away from consistency. This is demonstrated by both increasing
the number of templates (whereas my proposed patch shrinks
them) as well as ...

> --- a/gas/config/tc-i386.c

> +++ b/gas/config/tc-i386.c

> @@ -4395,7 +4395,9 @@ md_assemble (char *line)

>  	  && intel_syntax)

>  	as_bad (_("ambiguous operand size for `%s'"), i.tm.name);

>  

> -      i.suffix = 0;

> +      /* movzx and movsx only allow the 'b' suffix in AT&T syntax.  */

> +      if (i.suffix == BYTE_MNEM_SUFFIX || intel_syntax)

> +	i.suffix = 0;

>      }


... a change like this. Recall that mine does away with this
rather arbitrary check here altogether, putting in place
less arbitrary (imo) checks/adjustments elsewhere instead?

While secondary, I also get the impression that, other than
my patch again, and in contrast to the adjustments recently
done for MOVSXD, the (not very useful) form having 16-bit
source and destination doesn't get supported by this change.
Which underlines what I've said initially: There first of
all needs to be a clear (and consistent) picture of what is
or is not supposed to work.

Jan

Patch

diff --git a/gas/config/tc-i386.c b/gas/config/tc-i386.c
index fec132ab760..69c05561ed1 100644
--- a/gas/config/tc-i386.c
+++ b/gas/config/tc-i386.c
@@ -4395,7 +4395,9 @@  md_assemble (char *line)
 	  && intel_syntax)
 	as_bad (_("ambiguous operand size for `%s'"), i.tm.name);
 
-      i.suffix = 0;
+      /* movzx and movsx only allow the 'b' suffix in AT&T syntax.  */
+      if (i.suffix == BYTE_MNEM_SUFFIX || intel_syntax)
+	i.suffix = 0;
     }
 
   if (i.tm.opcode_modifier.fwait)
@@ -6826,8 +6828,10 @@  check_word_reg (void)
 	     && i.tm.operand_types[op].bitfield.word)
       {
 	/* Prohibit these changes in the 64bit mode, since the
-	   lowering is more complicated.  */
-	if (flag_code == CODE_64BIT)
+	   lowering is more complicated.  FIXME: This should be
+	   an error for all.  */
+	if (flag_code == CODE_64BIT
+	    || (i.tm.base_opcode & ~9) == 0x0fb6)
 	  {
 	    as_bad (_("incorrect register `%s%s' used with `%c' suffix"),
 		    register_prefix, i.op[op].regs->reg_name,
diff --git a/gas/doc/c-i386.texi b/gas/doc/c-i386.texi
index f0189ccb443..9682a48d074 100644
--- a/gas/doc/c-i386.texi
+++ b/gas/doc/c-i386.texi
@@ -835,6 +835,49 @@  are called @samp{cbtw}, @samp{cwtl}, @samp{cwtd}, @samp{cltd}, @samp{cltq}, and
 @samp{cqto} in AT&T naming.  @code{@value{AS}} accepts either naming for these
 instructions.
 
+@cindex extension instructions, i386
+@cindex i386 extension instructions
+@cindex extension instructions, x86-64
+@cindex x86-64 extension instructions
+The Intel-syntax extension instructions
+
+@itemize @bullet
+@item
+@samp{movsx} --- sign-extend @samp{reg8/mem8} to @samp{reg16}.
+
+@samp{movsx} --- sign-extend @samp{reg8/mem8} to @samp{reg32}.
+
+@samp{movsx} --- sign-extend @samp{reg8/mem8} to @samp{reg64}
+(x86-64 only).
+
+@samp{movsx} --- sign-extend @samp{reg16/mem16} to @samp{reg32}
+
+@samp{movsx} --- sign-extend @samp{reg16/mem16} to @samp{reg64}
+(x86-64 only).
+
+@samp{movsxd} --- sign-extend @samp{reg32/mem32} to @samp{reg64}
+(x86-64 only).
+
+@samp{movzx} --- zero-extend @samp{reg8/mem8} to @samp{reg16}.
+
+@samp{movzx} --- zero-extend @samp{reg8/mem8} to @samp{reg32}.
+
+@samp{movzx} --- zero-extend @samp{reg8/mem8} to @samp{reg64}
+(x86-64 only).
+
+@samp{movzx} --- zero-extend @samp{reg16/mem16} to @samp{reg32}
+
+@samp{movzx} --- zero-extend @samp{reg16/mem16} to @samp{reg64}
+(x86-64 only).
+@end itemize
+
+@noindent
+are called @samp{movsbw/movsxb/movsx}, @samp{movsbl/movsxb/movsx},
+@samp{movsbq/movsb/movsx}, @samp{movswl/movsxw}, @samp{movswq/movsxw},
+@samp{movslq/movsxl}, @samp{movzbw/movzxb/movzx},
+@samp{movzbl/movzxb/movzx}, @samp{movzbq/movzxb/movzx},
+@samp{movzwl/movzxw} and @samp{movzwq/movzxw} in AT&T syntax.
+
 @cindex jump instructions, i386
 @cindex call instructions, i386
 @cindex jump instructions, x86-64
diff --git a/gas/testsuite/gas/i386/i386-intel.d b/gas/testsuite/gas/i386/i386-intel.d
index 1913e8da191..27fc83062a1 100644
--- a/gas/testsuite/gas/i386/i386-intel.d
+++ b/gas/testsuite/gas/i386/i386-intel.d
@@ -14,6 +14,9 @@  Disassembly of section .text:
 [ 	]*[a-f0-9]+:	66 0f be f0          	movsx  si,al
 [ 	]*[a-f0-9]+:	0f be f0             	movsx  esi,al
 [ 	]*[a-f0-9]+:	0f bf f0             	movsx  esi,ax
+[ 	]*[a-f0-9]+:	66 0f be f0          	movsx  si,al
+[ 	]*[a-f0-9]+:	0f be f0             	movsx  esi,al
+[ 	]*[a-f0-9]+:	0f bf f0             	movsx  esi,ax
 [ 	]*[a-f0-9]+:	0f be 10             	movsx  edx,BYTE PTR \[eax\]
 [ 	]*[a-f0-9]+:	66 0f be 10          	movsx  dx,BYTE PTR \[eax\]
 [ 	]*[a-f0-9]+:	66 0f be 10          	movsx  dx,BYTE PTR \[eax\]
@@ -25,6 +28,9 @@  Disassembly of section .text:
 [ 	]*[a-f0-9]+:	66 0f b6 f0          	movzx  si,al
 [ 	]*[a-f0-9]+:	0f b6 f0             	movzx  esi,al
 [ 	]*[a-f0-9]+:	0f b7 f0             	movzx  esi,ax
+[ 	]*[a-f0-9]+:	66 0f b6 f0          	movzx  si,al
+[ 	]*[a-f0-9]+:	0f b6 f0             	movzx  esi,al
+[ 	]*[a-f0-9]+:	0f b7 f0             	movzx  esi,ax
 [ 	]*[a-f0-9]+:	0f b6 10             	movzx  edx,BYTE PTR \[eax\]
 [ 	]*[a-f0-9]+:	66 0f b6 10          	movzx  dx,BYTE PTR \[eax\]
 [ 	]*[a-f0-9]+:	66 0f b6 10          	movzx  dx,BYTE PTR \[eax\]
diff --git a/gas/testsuite/gas/i386/i386.d b/gas/testsuite/gas/i386/i386.d
index 1c6c4cc3fd5..5d967ac8fe3 100644
--- a/gas/testsuite/gas/i386/i386.d
+++ b/gas/testsuite/gas/i386/i386.d
@@ -13,6 +13,9 @@  Disassembly of section .text:
 [ 	]*[a-f0-9]+:	66 0f be f0          	movsbw %al,%si
 [ 	]*[a-f0-9]+:	0f be f0             	movsbl %al,%esi
 [ 	]*[a-f0-9]+:	0f bf f0             	movswl %ax,%esi
+[ 	]*[a-f0-9]+:	66 0f be f0          	movsbw %al,%si
+[ 	]*[a-f0-9]+:	0f be f0             	movsbl %al,%esi
+[ 	]*[a-f0-9]+:	0f bf f0             	movswl %ax,%esi
 [ 	]*[a-f0-9]+:	0f be 10             	movsbl \(%eax\),%edx
 [ 	]*[a-f0-9]+:	66 0f be 10          	movsbw \(%eax\),%dx
 [ 	]*[a-f0-9]+:	66 0f be 10          	movsbw \(%eax\),%dx
@@ -24,6 +27,9 @@  Disassembly of section .text:
 [ 	]*[a-f0-9]+:	66 0f b6 f0          	movzbw %al,%si
 [ 	]*[a-f0-9]+:	0f b6 f0             	movzbl %al,%esi
 [ 	]*[a-f0-9]+:	0f b7 f0             	movzwl %ax,%esi
+[ 	]*[a-f0-9]+:	66 0f b6 f0          	movzbw %al,%si
+[ 	]*[a-f0-9]+:	0f b6 f0             	movzbl %al,%esi
+[ 	]*[a-f0-9]+:	0f b7 f0             	movzwl %ax,%esi
 [ 	]*[a-f0-9]+:	0f b6 10             	movzbl \(%eax\),%edx
 [ 	]*[a-f0-9]+:	66 0f b6 10          	movzbw \(%eax\),%dx
 [ 	]*[a-f0-9]+:	66 0f b6 10          	movzbw \(%eax\),%dx
diff --git a/gas/testsuite/gas/i386/i386.exp b/gas/testsuite/gas/i386/i386.exp
index c4280417c58..40154f39c9c 100644
--- a/gas/testsuite/gas/i386/i386.exp
+++ b/gas/testsuite/gas/i386/i386.exp
@@ -491,6 +491,7 @@  if [expr ([istarget "i*86-*-*"] ||  [istarget "x86_64-*-*"]) && [gas_32_check]]
     run_list_test "inval-pseudo" "-al"
     run_dump_test "nop-1"
     run_dump_test "nop-2"
+    run_list_test "movszx-inval" "-al"
     run_dump_test "optimize-1"
     run_dump_test "optimize-1a"
     run_dump_test "optimize-2"
@@ -1052,6 +1053,7 @@  if [expr ([istarget "i*86-*-*"] || [istarget "x86_64-*-*"]) && [gas_64_check]] t
     run_dump_test "x86-64-movd-intel"
     run_dump_test "x86-64-nop-1"
     run_dump_test "x86-64-nop-2"
+    run_list_test "x86-64-movszx-inval" "-al"
     run_dump_test "x86-64-movsxd"
     run_dump_test "x86-64-movsxd-intel"
     run_list_test "x86-64-movsxd-inval" "-al"
diff --git a/gas/testsuite/gas/i386/i386.s b/gas/testsuite/gas/i386/i386.s
index 7da361f5f85..8812a18814a 100644
--- a/gas/testsuite/gas/i386/i386.s
+++ b/gas/testsuite/gas/i386/i386.s
@@ -9,6 +9,9 @@ 
 	movsx	%al, %si
 	movsx	%al, %esi
 	movsx	%ax, %esi
+	movsxb	%al, %si
+	movsxb	%al, %esi
+	movsxw	%ax, %esi
 	movsx	(%eax), %edx
 	movsx	(%eax), %dx
 	movsxb	(%eax), %dx
@@ -21,6 +24,9 @@ 
 	movzx	%al, %si
 	movzx	%al, %esi
 	movzx	%ax, %esi
+	movzxb	%al, %si
+	movzxb	%al, %esi
+	movzxw	%ax, %esi
 	movzx	(%eax), %edx
 	movzx	(%eax), %dx
 	movzxb	(%eax), %dx
diff --git a/gas/testsuite/gas/i386/iamcu-1.d b/gas/testsuite/gas/i386/iamcu-1.d
index 2b1df5de4b7..aad623adc55 100644
--- a/gas/testsuite/gas/i386/iamcu-1.d
+++ b/gas/testsuite/gas/i386/iamcu-1.d
@@ -10,6 +10,9 @@  Disassembly of section .text:
 [ 	]*[a-f0-9]+:	66 0f be f0          	movsbw %al,%si
 [ 	]*[a-f0-9]+:	0f be f0             	movsbl %al,%esi
 [ 	]*[a-f0-9]+:	0f bf f0             	movswl %ax,%esi
+[ 	]*[a-f0-9]+:	66 0f be f0          	movsbw %al,%si
+[ 	]*[a-f0-9]+:	0f be f0             	movsbl %al,%esi
+[ 	]*[a-f0-9]+:	0f bf f0             	movswl %ax,%esi
 [ 	]*[a-f0-9]+:	0f be 10             	movsbl \(%eax\),%edx
 [ 	]*[a-f0-9]+:	66 0f be 10          	movsbw \(%eax\),%dx
 [ 	]*[a-f0-9]+:	66 0f be 10          	movsbw \(%eax\),%dx
@@ -21,6 +24,9 @@  Disassembly of section .text:
 [ 	]*[a-f0-9]+:	66 0f b6 f0          	movzbw %al,%si
 [ 	]*[a-f0-9]+:	0f b6 f0             	movzbl %al,%esi
 [ 	]*[a-f0-9]+:	0f b7 f0             	movzwl %ax,%esi
+[ 	]*[a-f0-9]+:	66 0f b6 f0          	movzbw %al,%si
+[ 	]*[a-f0-9]+:	0f b6 f0             	movzbl %al,%esi
+[ 	]*[a-f0-9]+:	0f b7 f0             	movzwl %ax,%esi
 [ 	]*[a-f0-9]+:	0f b6 10             	movzbl \(%eax\),%edx
 [ 	]*[a-f0-9]+:	66 0f b6 10          	movzbw \(%eax\),%dx
 [ 	]*[a-f0-9]+:	66 0f b6 10          	movzbw \(%eax\),%dx
diff --git a/gas/testsuite/gas/i386/iamcu-1.s b/gas/testsuite/gas/i386/iamcu-1.s
index b631dfa17ef..fc33c73c745 100644
--- a/gas/testsuite/gas/i386/iamcu-1.s
+++ b/gas/testsuite/gas/i386/iamcu-1.s
@@ -4,6 +4,9 @@ 
 	movsx	%al, %si
 	movsx	%al, %esi
 	movsx	%ax, %esi
+	movsxb	%al, %si
+	movsxb	%al, %esi
+	movsxw	%ax, %esi
 	movsx	(%eax), %edx
 	movsx	(%eax), %dx
 	movsxb	(%eax), %dx
@@ -16,6 +19,9 @@ 
 	movzx	%al, %si
 	movzx	%al, %esi
 	movzx	%ax, %esi
+	movzxb	%al, %si
+	movzxb	%al, %esi
+	movzxw	%ax, %esi
 	movzx	(%eax), %edx
 	movzx	(%eax), %dx
 	movzxb	(%eax), %dx
diff --git a/gas/testsuite/gas/i386/ilp32/x86-64.d b/gas/testsuite/gas/i386/ilp32/x86-64.d
index 33722c90f9c..f58b3ba8546 100644
--- a/gas/testsuite/gas/i386/ilp32/x86-64.d
+++ b/gas/testsuite/gas/i386/ilp32/x86-64.d
@@ -162,6 +162,12 @@  Disassembly of section .text:
 [ 	]*[a-f0-9]+:	0f bf f0             	movswl %ax,%esi
 [ 	]*[a-f0-9]+:	48 0f bf f0          	movswq %ax,%rsi
 [ 	]*[a-f0-9]+:	48 63 f0             	movslq %eax,%rsi
+[ 	]*[a-f0-9]+:	66 0f be f0          	movsbw %al,%si
+[ 	]*[a-f0-9]+:	0f be f0             	movsbl %al,%esi
+[ 	]*[a-f0-9]+:	48 0f be f0          	movsbq %al,%rsi
+[ 	]*[a-f0-9]+:	0f bf f0             	movswl %ax,%esi
+[ 	]*[a-f0-9]+:	48 0f bf f0          	movswq %ax,%rsi
+[ 	]*[a-f0-9]+:	48 63 f0             	movslq %eax,%rsi
 [ 	]*[a-f0-9]+:	0f be 10             	movsbl \(%rax\),%edx
 [ 	]*[a-f0-9]+:	48 0f be 10          	movsbq \(%rax\),%rdx
 [ 	]*[a-f0-9]+:	66 0f be 10          	movsbw \(%rax\),%dx
@@ -175,6 +181,11 @@  Disassembly of section .text:
 [ 	]*[a-f0-9]+:	48 0f b6 f0          	movzbq %al,%rsi
 [ 	]*[a-f0-9]+:	0f b7 f0             	movzwl %ax,%esi
 [ 	]*[a-f0-9]+:	48 0f b7 f0          	movzwq %ax,%rsi
+[ 	]*[a-f0-9]+:	66 0f b6 f0          	movzbw %al,%si
+[ 	]*[a-f0-9]+:	0f b6 f0             	movzbl %al,%esi
+[ 	]*[a-f0-9]+:	48 0f b6 f0          	movzbq %al,%rsi
+[ 	]*[a-f0-9]+:	0f b7 f0             	movzwl %ax,%esi
+[ 	]*[a-f0-9]+:	48 0f b7 f0          	movzwq %ax,%rsi
 [ 	]*[a-f0-9]+:	0f b6 10             	movzbl \(%rax\),%edx
 [ 	]*[a-f0-9]+:	48 0f b6 10          	movzbq \(%rax\),%rdx
 [ 	]*[a-f0-9]+:	66 0f b6 10          	movzbw \(%rax\),%dx
diff --git a/gas/testsuite/gas/i386/ilp32/x86-64.s b/gas/testsuite/gas/i386/ilp32/x86-64.s
index d1f7ae3b495..c6015947cb9 100644
--- a/gas/testsuite/gas/i386/ilp32/x86-64.s
+++ b/gas/testsuite/gas/i386/ilp32/x86-64.s
@@ -194,6 +194,12 @@  cmpxchg16b oword ptr [rax]
 	movsx	%ax, %esi
 	movsx	%ax, %rsi
 	movsx	%eax, %rsi
+	movsxb	%al, %si
+	movsxb	%al, %esi
+	movsxb	%al, %rsi
+	movsxw	%ax, %esi
+	movsxw	%ax, %rsi
+	movsxl	%eax, %rsi
 	movsx	(%rax), %edx
 	movsx	(%rax), %rdx
 	movsx	(%rax), %dx
@@ -208,6 +214,11 @@  cmpxchg16b oword ptr [rax]
 	movzx	%al, %rsi
 	movzx	%ax, %esi
 	movzx	%ax, %rsi
+	movzxb	%al, %si
+	movzxb	%al, %esi
+	movzxb	%al, %rsi
+	movzxw	%ax, %esi
+	movzxw	%ax, %rsi
 	movzx	(%rax), %edx
 	movzx	(%rax), %rdx
 	movzx	(%rax), %dx
diff --git a/gas/testsuite/gas/i386/k1om.d b/gas/testsuite/gas/i386/k1om.d
index 7767f5b4188..617e5275bcd 100644
--- a/gas/testsuite/gas/i386/k1om.d
+++ b/gas/testsuite/gas/i386/k1om.d
@@ -175,6 +175,12 @@  Disassembly of section .text:
 [ 	]*[a-f0-9]+:	0f bf f0             	movswl %ax,%esi
 [ 	]*[a-f0-9]+:	48 0f bf f0          	movswq %ax,%rsi
 [ 	]*[a-f0-9]+:	48 63 f0             	movslq %eax,%rsi
+[ 	]*[a-f0-9]+:	66 0f be f0          	movsbw %al,%si
+[ 	]*[a-f0-9]+:	0f be f0             	movsbl %al,%esi
+[ 	]*[a-f0-9]+:	48 0f be f0          	movsbq %al,%rsi
+[ 	]*[a-f0-9]+:	0f bf f0             	movswl %ax,%esi
+[ 	]*[a-f0-9]+:	48 0f bf f0          	movswq %ax,%rsi
+[ 	]*[a-f0-9]+:	48 63 f0             	movslq %eax,%rsi
 [ 	]*[a-f0-9]+:	0f be 10             	movsbl \(%rax\),%edx
 [ 	]*[a-f0-9]+:	48 0f be 10          	movsbq \(%rax\),%rdx
 [ 	]*[a-f0-9]+:	66 0f be 10          	movsbw \(%rax\),%dx
@@ -188,6 +194,11 @@  Disassembly of section .text:
 [ 	]*[a-f0-9]+:	48 0f b6 f0          	movzbq %al,%rsi
 [ 	]*[a-f0-9]+:	0f b7 f0             	movzwl %ax,%esi
 [ 	]*[a-f0-9]+:	48 0f b7 f0          	movzwq %ax,%rsi
+[ 	]*[a-f0-9]+:	66 0f b6 f0          	movzbw %al,%si
+[ 	]*[a-f0-9]+:	0f b6 f0             	movzbl %al,%esi
+[ 	]*[a-f0-9]+:	48 0f b6 f0          	movzbq %al,%rsi
+[ 	]*[a-f0-9]+:	0f b7 f0             	movzwl %ax,%esi
+[ 	]*[a-f0-9]+:	48 0f b7 f0          	movzwq %ax,%rsi
 [ 	]*[a-f0-9]+:	0f b6 10             	movzbl \(%rax\),%edx
 [ 	]*[a-f0-9]+:	48 0f b6 10          	movzbq \(%rax\),%rdx
 [ 	]*[a-f0-9]+:	66 0f b6 10          	movzbw \(%rax\),%dx
diff --git a/gas/testsuite/gas/i386/l1om.d b/gas/testsuite/gas/i386/l1om.d
index 858d1827f92..8c279dcfb2c 100644
--- a/gas/testsuite/gas/i386/l1om.d
+++ b/gas/testsuite/gas/i386/l1om.d
@@ -175,6 +175,12 @@  Disassembly of section .text:
 [ 	]*[a-f0-9]+:	0f bf f0             	movswl %ax,%esi
 [ 	]*[a-f0-9]+:	48 0f bf f0          	movswq %ax,%rsi
 [ 	]*[a-f0-9]+:	48 63 f0             	movslq %eax,%rsi
+[ 	]*[a-f0-9]+:	66 0f be f0          	movsbw %al,%si
+[ 	]*[a-f0-9]+:	0f be f0             	movsbl %al,%esi
+[ 	]*[a-f0-9]+:	48 0f be f0          	movsbq %al,%rsi
+[ 	]*[a-f0-9]+:	0f bf f0             	movswl %ax,%esi
+[ 	]*[a-f0-9]+:	48 0f bf f0          	movswq %ax,%rsi
+[ 	]*[a-f0-9]+:	48 63 f0             	movslq %eax,%rsi
 [ 	]*[a-f0-9]+:	0f be 10             	movsbl \(%rax\),%edx
 [ 	]*[a-f0-9]+:	48 0f be 10          	movsbq \(%rax\),%rdx
 [ 	]*[a-f0-9]+:	66 0f be 10          	movsbw \(%rax\),%dx
@@ -188,6 +194,11 @@  Disassembly of section .text:
 [ 	]*[a-f0-9]+:	48 0f b6 f0          	movzbq %al,%rsi
 [ 	]*[a-f0-9]+:	0f b7 f0             	movzwl %ax,%esi
 [ 	]*[a-f0-9]+:	48 0f b7 f0          	movzwq %ax,%rsi
+[ 	]*[a-f0-9]+:	66 0f b6 f0          	movzbw %al,%si
+[ 	]*[a-f0-9]+:	0f b6 f0             	movzbl %al,%esi
+[ 	]*[a-f0-9]+:	48 0f b6 f0          	movzbq %al,%rsi
+[ 	]*[a-f0-9]+:	0f b7 f0             	movzwl %ax,%esi
+[ 	]*[a-f0-9]+:	48 0f b7 f0          	movzwq %ax,%rsi
 [ 	]*[a-f0-9]+:	0f b6 10             	movzbl \(%rax\),%edx
 [ 	]*[a-f0-9]+:	48 0f b6 10          	movzbq \(%rax\),%rdx
 [ 	]*[a-f0-9]+:	66 0f b6 10          	movzbw \(%rax\),%dx
diff --git a/gas/testsuite/gas/i386/movszx-inval.l b/gas/testsuite/gas/i386/movszx-inval.l
new file mode 100644
index 00000000000..bb6b48963fd
--- /dev/null
+++ b/gas/testsuite/gas/i386/movszx-inval.l
@@ -0,0 +1,66 @@ 
+.*: Assembler messages:
+.*:4: Error: .*
+.*:5: Error: .*
+.*:6: Error: .*
+.*:7: Error: .*
+.*:8: Error: .*
+.*:9: Error: .*
+.*:10: Error: .*
+.*:11: Error: .*
+.*:12: Error: .*
+.*:13: Error: .*
+.*:14: Error: .*
+.*:15: Error: .*
+.*:16: Error: .*
+.*:17: Error: .*
+.*:18: Error: .*
+.*:19: Error: .*
+.*:20: Error: .*
+.*:21: Error: .*
+.*:22: Error: .*
+.*:23: Error: .*
+.*:24: Error: .*
+.*:25: Error: .*
+.*:28: Error: .*
+.*:29: Error: .*
+.*:30: Error: .*
+.*:31: Error: .*
+.*:32: Error: .*
+.*:33: Error: .*
+GAS LISTING .*
+
+
+[ 	]*1[ 	]+\# Invalid 32-bit movsx and movzx\.
+[ 	]*2[ 	]+\.text
+[ 	]*3[ 	]+_start:
+[ 	]*4[ 	]+movsbw	%al, %ecx
+[ 	]*5[ 	]+movsbl	%al, %cx
+[ 	]*6[ 	]+movsbw	%al, %ecx
+[ 	]*7[ 	]+movsbw	%al, %ecx
+[ 	]*8[ 	]+movsbl	%al, %cx
+[ 	]*9[ 	]+movsbw	%al, %ecx
+[ 	]*10[ 	]+movsbw	%al, %ecx
+[ 	]*11[ 	]+movsbl	%al, %cx
+[ 	]*12[ 	]+movsbq	%al, %cx
+[ 	]*13[ 	]+movsbq	%al, %ecx
+[ 	]*14[ 	]+movswq	%ax, %ecx
+[ 	]*15[ 	]+movzbw	%al, %ecx
+[ 	]*16[ 	]+movzbl	%al, %cx
+[ 	]*17[ 	]+movzbw	%al, %ecx
+[ 	]*18[ 	]+movzbw	%al, %ecx
+[ 	]*19[ 	]+movzbl	%al, %cx
+[ 	]*20[ 	]+movzbw	%al, %ecx
+[ 	]*21[ 	]+movzbw	%al, %ecx
+[ 	]*22[ 	]+movzbl	%al, %cx
+[ 	]*23[ 	]+movzbq	%al, %cx
+[ 	]*24[ 	]+movzbq	%al, %ecx
+[ 	]*25[ 	]+movzwq	%ax, %ecx
+[ 	]*26[ 	]+
+[ 	]*27[ 	]+\.intel_syntax noprefix
+[ 	]*28[ 	]+movsxb ax, BYTE PTR \[eax\]
+[ 	]*29[ 	]+movsxb eax, BYTE PTR \[eax\]
+[ 	]*30[ 	]+movsxw eax, WORD PTR \[eax\]
+[ 	]*31[ 	]+movzxb ax, BYTE PTR \[eax\]
+[ 	]*32[ 	]+movzxb eax, BYTE PTR \[eax\]
+[ 	]*33[ 	]+movzxw eax, WORD PTR \[eax\]
+#pass
diff --git a/gas/testsuite/gas/i386/movszx-inval.s b/gas/testsuite/gas/i386/movszx-inval.s
new file mode 100644
index 00000000000..7e10f736be0
--- /dev/null
+++ b/gas/testsuite/gas/i386/movszx-inval.s
@@ -0,0 +1,33 @@ 
+# Invalid 32-bit movsx and movzx.
+	.text
+_start:
+	movsbw	%al, %ecx
+	movsbl	%al, %cx
+	movsbw	%al, %ecx
+	movsbw	%al, %ecx
+	movsbl	%al, %cx
+	movsbw	%al, %ecx
+	movsbw	%al, %ecx
+	movsbl	%al, %cx
+	movsbq	%al, %cx
+	movsbq	%al, %ecx
+	movswq	%ax, %ecx
+	movzbw	%al, %ecx
+	movzbl	%al, %cx
+	movzbw	%al, %ecx
+	movzbw	%al, %ecx
+	movzbl	%al, %cx
+	movzbw	%al, %ecx
+	movzbw	%al, %ecx
+	movzbl	%al, %cx
+	movzbq	%al, %cx
+	movzbq	%al, %ecx
+	movzwq	%ax, %ecx
+
+	.intel_syntax noprefix
+	movsxb ax, BYTE PTR [eax]
+	movsxb eax, BYTE PTR [eax]
+	movsxw eax, WORD PTR [eax]
+	movzxb ax, BYTE PTR [eax]
+	movzxb eax, BYTE PTR [eax]
+	movzxw eax, WORD PTR [eax]
diff --git a/gas/testsuite/gas/i386/x86-64-movszx-inval.l b/gas/testsuite/gas/i386/x86-64-movszx-inval.l
new file mode 100644
index 00000000000..fdb149425be
--- /dev/null
+++ b/gas/testsuite/gas/i386/x86-64-movszx-inval.l
@@ -0,0 +1,86 @@ 
+.*: Assembler messages:
+.*:4: Error: .*
+.*:5: Error: .*
+.*:6: Error: .*
+.*:7: Error: .*
+.*:8: Error: .*
+.*:9: Error: .*
+.*:10: Error: .*
+.*:11: Error: .*
+.*:12: Error: .*
+.*:13: Error: .*
+.*:14: Error: .*
+.*:15: Error: .*
+.*:16: Error: .*
+.*:17: Error: .*
+.*:18: Error: .*
+.*:19: Error: .*
+.*:20: Error: .*
+.*:21: Error: .*
+.*:22: Error: .*
+.*:23: Error: .*
+.*:24: Error: .*
+.*:25: Error: .*
+.*:26: Error: .*
+.*:27: Error: .*
+.*:28: Error: .*
+.*:29: Error: .*
+.*:30: Error: .*
+.*:31: Error: .*
+.*:34: Error: .*
+.*:35: Error: .*
+.*:36: Error: .*
+.*:37: Error: .*
+.*:38: Error: .*
+.*:39: Error: .*
+.*:40: Error: .*
+.*:41: Error: .*
+.*:42: Error: .*
+.*:43: Error: .*
+GAS LISTING .*
+
+
+[ 	]*1[ 	]+\# Invalid 64-bit movsx and movzx\.
+[ 	]*2[ 	]+\.text
+[ 	]*3[ 	]+_start:
+[ 	]*4[ 	]+movsbw	%al, %ecx
+[ 	]*5[ 	]+movsbl	%al, %cx
+[ 	]*6[ 	]+movsbw	%al, %ecx
+[ 	]*7[ 	]+movsbw	%al, %ecx
+[ 	]*8[ 	]+movsbl	%al, %cx
+[ 	]*9[ 	]+movsbw	%al, %ecx
+[ 	]*10[ 	]+movsbw	%al, %ecx
+[ 	]*11[ 	]+movsbw	%al, %rcx
+[ 	]*12[ 	]+movsbl	%al, %cx
+[ 	]*13[ 	]+movsbl	%al, %rcx
+[ 	]*14[ 	]+movsbq	%al, %cx
+[ 	]*15[ 	]+movsbq	%al, %ecx
+[ 	]*16[ 	]+movswl	%ax, %rcx
+[ 	]*17[ 	]+movswq	%ax, %ecx
+[ 	]*18[ 	]+movzbw	%al, %ecx
+[ 	]*19[ 	]+movzbl	%al, %cx
+[ 	]*20[ 	]+movzbw	%al, %ecx
+[ 	]*21[ 	]+movzbw	%al, %ecx
+[ 	]*22[ 	]+movzbl	%al, %cx
+[ 	]*23[ 	]+movzbw	%al, %ecx
+[ 	]*24[ 	]+movzbw	%al, %ecx
+[ 	]*25[ 	]+movzbw	%al, %rcx
+[ 	]*26[ 	]+movzbl	%al, %cx
+[ 	]*27[ 	]+movzbl	%al, %rcx
+[ 	]*28[ 	]+movzbq	%al, %cx
+[ 	]*29[ 	]+movzbq	%al, %ecx
+[ 	]*30[ 	]+movzwl	%ax, %rcx
+[ 	]*31[ 	]+movzwq	%ax, %ecx
+[ 	]*32[ 	]+
+[ 	]*33[ 	]+\.intel_syntax noprefix
+[ 	]*34[ 	]+movsxb ax, BYTE PTR \[rax\]
+[ 	]*35[ 	]+movsxb eax, BYTE PTR \[rax\]
+[ 	]*36[ 	]+movsxb rax, BYTE PTR \[rax\]
+[ 	]*37[ 	]+movsxw eax, WORD PTR \[rax\]
+[ 	]*38[ 	]+movsxw rax, WORD PTR \[rax\]
+[ 	]*39[ 	]+movzxb ax, BYTE PTR \[rax\]
+[ 	]*40[ 	]+movzxb eax, BYTE PTR \[rax\]
+[ 	]*41[ 	]+movzxb rax, BYTE PTR \[rax\]
+[ 	]*42[ 	]+movzxw eax, WORD PTR \[rax\]
+[ 	]*43[ 	]+movzxw rax, WORD PTR \[rax\]
+#pass
diff --git a/gas/testsuite/gas/i386/x86-64-movszx-inval.s b/gas/testsuite/gas/i386/x86-64-movszx-inval.s
new file mode 100644
index 00000000000..81b6d11bb44
--- /dev/null
+++ b/gas/testsuite/gas/i386/x86-64-movszx-inval.s
@@ -0,0 +1,43 @@ 
+# Invalid 64-bit movsx and movzx.
+	.text
+_start:
+	movsbw	%al, %ecx
+	movsbl	%al, %cx
+	movsbw	%al, %ecx
+	movsbw	%al, %ecx
+	movsbl	%al, %cx
+	movsbw	%al, %ecx
+	movsbw	%al, %ecx
+	movsbw	%al, %rcx
+	movsbl	%al, %cx
+	movsbl	%al, %rcx
+	movsbq	%al, %cx
+	movsbq	%al, %ecx
+	movswl	%ax, %rcx
+	movswq	%ax, %ecx
+	movzbw	%al, %ecx
+	movzbl	%al, %cx
+	movzbw	%al, %ecx
+	movzbw	%al, %ecx
+	movzbl	%al, %cx
+	movzbw	%al, %ecx
+	movzbw	%al, %ecx
+	movzbw	%al, %rcx
+	movzbl	%al, %cx
+	movzbl	%al, %rcx
+	movzbq	%al, %cx
+	movzbq	%al, %ecx
+	movzwl	%ax, %rcx
+	movzwq	%ax, %ecx
+
+	.intel_syntax noprefix
+	movsxb ax, BYTE PTR [rax]
+	movsxb eax, BYTE PTR [rax]
+	movsxb rax, BYTE PTR [rax]
+	movsxw eax, WORD PTR [rax]
+	movsxw rax, WORD PTR [rax]
+	movzxb ax, BYTE PTR [rax]
+	movzxb eax, BYTE PTR [rax]
+	movzxb rax, BYTE PTR [rax]
+	movzxw eax, WORD PTR [rax]
+	movzxw rax, WORD PTR [rax]
diff --git a/gas/testsuite/gas/i386/x86_64-intel.d b/gas/testsuite/gas/i386/x86_64-intel.d
index 8dd8893e79a..f66785ab78e 100644
--- a/gas/testsuite/gas/i386/x86_64-intel.d
+++ b/gas/testsuite/gas/i386/x86_64-intel.d
@@ -173,6 +173,12 @@  Disassembly of section .text:
 [ 	]*[a-f0-9]+:	0f bf f0             	movsx  esi,ax
 [ 	]*[a-f0-9]+:	48 0f bf f0          	movsx  rsi,ax
 [ 	]*[a-f0-9]+:	48 63 f0             	movsxd rsi,eax
+[ 	]*[a-f0-9]+:	66 0f be f0          	movsx  si,al
+[ 	]*[a-f0-9]+:	0f be f0             	movsx  esi,al
+[ 	]*[a-f0-9]+:	48 0f be f0          	movsx  rsi,al
+[ 	]*[a-f0-9]+:	0f bf f0             	movsx  esi,ax
+[ 	]*[a-f0-9]+:	48 0f bf f0          	movsx  rsi,ax
+[ 	]*[a-f0-9]+:	48 63 f0             	movsxd rsi,eax
 [ 	]*[a-f0-9]+:	0f be 10             	movsx  edx,BYTE PTR \[rax\]
 [ 	]*[a-f0-9]+:	48 0f be 10          	movsx  rdx,BYTE PTR \[rax\]
 [ 	]*[a-f0-9]+:	66 0f be 10          	movsx  dx,BYTE PTR \[rax\]
@@ -186,6 +192,11 @@  Disassembly of section .text:
 [ 	]*[a-f0-9]+:	48 0f b6 f0          	movzx  rsi,al
 [ 	]*[a-f0-9]+:	0f b7 f0             	movzx  esi,ax
 [ 	]*[a-f0-9]+:	48 0f b7 f0          	movzx  rsi,ax
+[ 	]*[a-f0-9]+:	66 0f b6 f0          	movzx  si,al
+[ 	]*[a-f0-9]+:	0f b6 f0             	movzx  esi,al
+[ 	]*[a-f0-9]+:	48 0f b6 f0          	movzx  rsi,al
+[ 	]*[a-f0-9]+:	0f b7 f0             	movzx  esi,ax
+[ 	]*[a-f0-9]+:	48 0f b7 f0          	movzx  rsi,ax
 [ 	]*[a-f0-9]+:	0f b6 10             	movzx  edx,BYTE PTR \[rax\]
 [ 	]*[a-f0-9]+:	48 0f b6 10          	movzx  rdx,BYTE PTR \[rax\]
 [ 	]*[a-f0-9]+:	66 0f b6 10          	movzx  dx,BYTE PTR \[rax\]
diff --git a/gas/testsuite/gas/i386/x86_64.d b/gas/testsuite/gas/i386/x86_64.d
index 0bdbc79021a..72ed23aa4ba 100644
--- a/gas/testsuite/gas/i386/x86_64.d
+++ b/gas/testsuite/gas/i386/x86_64.d
@@ -173,6 +173,12 @@  Disassembly of section .text:
 [ 	]*[a-f0-9]+:	0f bf f0             	movswl %ax,%esi
 [ 	]*[a-f0-9]+:	48 0f bf f0          	movswq %ax,%rsi
 [ 	]*[a-f0-9]+:	48 63 f0             	movslq %eax,%rsi
+[ 	]*[a-f0-9]+:	66 0f be f0          	movsbw %al,%si
+[ 	]*[a-f0-9]+:	0f be f0             	movsbl %al,%esi
+[ 	]*[a-f0-9]+:	48 0f be f0          	movsbq %al,%rsi
+[ 	]*[a-f0-9]+:	0f bf f0             	movswl %ax,%esi
+[ 	]*[a-f0-9]+:	48 0f bf f0          	movswq %ax,%rsi
+[ 	]*[a-f0-9]+:	48 63 f0             	movslq %eax,%rsi
 [ 	]*[a-f0-9]+:	0f be 10             	movsbl \(%rax\),%edx
 [ 	]*[a-f0-9]+:	48 0f be 10          	movsbq \(%rax\),%rdx
 [ 	]*[a-f0-9]+:	66 0f be 10          	movsbw \(%rax\),%dx
@@ -186,6 +192,11 @@  Disassembly of section .text:
 [ 	]*[a-f0-9]+:	48 0f b6 f0          	movzbq %al,%rsi
 [ 	]*[a-f0-9]+:	0f b7 f0             	movzwl %ax,%esi
 [ 	]*[a-f0-9]+:	48 0f b7 f0          	movzwq %ax,%rsi
+[ 	]*[a-f0-9]+:	66 0f b6 f0          	movzbw %al,%si
+[ 	]*[a-f0-9]+:	0f b6 f0             	movzbl %al,%esi
+[ 	]*[a-f0-9]+:	48 0f b6 f0          	movzbq %al,%rsi
+[ 	]*[a-f0-9]+:	0f b7 f0             	movzwl %ax,%esi
+[ 	]*[a-f0-9]+:	48 0f b7 f0          	movzwq %ax,%rsi
 [ 	]*[a-f0-9]+:	0f b6 10             	movzbl \(%rax\),%edx
 [ 	]*[a-f0-9]+:	48 0f b6 10          	movzbq \(%rax\),%rdx
 [ 	]*[a-f0-9]+:	66 0f b6 10          	movzbw \(%rax\),%dx
diff --git a/gas/testsuite/gas/i386/x86_64.s b/gas/testsuite/gas/i386/x86_64.s
index 377580be341..b8dfafbcd53 100644
--- a/gas/testsuite/gas/i386/x86_64.s
+++ b/gas/testsuite/gas/i386/x86_64.s
@@ -208,6 +208,12 @@  cmpxchg16b oword ptr [rax]
 	movsx	%ax, %esi
 	movsx	%ax, %rsi
 	movsx	%eax, %rsi
+	movsxb	%al, %si
+	movsxb	%al, %esi
+	movsxb	%al, %rsi
+	movsxw	%ax, %esi
+	movsxw	%ax, %rsi
+	movsxl	%eax, %rsi
 	movsx	(%rax), %edx
 	movsx	(%rax), %rdx
 	movsx	(%rax), %dx
@@ -222,6 +228,11 @@  cmpxchg16b oword ptr [rax]
 	movzx	%al, %rsi
 	movzx	%ax, %esi
 	movzx	%ax, %rsi
+	movzxb	%al, %si
+	movzxb	%al, %esi
+	movzxb	%al, %rsi
+	movzxw	%ax, %esi
+	movzxw	%ax, %rsi
 	movzx	(%rax), %edx
 	movzx	(%rax), %rdx
 	movzx	(%rax), %dx
diff --git a/opcodes/i386-opc.tbl b/opcodes/i386-opc.tbl
index d805e6916a1..3c4d67baf1e 100644
--- a/opcodes/i386-opc.tbl
+++ b/opcodes/i386-opc.tbl
@@ -132,13 +132,15 @@  movswl, 2, 0xfbf, None, 2, Cpu386, Modrm|No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_qSuf
 movsbq, 2, 0xfbe, None, 2, Cpu64, Modrm|No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_qSuf|No_ldSuf|Rex64, { Reg8|Byte|Unspecified|BaseIndex, Reg64 }
 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 }
+movsx, 2, 0xfbf, None, 2, Cpu386, Modrm|No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_qSuf|No_ldSuf|ATTSyntax, { Reg16, Reg32|Reg64 }
+movsxw, 2, 0xfbf, None, 2, Cpu386, Modrm|No_bSuf|No_wSuf|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_lSuf|No_sSuf|No_qSuf|No_ldSuf|ATTSyntax, { Reg32, Reg64 }
+movsxl, 2, 0x63, None, 1, Cpu64, Modrm|No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_qSuf|No_ldSuf|ATTSyntax, { Reg32|Unspecified|BaseIndex, Reg64 }
+// Intel Syntax next 3 insns
+movsx, 2, 0xfbe, None, 2, Cpu386, Modrm|No_bSuf|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_wSuf|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_lSuf|No_sSuf|No_qSuf|No_ldSuf|Rex64|IntelSyntax, { Reg32|Dword|BaseIndex, Reg64 }
 movsxd, 2, 0x63, None, 1, Cpu64, Modrm|No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_qSuf|No_ldSuf, { Reg32|Unspecified|BaseIndex, Reg32|Reg64 }
 movsxd, 2, 0x63, None, 1, Cpu64, Amd64|Modrm|No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_qSuf|No_ldSuf, { Reg32|Unspecified|BaseIndex, Reg16 }
 movsxd, 2, 0x63, None, 1, Cpu64, Intel64|Modrm|No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_qSuf|No_ldSuf, { Reg16|Unspecified|BaseIndex, Reg16 }
@@ -146,12 +148,13 @@  movsxd, 2, 0x63, None, 1, Cpu64, Intel64|Modrm|No_bSuf|No_wSuf|No_lSuf|No_sSuf|N
 // 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 }
+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_wSuf|No_lSuf|No_sSuf|No_qSuf|No_ldSuf|ATTSyntax, { Reg16, Reg32|Reg64 }
+movzxw, 2, 0xfb7, None, 2, Cpu386, Modrm|No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_qSuf|No_ldSuf|ATTSyntax, { Reg16|Unspecified|BaseIndex, Reg32|Reg64 }
 // Intel Syntax next 2 insns (the 64-bit variants are 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, Modrm|No_bSuf|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_wSuf|No_lSuf|No_sSuf|No_qSuf|No_ldSuf|IntelSyntax, { Reg16|Word|BaseIndex, Reg32|Reg64 }
 
 // Push instructions.
 push, 1, 0x50, None, 1, CpuNo64, No_bSuf|No_sSuf|No_qSuf|No_ldSuf, { Reg16|Reg32 }