X86: Ignore REX_B bit for 32-bit XOP instructions
authorAmit Pawar <Amit.Pawar@amd.com>
Mon, 28 Nov 2016 17:21:05 +0000 (09:21 -0800)
committerH.J. Lu <hjl.tools@gmail.com>
Mon, 28 Nov 2016 17:21:05 +0000 (09:21 -0800)
While decoding 32-bit XOP instructions, 64 bit registers names are printed.
This patch fixes this by ignoring REX_B bit in 32-bit mode.

opcodes/

PR binutils/20637
* i386-dis.c (get_valid_dis386): Ignore REX_B for 32-bit XOP
instructions.

gas/

PR binutils/20637
* testsuite/gas/i386/xop32reg.d: New file.
* testsuite/gas/i386/xop32reg.s: New file.
* testsuite/gas/i386/i386.exp: Run new test.

gas/ChangeLog
gas/testsuite/gas/i386/i386.exp
gas/testsuite/gas/i386/xop32reg.d [new file with mode: 0644]
gas/testsuite/gas/i386/xop32reg.s [new file with mode: 0644]
opcodes/ChangeLog
opcodes/i386-dis.c

index cd0d2ab..c88a5f3 100644 (file)
@@ -1,3 +1,11 @@
+2016-11-28  Ramiro Polla  <ramiro@hex-rays.com>
+           Amit Pawar  <amit.pawar@amd.com>
+
+       PR binutils/20637
+       * testsuite/gas/i386/xop32reg.d: New file.
+       * testsuite/gas/i386/xop32reg.s: New file.
+       * testsuite/gas/i386/i386.exp: Run new test.
+
 2016-11-27  Ambrogino Modigliani  <ambrogino.modigliani@gmail.com>
 
        * arparse.y: Fix spelling in comments.
index 1b28fa1..29282b8 100644 (file)
@@ -261,6 +261,7 @@ if [expr ([istarget "i*86-*-*"] ||  [istarget "x86_64-*-*"]) && [gas_32_check]]
     run_dump_test "fma4"
     run_dump_test "lwp"
     run_dump_test "xop"
+    run_dump_test "xop32reg"
     run_dump_test "bmi"
     run_dump_test "bmi-intel"
     run_dump_test "tbm"
diff --git a/gas/testsuite/gas/i386/xop32reg.d b/gas/testsuite/gas/i386/xop32reg.d
new file mode 100644 (file)
index 0000000..395bbca
--- /dev/null
@@ -0,0 +1,15 @@
+#source: xop32reg.s
+#objdump: -dw
+#name: i386 ignore rex_b in case of 32 bit decoding
+
+.*: +file format .*
+
+
+Disassembly of section \.text:
+
+0+ <_start>:
+[      ]*[a-f0-9]+:    8f e9 78 e1 4d c2[      ]+vphsubbw -0x3e\(%ebp\),%xmm1
+[      ]*[a-f0-9]+:    8f c9 78 e1 4d c2[      ]+vphsubbw -0x3e\(%ebp\),%xmm1
+[       ]*[a-f0-9]+:   8f e8 40 cd 04 08 07[   ]+vpcomw \$0x7,\(%eax,%ecx,1\),%xmm7,%xmm0
+[       ]*[a-f0-9]+:   8f c8 40 cd 04 08 07[   ]+vpcomw \$0x7,\(%eax,%ecx,1\),%xmm7,%xmm0
+#pass
diff --git a/gas/testsuite/gas/i386/xop32reg.s b/gas/testsuite/gas/i386/xop32reg.s
new file mode 100644 (file)
index 0000000..a547bd5
--- /dev/null
@@ -0,0 +1,13 @@
+
+       .text
+_start:
+       .long 0xe178e98f
+       .word 0xc24d
+       .long 0xe178c98f
+       .word 0xc24d
+       .long 0xcd40e88f
+       .word 0x0804
+       .byte 0x07
+       .long 0xcd40c88f
+       .word 0x0804
+       .byte 0x07
index a839a68..9bfd67b 100644 (file)
@@ -1,3 +1,10 @@
+2016-11-28  Ramiro Polla  <ramiro@hex-rays.com>
+           Amit Pawar  <amit.pawar@amd.com>
+
+       PR binutils/20637
+       * i386-dis.c (get_valid_dis386): Ignore REX_B for 32-bit XOP
+       instructions.
+
 2016-11-22  Ambrogino Modigliani  <ambrogino.modigliani@gmail.com>
 
         * configure: Regenerate.
index 5f49f91..ada4401 100644 (file)
@@ -12670,11 +12670,15 @@ get_valid_dis386 (const struct dis386 *dp, disassemble_info *info)
        rex |= REX_W;
 
       vex.register_specifier = (~(*codep >> 3)) & 0xf;
-      if (address_mode != mode_64bit
-         && vex.register_specifier > 0x7)
+      if (address_mode != mode_64bit)
        {
-         dp = &bad_opcode;
-         return dp;
+         /* In 16/32-bit mode REX_B is silently ignored.  */
+         rex &= ~REX_B;
+         if (vex.register_specifier > 0x7)
+           {
+             dp = &bad_opcode;
+             return dp;
+           }
        }
 
       vex.length = (*codep & 0x4) ? 256 : 128;