X86: Disassemble primary opcode map's group 2 ModRM.reg == 6 aliases correctly
authorBorislav Petkov <bp@suse.de>
Wed, 5 Jul 2017 09:27:49 +0000 (11:27 +0200)
committerJan Beulich <jbeulich@suse.com>
Wed, 5 Jul 2017 09:27:49 +0000 (11:27 +0200)
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

gas/ChangeLog
gas/testsuite/gas/i386/opcode.d
gas/testsuite/gas/i386/opcode.s
gas/testsuite/gas/i386/x86-64-opcode.d
gas/testsuite/gas/i386/x86-64-opcode.s
opcodes/ChangeLog
opcodes/i386-dis.c

index d693b66..a57b5d3 100644 (file)
@@ -1,3 +1,10 @@
+2017-07-05  Borislav Petkov  <bp@suse.de>
+
+       * 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.
+
 2017-07-04  Ramana Radhakrishnan  <ramana.radhakrishnan@arm.com>
 
         * config/tc-arm.c (arm_regs): Add MVFR2.
index c7dc410..b80a78c 100644 (file)
@@ -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
index 64357b5..db47446 100644 (file)
@@ -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
index a6087e0..bfffb6e 100644 (file)
@@ -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
index ffc8b94..5df5d13 100644 (file)
        .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
index 6c18442..a076189 100644 (file)
@@ -1,3 +1,7 @@
+2017-07-05  Borislav Petkov  <bp@suse.de>
+
+       * i386-dis.c: Enable ModRM.reg /6 aliases.
+
 2017-07-04  Ramana Radhakrishnan  <ramana.radhakrishnan@arm.com>
 
         * opcodes/arm-dis.c: Support MVFR2 in disassembly
index 612e06f..e95311e 100644 (file)
@@ -3441,7 +3441,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 */
@@ -3452,7 +3452,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 */
@@ -3485,7 +3485,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 */
@@ -3496,7 +3496,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 */
@@ -3507,7 +3507,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 */
@@ -3518,7 +3518,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 */