This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
Re: [RFC PATCH] Fix decoding of superfluous data32 prefix before superfluous rex.W prefix before push.
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 ();