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
This commit is contained in:
Borislav Petkov 2017-07-05 11:27:49 +02:00 committed by Jan Beulich
parent 60c96dbf02
commit e4bdd67955
7 changed files with 47 additions and 6 deletions

View 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> 2017-07-04 Ramana Radhakrishnan <ramana.radhakrishnan@arm.com>
* config/tc-arm.c (arm_regs): Add MVFR2. * config/tc-arm.c (arm_regs): Add MVFR2.

View File

@ -603,4 +603,10 @@ Disassembly of section .text:
+[a-f0-9]+: f6 c9 01 test \$(0x)?0*1,%cl +[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]+: 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]+: 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 #pass

View File

@ -604,3 +604,9 @@ foo:
.byte 0xf6, 0xc9, 0x01 .byte 0xf6, 0xc9, 0x01
.byte 0x66, 0xf7, 0xc9, 0x02, 0x00 .byte 0x66, 0xf7, 0xc9, 0x02, 0x00
.byte 0xf7, 0xc9, 0x04, 0x00, 0x00, 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

View 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]+: 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]+: 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]+: 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 #pass

View File

@ -432,3 +432,12 @@
.byte 0x66, 0xf7, 0xc9, 0x02, 0x00 .byte 0x66, 0xf7, 0xc9, 0x02, 0x00
.byte 0xf7, 0xc9, 0x04, 0x00, 0x00, 0x00 .byte 0xf7, 0xc9, 0x04, 0x00, 0x00, 0x00
.byte 0x48, 0xf7, 0xc9, 0x08, 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

View 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> 2017-07-04 Ramana Radhakrishnan <ramana.radhakrishnan@arm.com>
* opcodes/arm-dis.c: Support MVFR2 in disassembly * opcodes/arm-dis.c: Support MVFR2 in disassembly

View File

@ -3441,7 +3441,7 @@ static const struct dis386 reg_table[][8] = {
{ "rcrA", { Eb, Ib }, 0 }, { "rcrA", { Eb, Ib }, 0 },
{ "shlA", { Eb, Ib }, 0 }, { "shlA", { Eb, Ib }, 0 },
{ "shrA", { Eb, Ib }, 0 }, { "shrA", { Eb, Ib }, 0 },
{ Bad_Opcode }, { "shlA", { Eb, Ib }, 0 },
{ "sarA", { Eb, Ib }, 0 }, { "sarA", { Eb, Ib }, 0 },
}, },
/* REG_C1 */ /* REG_C1 */
@ -3452,7 +3452,7 @@ static const struct dis386 reg_table[][8] = {
{ "rcrQ", { Ev, Ib }, 0 }, { "rcrQ", { Ev, Ib }, 0 },
{ "shlQ", { Ev, Ib }, 0 }, { "shlQ", { Ev, Ib }, 0 },
{ "shrQ", { Ev, Ib }, 0 }, { "shrQ", { Ev, Ib }, 0 },
{ Bad_Opcode }, { "shlQ", { Ev, Ib }, 0 },
{ "sarQ", { Ev, Ib }, 0 }, { "sarQ", { Ev, Ib }, 0 },
}, },
/* REG_C6 */ /* REG_C6 */
@ -3485,7 +3485,7 @@ static const struct dis386 reg_table[][8] = {
{ "rcrA", { Eb, I1 }, 0 }, { "rcrA", { Eb, I1 }, 0 },
{ "shlA", { Eb, I1 }, 0 }, { "shlA", { Eb, I1 }, 0 },
{ "shrA", { Eb, I1 }, 0 }, { "shrA", { Eb, I1 }, 0 },
{ Bad_Opcode }, { "shlA", { Eb, I1 }, 0 },
{ "sarA", { Eb, I1 }, 0 }, { "sarA", { Eb, I1 }, 0 },
}, },
/* REG_D1 */ /* REG_D1 */
@ -3496,7 +3496,7 @@ static const struct dis386 reg_table[][8] = {
{ "rcrQ", { Ev, I1 }, 0 }, { "rcrQ", { Ev, I1 }, 0 },
{ "shlQ", { Ev, I1 }, 0 }, { "shlQ", { Ev, I1 }, 0 },
{ "shrQ", { Ev, I1 }, 0 }, { "shrQ", { Ev, I1 }, 0 },
{ Bad_Opcode }, { "shlQ", { Ev, I1 }, 0 },
{ "sarQ", { Ev, I1 }, 0 }, { "sarQ", { Ev, I1 }, 0 },
}, },
/* REG_D2 */ /* REG_D2 */
@ -3507,7 +3507,7 @@ static const struct dis386 reg_table[][8] = {
{ "rcrA", { Eb, CL }, 0 }, { "rcrA", { Eb, CL }, 0 },
{ "shlA", { Eb, CL }, 0 }, { "shlA", { Eb, CL }, 0 },
{ "shrA", { Eb, CL }, 0 }, { "shrA", { Eb, CL }, 0 },
{ Bad_Opcode }, { "shlA", { Eb, CL }, 0 },
{ "sarA", { Eb, CL }, 0 }, { "sarA", { Eb, CL }, 0 },
}, },
/* REG_D3 */ /* REG_D3 */
@ -3518,7 +3518,7 @@ static const struct dis386 reg_table[][8] = {
{ "rcrQ", { Ev, CL }, 0 }, { "rcrQ", { Ev, CL }, 0 },
{ "shlQ", { Ev, CL }, 0 }, { "shlQ", { Ev, CL }, 0 },
{ "shrQ", { Ev, CL }, 0 }, { "shrQ", { Ev, CL }, 0 },
{ Bad_Opcode }, { "shlQ", { Ev, CL }, 0 },
{ "sarQ", { Ev, CL }, 0 }, { "sarQ", { Ev, CL }, 0 },
}, },
/* REG_F6 */ /* REG_F6 */