public inbox for binutils@sourceware.org
 help / color / mirror / Atom feed
* [RFC PATCH] Fix decoding of superfluous data32 prefix before superfluous rex.W prefix before push.
@ 2012-08-03 18:47 Roland McGrath
  2012-08-03 18:54 ` H.J. Lu
  0 siblings, 1 reply; 11+ messages in thread
From: Roland McGrath @ 2012-08-03 18:47 UTC (permalink / raw)
  To: hjl.tools; +Cc: Victor Khimenko, binutils

x86-64 hardware ignores a superfluous data32 (0x66) prefix that precedes a
superfluous rex.W (0x48) prefix that precedes a push-immediate (0x68)
instruction.  But the disassembler gets confused by this:

   0:	48 68 01 02 03 04    	rex.W pushq $0x4030201
   6:	66 48 68 01 02       	data32 pushq $0x201
   b:	03                   	.byte 0x3
   c:	04                   	.byte 0x4

With this change it's at least not confused in the decoding:

   0:	48 68 01 02 03 04    	rex.W pushq $0x4030201
   6:	66 48 68 01 02 03 04 	data32 pushq $0x4030201

That's the most important thing, since it prevents it losing track of the
instruction boundaries.  But I'm not at all sure this is really the best
way to fix that.  The i386-dis.c code is extremely hairy and barely
commented.

As of 2.20, it was not so confused and printed:

   0:	66 48 68 01 02 03 04 	pushq  $0x4030201

So this is a regression of sorts.

What would really be ideal is:

   0:	48 68 01 02 03 04    	rex.W pushq $0x4030201
   6:	66 48 68 01 02 03 04 	data32 rex.W pushq $0x4030201

i.e., print both superfluous prefixes rather than ignoring either.
But it's not at all clear to me how to make that happen.  I also really
have no idea what other cases might be affected by the same sort of problem.

HJ, do you have any insight into all this?


Thanks,
Roland


binutils/testsuite/
2012-08-03  Roland McGrath  <mcgrathr@google.com>

	* binutils-all/x86-64/data32-pushq-imm.s: New file.
	* binutils-all/x86-64/data32-pushq-imm.d: New file.

opcodes/
2012-08-03  Roland McGrath  <mcgrathr@google.com>
	    Victor Khimenko  <khim@google.com>

	* i386-dis.c (OP_sI): In v_mode, REX_W trumps DFLAG.


diff --git a/binutils/testsuite/binutils-all/x86-64/data32-pushq-imm.d b/binutils/testsuite/binutils-all/x86-64/data32-pushq-imm.d
new file mode 100644
index 0000000..211b2ca
--- /dev/null
+++ b/binutils/testsuite/binutils-all/x86-64/data32-pushq-imm.d
@@ -0,0 +1,13 @@
+# This is really a test of the disassembler in objdump, but run_dump_test
+# wants us to specify some other program to run first after assembling.
+#PROG: objcopy
+#as: --64
+#objdump: -d
+
+.*: +file format .*
+
+
+Disassembly of section \.text:
+
+0+ <foo>:
+\s*0:	66 48 68 01 02 03 04 	data32 pushq \$0x4030201
diff --git a/binutils/testsuite/binutils-all/x86-64/data32-pushq-imm.s b/binutils/testsuite/binutils-all/x86-64/data32-pushq-imm.s
new file mode 100644
index 0000000..6d9d39a
--- /dev/null
+++ b/binutils/testsuite/binutils-all/x86-64/data32-pushq-imm.s
@@ -0,0 +1,4 @@
+.text
+foo:
+	.byte 0x66
+	rex.W pushq $0x04030201
diff --git a/opcodes/i386-dis.c b/opcodes/i386-dis.c
index 685e968..5f2eb78 100644
--- a/opcodes/i386-dis.c
+++ b/opcodes/i386-dis.c
@@ -1,6 +1,6 @@
 /* Print i386 instructions for GDB, the GNU debugger.
    Copyright 1988, 1989, 1991, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
-   2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011
+   2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012
    Free Software Foundation, Inc.
 
    This file is part of the GNU opcodes library.
@@ -13730,7 +13730,8 @@ OP_sI (int bytemode, int sizeflag)
 	}
       break;
     case v_mode:
-      if (sizeflag & DFLAG)
+      /* The operand-size prefix is overridden by a REX prefix.  */
+      if ((sizeflag & DFLAG) || (rex & REX_W))
 	op = get32s ();
       else
 	op = get16 ();

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [RFC PATCH] Fix decoding of superfluous data32 prefix before superfluous rex.W prefix before push.
  2012-08-03 18:47 [RFC PATCH] Fix decoding of superfluous data32 prefix before superfluous rex.W prefix before push Roland McGrath
@ 2012-08-03 18:54 ` H.J. Lu
  2012-08-03 19:52   ` H.J. Lu
  2012-08-03 23:24   ` Roland McGrath
  0 siblings, 2 replies; 11+ messages in thread
From: H.J. Lu @ 2012-08-03 18:54 UTC (permalink / raw)
  To: Roland McGrath; +Cc: Victor Khimenko, binutils

On Fri, Aug 3, 2012 at 11:17 AM, Roland McGrath <mcgrathr@google.com> wrote:
> x86-64 hardware ignores a superfluous data32 (0x66) prefix that precedes a
> superfluous rex.W (0x48) prefix that precedes a push-immediate (0x68)
> instruction.  But the disassembler gets confused by this:
>
>    0:   48 68 01 02 03 04       rex.W pushq $0x4030201
>    6:   66 48 68 01 02          data32 pushq $0x201
>    b:   03                      .byte 0x3
>    c:   04                      .byte 0x4
>
> With this change it's at least not confused in the decoding:
>
>    0:   48 68 01 02 03 04       rex.W pushq $0x4030201
>    6:   66 48 68 01 02 03 04    data32 pushq $0x4030201
>
> That's the most important thing, since it prevents it losing track of the
> instruction boundaries.  But I'm not at all sure this is really the best
> way to fix that.  The i386-dis.c code is extremely hairy and barely
> commented.
>
> As of 2.20, it was not so confused and printed:
>
>    0:   66 48 68 01 02 03 04    pushq  $0x4030201
>
> So this is a regression of sorts.
>
> What would really be ideal is:
>
>    0:   48 68 01 02 03 04       rex.W pushq $0x4030201
>    6:   66 48 68 01 02 03 04    data32 rex.W pushq $0x4030201
>
> i.e., print both superfluous prefixes rather than ignoring either.
> But it's not at all clear to me how to make that happen.  I also really
> have no idea what other cases might be affected by the same sort of problem.
>
> HJ, do you have any insight into all this?
>

Please also fix "pushq $-1" with a testcase:

[hjl@gnu-6 tmp]$ cat p.s
.text
pushq $-1
rex.W pushq $-1
.byte 0x66
rex.W pushq $-1
[hjl@gnu-6 tmp]$ gcc -c p.s
[hjl@gnu-6 tmp]$ objdump -dw p.o

p.o:     file format elf64-x86-64


Disassembly of section .text:

0000000000000000 <.text>:
   0:	6a ff                	pushq  $0xffffffffffffffff
   2:	48 6a ff             	rex.W pushq $0xffffffffffffffff
   5:	66 48 6a ff          	data32 pushq $0xffff
[hjl@gnu-6 tmp]$

OK with this change.

Thanks.

-- 
H.J.

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [RFC PATCH] Fix decoding of superfluous data32 prefix before superfluous rex.W prefix before push.
  2012-08-03 18:54 ` H.J. Lu
@ 2012-08-03 19:52   ` H.J. Lu
  2012-08-03 21:55     ` Roland McGrath
  2012-08-03 23:24   ` Roland McGrath
  1 sibling, 1 reply; 11+ messages in thread
From: H.J. Lu @ 2012-08-03 19:52 UTC (permalink / raw)
  To: Roland McGrath; +Cc: Victor Khimenko, binutils

On Fri, Aug 3, 2012 at 11:47 AM, H.J. Lu <hjl.tools@gmail.com> wrote:
> On Fri, Aug 3, 2012 at 11:17 AM, Roland McGrath <mcgrathr@google.com> wrote:
>> x86-64 hardware ignores a superfluous data32 (0x66) prefix that precedes a
>> superfluous rex.W (0x48) prefix that precedes a push-immediate (0x68)
>> instruction.  But the disassembler gets confused by this:
>>
>>    0:   48 68 01 02 03 04       rex.W pushq $0x4030201
>>    6:   66 48 68 01 02          data32 pushq $0x201
>>    b:   03                      .byte 0x3
>>    c:   04                      .byte 0x4
>>
>> With this change it's at least not confused in the decoding:
>>
>>    0:   48 68 01 02 03 04       rex.W pushq $0x4030201
>>    6:   66 48 68 01 02 03 04    data32 pushq $0x4030201
>>
>> That's the most important thing, since it prevents it losing track of the
>> instruction boundaries.  But I'm not at all sure this is really the best
>> way to fix that.  The i386-dis.c code is extremely hairy and barely
>> commented.
>>
>> As of 2.20, it was not so confused and printed:
>>
>>    0:   66 48 68 01 02 03 04    pushq  $0x4030201
>>
>> So this is a regression of sorts.
>>
>> What would really be ideal is:
>>
>>    0:   48 68 01 02 03 04       rex.W pushq $0x4030201
>>    6:   66 48 68 01 02 03 04    data32 rex.W pushq $0x4030201
>>
>> i.e., print both superfluous prefixes rather than ignoring either.
>> But it's not at all clear to me how to make that happen.  I also really
>> have no idea what other cases might be affected by the same sort of problem.
>>
>> HJ, do you have any insight into all this?
>>
>
> Please also fix "pushq $-1" with a testcase:
>
> [hjl@gnu-6 tmp]$ cat p.s
> .text
> pushq $-1
> rex.W pushq $-1
> .byte 0x66
> rex.W pushq $-1
> [hjl@gnu-6 tmp]$ gcc -c p.s
> [hjl@gnu-6 tmp]$ objdump -dw p.o
>
> p.o:     file format elf64-x86-64
>
>
> Disassembly of section .text:
>
> 0000000000000000 <.text>:
>    0:   6a ff                   pushq  $0xffffffffffffffff
>    2:   48 6a ff                rex.W pushq $0xffffffffffffffff
>    5:   66 48 6a ff             data32 pushq $0xffff
> [hjl@gnu-6 tmp]$
>
> OK with this change.
>

Also the new testcases should be added to
x86-64-stack.s, not a new file.

Thanks.

-- 
H.J.

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [RFC PATCH] Fix decoding of superfluous data32 prefix before superfluous rex.W prefix before push.
  2012-08-03 19:52   ` H.J. Lu
@ 2012-08-03 21:55     ` Roland McGrath
  2012-08-03 22:10       ` H.J. Lu
  0 siblings, 1 reply; 11+ messages in thread
From: Roland McGrath @ 2012-08-03 21:55 UTC (permalink / raw)
  To: H.J. Lu; +Cc: Victor Khimenko, binutils

On Fri, Aug 3, 2012 at 11:54 AM, H.J. Lu <hjl.tools@gmail.com> wrote:
> Also the new testcases should be added to x86-64-stack.s, not a new file.

I started out with just covering the rex.W prefix without data32 for the
existing cases, as below.  I'm committing this now.

Thanks,
Roland

gas/testsuite/
2012-08-03  Roland McGrath  <mcgrathr@google.com>

	* gas/i386/x86-64-stack.s (try): Also try just rex.W (0x48) prefix.
	* gas/testsuite/gas/i386/ilp32/x86-64-stack-intel.d: Updated.
	* gas/testsuite/gas/i386/ilp32/x86-64-stack-suffix.d: Updated.
	* gas/testsuite/gas/i386/ilp32/x86-64-stack.d: Updated.
	* gas/testsuite/gas/i386/x86-64-stack-intel.d: Updated.
	* gas/testsuite/gas/i386/x86-64-stack-suffix.d: Updated.
	* gas/testsuite/gas/i386/x86-64-stack.d: Updated.

diff --git a/gas/testsuite/gas/i386/ilp32/x86-64-stack-intel.d
b/gas/testsuite/gas/i386/ilp32/x86-64-stack-intel.d
index 59b4ced..7092a42 100644
--- a/gas/testsuite/gas/i386/ilp32/x86-64-stack-intel.d
+++ b/gas/testsuite/gas/i386/ilp32/x86-64-stack-intel.d
@@ -9,32 +9,42 @@ Disassembly of section .text:
 0+ <_start>:
 [ 	]*[a-f0-9]+:	50                   	push   rax
 [ 	]*[a-f0-9]+:	66 50                	push   ax
+[ 	]*[a-f0-9]+:	48 50                	rex.W push rax
 [ 	]*[a-f0-9]+:	66 48 50             	data32 push rax
 [ 	]*[a-f0-9]+:	58                   	pop    rax
 [ 	]*[a-f0-9]+:	66 58                	pop    ax
+[ 	]*[a-f0-9]+:	48 58                	rex.W pop rax
 [ 	]*[a-f0-9]+:	66 48 58             	data32 pop rax
 [ 	]*[a-f0-9]+:	8f c0                	pop    rax
 [ 	]*[a-f0-9]+:	66 8f c0             	pop    ax
+[ 	]*[a-f0-9]+:	48 8f c0             	rex.W pop rax
 [ 	]*[a-f0-9]+:	66 48 8f c0          	data32 pop rax
 [ 	]*[a-f0-9]+:	8f 00                	pop    QWORD PTR \[rax\]
 [ 	]*[a-f0-9]+:	66 8f 00             	pop    WORD PTR \[rax\]
+[ 	]*[a-f0-9]+:	48 8f 00             	rex.W pop QWORD PTR \[rax\]
 [ 	]*[a-f0-9]+:	66 48 8f 00          	data32 pop QWORD PTR \[rax\]
 [ 	]*[a-f0-9]+:	ff d0                	call   rax
 [ 	]*[a-f0-9]+:	66 ff d0             	call   ax
+[ 	]*[a-f0-9]+:	48 ff d0             	rex.W call rax
 [ 	]*[a-f0-9]+:	66 48 ff d0          	data32 call rax
 [ 	]*[a-f0-9]+:	ff 10                	call   QWORD PTR \[rax\]
 [ 	]*[a-f0-9]+:	66 ff 10             	call   WORD PTR \[rax\]
+[ 	]*[a-f0-9]+:	48 ff 10             	rex.W call QWORD PTR \[rax\]
 [ 	]*[a-f0-9]+:	66 48 ff 10          	data32 call QWORD PTR \[rax\]
 [ 	]*[a-f0-9]+:	ff e0                	jmp    rax
 [ 	]*[a-f0-9]+:	66 ff e0             	jmp    ax
+[ 	]*[a-f0-9]+:	48 ff e0             	rex.W jmp rax
 [ 	]*[a-f0-9]+:	66 48 ff e0          	data32 jmp rax
 [ 	]*[a-f0-9]+:	ff 20                	jmp    QWORD PTR \[rax\]
 [ 	]*[a-f0-9]+:	66 ff 20             	jmp    WORD PTR \[rax\]
+[ 	]*[a-f0-9]+:	48 ff 20             	rex.W jmp QWORD PTR \[rax\]
 [ 	]*[a-f0-9]+:	66 48 ff 20          	data32 jmp QWORD PTR \[rax\]
 [ 	]*[a-f0-9]+:	ff f0                	push   rax
 [ 	]*[a-f0-9]+:	66 ff f0             	push   ax
+[ 	]*[a-f0-9]+:	48 ff f0             	rex.W push rax
 [ 	]*[a-f0-9]+:	66 48 ff f0          	data32 push rax
 [ 	]*[a-f0-9]+:	ff 30                	push   QWORD PTR \[rax\]
 [ 	]*[a-f0-9]+:	66 ff 30             	push   WORD PTR \[rax\]
+[ 	]*[a-f0-9]+:	48 ff 30             	rex.W push QWORD PTR \[rax\]
 [ 	]*[a-f0-9]+:	66 48 ff 30          	data32 push QWORD PTR \[rax\]
 #pass
diff --git a/gas/testsuite/gas/i386/ilp32/x86-64-stack-suffix.d
b/gas/testsuite/gas/i386/ilp32/x86-64-stack-suffix.d
index 1d4db2d..45101dd 100644
--- a/gas/testsuite/gas/i386/ilp32/x86-64-stack-suffix.d
+++ b/gas/testsuite/gas/i386/ilp32/x86-64-stack-suffix.d
@@ -9,32 +9,42 @@ Disassembly of section .text:
 0+ <_start>:
 [ 	]*[a-f0-9]+:	50                   	pushq  %rax
 [ 	]*[a-f0-9]+:	66 50                	pushw  %ax
+[ 	]*[a-f0-9]+:	48 50                	rex.W pushq %rax
 [ 	]*[a-f0-9]+:	66 48 50             	data32 pushq %rax
 [ 	]*[a-f0-9]+:	58                   	popq   %rax
 [ 	]*[a-f0-9]+:	66 58                	popw   %ax
+[ 	]*[a-f0-9]+:	48 58                	rex.W popq %rax
 [ 	]*[a-f0-9]+:	66 48 58             	data32 popq %rax
 [ 	]*[a-f0-9]+:	8f c0                	popq   %rax
 [ 	]*[a-f0-9]+:	66 8f c0             	popw   %ax
+[ 	]*[a-f0-9]+:	48 8f c0             	rex.W popq %rax
 [ 	]*[a-f0-9]+:	66 48 8f c0          	data32 popq %rax
 [ 	]*[a-f0-9]+:	8f 00                	popq   \(%rax\)
 [ 	]*[a-f0-9]+:	66 8f 00             	popw   \(%rax\)
+[ 	]*[a-f0-9]+:	48 8f 00             	rex.W popq \(%rax\)
 [ 	]*[a-f0-9]+:	66 48 8f 00          	data32 popq \(%rax\)
 [ 	]*[a-f0-9]+:	ff d0                	callq  \*%rax
 [ 	]*[a-f0-9]+:	66 ff d0             	callw  \*%ax
+[ 	]*[a-f0-9]+:	48 ff d0             	rex.W callq \*%rax
 [ 	]*[a-f0-9]+:	66 48 ff d0          	data32 callq \*%rax
 [ 	]*[a-f0-9]+:	ff 10                	callq  \*\(%rax\)
 [ 	]*[a-f0-9]+:	66 ff 10             	callw  \*\(%rax\)
+[ 	]*[a-f0-9]+:	48 ff 10             	rex.W callq \*\(%rax\)
 [ 	]*[a-f0-9]+:	66 48 ff 10          	data32 callq \*\(%rax\)
 [ 	]*[a-f0-9]+:	ff e0                	jmpq   \*%rax
 [ 	]*[a-f0-9]+:	66 ff e0             	jmpw   \*%ax
+[ 	]*[a-f0-9]+:	48 ff e0             	rex.W jmpq \*%rax
 [ 	]*[a-f0-9]+:	66 48 ff e0          	data32 jmpq \*%rax
 [ 	]*[a-f0-9]+:	ff 20                	jmpq   \*\(%rax\)
 [ 	]*[a-f0-9]+:	66 ff 20             	jmpw   \*\(%rax\)
+[ 	]*[a-f0-9]+:	48 ff 20             	rex.W jmpq \*\(%rax\)
 [ 	]*[a-f0-9]+:	66 48 ff 20          	data32 jmpq \*\(%rax\)
 [ 	]*[a-f0-9]+:	ff f0                	pushq  %rax
 [ 	]*[a-f0-9]+:	66 ff f0             	pushw  %ax
+[ 	]*[a-f0-9]+:	48 ff f0             	rex.W pushq %rax
 [ 	]*[a-f0-9]+:	66 48 ff f0          	data32 pushq %rax
 [ 	]*[a-f0-9]+:	ff 30                	pushq  \(%rax\)
 [ 	]*[a-f0-9]+:	66 ff 30             	pushw  \(%rax\)
+[ 	]*[a-f0-9]+:	48 ff 30             	rex.W pushq \(%rax\)
 [ 	]*[a-f0-9]+:	66 48 ff 30          	data32 pushq \(%rax\)
 #pass
diff --git a/gas/testsuite/gas/i386/ilp32/x86-64-stack.d
b/gas/testsuite/gas/i386/ilp32/x86-64-stack.d
index 608baba..4976597 100644
--- a/gas/testsuite/gas/i386/ilp32/x86-64-stack.d
+++ b/gas/testsuite/gas/i386/ilp32/x86-64-stack.d
@@ -9,32 +9,42 @@ Disassembly of section .text:
 0+ <_start>:
 [ 	]*[a-f0-9]+:	50                   	push   %rax
 [ 	]*[a-f0-9]+:	66 50                	push   %ax
+[ 	]*[a-f0-9]+:	48 50                	rex.W push %rax
 [ 	]*[a-f0-9]+:	66 48 50             	data32 push %rax
 [ 	]*[a-f0-9]+:	58                   	pop    %rax
 [ 	]*[a-f0-9]+:	66 58                	pop    %ax
+[ 	]*[a-f0-9]+:	48 58                	rex.W pop %rax
 [ 	]*[a-f0-9]+:	66 48 58             	data32 pop %rax
 [ 	]*[a-f0-9]+:	8f c0                	pop    %rax
 [ 	]*[a-f0-9]+:	66 8f c0             	pop    %ax
+[ 	]*[a-f0-9]+:	48 8f c0             	rex.W pop %rax
 [ 	]*[a-f0-9]+:	66 48 8f c0          	data32 pop %rax
 [ 	]*[a-f0-9]+:	8f 00                	popq   \(%rax\)
 [ 	]*[a-f0-9]+:	66 8f 00             	popw   \(%rax\)
+[ 	]*[a-f0-9]+:	48 8f 00             	rex.W popq \(%rax\)
 [ 	]*[a-f0-9]+:	66 48 8f 00          	data32 popq \(%rax\)
 [ 	]*[a-f0-9]+:	ff d0                	callq  \*%rax
 [ 	]*[a-f0-9]+:	66 ff d0             	callw  \*%ax
+[ 	]*[a-f0-9]+:	48 ff d0             	rex.W callq \*%rax
 [ 	]*[a-f0-9]+:	66 48 ff d0          	data32 callq \*%rax
 [ 	]*[a-f0-9]+:	ff 10                	callq  \*\(%rax\)
 [ 	]*[a-f0-9]+:	66 ff 10             	callw  \*\(%rax\)
+[ 	]*[a-f0-9]+:	48 ff 10             	rex.W callq \*\(%rax\)
 [ 	]*[a-f0-9]+:	66 48 ff 10          	data32 callq \*\(%rax\)
 [ 	]*[a-f0-9]+:	ff e0                	jmpq   \*%rax
 [ 	]*[a-f0-9]+:	66 ff e0             	jmpw   \*%ax
+[ 	]*[a-f0-9]+:	48 ff e0             	rex.W jmpq \*%rax
 [ 	]*[a-f0-9]+:	66 48 ff e0          	data32 jmpq \*%rax
 [ 	]*[a-f0-9]+:	ff 20                	jmpq   \*\(%rax\)
 [ 	]*[a-f0-9]+:	66 ff 20             	jmpw   \*\(%rax\)
+[ 	]*[a-f0-9]+:	48 ff 20             	rex.W jmpq \*\(%rax\)
 [ 	]*[a-f0-9]+:	66 48 ff 20          	data32 jmpq \*\(%rax\)
 [ 	]*[a-f0-9]+:	ff f0                	push   %rax
 [ 	]*[a-f0-9]+:	66 ff f0             	push   %ax
+[ 	]*[a-f0-9]+:	48 ff f0             	rex.W push %rax
 [ 	]*[a-f0-9]+:	66 48 ff f0          	data32 push %rax
 [ 	]*[a-f0-9]+:	ff 30                	pushq  \(%rax\)
 [ 	]*[a-f0-9]+:	66 ff 30             	pushw  \(%rax\)
+[ 	]*[a-f0-9]+:	48 ff 30             	rex.W pushq \(%rax\)
 [ 	]*[a-f0-9]+:	66 48 ff 30          	data32 pushq \(%rax\)
 #pass
diff --git a/gas/testsuite/gas/i386/x86-64-stack-intel.d
b/gas/testsuite/gas/i386/x86-64-stack-intel.d
index a09be6c..4c54af7 100644
--- a/gas/testsuite/gas/i386/x86-64-stack-intel.d
+++ b/gas/testsuite/gas/i386/x86-64-stack-intel.d
@@ -9,32 +9,42 @@ Disassembly of section .text:
 0+ <_start>:
 [ 	]*[a-f0-9]+:	50                   	push   rax
 [ 	]*[a-f0-9]+:	66 50                	push   ax
+[ 	]*[a-f0-9]+:	48 50                	rex.W push rax
 [ 	]*[a-f0-9]+:	66 48 50             	data32 push rax
 [ 	]*[a-f0-9]+:	58                   	pop    rax
 [ 	]*[a-f0-9]+:	66 58                	pop    ax
+[ 	]*[a-f0-9]+:	48 58                	rex.W pop rax
 [ 	]*[a-f0-9]+:	66 48 58             	data32 pop rax
 [ 	]*[a-f0-9]+:	8f c0                	pop    rax
 [ 	]*[a-f0-9]+:	66 8f c0             	pop    ax
+[ 	]*[a-f0-9]+:	48 8f c0             	rex.W pop rax
 [ 	]*[a-f0-9]+:	66 48 8f c0          	data32 pop rax
 [ 	]*[a-f0-9]+:	8f 00                	pop    QWORD PTR \[rax\]
 [ 	]*[a-f0-9]+:	66 8f 00             	pop    WORD PTR \[rax\]
+[ 	]*[a-f0-9]+:	48 8f 00             	rex.W pop QWORD PTR \[rax\]
 [ 	]*[a-f0-9]+:	66 48 8f 00          	data32 pop QWORD PTR \[rax\]
 [ 	]*[a-f0-9]+:	ff d0                	call   rax
 [ 	]*[a-f0-9]+:	66 ff d0             	call   ax
+[ 	]*[a-f0-9]+:	48 ff d0             	rex.W call rax
 [ 	]*[a-f0-9]+:	66 48 ff d0          	data32 call rax
 [ 	]*[a-f0-9]+:	ff 10                	call   QWORD PTR \[rax\]
 [ 	]*[a-f0-9]+:	66 ff 10             	call   WORD PTR \[rax\]
+[ 	]*[a-f0-9]+:	48 ff 10             	rex.W call QWORD PTR \[rax\]
 [ 	]*[a-f0-9]+:	66 48 ff 10          	data32 call QWORD PTR \[rax\]
 [ 	]*[a-f0-9]+:	ff e0                	jmp    rax
 [ 	]*[a-f0-9]+:	66 ff e0             	jmp    ax
+[ 	]*[a-f0-9]+:	48 ff e0             	rex.W jmp rax
 [ 	]*[a-f0-9]+:	66 48 ff e0          	data32 jmp rax
 [ 	]*[a-f0-9]+:	ff 20                	jmp    QWORD PTR \[rax\]
 [ 	]*[a-f0-9]+:	66 ff 20             	jmp    WORD PTR \[rax\]
+[ 	]*[a-f0-9]+:	48 ff 20             	rex.W jmp QWORD PTR \[rax\]
 [ 	]*[a-f0-9]+:	66 48 ff 20          	data32 jmp QWORD PTR \[rax\]
 [ 	]*[a-f0-9]+:	ff f0                	push   rax
 [ 	]*[a-f0-9]+:	66 ff f0             	push   ax
+[ 	]*[a-f0-9]+:	48 ff f0             	rex.W push rax
 [ 	]*[a-f0-9]+:	66 48 ff f0          	data32 push rax
 [ 	]*[a-f0-9]+:	ff 30                	push   QWORD PTR \[rax\]
 [ 	]*[a-f0-9]+:	66 ff 30             	push   WORD PTR \[rax\]
+[ 	]*[a-f0-9]+:	48 ff 30             	rex.W push QWORD PTR \[rax\]
 [ 	]*[a-f0-9]+:	66 48 ff 30          	data32 push QWORD PTR \[rax\]
 #pass
diff --git a/gas/testsuite/gas/i386/x86-64-stack-suffix.d
b/gas/testsuite/gas/i386/x86-64-stack-suffix.d
index ce1386a..07bf79b 100644
--- a/gas/testsuite/gas/i386/x86-64-stack-suffix.d
+++ b/gas/testsuite/gas/i386/x86-64-stack-suffix.d
@@ -9,32 +9,42 @@ Disassembly of section .text:
 0+ <_start>:
 [ 	]*[a-f0-9]+:	50                   	pushq  %rax
 [ 	]*[a-f0-9]+:	66 50                	pushw  %ax
+[ 	]*[a-f0-9]+:	48 50                	rex.W pushq %rax
 [ 	]*[a-f0-9]+:	66 48 50             	data32 pushq %rax
 [ 	]*[a-f0-9]+:	58                   	popq   %rax
 [ 	]*[a-f0-9]+:	66 58                	popw   %ax
+[ 	]*[a-f0-9]+:	48 58                	rex.W popq %rax
 [ 	]*[a-f0-9]+:	66 48 58             	data32 popq %rax
 [ 	]*[a-f0-9]+:	8f c0                	popq   %rax
 [ 	]*[a-f0-9]+:	66 8f c0             	popw   %ax
+[ 	]*[a-f0-9]+:	48 8f c0             	rex.W popq %rax
 [ 	]*[a-f0-9]+:	66 48 8f c0          	data32 popq %rax
 [ 	]*[a-f0-9]+:	8f 00                	popq   \(%rax\)
 [ 	]*[a-f0-9]+:	66 8f 00             	popw   \(%rax\)
+[ 	]*[a-f0-9]+:	48 8f 00             	rex.W popq \(%rax\)
 [ 	]*[a-f0-9]+:	66 48 8f 00          	data32 popq \(%rax\)
 [ 	]*[a-f0-9]+:	ff d0                	callq  \*%rax
 [ 	]*[a-f0-9]+:	66 ff d0             	callw  \*%ax
+[ 	]*[a-f0-9]+:	48 ff d0             	rex.W callq \*%rax
 [ 	]*[a-f0-9]+:	66 48 ff d0          	data32 callq \*%rax
 [ 	]*[a-f0-9]+:	ff 10                	callq  \*\(%rax\)
 [ 	]*[a-f0-9]+:	66 ff 10             	callw  \*\(%rax\)
+[ 	]*[a-f0-9]+:	48 ff 10             	rex.W callq \*\(%rax\)
 [ 	]*[a-f0-9]+:	66 48 ff 10          	data32 callq \*\(%rax\)
 [ 	]*[a-f0-9]+:	ff e0                	jmpq   \*%rax
 [ 	]*[a-f0-9]+:	66 ff e0             	jmpw   \*%ax
+[ 	]*[a-f0-9]+:	48 ff e0             	rex.W jmpq \*%rax
 [ 	]*[a-f0-9]+:	66 48 ff e0          	data32 jmpq \*%rax
 [ 	]*[a-f0-9]+:	ff 20                	jmpq   \*\(%rax\)
 [ 	]*[a-f0-9]+:	66 ff 20             	jmpw   \*\(%rax\)
+[ 	]*[a-f0-9]+:	48 ff 20             	rex.W jmpq \*\(%rax\)
 [ 	]*[a-f0-9]+:	66 48 ff 20          	data32 jmpq \*\(%rax\)
 [ 	]*[a-f0-9]+:	ff f0                	pushq  %rax
 [ 	]*[a-f0-9]+:	66 ff f0             	pushw  %ax
+[ 	]*[a-f0-9]+:	48 ff f0             	rex.W pushq %rax
 [ 	]*[a-f0-9]+:	66 48 ff f0          	data32 pushq %rax
 [ 	]*[a-f0-9]+:	ff 30                	pushq  \(%rax\)
 [ 	]*[a-f0-9]+:	66 ff 30             	pushw  \(%rax\)
+[ 	]*[a-f0-9]+:	48 ff 30             	rex.W pushq \(%rax\)
 [ 	]*[a-f0-9]+:	66 48 ff 30          	data32 pushq \(%rax\)
 #pass
diff --git a/gas/testsuite/gas/i386/x86-64-stack.d
b/gas/testsuite/gas/i386/x86-64-stack.d
index 2d806f4..0ab339d 100644
--- a/gas/testsuite/gas/i386/x86-64-stack.d
+++ b/gas/testsuite/gas/i386/x86-64-stack.d
@@ -8,32 +8,42 @@ Disassembly of section .text:
 0+ <_start>:
 [ 	]*[a-f0-9]+:	50                   	push   %rax
 [ 	]*[a-f0-9]+:	66 50                	push   %ax
+[ 	]*[a-f0-9]+:	48 50                	rex.W push %rax
 [ 	]*[a-f0-9]+:	66 48 50             	data32 push %rax
 [ 	]*[a-f0-9]+:	58                   	pop    %rax
 [ 	]*[a-f0-9]+:	66 58                	pop    %ax
+[ 	]*[a-f0-9]+:	48 58                	rex.W pop %rax
 [ 	]*[a-f0-9]+:	66 48 58             	data32 pop %rax
 [ 	]*[a-f0-9]+:	8f c0                	pop    %rax
 [ 	]*[a-f0-9]+:	66 8f c0             	pop    %ax
+[ 	]*[a-f0-9]+:	48 8f c0             	rex.W pop %rax
 [ 	]*[a-f0-9]+:	66 48 8f c0          	data32 pop %rax
 [ 	]*[a-f0-9]+:	8f 00                	popq   \(%rax\)
 [ 	]*[a-f0-9]+:	66 8f 00             	popw   \(%rax\)
+[ 	]*[a-f0-9]+:	48 8f 00             	rex.W popq \(%rax\)
 [ 	]*[a-f0-9]+:	66 48 8f 00          	data32 popq \(%rax\)
 [ 	]*[a-f0-9]+:	ff d0                	callq  \*%rax
 [ 	]*[a-f0-9]+:	66 ff d0             	callw  \*%ax
+[ 	]*[a-f0-9]+:	48 ff d0             	rex.W callq \*%rax
 [ 	]*[a-f0-9]+:	66 48 ff d0          	data32 callq \*%rax
 [ 	]*[a-f0-9]+:	ff 10                	callq  \*\(%rax\)
 [ 	]*[a-f0-9]+:	66 ff 10             	callw  \*\(%rax\)
+[ 	]*[a-f0-9]+:	48 ff 10             	rex.W callq \*\(%rax\)
 [ 	]*[a-f0-9]+:	66 48 ff 10          	data32 callq \*\(%rax\)
 [ 	]*[a-f0-9]+:	ff e0                	jmpq   \*%rax
 [ 	]*[a-f0-9]+:	66 ff e0             	jmpw   \*%ax
+[ 	]*[a-f0-9]+:	48 ff e0             	rex.W jmpq \*%rax
 [ 	]*[a-f0-9]+:	66 48 ff e0          	data32 jmpq \*%rax
 [ 	]*[a-f0-9]+:	ff 20                	jmpq   \*\(%rax\)
 [ 	]*[a-f0-9]+:	66 ff 20             	jmpw   \*\(%rax\)
+[ 	]*[a-f0-9]+:	48 ff 20             	rex.W jmpq \*\(%rax\)
 [ 	]*[a-f0-9]+:	66 48 ff 20          	data32 jmpq \*\(%rax\)
 [ 	]*[a-f0-9]+:	ff f0                	push   %rax
 [ 	]*[a-f0-9]+:	66 ff f0             	push   %ax
+[ 	]*[a-f0-9]+:	48 ff f0             	rex.W push %rax
 [ 	]*[a-f0-9]+:	66 48 ff f0          	data32 push %rax
 [ 	]*[a-f0-9]+:	ff 30                	pushq  \(%rax\)
 [ 	]*[a-f0-9]+:	66 ff 30             	pushw  \(%rax\)
+[ 	]*[a-f0-9]+:	48 ff 30             	rex.W pushq \(%rax\)
 [ 	]*[a-f0-9]+:	66 48 ff 30          	data32 pushq \(%rax\)
 #pass
diff --git a/gas/testsuite/gas/i386/x86-64-stack.s
b/gas/testsuite/gas/i386/x86-64-stack.s
index e0fc046..d114887 100644
--- a/gas/testsuite/gas/i386/x86-64-stack.s
+++ b/gas/testsuite/gas/i386/x86-64-stack.s
@@ -1,6 +1,7 @@
  .macro try bytes:vararg
   .byte \bytes
   .byte 0x66, \bytes
+  .byte 0x48, \bytes
   .byte 0x66, 0x48, \bytes
  .endm

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [RFC PATCH] Fix decoding of superfluous data32 prefix before superfluous rex.W prefix before push.
  2012-08-03 21:55     ` Roland McGrath
@ 2012-08-03 22:10       ` H.J. Lu
  0 siblings, 0 replies; 11+ messages in thread
From: H.J. Lu @ 2012-08-03 22:10 UTC (permalink / raw)
  To: Roland McGrath; +Cc: Victor Khimenko, binutils

On Fri, Aug 3, 2012 at 2:45 PM, Roland McGrath <mcgrathr@google.com> wrote:
> On Fri, Aug 3, 2012 at 11:54 AM, H.J. Lu <hjl.tools@gmail.com> wrote:
>> Also the new testcases should be added to x86-64-stack.s, not a new file.
>
> I started out with just covering the rex.W prefix without data32 for the
> existing cases, as below.  I'm committing this now.
>
> Thanks,
> Roland
>
> gas/testsuite/
> 2012-08-03  Roland McGrath  <mcgrathr@google.com>
>
>         * gas/i386/x86-64-stack.s (try): Also try just rex.W (0x48) prefix.
>         * gas/testsuite/gas/i386/ilp32/x86-64-stack-intel.d: Updated.
>         * gas/testsuite/gas/i386/ilp32/x86-64-stack-suffix.d: Updated.
>         * gas/testsuite/gas/i386/ilp32/x86-64-stack.d: Updated.
>         * gas/testsuite/gas/i386/x86-64-stack-intel.d: Updated.
>         * gas/testsuite/gas/i386/x86-64-stack-suffix.d: Updated.
>         * gas/testsuite/gas/i386/x86-64-stack.d: Updated.
>

Thanks.

-- 
H.J.

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [RFC PATCH] Fix decoding of superfluous data32 prefix before superfluous rex.W prefix before push.
  2012-08-03 18:54 ` H.J. Lu
  2012-08-03 19:52   ` H.J. Lu
@ 2012-08-03 23:24   ` Roland McGrath
  2012-08-03 23:36     ` H.J. Lu
  1 sibling, 1 reply; 11+ messages in thread
From: Roland McGrath @ 2012-08-03 23:24 UTC (permalink / raw)
  To: H.J. Lu; +Cc: Victor Khimenko, binutils

I noticed that since you used #pass in the .d files, one could add more
cases to the end of x86-64-stack.s and not notice if one failed to update
all the .d files appropriately.  So I added a nop at the end, to make sure
that's matched last.

What I was hoping is that you could tell me how to change:

   0:	66 48 6a ff          	data32 pushq $0xffffffffffffffff
   4:	66 48 68 01 02 03 04 	data32 pushq $0x4030201

into:

   0:	66 48 6a ff          	data32 rex.W pushq $0xffffffffffffffff
   4:	66 48 68 01 02 03 04 	data32 rex.W pushq $0x4030201

i.e., recognize that the rex.W prefix was not used, as it already
does when there is no data32 prefix before it.  Do you have an idea
to fix that?

Here's what I have now.  But I'd really prefer not to commit it like this
if we can make it show the unused rex.W prefix instead.


Thanks,
Roland


gas/testsuite/
	* gas/i386/x86-64-stack.s: Add cases for push immediate.
	* gas/testsuite/gas/i386/ilp32/x86-64-stack-intel.d: Updated.
	* gas/testsuite/gas/i386/ilp32/x86-64-stack-suffix.d: Updated.
	* gas/testsuite/gas/i386/ilp32/x86-64-stack.d: Updated.
	* gas/testsuite/gas/i386/x86-64-stack-intel.d: Updated.
	* gas/testsuite/gas/i386/x86-64-stack-suffix.d: Updated.
	* gas/testsuite/gas/i386/x86-64-stack.d: Updated.

opcodes/
2012-08-03  Roland McGrath  <mcgrathr@google.com>
	    Victor Khimenko  <khim@google.com>

	* i386-dis.c (OP_sI): In b_T_mode and v_mode, REX_W trumps DFLAG.


diff --git a/gas/testsuite/gas/i386/ilp32/x86-64-stack-intel.d
b/gas/testsuite/gas/i386/ilp32/x86-64-stack-intel.d
index 7092a42..a5692c9 100644
--- a/gas/testsuite/gas/i386/ilp32/x86-64-stack-intel.d
+++ b/gas/testsuite/gas/i386/ilp32/x86-64-stack-intel.d
@@ -47,4 +47,14 @@ Disassembly of section .text:
 [ 	]*[a-f0-9]+:	66 ff 30             	push   WORD PTR \[rax\]
 [ 	]*[a-f0-9]+:	48 ff 30             	rex.W push QWORD PTR \[rax\]
 [ 	]*[a-f0-9]+:	66 48 ff 30          	data32 push QWORD PTR \[rax\]
+[ 	]*[a-f0-9]+:	6a ff                	push   0xffffffffffffffff
+[ 	]*[a-f0-9]+:	66 6a ff             	pushw  0xffff
+[ 	]*[a-f0-9]+:	48 6a ff             	rex.W push 0xffffffffffffffff
+[ 	]*[a-f0-9]+:	66 48 6a ff          	data32 rex.W push 0xffffffffffffffff
+[ 	]*[a-f0-9]+:	68 01 02 03 04       	push   0x4030201
+[ 	]*[a-f0-9]+:	66 68 01 02          	pushw  0x201
+[ 	]*[a-f0-9]+:	03 04 48             	add    eax,DWORD PTR \[rax\+rcx\*2\]
+[ 	]*[a-f0-9]+:	68 01 02 03 04       	push   0x4030201
+[ 	]*[a-f0-9]+:	66 48 68 01 02 03 04 	data32 rex.W push 0x4030201
+[ 	]*[a-f0-9]+:	90                   	nop
 #pass
diff --git a/gas/testsuite/gas/i386/ilp32/x86-64-stack-suffix.d
b/gas/testsuite/gas/i386/ilp32/x86-64-stack-suffix.d
index 45101dd..ecc8c75 100644
--- a/gas/testsuite/gas/i386/ilp32/x86-64-stack-suffix.d
+++ b/gas/testsuite/gas/i386/ilp32/x86-64-stack-suffix.d
@@ -47,4 +47,14 @@ Disassembly of section .text:
 [ 	]*[a-f0-9]+:	66 ff 30             	pushw  \(%rax\)
 [ 	]*[a-f0-9]+:	48 ff 30             	rex.W pushq \(%rax\)
 [ 	]*[a-f0-9]+:	66 48 ff 30          	data32 pushq \(%rax\)
+[ 	]*[a-f0-9]+:	6a ff                	pushq  \$0xffffffffffffffff
+[ 	]*[a-f0-9]+:	66 6a ff             	pushw  \$0xffff
+[ 	]*[a-f0-9]+:	48 6a ff             	rex.W pushq \$0xffffffffffffffff
+[ 	]*[a-f0-9]+:	66 48 6a ff          	data32 pushq \$0xffffffffffffffff
+[ 	]*[a-f0-9]+:	68 01 02 03 04       	pushq  \$0x4030201
+[ 	]*[a-f0-9]+:	66 68 01 02          	pushw  \$0x201
+[ 	]*[a-f0-9]+:	03 04 48             	addl   \(%rax,%rcx,2\),%eax
+[ 	]*[a-f0-9]+:	68 01 02 03 04       	pushq  \$0x4030201
+[ 	]*[a-f0-9]+:	66 48 68 01 02 03 04 	data32 pushq \$0x4030201
+[ 	]*[a-f0-9]+:	90                   	nop
 #pass
diff --git a/gas/testsuite/gas/i386/ilp32/x86-64-stack.d
b/gas/testsuite/gas/i386/ilp32/x86-64-stack.d
index 4976597..67b89f4 100644
--- a/gas/testsuite/gas/i386/ilp32/x86-64-stack.d
+++ b/gas/testsuite/gas/i386/ilp32/x86-64-stack.d
@@ -47,4 +47,14 @@ Disassembly of section .text:
 [ 	]*[a-f0-9]+:	66 ff 30             	pushw  \(%rax\)
 [ 	]*[a-f0-9]+:	48 ff 30             	rex.W pushq \(%rax\)
 [ 	]*[a-f0-9]+:	66 48 ff 30          	data32 pushq \(%rax\)
+[ 	]*[a-f0-9]+:	6a ff                	pushq  \$0xffffffffffffffff
+[ 	]*[a-f0-9]+:	66 6a ff             	pushw  \$0xffff
+[ 	]*[a-f0-9]+:	48 6a ff             	rex.W pushq \$0xffffffffffffffff
+[ 	]*[a-f0-9]+:	66 48 6a ff          	data32 pushq \$0xffffffffffffffff
+[ 	]*[a-f0-9]+:	68 01 02 03 04       	pushq  \$0x4030201
+[ 	]*[a-f0-9]+:	66 68 01 02          	pushw  \$0x201
+[ 	]*[a-f0-9]+:	03 04 48             	add    \(%rax,%rcx,2\),%eax
+[ 	]*[a-f0-9]+:	68 01 02 03 04       	pushq  \$0x4030201
+[ 	]*[a-f0-9]+:	66 48 68 01 02 03 04 	data32 pushq \$0x4030201
+[ 	]*[a-f0-9]+:	90                   	nop
 #pass
diff --git a/gas/testsuite/gas/i386/x86-64-stack-intel.d
b/gas/testsuite/gas/i386/x86-64-stack-intel.d
index 4c54af7..cbe4880 100644
--- a/gas/testsuite/gas/i386/x86-64-stack-intel.d
+++ b/gas/testsuite/gas/i386/x86-64-stack-intel.d
@@ -47,4 +47,14 @@ Disassembly of section .text:
 [ 	]*[a-f0-9]+:	66 ff 30             	push   WORD PTR \[rax\]
 [ 	]*[a-f0-9]+:	48 ff 30             	rex.W push QWORD PTR \[rax\]
 [ 	]*[a-f0-9]+:	66 48 ff 30          	data32 push QWORD PTR \[rax\]
+[ 	]*[a-f0-9]+:	6a ff                	push   0xffffffffffffffff
+[ 	]*[a-f0-9]+:	66 6a ff             	pushw  0xffff
+[ 	]*[a-f0-9]+:	48 6a ff             	rex.W push 0xffffffffffffffff
+[ 	]*[a-f0-9]+:	66 48 6a ff          	data32 rex.W push 0xffffffffffffffff
+[ 	]*[a-f0-9]+:	68 01 02 03 04       	push   0x4030201
+[ 	]*[a-f0-9]+:	66 68 01 02          	pushw  0x201
+[ 	]*[a-f0-9]+:	03 04 48             	add    eax,DWORD PTR \[rax\+rcx\*2\]
+[ 	]*[a-f0-9]+:	68 01 02 03 04       	push   0x4030201
+[ 	]*[a-f0-9]+:	66 48 68 01 02 03 04 	data32 rex.W push 0x4030201
+[ 	]*[a-f0-9]+:	90                   	nop
 #pass
diff --git a/gas/testsuite/gas/i386/x86-64-stack-suffix.d
b/gas/testsuite/gas/i386/x86-64-stack-suffix.d
index 07bf79b..fc9b1ff 100644
--- a/gas/testsuite/gas/i386/x86-64-stack-suffix.d
+++ b/gas/testsuite/gas/i386/x86-64-stack-suffix.d
@@ -47,4 +47,14 @@ Disassembly of section .text:
 [ 	]*[a-f0-9]+:	66 ff 30             	pushw  \(%rax\)
 [ 	]*[a-f0-9]+:	48 ff 30             	rex.W pushq \(%rax\)
 [ 	]*[a-f0-9]+:	66 48 ff 30          	data32 pushq \(%rax\)
+[ 	]*[a-f0-9]+:	6a ff                	pushq  \$0xffffffffffffffff
+[ 	]*[a-f0-9]+:	66 6a ff             	pushw  \$0xffff
+[ 	]*[a-f0-9]+:	48 6a ff             	rex.W pushq \$0xffffffffffffffff
+[ 	]*[a-f0-9]+:	66 48 6a ff          	data32 pushq \$0xffffffffffffffff
+[ 	]*[a-f0-9]+:	68 01 02 03 04       	pushq  \$0x4030201
+[ 	]*[a-f0-9]+:	66 68 01 02          	pushw  \$0x201
+[ 	]*[a-f0-9]+:	03 04 48             	addl   \(%rax,%rcx,2\),%eax
+[ 	]*[a-f0-9]+:	68 01 02 03 04       	pushq  \$0x4030201
+[ 	]*[a-f0-9]+:	66 48 68 01 02 03 04 	data32 pushq \$0x4030201
+[ 	]*[a-f0-9]+:	90                   	nop
 #pass
diff --git a/gas/testsuite/gas/i386/x86-64-stack.d
b/gas/testsuite/gas/i386/x86-64-stack.d
index 0ab339d..899eff0 100644
--- a/gas/testsuite/gas/i386/x86-64-stack.d
+++ b/gas/testsuite/gas/i386/x86-64-stack.d
@@ -46,4 +46,14 @@ Disassembly of section .text:
 [ 	]*[a-f0-9]+:	66 ff 30             	pushw  \(%rax\)
 [ 	]*[a-f0-9]+:	48 ff 30             	rex.W pushq \(%rax\)
 [ 	]*[a-f0-9]+:	66 48 ff 30          	data32 pushq \(%rax\)
+[ 	]*[a-f0-9]+:	6a ff                	pushq  \$0xffffffffffffffff
+[ 	]*[a-f0-9]+:	66 6a ff             	pushw  \$0xffff
+[ 	]*[a-f0-9]+:	48 6a ff             	rex.W pushq \$0xffffffffffffffff
+[ 	]*[a-f0-9]+:	66 48 6a ff          	data32 pushq \$0xffffffffffffffff
+[ 	]*[a-f0-9]+:	68 01 02 03 04       	pushq  \$0x4030201
+[ 	]*[a-f0-9]+:	66 68 01 02          	pushw  \$0x201
+[ 	]*[a-f0-9]+:	03 04 48             	add    \(%rax,%rcx,2\),%eax
+[ 	]*[a-f0-9]+:	68 01 02 03 04       	pushq  \$0x4030201
+[ 	]*[a-f0-9]+:	66 48 68 01 02 03 04 	data32 pushq \$0x4030201
+[ 	]*[a-f0-9]+:	90                   	nop
 #pass
diff --git a/gas/testsuite/gas/i386/x86-64-stack.s
b/gas/testsuite/gas/i386/x86-64-stack.s
index d114887..2da658b 100644
--- a/gas/testsuite/gas/i386/x86-64-stack.s
+++ b/gas/testsuite/gas/i386/x86-64-stack.s
@@ -22,3 +22,13 @@ _start:

 	try	0xff, 0xf0
 	try	0xff, 0x30
+
+	# push with a 1-byte immediate
+	try	0x6a, 0xff
+
+	# push with a 4-byte immediate
+	try	0x68, 0x01, 0x02, 0x03, 0x04
+
+	# This is just to synchronize the disassembly.
+	# Any new cases must come before this line!
+	nop
diff --git a/opcodes/i386-dis.c b/opcodes/i386-dis.c
index 685e968..c207e06 100644
--- a/opcodes/i386-dis.c
+++ b/opcodes/i386-dis.c
@@ -1,6 +1,6 @@
 /* Print i386 instructions for GDB, the GNU debugger.
    Copyright 1988, 1989, 1991, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
-   2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011
+   2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012
    Free Software Foundation, Inc.

    This file is part of the GNU opcodes library.
@@ -13710,9 +13710,10 @@ OP_sI (int bytemode, int sizeflag)
       if (bytemode == b_T_mode)
 	{
 	  if (address_mode != mode_64bit
-	      || !(sizeflag & DFLAG))
+	      || !((sizeflag & DFLAG) || (rex & REX_W)))
 	    {
-	      if (sizeflag & DFLAG)
+              /* The operand-size prefix is overridden by a REX prefix.  */
+              if ((sizeflag & DFLAG) || (rex & REX_W))
 		op &= 0xffffffff;
 	      else
 		op &= 0xffff;
@@ -13730,7 +13731,8 @@ OP_sI (int bytemode, int sizeflag)
 	}
       break;
     case v_mode:
-      if (sizeflag & DFLAG)
+      /* The operand-size prefix is overridden by a REX prefix.  */
+      if ((sizeflag & DFLAG) || (rex & REX_W))
 	op = get32s ();
       else
 	op = get16 ();

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [RFC PATCH] Fix decoding of superfluous data32 prefix before superfluous rex.W prefix before push.
  2012-08-03 23:24   ` Roland McGrath
@ 2012-08-03 23:36     ` H.J. Lu
  2012-08-04  0:30       ` H.J. Lu
  0 siblings, 1 reply; 11+ messages in thread
From: H.J. Lu @ 2012-08-03 23:36 UTC (permalink / raw)
  To: Roland McGrath; +Cc: Victor Khimenko, binutils

On Fri, Aug 3, 2012 at 3:59 PM, Roland McGrath <mcgrathr@google.com> wrote:
> I noticed that since you used #pass in the .d files, one could add more
> cases to the end of x86-64-stack.s and not notice if one failed to update
> all the .d files appropriately.  So I added a nop at the end, to make sure
> that's matched last.
>
> What I was hoping is that you could tell me how to change:
>
>    0:   66 48 6a ff             data32 pushq $0xffffffffffffffff
>    4:   66 48 68 01 02 03 04    data32 pushq $0x4030201
>
> into:
>
>    0:   66 48 6a ff             data32 rex.W pushq $0xffffffffffffffff
>    4:   66 48 68 01 02 03 04    data32 rex.W pushq $0x4030201
>
> i.e., recognize that the rex.W prefix was not used, as it already
> does when there is no data32 prefix before it.  Do you have an idea
> to fix that?
>

There are

/* Bits of REX we've already used.  */
static int rex_used;

Please make sure that it isn't set for push.

-- 
H.J.

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [RFC PATCH] Fix decoding of superfluous data32 prefix before superfluous rex.W prefix before push.
  2012-08-03 23:36     ` H.J. Lu
@ 2012-08-04  0:30       ` H.J. Lu
  2012-08-06 20:02         ` Roland McGrath
  0 siblings, 1 reply; 11+ messages in thread
From: H.J. Lu @ 2012-08-04  0:30 UTC (permalink / raw)
  To: Roland McGrath; +Cc: Victor Khimenko, binutils

On Fri, Aug 3, 2012 at 4:24 PM, H.J. Lu <hjl.tools@gmail.com> wrote:
> On Fri, Aug 3, 2012 at 3:59 PM, Roland McGrath <mcgrathr@google.com> wrote:
>> I noticed that since you used #pass in the .d files, one could add more
>> cases to the end of x86-64-stack.s and not notice if one failed to update
>> all the .d files appropriately.  So I added a nop at the end, to make sure
>> that's matched last.
>>
>> What I was hoping is that you could tell me how to change:
>>
>>    0:   66 48 6a ff             data32 pushq $0xffffffffffffffff
>>    4:   66 48 68 01 02 03 04    data32 pushq $0x4030201
>>
>> into:
>>
>>    0:   66 48 6a ff             data32 rex.W pushq $0xffffffffffffffff
>>    4:   66 48 68 01 02 03 04    data32 rex.W pushq $0x4030201
>>
>> i.e., recognize that the rex.W prefix was not used, as it already
>> does when there is no data32 prefix before it.  Do you have an idea
>> to fix that?
>>
>
> There are
>
> /* Bits of REX we've already used.  */
> static int rex_used;
>
> Please make sure that it isn't set for push.

This seems to work:

diff --git a/opcodes/i386-dis.c b/opcodes/i386-dis.c
index 685e968..ed79d92 100644
--- a/opcodes/i386-dis.c
+++ b/opcodes/i386-dis.c
@@ -12275,7 +12275,7 @@ case_L:
   case 'T':
     if (!intel_syntax
         && address_mode == mode_64bit
-        && (sizeflag & DFLAG))
+        && ((rex & REX_W) || (sizeflag & DFLAG)))
       {
         *obufp++ = 'q';
         break;

We need to update some testcases.

-- 
H.J.

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [RFC PATCH] Fix decoding of superfluous data32 prefix before superfluous rex.W prefix before push.
  2012-08-04  0:30       ` H.J. Lu
@ 2012-08-06 20:02         ` Roland McGrath
  2012-08-06 20:20           ` H.J. Lu
  0 siblings, 1 reply; 11+ messages in thread
From: Roland McGrath @ 2012-08-06 20:02 UTC (permalink / raw)
  To: H.J. Lu; +Cc: Victor Khimenko, binutils

Thanks for that pointer.  I followed that hint to do a few more similar
changes and managed to get to where all the "66 48 ..." cases in
x86-64-stack.s produce "data32 rex.W ...".  Here's the final change
including all that.

There are no other 'make check' regressions on x86_64-linux-gnu.
The disassembler code is so hairy that I can't be sure I haven't broken
some other case for which there is no test coverage.  But you might
know it enough better that you can be more confident than I am.

Ok for trunk?


Thanks,
Roland


gas/testsuite/
2012-08-06  Roland McGrath  <mcgrathr@google.com>

	* gas/i386/x86-64-stack.s: Add cases for push immediate.
	* gas/testsuite/gas/i386/ilp32/x86-64-stack-intel.d: Updated.
	* gas/testsuite/gas/i386/ilp32/x86-64-stack-suffix.d: Updated.
	* gas/testsuite/gas/i386/ilp32/x86-64-stack.d: Updated.
	* gas/testsuite/gas/i386/x86-64-stack-intel.d: Updated.
	* gas/testsuite/gas/i386/x86-64-stack-suffix.d: Updated.
	* gas/testsuite/gas/i386/x86-64-stack.d: Updated.

opcodes/
2012-08-06  Roland McGrath  <mcgrathr@google.com>
	    Victor Khimenko  <khim@google.com>
	    H.J. Lu  <hongjiu.lu@intel.com>

	* i386-dis.c (OP_sI): In b_T_mode and v_mode, REX_W trumps DFLAG.
	(putop): For 'T', 'U', and 'V', treat REX_W like DFLAG.
	(intel_operand_size): For stack_v_mode, treat REX_W like DFLAG.
	(OP_E_register): Likewise.
	(OP_REG): For low 8 whole registers, treat REX_W like DFLAG.

diff --git a/gas/testsuite/gas/i386/ilp32/x86-64-stack-intel.d
b/gas/testsuite/gas/i386/ilp32/x86-64-stack-intel.d
index 7092a42..fbcada2 100644
--- a/gas/testsuite/gas/i386/ilp32/x86-64-stack-intel.d
+++ b/gas/testsuite/gas/i386/ilp32/x86-64-stack-intel.d
@@ -10,41 +10,51 @@ Disassembly of section .text:
 [ 	]*[a-f0-9]+:	50                   	push   rax
 [ 	]*[a-f0-9]+:	66 50                	push   ax
 [ 	]*[a-f0-9]+:	48 50                	rex.W push rax
-[ 	]*[a-f0-9]+:	66 48 50             	data32 push rax
+[ 	]*[a-f0-9]+:	66 48 50             	data32 rex.W push rax
 [ 	]*[a-f0-9]+:	58                   	pop    rax
 [ 	]*[a-f0-9]+:	66 58                	pop    ax
 [ 	]*[a-f0-9]+:	48 58                	rex.W pop rax
-[ 	]*[a-f0-9]+:	66 48 58             	data32 pop rax
+[ 	]*[a-f0-9]+:	66 48 58             	data32 rex.W pop rax
 [ 	]*[a-f0-9]+:	8f c0                	pop    rax
 [ 	]*[a-f0-9]+:	66 8f c0             	pop    ax
 [ 	]*[a-f0-9]+:	48 8f c0             	rex.W pop rax
-[ 	]*[a-f0-9]+:	66 48 8f c0          	data32 pop rax
+[ 	]*[a-f0-9]+:	66 48 8f c0          	data32 rex.W pop rax
 [ 	]*[a-f0-9]+:	8f 00                	pop    QWORD PTR \[rax\]
 [ 	]*[a-f0-9]+:	66 8f 00             	pop    WORD PTR \[rax\]
 [ 	]*[a-f0-9]+:	48 8f 00             	rex.W pop QWORD PTR \[rax\]
-[ 	]*[a-f0-9]+:	66 48 8f 00          	data32 pop QWORD PTR \[rax\]
+[ 	]*[a-f0-9]+:	66 48 8f 00          	data32 rex.W pop QWORD PTR \[rax\]
 [ 	]*[a-f0-9]+:	ff d0                	call   rax
 [ 	]*[a-f0-9]+:	66 ff d0             	call   ax
 [ 	]*[a-f0-9]+:	48 ff d0             	rex.W call rax
-[ 	]*[a-f0-9]+:	66 48 ff d0          	data32 call rax
+[ 	]*[a-f0-9]+:	66 48 ff d0          	data32 rex.W call rax
 [ 	]*[a-f0-9]+:	ff 10                	call   QWORD PTR \[rax\]
 [ 	]*[a-f0-9]+:	66 ff 10             	call   WORD PTR \[rax\]
 [ 	]*[a-f0-9]+:	48 ff 10             	rex.W call QWORD PTR \[rax\]
-[ 	]*[a-f0-9]+:	66 48 ff 10          	data32 call QWORD PTR \[rax\]
+[ 	]*[a-f0-9]+:	66 48 ff 10          	data32 rex.W call QWORD PTR \[rax\]
 [ 	]*[a-f0-9]+:	ff e0                	jmp    rax
 [ 	]*[a-f0-9]+:	66 ff e0             	jmp    ax
 [ 	]*[a-f0-9]+:	48 ff e0             	rex.W jmp rax
-[ 	]*[a-f0-9]+:	66 48 ff e0          	data32 jmp rax
+[ 	]*[a-f0-9]+:	66 48 ff e0          	data32 rex.W jmp rax
 [ 	]*[a-f0-9]+:	ff 20                	jmp    QWORD PTR \[rax\]
 [ 	]*[a-f0-9]+:	66 ff 20             	jmp    WORD PTR \[rax\]
 [ 	]*[a-f0-9]+:	48 ff 20             	rex.W jmp QWORD PTR \[rax\]
-[ 	]*[a-f0-9]+:	66 48 ff 20          	data32 jmp QWORD PTR \[rax\]
+[ 	]*[a-f0-9]+:	66 48 ff 20          	data32 rex.W jmp QWORD PTR \[rax\]
 [ 	]*[a-f0-9]+:	ff f0                	push   rax
 [ 	]*[a-f0-9]+:	66 ff f0             	push   ax
 [ 	]*[a-f0-9]+:	48 ff f0             	rex.W push rax
-[ 	]*[a-f0-9]+:	66 48 ff f0          	data32 push rax
+[ 	]*[a-f0-9]+:	66 48 ff f0          	data32 rex.W push rax
 [ 	]*[a-f0-9]+:	ff 30                	push   QWORD PTR \[rax\]
 [ 	]*[a-f0-9]+:	66 ff 30             	push   WORD PTR \[rax\]
 [ 	]*[a-f0-9]+:	48 ff 30             	rex.W push QWORD PTR \[rax\]
-[ 	]*[a-f0-9]+:	66 48 ff 30          	data32 push QWORD PTR \[rax\]
+[ 	]*[a-f0-9]+:	66 48 ff 30          	data32 rex.W push QWORD PTR \[rax\]
+[ 	]*[a-f0-9]+:	6a ff                	push   0xffffffffffffffff
+[ 	]*[a-f0-9]+:	66 6a ff             	pushw  0xffff
+[ 	]*[a-f0-9]+:	48 6a ff             	rex.W push 0xffffffffffffffff
+[ 	]*[a-f0-9]+:	66 48 6a ff          	data32 rex.W push 0xffffffffffffffff
+[ 	]*[a-f0-9]+:	68 01 02 03 04       	push   0x4030201
+[ 	]*[a-f0-9]+:	66 68 01 02          	pushw  0x201
+[ 	]*[a-f0-9]+:	03 04 48             	add    eax,DWORD PTR \[rax\+rcx\*2\]
+[ 	]*[a-f0-9]+:	68 01 02 03 04       	push   0x4030201
+[ 	]*[a-f0-9]+:	66 48 68 01 02 03 04 	data32 rex.W push 0x4030201
+[ 	]*[a-f0-9]+:	90                   	nop
 #pass
diff --git a/gas/testsuite/gas/i386/ilp32/x86-64-stack-suffix.d
b/gas/testsuite/gas/i386/ilp32/x86-64-stack-suffix.d
index 45101dd..dd2f3da 100644
--- a/gas/testsuite/gas/i386/ilp32/x86-64-stack-suffix.d
+++ b/gas/testsuite/gas/i386/ilp32/x86-64-stack-suffix.d
@@ -10,41 +10,51 @@ Disassembly of section .text:
 [ 	]*[a-f0-9]+:	50                   	pushq  %rax
 [ 	]*[a-f0-9]+:	66 50                	pushw  %ax
 [ 	]*[a-f0-9]+:	48 50                	rex.W pushq %rax
-[ 	]*[a-f0-9]+:	66 48 50             	data32 pushq %rax
+[ 	]*[a-f0-9]+:	66 48 50             	data32 rex.W pushq %rax
 [ 	]*[a-f0-9]+:	58                   	popq   %rax
 [ 	]*[a-f0-9]+:	66 58                	popw   %ax
 [ 	]*[a-f0-9]+:	48 58                	rex.W popq %rax
-[ 	]*[a-f0-9]+:	66 48 58             	data32 popq %rax
+[ 	]*[a-f0-9]+:	66 48 58             	data32 rex.W popq %rax
 [ 	]*[a-f0-9]+:	8f c0                	popq   %rax
 [ 	]*[a-f0-9]+:	66 8f c0             	popw   %ax
 [ 	]*[a-f0-9]+:	48 8f c0             	rex.W popq %rax
-[ 	]*[a-f0-9]+:	66 48 8f c0          	data32 popq %rax
+[ 	]*[a-f0-9]+:	66 48 8f c0          	data32 rex.W popq %rax
 [ 	]*[a-f0-9]+:	8f 00                	popq   \(%rax\)
 [ 	]*[a-f0-9]+:	66 8f 00             	popw   \(%rax\)
 [ 	]*[a-f0-9]+:	48 8f 00             	rex.W popq \(%rax\)
-[ 	]*[a-f0-9]+:	66 48 8f 00          	data32 popq \(%rax\)
+[ 	]*[a-f0-9]+:	66 48 8f 00          	data32 rex.W popq \(%rax\)
 [ 	]*[a-f0-9]+:	ff d0                	callq  \*%rax
 [ 	]*[a-f0-9]+:	66 ff d0             	callw  \*%ax
 [ 	]*[a-f0-9]+:	48 ff d0             	rex.W callq \*%rax
-[ 	]*[a-f0-9]+:	66 48 ff d0          	data32 callq \*%rax
+[ 	]*[a-f0-9]+:	66 48 ff d0          	data32 rex.W callq \*%rax
 [ 	]*[a-f0-9]+:	ff 10                	callq  \*\(%rax\)
 [ 	]*[a-f0-9]+:	66 ff 10             	callw  \*\(%rax\)
 [ 	]*[a-f0-9]+:	48 ff 10             	rex.W callq \*\(%rax\)
-[ 	]*[a-f0-9]+:	66 48 ff 10          	data32 callq \*\(%rax\)
+[ 	]*[a-f0-9]+:	66 48 ff 10          	data32 rex.W callq \*\(%rax\)
 [ 	]*[a-f0-9]+:	ff e0                	jmpq   \*%rax
 [ 	]*[a-f0-9]+:	66 ff e0             	jmpw   \*%ax
 [ 	]*[a-f0-9]+:	48 ff e0             	rex.W jmpq \*%rax
-[ 	]*[a-f0-9]+:	66 48 ff e0          	data32 jmpq \*%rax
+[ 	]*[a-f0-9]+:	66 48 ff e0          	data32 rex.W jmpq \*%rax
 [ 	]*[a-f0-9]+:	ff 20                	jmpq   \*\(%rax\)
 [ 	]*[a-f0-9]+:	66 ff 20             	jmpw   \*\(%rax\)
 [ 	]*[a-f0-9]+:	48 ff 20             	rex.W jmpq \*\(%rax\)
-[ 	]*[a-f0-9]+:	66 48 ff 20          	data32 jmpq \*\(%rax\)
+[ 	]*[a-f0-9]+:	66 48 ff 20          	data32 rex.W jmpq \*\(%rax\)
 [ 	]*[a-f0-9]+:	ff f0                	pushq  %rax
 [ 	]*[a-f0-9]+:	66 ff f0             	pushw  %ax
 [ 	]*[a-f0-9]+:	48 ff f0             	rex.W pushq %rax
-[ 	]*[a-f0-9]+:	66 48 ff f0          	data32 pushq %rax
+[ 	]*[a-f0-9]+:	66 48 ff f0          	data32 rex.W pushq %rax
 [ 	]*[a-f0-9]+:	ff 30                	pushq  \(%rax\)
 [ 	]*[a-f0-9]+:	66 ff 30             	pushw  \(%rax\)
 [ 	]*[a-f0-9]+:	48 ff 30             	rex.W pushq \(%rax\)
-[ 	]*[a-f0-9]+:	66 48 ff 30          	data32 pushq \(%rax\)
+[ 	]*[a-f0-9]+:	66 48 ff 30          	data32 rex.W pushq \(%rax\)
+[ 	]*[a-f0-9]+:	6a ff                	pushq  \$0xffffffffffffffff
+[ 	]*[a-f0-9]+:	66 6a ff             	pushw  \$0xffff
+[ 	]*[a-f0-9]+:	48 6a ff             	rex.W pushq \$0xffffffffffffffff
+[ 	]*[a-f0-9]+:	66 48 6a ff          	data32 rex.W pushq \$0xffffffffffffffff
+[ 	]*[a-f0-9]+:	68 01 02 03 04       	pushq  \$0x4030201
+[ 	]*[a-f0-9]+:	66 68 01 02          	pushw  \$0x201
+[ 	]*[a-f0-9]+:	03 04 48             	addl   \(%rax,%rcx,2\),%eax
+[ 	]*[a-f0-9]+:	68 01 02 03 04       	pushq  \$0x4030201
+[ 	]*[a-f0-9]+:	66 48 68 01 02 03 04 	data32 rex.W pushq \$0x4030201
+[ 	]*[a-f0-9]+:	90                   	nop
 #pass
diff --git a/gas/testsuite/gas/i386/ilp32/x86-64-stack.d
b/gas/testsuite/gas/i386/ilp32/x86-64-stack.d
index 4976597..9f4553a 100644
--- a/gas/testsuite/gas/i386/ilp32/x86-64-stack.d
+++ b/gas/testsuite/gas/i386/ilp32/x86-64-stack.d
@@ -10,41 +10,51 @@ Disassembly of section .text:
 [ 	]*[a-f0-9]+:	50                   	push   %rax
 [ 	]*[a-f0-9]+:	66 50                	push   %ax
 [ 	]*[a-f0-9]+:	48 50                	rex.W push %rax
-[ 	]*[a-f0-9]+:	66 48 50             	data32 push %rax
+[ 	]*[a-f0-9]+:	66 48 50             	data32 rex.W push %rax
 [ 	]*[a-f0-9]+:	58                   	pop    %rax
 [ 	]*[a-f0-9]+:	66 58                	pop    %ax
 [ 	]*[a-f0-9]+:	48 58                	rex.W pop %rax
-[ 	]*[a-f0-9]+:	66 48 58             	data32 pop %rax
+[ 	]*[a-f0-9]+:	66 48 58             	data32 rex.W pop %rax
 [ 	]*[a-f0-9]+:	8f c0                	pop    %rax
 [ 	]*[a-f0-9]+:	66 8f c0             	pop    %ax
 [ 	]*[a-f0-9]+:	48 8f c0             	rex.W pop %rax
-[ 	]*[a-f0-9]+:	66 48 8f c0          	data32 pop %rax
+[ 	]*[a-f0-9]+:	66 48 8f c0          	data32 rex.W pop %rax
 [ 	]*[a-f0-9]+:	8f 00                	popq   \(%rax\)
 [ 	]*[a-f0-9]+:	66 8f 00             	popw   \(%rax\)
 [ 	]*[a-f0-9]+:	48 8f 00             	rex.W popq \(%rax\)
-[ 	]*[a-f0-9]+:	66 48 8f 00          	data32 popq \(%rax\)
+[ 	]*[a-f0-9]+:	66 48 8f 00          	data32 rex.W popq \(%rax\)
 [ 	]*[a-f0-9]+:	ff d0                	callq  \*%rax
 [ 	]*[a-f0-9]+:	66 ff d0             	callw  \*%ax
 [ 	]*[a-f0-9]+:	48 ff d0             	rex.W callq \*%rax
-[ 	]*[a-f0-9]+:	66 48 ff d0          	data32 callq \*%rax
+[ 	]*[a-f0-9]+:	66 48 ff d0          	data32 rex.W callq \*%rax
 [ 	]*[a-f0-9]+:	ff 10                	callq  \*\(%rax\)
 [ 	]*[a-f0-9]+:	66 ff 10             	callw  \*\(%rax\)
 [ 	]*[a-f0-9]+:	48 ff 10             	rex.W callq \*\(%rax\)
-[ 	]*[a-f0-9]+:	66 48 ff 10          	data32 callq \*\(%rax\)
+[ 	]*[a-f0-9]+:	66 48 ff 10          	data32 rex.W callq \*\(%rax\)
 [ 	]*[a-f0-9]+:	ff e0                	jmpq   \*%rax
 [ 	]*[a-f0-9]+:	66 ff e0             	jmpw   \*%ax
 [ 	]*[a-f0-9]+:	48 ff e0             	rex.W jmpq \*%rax
-[ 	]*[a-f0-9]+:	66 48 ff e0          	data32 jmpq \*%rax
+[ 	]*[a-f0-9]+:	66 48 ff e0          	data32 rex.W jmpq \*%rax
 [ 	]*[a-f0-9]+:	ff 20                	jmpq   \*\(%rax\)
 [ 	]*[a-f0-9]+:	66 ff 20             	jmpw   \*\(%rax\)
 [ 	]*[a-f0-9]+:	48 ff 20             	rex.W jmpq \*\(%rax\)
-[ 	]*[a-f0-9]+:	66 48 ff 20          	data32 jmpq \*\(%rax\)
+[ 	]*[a-f0-9]+:	66 48 ff 20          	data32 rex.W jmpq \*\(%rax\)
 [ 	]*[a-f0-9]+:	ff f0                	push   %rax
 [ 	]*[a-f0-9]+:	66 ff f0             	push   %ax
 [ 	]*[a-f0-9]+:	48 ff f0             	rex.W push %rax
-[ 	]*[a-f0-9]+:	66 48 ff f0          	data32 push %rax
+[ 	]*[a-f0-9]+:	66 48 ff f0          	data32 rex.W push %rax
 [ 	]*[a-f0-9]+:	ff 30                	pushq  \(%rax\)
 [ 	]*[a-f0-9]+:	66 ff 30             	pushw  \(%rax\)
 [ 	]*[a-f0-9]+:	48 ff 30             	rex.W pushq \(%rax\)
-[ 	]*[a-f0-9]+:	66 48 ff 30          	data32 pushq \(%rax\)
+[ 	]*[a-f0-9]+:	66 48 ff 30          	data32 rex.W pushq \(%rax\)
+[ 	]*[a-f0-9]+:	6a ff                	pushq  \$0xffffffffffffffff
+[ 	]*[a-f0-9]+:	66 6a ff             	pushw  \$0xffff
+[ 	]*[a-f0-9]+:	48 6a ff             	rex.W pushq \$0xffffffffffffffff
+[ 	]*[a-f0-9]+:	66 48 6a ff          	data32 rex.W pushq \$0xffffffffffffffff
+[ 	]*[a-f0-9]+:	68 01 02 03 04       	pushq  \$0x4030201
+[ 	]*[a-f0-9]+:	66 68 01 02          	pushw  \$0x201
+[ 	]*[a-f0-9]+:	03 04 48             	add    \(%rax,%rcx,2\),%eax
+[ 	]*[a-f0-9]+:	68 01 02 03 04       	pushq  \$0x4030201
+[ 	]*[a-f0-9]+:	66 48 68 01 02 03 04 	data32 rex.W pushq \$0x4030201
+[ 	]*[a-f0-9]+:	90                   	nop
 #pass
diff --git a/gas/testsuite/gas/i386/x86-64-stack-intel.d
b/gas/testsuite/gas/i386/x86-64-stack-intel.d
index 4c54af7..cb9ee89 100644
--- a/gas/testsuite/gas/i386/x86-64-stack-intel.d
+++ b/gas/testsuite/gas/i386/x86-64-stack-intel.d
@@ -10,41 +10,51 @@ Disassembly of section .text:
 [ 	]*[a-f0-9]+:	50                   	push   rax
 [ 	]*[a-f0-9]+:	66 50                	push   ax
 [ 	]*[a-f0-9]+:	48 50                	rex.W push rax
-[ 	]*[a-f0-9]+:	66 48 50             	data32 push rax
+[ 	]*[a-f0-9]+:	66 48 50             	data32 rex.W push rax
 [ 	]*[a-f0-9]+:	58                   	pop    rax
 [ 	]*[a-f0-9]+:	66 58                	pop    ax
 [ 	]*[a-f0-9]+:	48 58                	rex.W pop rax
-[ 	]*[a-f0-9]+:	66 48 58             	data32 pop rax
+[ 	]*[a-f0-9]+:	66 48 58             	data32 rex.W pop rax
 [ 	]*[a-f0-9]+:	8f c0                	pop    rax
 [ 	]*[a-f0-9]+:	66 8f c0             	pop    ax
 [ 	]*[a-f0-9]+:	48 8f c0             	rex.W pop rax
-[ 	]*[a-f0-9]+:	66 48 8f c0          	data32 pop rax
+[ 	]*[a-f0-9]+:	66 48 8f c0          	data32 rex.W pop rax
 [ 	]*[a-f0-9]+:	8f 00                	pop    QWORD PTR \[rax\]
 [ 	]*[a-f0-9]+:	66 8f 00             	pop    WORD PTR \[rax\]
 [ 	]*[a-f0-9]+:	48 8f 00             	rex.W pop QWORD PTR \[rax\]
-[ 	]*[a-f0-9]+:	66 48 8f 00          	data32 pop QWORD PTR \[rax\]
+[ 	]*[a-f0-9]+:	66 48 8f 00          	data32 rex.W pop QWORD PTR \[rax\]
 [ 	]*[a-f0-9]+:	ff d0                	call   rax
 [ 	]*[a-f0-9]+:	66 ff d0             	call   ax
 [ 	]*[a-f0-9]+:	48 ff d0             	rex.W call rax
-[ 	]*[a-f0-9]+:	66 48 ff d0          	data32 call rax
+[ 	]*[a-f0-9]+:	66 48 ff d0          	data32 rex.W call rax
 [ 	]*[a-f0-9]+:	ff 10                	call   QWORD PTR \[rax\]
 [ 	]*[a-f0-9]+:	66 ff 10             	call   WORD PTR \[rax\]
 [ 	]*[a-f0-9]+:	48 ff 10             	rex.W call QWORD PTR \[rax\]
-[ 	]*[a-f0-9]+:	66 48 ff 10          	data32 call QWORD PTR \[rax\]
+[ 	]*[a-f0-9]+:	66 48 ff 10          	data32 rex.W call QWORD PTR \[rax\]
 [ 	]*[a-f0-9]+:	ff e0                	jmp    rax
 [ 	]*[a-f0-9]+:	66 ff e0             	jmp    ax
 [ 	]*[a-f0-9]+:	48 ff e0             	rex.W jmp rax
-[ 	]*[a-f0-9]+:	66 48 ff e0          	data32 jmp rax
+[ 	]*[a-f0-9]+:	66 48 ff e0          	data32 rex.W jmp rax
 [ 	]*[a-f0-9]+:	ff 20                	jmp    QWORD PTR \[rax\]
 [ 	]*[a-f0-9]+:	66 ff 20             	jmp    WORD PTR \[rax\]
 [ 	]*[a-f0-9]+:	48 ff 20             	rex.W jmp QWORD PTR \[rax\]
-[ 	]*[a-f0-9]+:	66 48 ff 20          	data32 jmp QWORD PTR \[rax\]
+[ 	]*[a-f0-9]+:	66 48 ff 20          	data32 rex.W jmp QWORD PTR \[rax\]
 [ 	]*[a-f0-9]+:	ff f0                	push   rax
 [ 	]*[a-f0-9]+:	66 ff f0             	push   ax
 [ 	]*[a-f0-9]+:	48 ff f0             	rex.W push rax
-[ 	]*[a-f0-9]+:	66 48 ff f0          	data32 push rax
+[ 	]*[a-f0-9]+:	66 48 ff f0          	data32 rex.W push rax
 [ 	]*[a-f0-9]+:	ff 30                	push   QWORD PTR \[rax\]
 [ 	]*[a-f0-9]+:	66 ff 30             	push   WORD PTR \[rax\]
 [ 	]*[a-f0-9]+:	48 ff 30             	rex.W push QWORD PTR \[rax\]
-[ 	]*[a-f0-9]+:	66 48 ff 30          	data32 push QWORD PTR \[rax\]
+[ 	]*[a-f0-9]+:	66 48 ff 30          	data32 rex.W push QWORD PTR \[rax\]
+[ 	]*[a-f0-9]+:	6a ff                	push   0xffffffffffffffff
+[ 	]*[a-f0-9]+:	66 6a ff             	pushw  0xffff
+[ 	]*[a-f0-9]+:	48 6a ff             	rex.W push 0xffffffffffffffff
+[ 	]*[a-f0-9]+:	66 48 6a ff          	data32 rex.W push 0xffffffffffffffff
+[ 	]*[a-f0-9]+:	68 01 02 03 04       	push   0x4030201
+[ 	]*[a-f0-9]+:	66 68 01 02          	pushw  0x201
+[ 	]*[a-f0-9]+:	03 04 48             	add    eax,DWORD PTR \[rax\+rcx\*2\]
+[ 	]*[a-f0-9]+:	68 01 02 03 04       	push   0x4030201
+[ 	]*[a-f0-9]+:	66 48 68 01 02 03 04 	data32 rex.W push 0x4030201
+[ 	]*[a-f0-9]+:	90                   	nop
 #pass
diff --git a/gas/testsuite/gas/i386/x86-64-stack-suffix.d
b/gas/testsuite/gas/i386/x86-64-stack-suffix.d
index 07bf79b..a0b94d0 100644
--- a/gas/testsuite/gas/i386/x86-64-stack-suffix.d
+++ b/gas/testsuite/gas/i386/x86-64-stack-suffix.d
@@ -10,41 +10,51 @@ Disassembly of section .text:
 [ 	]*[a-f0-9]+:	50                   	pushq  %rax
 [ 	]*[a-f0-9]+:	66 50                	pushw  %ax
 [ 	]*[a-f0-9]+:	48 50                	rex.W pushq %rax
-[ 	]*[a-f0-9]+:	66 48 50             	data32 pushq %rax
+[ 	]*[a-f0-9]+:	66 48 50             	data32 rex.W pushq %rax
 [ 	]*[a-f0-9]+:	58                   	popq   %rax
 [ 	]*[a-f0-9]+:	66 58                	popw   %ax
 [ 	]*[a-f0-9]+:	48 58                	rex.W popq %rax
-[ 	]*[a-f0-9]+:	66 48 58             	data32 popq %rax
+[ 	]*[a-f0-9]+:	66 48 58             	data32 rex.W popq %rax
 [ 	]*[a-f0-9]+:	8f c0                	popq   %rax
 [ 	]*[a-f0-9]+:	66 8f c0             	popw   %ax
 [ 	]*[a-f0-9]+:	48 8f c0             	rex.W popq %rax
-[ 	]*[a-f0-9]+:	66 48 8f c0          	data32 popq %rax
+[ 	]*[a-f0-9]+:	66 48 8f c0          	data32 rex.W popq %rax
 [ 	]*[a-f0-9]+:	8f 00                	popq   \(%rax\)
 [ 	]*[a-f0-9]+:	66 8f 00             	popw   \(%rax\)
 [ 	]*[a-f0-9]+:	48 8f 00             	rex.W popq \(%rax\)
-[ 	]*[a-f0-9]+:	66 48 8f 00          	data32 popq \(%rax\)
+[ 	]*[a-f0-9]+:	66 48 8f 00          	data32 rex.W popq \(%rax\)
 [ 	]*[a-f0-9]+:	ff d0                	callq  \*%rax
 [ 	]*[a-f0-9]+:	66 ff d0             	callw  \*%ax
 [ 	]*[a-f0-9]+:	48 ff d0             	rex.W callq \*%rax
-[ 	]*[a-f0-9]+:	66 48 ff d0          	data32 callq \*%rax
+[ 	]*[a-f0-9]+:	66 48 ff d0          	data32 rex.W callq \*%rax
 [ 	]*[a-f0-9]+:	ff 10                	callq  \*\(%rax\)
 [ 	]*[a-f0-9]+:	66 ff 10             	callw  \*\(%rax\)
 [ 	]*[a-f0-9]+:	48 ff 10             	rex.W callq \*\(%rax\)
-[ 	]*[a-f0-9]+:	66 48 ff 10          	data32 callq \*\(%rax\)
+[ 	]*[a-f0-9]+:	66 48 ff 10          	data32 rex.W callq \*\(%rax\)
 [ 	]*[a-f0-9]+:	ff e0                	jmpq   \*%rax
 [ 	]*[a-f0-9]+:	66 ff e0             	jmpw   \*%ax
 [ 	]*[a-f0-9]+:	48 ff e0             	rex.W jmpq \*%rax
-[ 	]*[a-f0-9]+:	66 48 ff e0          	data32 jmpq \*%rax
+[ 	]*[a-f0-9]+:	66 48 ff e0          	data32 rex.W jmpq \*%rax
 [ 	]*[a-f0-9]+:	ff 20                	jmpq   \*\(%rax\)
 [ 	]*[a-f0-9]+:	66 ff 20             	jmpw   \*\(%rax\)
 [ 	]*[a-f0-9]+:	48 ff 20             	rex.W jmpq \*\(%rax\)
-[ 	]*[a-f0-9]+:	66 48 ff 20          	data32 jmpq \*\(%rax\)
+[ 	]*[a-f0-9]+:	66 48 ff 20          	data32 rex.W jmpq \*\(%rax\)
 [ 	]*[a-f0-9]+:	ff f0                	pushq  %rax
 [ 	]*[a-f0-9]+:	66 ff f0             	pushw  %ax
 [ 	]*[a-f0-9]+:	48 ff f0             	rex.W pushq %rax
-[ 	]*[a-f0-9]+:	66 48 ff f0          	data32 pushq %rax
+[ 	]*[a-f0-9]+:	66 48 ff f0          	data32 rex.W pushq %rax
 [ 	]*[a-f0-9]+:	ff 30                	pushq  \(%rax\)
 [ 	]*[a-f0-9]+:	66 ff 30             	pushw  \(%rax\)
 [ 	]*[a-f0-9]+:	48 ff 30             	rex.W pushq \(%rax\)
-[ 	]*[a-f0-9]+:	66 48 ff 30          	data32 pushq \(%rax\)
+[ 	]*[a-f0-9]+:	66 48 ff 30          	data32 rex.W pushq \(%rax\)
+[ 	]*[a-f0-9]+:	6a ff                	pushq  \$0xffffffffffffffff
+[ 	]*[a-f0-9]+:	66 6a ff             	pushw  \$0xffff
+[ 	]*[a-f0-9]+:	48 6a ff             	rex.W pushq \$0xffffffffffffffff
+[ 	]*[a-f0-9]+:	66 48 6a ff          	data32 rex.W pushq \$0xffffffffffffffff
+[ 	]*[a-f0-9]+:	68 01 02 03 04       	pushq  \$0x4030201
+[ 	]*[a-f0-9]+:	66 68 01 02          	pushw  \$0x201
+[ 	]*[a-f0-9]+:	03 04 48             	addl   \(%rax,%rcx,2\),%eax
+[ 	]*[a-f0-9]+:	68 01 02 03 04       	pushq  \$0x4030201
+[ 	]*[a-f0-9]+:	66 48 68 01 02 03 04 	data32 rex.W pushq \$0x4030201
+[ 	]*[a-f0-9]+:	90                   	nop
 #pass
diff --git a/gas/testsuite/gas/i386/x86-64-stack.d
b/gas/testsuite/gas/i386/x86-64-stack.d
index 0ab339d..76f7151 100644
--- a/gas/testsuite/gas/i386/x86-64-stack.d
+++ b/gas/testsuite/gas/i386/x86-64-stack.d
@@ -9,41 +9,51 @@ Disassembly of section .text:
 [ 	]*[a-f0-9]+:	50                   	push   %rax
 [ 	]*[a-f0-9]+:	66 50                	push   %ax
 [ 	]*[a-f0-9]+:	48 50                	rex.W push %rax
-[ 	]*[a-f0-9]+:	66 48 50             	data32 push %rax
+[ 	]*[a-f0-9]+:	66 48 50             	data32 rex.W push %rax
 [ 	]*[a-f0-9]+:	58                   	pop    %rax
 [ 	]*[a-f0-9]+:	66 58                	pop    %ax
 [ 	]*[a-f0-9]+:	48 58                	rex.W pop %rax
-[ 	]*[a-f0-9]+:	66 48 58             	data32 pop %rax
+[ 	]*[a-f0-9]+:	66 48 58             	data32 rex.W pop %rax
 [ 	]*[a-f0-9]+:	8f c0                	pop    %rax
 [ 	]*[a-f0-9]+:	66 8f c0             	pop    %ax
 [ 	]*[a-f0-9]+:	48 8f c0             	rex.W pop %rax
-[ 	]*[a-f0-9]+:	66 48 8f c0          	data32 pop %rax
+[ 	]*[a-f0-9]+:	66 48 8f c0          	data32 rex.W pop %rax
 [ 	]*[a-f0-9]+:	8f 00                	popq   \(%rax\)
 [ 	]*[a-f0-9]+:	66 8f 00             	popw   \(%rax\)
 [ 	]*[a-f0-9]+:	48 8f 00             	rex.W popq \(%rax\)
-[ 	]*[a-f0-9]+:	66 48 8f 00          	data32 popq \(%rax\)
+[ 	]*[a-f0-9]+:	66 48 8f 00          	data32 rex.W popq \(%rax\)
 [ 	]*[a-f0-9]+:	ff d0                	callq  \*%rax
 [ 	]*[a-f0-9]+:	66 ff d0             	callw  \*%ax
 [ 	]*[a-f0-9]+:	48 ff d0             	rex.W callq \*%rax
-[ 	]*[a-f0-9]+:	66 48 ff d0          	data32 callq \*%rax
+[ 	]*[a-f0-9]+:	66 48 ff d0          	data32 rex.W callq \*%rax
 [ 	]*[a-f0-9]+:	ff 10                	callq  \*\(%rax\)
 [ 	]*[a-f0-9]+:	66 ff 10             	callw  \*\(%rax\)
 [ 	]*[a-f0-9]+:	48 ff 10             	rex.W callq \*\(%rax\)
-[ 	]*[a-f0-9]+:	66 48 ff 10          	data32 callq \*\(%rax\)
+[ 	]*[a-f0-9]+:	66 48 ff 10          	data32 rex.W callq \*\(%rax\)
 [ 	]*[a-f0-9]+:	ff e0                	jmpq   \*%rax
 [ 	]*[a-f0-9]+:	66 ff e0             	jmpw   \*%ax
 [ 	]*[a-f0-9]+:	48 ff e0             	rex.W jmpq \*%rax
-[ 	]*[a-f0-9]+:	66 48 ff e0          	data32 jmpq \*%rax
+[ 	]*[a-f0-9]+:	66 48 ff e0          	data32 rex.W jmpq \*%rax
 [ 	]*[a-f0-9]+:	ff 20                	jmpq   \*\(%rax\)
 [ 	]*[a-f0-9]+:	66 ff 20             	jmpw   \*\(%rax\)
 [ 	]*[a-f0-9]+:	48 ff 20             	rex.W jmpq \*\(%rax\)
-[ 	]*[a-f0-9]+:	66 48 ff 20          	data32 jmpq \*\(%rax\)
+[ 	]*[a-f0-9]+:	66 48 ff 20          	data32 rex.W jmpq \*\(%rax\)
 [ 	]*[a-f0-9]+:	ff f0                	push   %rax
 [ 	]*[a-f0-9]+:	66 ff f0             	push   %ax
 [ 	]*[a-f0-9]+:	48 ff f0             	rex.W push %rax
-[ 	]*[a-f0-9]+:	66 48 ff f0          	data32 push %rax
+[ 	]*[a-f0-9]+:	66 48 ff f0          	data32 rex.W push %rax
 [ 	]*[a-f0-9]+:	ff 30                	pushq  \(%rax\)
 [ 	]*[a-f0-9]+:	66 ff 30             	pushw  \(%rax\)
 [ 	]*[a-f0-9]+:	48 ff 30             	rex.W pushq \(%rax\)
-[ 	]*[a-f0-9]+:	66 48 ff 30          	data32 pushq \(%rax\)
+[ 	]*[a-f0-9]+:	66 48 ff 30          	data32 rex.W pushq \(%rax\)
+[ 	]*[a-f0-9]+:	6a ff                	pushq  \$0xffffffffffffffff
+[ 	]*[a-f0-9]+:	66 6a ff             	pushw  \$0xffff
+[ 	]*[a-f0-9]+:	48 6a ff             	rex.W pushq \$0xffffffffffffffff
+[ 	]*[a-f0-9]+:	66 48 6a ff          	data32 rex.W pushq \$0xffffffffffffffff
+[ 	]*[a-f0-9]+:	68 01 02 03 04       	pushq  \$0x4030201
+[ 	]*[a-f0-9]+:	66 68 01 02          	pushw  \$0x201
+[ 	]*[a-f0-9]+:	03 04 48             	add    \(%rax,%rcx,2\),%eax
+[ 	]*[a-f0-9]+:	68 01 02 03 04       	pushq  \$0x4030201
+[ 	]*[a-f0-9]+:	66 48 68 01 02 03 04 	data32 rex.W pushq \$0x4030201
+[ 	]*[a-f0-9]+:	90                   	nop
 #pass
diff --git a/gas/testsuite/gas/i386/x86-64-stack.s
b/gas/testsuite/gas/i386/x86-64-stack.s
index d114887..2da658b 100644
--- a/gas/testsuite/gas/i386/x86-64-stack.s
+++ b/gas/testsuite/gas/i386/x86-64-stack.s
@@ -22,3 +22,13 @@ _start:

 	try	0xff, 0xf0
 	try	0xff, 0x30
+
+	# push with a 1-byte immediate
+	try	0x6a, 0xff
+
+	# push with a 4-byte immediate
+	try	0x68, 0x01, 0x02, 0x03, 0x04
+
+	# This is just to synchronize the disassembly.
+	# Any new cases must come before this line!
+	nop
diff --git a/opcodes/i386-dis.c b/opcodes/i386-dis.c
index 685e968..43d7ac3 100644
--- a/opcodes/i386-dis.c
+++ b/opcodes/i386-dis.c
@@ -1,6 +1,6 @@
 /* Print i386 instructions for GDB, the GNU debugger.
    Copyright 1988, 1989, 1991, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
-   2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011
+   2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012
    Free Software Foundation, Inc.

    This file is part of the GNU opcodes library.
@@ -12275,7 +12275,7 @@ case_L:
 	case 'T':
 	  if (!intel_syntax
 	      && address_mode == mode_64bit
-	      && (sizeflag & DFLAG))
+	      && ((sizeflag & DFLAG) || (rex & REX_W)))
 	    {
 	      *obufp++ = 'q';
 	      break;
@@ -12313,7 +12313,8 @@ case_L:
 	case 'U':
 	  if (intel_syntax)
 	    break;
-	  if (address_mode == mode_64bit && (sizeflag & DFLAG))
+	  if (address_mode == mode_64bit
+              && ((sizeflag & DFLAG) || (rex & REX_W)))
 	    {
 	      if (modrm.mod != 3 || (sizeflag & SUFFIX_ALWAYS))
 		*obufp++ = 'q';
@@ -12385,7 +12386,8 @@ case_Q:
 	    {
 	      if (intel_syntax)
 		break;
-	      if (address_mode == mode_64bit && (sizeflag & DFLAG))
+	      if (address_mode == mode_64bit
+                  && ((sizeflag & DFLAG) || (rex & REX_W)))
 		{
 		  if (sizeflag & SUFFIX_ALWAYS)
 		    *obufp++ = 'q';
@@ -12721,7 +12723,7 @@ intel_operand_size (int bytemode, int sizeflag)
       oappend ("WORD PTR ");
       break;
     case stack_v_mode:
-      if (address_mode == mode_64bit && (sizeflag & DFLAG))
+      if (address_mode == mode_64bit && ((sizeflag & DFLAG) || (rex & REX_W)))
 	{
 	  oappend ("QWORD PTR ");
 	  break;
@@ -12998,7 +13000,7 @@ OP_E_register (int bytemode, int sizeflag)
       names = address_mode == mode_64bit ? names64 : names32;
       break;
     case stack_v_mode:
-      if (address_mode == mode_64bit && (sizeflag & DFLAG))
+      if (address_mode == mode_64bit && ((sizeflag & DFLAG) || (rex & REX_W)))
 	{
 	  names = names64;
 	  break;
@@ -13495,7 +13497,8 @@ OP_REG (int code, int sizeflag)
       break;
     case rAX_reg: case rCX_reg: case rDX_reg: case rBX_reg:
     case rSP_reg: case rBP_reg: case rSI_reg: case rDI_reg:
-      if (address_mode == mode_64bit && (sizeflag & DFLAG))
+      if (address_mode == mode_64bit
+          && ((sizeflag & DFLAG) || (rex & REX_W)))
 	{
 	  s = names64[code - rAX_reg + add];
 	  break;
@@ -13710,9 +13713,10 @@ OP_sI (int bytemode, int sizeflag)
       if (bytemode == b_T_mode)
 	{
 	  if (address_mode != mode_64bit
-	      || !(sizeflag & DFLAG))
+	      || !((sizeflag & DFLAG) || (rex & REX_W)))
 	    {
-	      if (sizeflag & DFLAG)
+              /* The operand-size prefix is overridden by a REX prefix.  */
+              if ((sizeflag & DFLAG) || (rex & REX_W))
 		op &= 0xffffffff;
 	      else
 		op &= 0xffff;
@@ -13730,7 +13734,8 @@ OP_sI (int bytemode, int sizeflag)
 	}
       break;
     case v_mode:
-      if (sizeflag & DFLAG)
+      /* The operand-size prefix is overridden by a REX prefix.  */
+      if ((sizeflag & DFLAG) || (rex & REX_W))
 	op = get32s ();
       else
 	op = get16 ();

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [RFC PATCH] Fix decoding of superfluous data32 prefix before superfluous rex.W prefix before push.
  2012-08-06 20:02         ` Roland McGrath
@ 2012-08-06 20:20           ` H.J. Lu
  2012-08-06 20:34             ` Roland McGrath
  0 siblings, 1 reply; 11+ messages in thread
From: H.J. Lu @ 2012-08-06 20:20 UTC (permalink / raw)
  To: Roland McGrath; +Cc: Victor Khimenko, binutils

On Mon, Aug 6, 2012 at 12:53 PM, Roland McGrath <mcgrathr@google.com> wrote:
> Thanks for that pointer.  I followed that hint to do a few more similar
> changes and managed to get to where all the "66 48 ..." cases in
> x86-64-stack.s produce "data32 rex.W ...".  Here's the final change
> including all that.
>
> There are no other 'make check' regressions on x86_64-linux-gnu.
> The disassembler code is so hairy that I can't be sure I haven't broken
> some other case for which there is no test coverage.  But you might
> know it enough better that you can be more confident than I am.
>
> Ok for trunk?
>
>
> Thanks,
> Roland
>
>
> gas/testsuite/
> 2012-08-06  Roland McGrath  <mcgrathr@google.com>
>
>         * gas/i386/x86-64-stack.s: Add cases for push immediate.
>         * gas/testsuite/gas/i386/ilp32/x86-64-stack-intel.d: Updated.
>         * gas/testsuite/gas/i386/ilp32/x86-64-stack-suffix.d: Updated.
>         * gas/testsuite/gas/i386/ilp32/x86-64-stack.d: Updated.
>         * gas/testsuite/gas/i386/x86-64-stack-intel.d: Updated.
>         * gas/testsuite/gas/i386/x86-64-stack-suffix.d: Updated.
>         * gas/testsuite/gas/i386/x86-64-stack.d: Updated.
>
> opcodes/
> 2012-08-06  Roland McGrath  <mcgrathr@google.com>
>             Victor Khimenko  <khim@google.com>
>             H.J. Lu  <hongjiu.lu@intel.com>
>
>         * i386-dis.c (OP_sI): In b_T_mode and v_mode, REX_W trumps DFLAG.
>         (putop): For 'T', 'U', and 'V', treat REX_W like DFLAG.
>         (intel_operand_size): For stack_v_mode, treat REX_W like DFLAG.
>         (OP_E_register): Likewise.
>         (OP_REG): For low 8 whole registers, treat REX_W like DFLAG.
>

It is OK.

Thanks.

-- 
H.J.

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [RFC PATCH] Fix decoding of superfluous data32 prefix before superfluous rex.W prefix before push.
  2012-08-06 20:20           ` H.J. Lu
@ 2012-08-06 20:34             ` Roland McGrath
  0 siblings, 0 replies; 11+ messages in thread
From: Roland McGrath @ 2012-08-06 20:34 UTC (permalink / raw)
  To: H.J. Lu; +Cc: Victor Khimenko, binutils

On Mon, Aug 6, 2012 at 1:02 PM, H.J. Lu <hjl.tools@gmail.com> wrote:
> It is OK.

Committed.

Thanks,
Roland

^ permalink raw reply	[flat|nested] 11+ messages in thread

end of thread, other threads:[~2012-08-06 20:20 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2012-08-03 18:47 [RFC PATCH] Fix decoding of superfluous data32 prefix before superfluous rex.W prefix before push Roland McGrath
2012-08-03 18:54 ` H.J. Lu
2012-08-03 19:52   ` H.J. Lu
2012-08-03 21:55     ` Roland McGrath
2012-08-03 22:10       ` H.J. Lu
2012-08-03 23:24   ` Roland McGrath
2012-08-03 23:36     ` H.J. Lu
2012-08-04  0:30       ` H.J. Lu
2012-08-06 20:02         ` Roland McGrath
2012-08-06 20:20           ` H.J. Lu
2012-08-06 20:34             ` Roland McGrath

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).