This is the mail archive of the binutils@sourceware.org mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [PATCH] X86: Disassemble primary opcode map's group 2 ModRM.reg == 6 aliases correctly


On Sun, May 28, 2017 at 12:12:43PM -0700, H.J. Lu wrote:
> Please add the same i386 testcases plus ones with REX byte
> to x86-64-opcode.s.

Ok, how's that?

---
From: Borislav Petkov <bp@suse.de>
Date: Tue, 16 May 2017 10:00:25 +0200
Subject: [PATCH] X86: Disassemble primary opcode map's group 2 ModRM.reg == 6 aliases correctly

The instructions are not documented in the Intel SDM but are documented
in the AMD APM as an alias to the group 2, ModRM.reg == 4 variant.

Both AMD and Intel CPUs execute the C[0-1] and D[0-3] instructions as
expected, i.e., like the /4 aliases:

  #include <stdio.h>

  int main(void)
  {
          int a = 2;

          printf ("a before: %d\n", a);

          asm volatile(".byte 0xd0,0xf0"          /* SHL %al */
                       : "+a" (a));

          printf("a after : %d\n", a);

          return 0;
  }

  $ ./a.out
  a before: 2
  a after : 4

Changelog:

gas/
* testsuite/gas/i386/opcode.s: Add tests for ModRM.reg == 6 variants.
* testsuite/gas/i386/opcode.d: ditto.
* testsuite/gas/i386/x86-64-opcode.s: Add x86_64 variants too.
* testsuite/gas/i386/x86-64-opcode.d: ditto.

opcodes/
* i386-dis.c: Enable ModRM.reg /6 aliases.
---
 gas/testsuite/gas/i386/opcode.d        |  6 ++++++
 gas/testsuite/gas/i386/opcode.s        |  6 ++++++
 gas/testsuite/gas/i386/x86-64-opcode.d |  9 +++++++++
 gas/testsuite/gas/i386/x86-64-opcode.s |  9 +++++++++
 opcodes/i386-dis.c                     | 12 ++++++------
 5 files changed, 36 insertions(+), 6 deletions(-)

diff --git a/gas/testsuite/gas/i386/opcode.d b/gas/testsuite/gas/i386/opcode.d
index c7dc41076a47..b80a78cd4b60 100644
--- a/gas/testsuite/gas/i386/opcode.d
+++ b/gas/testsuite/gas/i386/opcode.d
@@ -603,4 +603,10 @@ Disassembly of section .text:
  +[a-f0-9]+:	f6 c9 01             	test   \$(0x)?0*1,%cl
  +[a-f0-9]+:	66 f7 c9 02 00       	test   \$(0x)?0*2,%cx
  +[a-f0-9]+:	f7 c9 04 00 00 00    	test   \$(0x)?0*4,%ecx
+ +[a-f0-9]+:	c0 f0 02             	shl    \$0x2,%al
+ +[a-f0-9]+:	c1 f0 01             	shl    \$0x1,%eax
+ +[a-f0-9]+:	d0 f0                	shl    %al
+ +[a-f0-9]+:	d1 f0                	shl    %eax
+ +[a-f0-9]+:	d2 f0                	shl    %cl,%al
+ +[a-f0-9]+:	d3 f0                	shl    %cl,%eax
 #pass
diff --git a/gas/testsuite/gas/i386/opcode.s b/gas/testsuite/gas/i386/opcode.s
index 64357b53b5b5..db47446dfa92 100644
--- a/gas/testsuite/gas/i386/opcode.s
+++ b/gas/testsuite/gas/i386/opcode.s
@@ -604,3 +604,9 @@ foo:
 	.byte 0xf6, 0xc9, 0x01
 	.byte 0x66, 0xf7, 0xc9, 0x02, 0x00
 	.byte 0xf7, 0xc9, 0x04, 0x00, 0x00, 0x00
+	.byte 0xc0, 0xf0, 0x02
+	.byte 0xc1, 0xf0, 0x01
+	.byte 0xd0, 0xf0
+	.byte 0xd1, 0xf0
+	.byte 0xd2, 0xf0
+	.byte 0xd3, 0xf0
diff --git a/gas/testsuite/gas/i386/x86-64-opcode.d b/gas/testsuite/gas/i386/x86-64-opcode.d
index a6087e0c4550..bfffb6e0ae01 100644
--- a/gas/testsuite/gas/i386/x86-64-opcode.d
+++ b/gas/testsuite/gas/i386/x86-64-opcode.d
@@ -305,4 +305,13 @@ Disassembly of section .text:
 [ 	]*[a-f0-9]+:	66 f7 c9 02 00       	test   \$(0x)?0*2,%cx
 [ 	]*[a-f0-9]+:	f7 c9 04 00 00 00    	test   \$(0x)?0*4,%ecx
 [ 	]*[a-f0-9]+:	48 f7 c9 08 00 00 00 	test   \$(0x)?0*8,%rcx
+[ 	]*[a-f0-9]+:	c0 f0 02             	shl    \$0x2,%al
+[ 	]*[a-f0-9]+:	c1 f0 01             	shl    \$0x1,%eax
+[ 	]*[a-f0-9]+:	48 c1 f0 01          	shl    \$0x1,%rax
+[ 	]*[a-f0-9]+:	d0 f0                	shl    %al
+[ 	]*[a-f0-9]+:	d1 f0                	shl    %eax
+[ 	]*[a-f0-9]+:	48 d1 f0             	shl    %rax
+[ 	]*[a-f0-9]+:	d2 f0                	shl    %cl,%al
+[ 	]*[a-f0-9]+:	d3 f0                	shl    %cl,%eax
+[ 	]*[a-f0-9]+:	48 d3 f0             	shl    %cl,%rax
 #pass
diff --git a/gas/testsuite/gas/i386/x86-64-opcode.s b/gas/testsuite/gas/i386/x86-64-opcode.s
index ffc8b9479beb..5df5d13f7814 100644
--- a/gas/testsuite/gas/i386/x86-64-opcode.s
+++ b/gas/testsuite/gas/i386/x86-64-opcode.s
@@ -432,3 +432,12 @@
 	.byte 0x66, 0xf7, 0xc9, 0x02, 0x00
 	.byte 0xf7, 0xc9, 0x04, 0x00, 0x00, 0x00
 	.byte 0x48, 0xf7, 0xc9, 0x08, 0x00, 0x00, 0x00
+	.byte 0xc0, 0xf0, 0x02
+	.byte 0xc1, 0xf0, 0x01
+	.byte 0x48, 0xc1, 0xf0, 0x01
+	.byte 0xd0, 0xf0
+	.byte 0xd1, 0xf0
+	.byte 0x48, 0xd1, 0xf0
+	.byte 0xd2, 0xf0
+	.byte 0xd3, 0xf0
+	.byte 0x48, 0xd3, 0xf0
diff --git a/opcodes/i386-dis.c b/opcodes/i386-dis.c
index 3980c46ad19a..bfe83659f3a6 100644
--- a/opcodes/i386-dis.c
+++ b/opcodes/i386-dis.c
@@ -3438,7 +3438,7 @@ static const struct dis386 reg_table[][8] = {
     { "rcrA",	{ Eb, Ib }, 0 },
     { "shlA",	{ Eb, Ib }, 0 },
     { "shrA",	{ Eb, Ib }, 0 },
-    { Bad_Opcode },
+    { "shlA",	{ Eb, Ib }, 0 },
     { "sarA",	{ Eb, Ib }, 0 },
   },
   /* REG_C1 */
@@ -3449,7 +3449,7 @@ static const struct dis386 reg_table[][8] = {
     { "rcrQ",	{ Ev, Ib }, 0 },
     { "shlQ",	{ Ev, Ib }, 0 },
     { "shrQ",	{ Ev, Ib }, 0 },
-    { Bad_Opcode },
+    { "shlQ",	{ Ev, Ib }, 0 },
     { "sarQ",	{ Ev, Ib }, 0 },
   },
   /* REG_C6 */
@@ -3482,7 +3482,7 @@ static const struct dis386 reg_table[][8] = {
     { "rcrA",	{ Eb, I1 }, 0 },
     { "shlA",	{ Eb, I1 }, 0 },
     { "shrA",	{ Eb, I1 }, 0 },
-    { Bad_Opcode },
+    { "shlA",	{ Eb, I1 }, 0 },
     { "sarA",	{ Eb, I1 }, 0 },
   },
   /* REG_D1 */
@@ -3493,7 +3493,7 @@ static const struct dis386 reg_table[][8] = {
     { "rcrQ",	{ Ev, I1 }, 0 },
     { "shlQ",	{ Ev, I1 }, 0 },
     { "shrQ",	{ Ev, I1 }, 0 },
-    { Bad_Opcode },
+    { "shlQ",	{ Ev, I1 }, 0 },
     { "sarQ",	{ Ev, I1 }, 0 },
   },
   /* REG_D2 */
@@ -3504,7 +3504,7 @@ static const struct dis386 reg_table[][8] = {
     { "rcrA",	{ Eb, CL }, 0 },
     { "shlA",	{ Eb, CL }, 0 },
     { "shrA",	{ Eb, CL }, 0 },
-    { Bad_Opcode },
+    { "shlA",	{ Eb, CL }, 0 },
     { "sarA",	{ Eb, CL }, 0 },
   },
   /* REG_D3 */
@@ -3515,7 +3515,7 @@ static const struct dis386 reg_table[][8] = {
     { "rcrQ",	{ Ev, CL }, 0 },
     { "shlQ",	{ Ev, CL }, 0 },
     { "shrQ",	{ Ev, CL }, 0 },
-    { Bad_Opcode },
+    { "shlQ",	{ Ev, CL }, 0 },
     { "sarQ",	{ Ev, CL }, 0 },
   },
   /* REG_F6 */
-- 
2.11.0

SUSE Linux GmbH, GF: Felix Imendörffer, Jane Smithard, Graham Norton, HRB 21284 (AG Nürnberg)
-- 


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]