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 Mon, May 29, 2017 at 1:58 PM, Borislav Petkov <bp@suse.de> wrote:
> On Mon, May 29, 2017 at 12:17:24AM -0600, Jan Beulich wrote:
>> I think it would be slightly better to name all these opcodes SAL.
>> That way the output would immediately make clear that it's the
>> alias which is in use, and it would be in line with its neighbor
>> being SAR.
>
> ... and because the arithmetic shifts come last, i.e., /6 and /7, after
> the logical shifts. So yap, SAL would actually be the correct name for
> /6, strictly speaking.

Can you write some tests to verify it?

> ---
> 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..a3b446901b00 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                sal    \$0x2,%al
> + +[a-f0-9]+:   c1 f0 01                sal    \$0x1,%eax
> + +[a-f0-9]+:   d0 f0                   sal    %al
> + +[a-f0-9]+:   d1 f0                   sal    %eax
> + +[a-f0-9]+:   d2 f0                   sal    %cl,%al
> + +[a-f0-9]+:   d3 f0                   sal    %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..779facdfcb55 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                sal    \$0x2,%al
> +[      ]*[a-f0-9]+:    c1 f0 01                sal    \$0x1,%eax
> +[      ]*[a-f0-9]+:    48 c1 f0 01             sal    \$0x1,%rax
> +[      ]*[a-f0-9]+:    d0 f0                   sal    %al
> +[      ]*[a-f0-9]+:    d1 f0                   sal    %eax
> +[      ]*[a-f0-9]+:    48 d1 f0                sal    %rax
> +[      ]*[a-f0-9]+:    d2 f0                   sal    %cl,%al
> +[      ]*[a-f0-9]+:    d3 f0                   sal    %cl,%eax
> +[      ]*[a-f0-9]+:    48 d3 f0                sal    %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..3ec6bb16f3d8 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 },
> +    { "salA",  { 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 },
> +    { "salQ",  { 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 },
> +    { "salA",  { 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 },
> +    { "salQ",  { 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 },
> +    { "salA",  { 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 },
> +    { "salQ",  { 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)
> --



-- 
H.J.


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