x86: correct decoding of packed-FP-only AVX encodings
authorJan Beulich <jbeulich@suse.com>
Tue, 9 Jun 2020 06:56:39 +0000 (08:56 +0200)
committerJan Beulich <jbeulich@suse.com>
Tue, 9 Jun 2020 06:56:39 +0000 (08:56 +0200)
Various AVX insns utilizing the X macro fail to reject F3/F2 embedded
prefix encodings. As the PREFIX_OPCODE attribute wasn't used by any
non-legacy-encoded insns so far, re-use it to achieve the intended
effect.

gas/ChangeLog
gas/testsuite/gas/i386/prefix.d
gas/testsuite/gas/i386/prefix.s
opcodes/ChangeLog
opcodes/i386-dis.c

index b4476bf042b53e469f1bbd10e56a60a842af0e24..78ffd807ce3ad95c73a10ff91c4cf87923897674 100644 (file)
@@ -1,3 +1,9 @@
+2020-06-09  Jan Beulich  <jbeulich@suse.com>
+
+       * testsuite/gas/i386/prefix.s: Add bogus REP / EVEX.W prefix
+       with VEX/EVEX encoding tests.
+       * testsuite/gas/i386/prefix.d: Adjust expectations.
+
 2020-06-09  Jan Beulich  <jbeulich@suse.com>
 
        * config/tc-i386.c (process_suffix): Restrict defaulting to 'q'
index e9ad5eb56c014ecabf89d6a7b5ffe4572f4ad4ff..9e293bce2a75c66cce4f261aa9db7046511bd120 100644 (file)
@@ -72,6 +72,20 @@ Disassembly of section .text:
 [      ]*[a-f0-9]+:    90                      nop
 [      ]*[a-f0-9]+:    f2 0f c7                \(bad\)  
 [      ]*[a-f0-9]+:    f0 90                   lock nop
+[      ]*[a-f0-9]+:    f3 0f 28                repz \(bad\) *
+[      ]*[a-f0-9]+:    ff cc                   dec    %esp
+[      ]*[a-f0-9]+:    c5 fa 28                \(bad\) *
+[      ]*[a-f0-9]+:    ff cc                   dec    %esp
+[      ]*[a-f0-9]+:    c4 e1 7b 28             \(bad\) *
+[      ]*[a-f0-9]+:    ff cc                   dec    %esp
+[      ]*[a-f0-9]+:    62 f1 fc 08 28          \(bad\) *
+[      ]*[a-f0-9]+:    ff cc                   dec    %esp
+[      ]*[a-f0-9]+:    62 f1 7e 08 28          \(bad\) *
+[      ]*[a-f0-9]+:    ff cc                   dec    %esp
+[      ]*[a-f0-9]+:    62 f1 7d 08 28          \(bad\) *
+[      ]*[a-f0-9]+:    ff cc                   dec    %esp
+[      ]*[a-f0-9]+:    62 f1 ff 08 28          \(bad\) *
+[      ]*[a-f0-9]+:    ff cc                   dec    %esp
 [      ]*[a-f0-9]+:    c5 fb e6 40 20          vcvtpd2dqx 0x20\(%eax\),%xmm0
 [      ]*[a-f0-9]+:    62 f1 ff 18 e6 40 04    vcvtpd2dq 0x20\(%eax\)\{1to2\},%xmm0
 [      ]*[a-f0-9]+:    c5 fb e6 40 20          vcvtpd2dqx 0x20\(%eax\),%xmm0
index a4c60a71448494253a83ef9060c5919b6ace5aab..78fd478c3fb27581ea26f00fd965744d498aeb48 100644 (file)
 
        nop
 
+       repz; movaps %xmm7, %xmm7
+       int $3
+
+# "repz" vmovaps %xmm7, %xmm7
+       .byte 0xc5
+       .byte 0xfa
+       .byte 0x28
+       .byte 0xff
+
+       int $3
+
+# "repnz" {vex3} vmovaps %xmm7, %xmm7
+       .byte 0xc4
+       .byte 0xe1
+       .byte 0x7b
+       .byte 0x28
+       .byte 0xff
+
+       int $3
+
+# "EVEX.W1" vmovaps %xmm7, %xmm7
+       .byte 0x62
+       .byte 0xf1
+       .byte 0xfc
+       .byte 0x08
+       .byte 0x28
+       .byte 0xff
+
+       int $3
+
+# "repz" vmovaps %xmm7, %xmm7
+       .byte 0x62
+       .byte 0xf1
+       .byte 0x7e
+       .byte 0x08
+       .byte 0x28
+       .byte 0xff
+
+       int $3
+
+# "EVEX.W0" vmovapd %xmm7, %xmm7
+       .byte 0x62
+       .byte 0xf1
+       .byte 0x7d
+       .byte 0x08
+       .byte 0x28
+       .byte 0xff
+
+       int $3
+
+# "repnz" vmovapd %xmm7, %xmm7
+       .byte 0x62
+       .byte 0xf1
+       .byte 0xff
+       .byte 0x08
+       .byte 0x28
+       .byte 0xff
+
+       int $3
+
        vcvtpd2dqx 0x20(%eax),%xmm0
        vcvtpd2dq 0x20(%eax){1to2},%xmm0
        vcvtpd2dqx 0x20(%eax),%xmm0
index 0ef06c9910f5e018b7c228065707a8cc88380ec1..feda626dfb245f9947d9c4730b68c7aa1a3fdcdd 100644 (file)
@@ -1,3 +1,13 @@
+2020-06-09  Jan Beulich  <jbeulich@suse.com>
+
+       * i386-dis.c (vex_table): Use PREFIX_OPCODE for vunpcklpX,
+       vunpckhpX, vmovapX, vandpX, vandnpX, vorpX, vxorpX and vshufpX.
+       (vex_len_table) : Likewise for vmovlpX, vmovhpX, vmovntpX, and
+       vmovmskpX.
+       (print_insn): Drop pointless check against bad_opcode. Split
+       prefix validation into legacy and VEX-and-alike parts.
+       (putop): Re-work 'X' macro handling.
+
 2020-06-09  Jan Beulich  <jbeulich@suse.com>
 
        * i386-dis.c (MOD_0F51): Rename to ...
index 6721fac466c5d0f74455bf3a9027f1a265bab768..799d9d4a4d8329ac6e19baef05e715be9aba06f2 100644 (file)
@@ -8485,8 +8485,8 @@ static const struct dis386 vex_table[][256] = {
     { PREFIX_TABLE (PREFIX_VEX_0F11) },
     { PREFIX_TABLE (PREFIX_VEX_0F12) },
     { MOD_TABLE (MOD_VEX_0F13) },
-    { "vunpcklpX",     { XM, Vex, EXx }, 0 },
-    { "vunpckhpX",     { XM, Vex, EXx }, 0 },
+    { "vunpcklpX",     { XM, Vex, EXx }, PREFIX_OPCODE },
+    { "vunpckhpX",     { XM, Vex, EXx }, PREFIX_OPCODE },
     { PREFIX_TABLE (PREFIX_VEX_0F16) },
     { MOD_TABLE (MOD_VEX_0F17) },
     /* 18 */
@@ -8508,8 +8508,8 @@ static const struct dis386 vex_table[][256] = {
     { Bad_Opcode },
     { Bad_Opcode },
     /* 28 */
-    { "vmovapX",       { XM, EXx }, 0 },
-    { "vmovapX",       { EXxS, XM }, 0 },
+    { "vmovapX",       { XM, EXx }, PREFIX_OPCODE },
+    { "vmovapX",       { EXxS, XM }, PREFIX_OPCODE },
     { PREFIX_TABLE (PREFIX_VEX_0F2A) },
     { MOD_TABLE (MOD_VEX_0F2B) },
     { PREFIX_TABLE (PREFIX_VEX_0F2C) },
@@ -8557,10 +8557,10 @@ static const struct dis386 vex_table[][256] = {
     { PREFIX_TABLE (PREFIX_VEX_0F51) },
     { PREFIX_TABLE (PREFIX_VEX_0F52) },
     { PREFIX_TABLE (PREFIX_VEX_0F53) },
-    { "vandpX",                { XM, Vex, EXx }, 0 },
-    { "vandnpX",       { XM, Vex, EXx }, 0 },
-    { "vorpX",         { XM, Vex, EXx }, 0 },
-    { "vxorpX",                { XM, Vex, EXx }, 0 },
+    { "vandpX",                { XM, Vex, EXx }, PREFIX_OPCODE },
+    { "vandnpX",       { XM, Vex, EXx }, PREFIX_OPCODE },
+    { "vorpX",         { XM, Vex, EXx }, PREFIX_OPCODE },
+    { "vxorpX",                { XM, Vex, EXx }, PREFIX_OPCODE },
     /* 58 */
     { PREFIX_TABLE (PREFIX_VEX_0F58) },
     { PREFIX_TABLE (PREFIX_VEX_0F59) },
@@ -8685,7 +8685,7 @@ static const struct dis386 vex_table[][256] = {
     { Bad_Opcode },
     { PREFIX_TABLE (PREFIX_VEX_0FC4) },
     { PREFIX_TABLE (PREFIX_VEX_0FC5) },
-    { "vshufpX",       { XM, Vex, EXx, Ib }, 0 },
+    { "vshufpX",       { XM, Vex, EXx, Ib }, PREFIX_OPCODE },
     { Bad_Opcode },
     /* c8 */
     { Bad_Opcode },
@@ -9355,7 +9355,7 @@ static const struct dis386 vex_len_table[][2] = {
 
   /* VEX_LEN_0F13_M_0 */
   {
-    { "vmovlpX",       { EXq, XM }, 0 },
+    { "vmovlpX",       { EXq, XM }, PREFIX_OPCODE },
   },
 
   /* VEX_LEN_0F16_P_0_M_0 */
@@ -9375,7 +9375,7 @@ static const struct dis386 vex_len_table[][2] = {
 
   /* VEX_LEN_0F17_M_0 */
   {
-    { "vmovhpX",       { EXq, XM }, 0 },
+    { "vmovhpX",       { EXq, XM }, PREFIX_OPCODE },
   },
 
   /* VEX_LEN_0F41_P_0 */
@@ -10592,7 +10592,7 @@ static const struct dis386 mod_table[][2] = {
   },
   {
     /* MOD_VEX_0F2B */
-    { "vmovntpX",      { Mx, XM }, 0 },
+    { "vmovntpX",      { Mx, XM }, PREFIX_OPCODE },
   },
   {
     /* MOD_VEX_W_0_0F41_P_0_LEN_1 */
@@ -10752,7 +10752,7 @@ static const struct dis386 mod_table[][2] = {
   {
     /* MOD_VEX_0F50 */
     { Bad_Opcode },
-    { "vmovmskpX",     { Gdq, XS }, 0 },
+    { "vmovmskpX",     { Gdq, XS }, PREFIX_OPCODE },
   },
   {
     /* MOD_VEX_0F71_REG_2 */
@@ -12266,14 +12266,18 @@ print_insn (bfd_vma pc, disassemble_info *info)
      PREFIX_REPZ/PREFIX_REPNZ fix, we check the PREFIX_DATA prefix
      separately.  */
   if (dp->prefix_requirement == PREFIX_OPCODE
-      && dp != &bad_opcode
-      && (((prefixes
-           & (PREFIX_REPZ | PREFIX_REPNZ)) != 0
+      && (((need_vex
+           ? vex.prefix == REPE_PREFIX_OPCODE
+             || vex.prefix == REPNE_PREFIX_OPCODE
+           : (prefixes
+              & (PREFIX_REPZ | PREFIX_REPNZ)) != 0)
           && (used_prefixes
               & (PREFIX_REPZ | PREFIX_REPNZ)) == 0)
-         || ((((prefixes
-                & (PREFIX_REPZ | PREFIX_REPNZ | PREFIX_DATA))
-               == PREFIX_DATA)
+         || (((need_vex
+               ? vex.prefix == DATA_PREFIX_OPCODE
+               : ((prefixes
+                   & (PREFIX_REPZ | PREFIX_REPNZ | PREFIX_DATA))
+                  == PREFIX_DATA))
               && (used_prefixes & PREFIX_DATA) == 0))))
     {
       (*info->fprintf_func) (info->stream, "(bad)");
@@ -13230,21 +13234,15 @@ putop (const char *in_template, int sizeflag)
              SAVE_LAST (*p);
              break;
            }
-         if (need_vex && vex.prefix)
+         if (need_vex
+             ? vex.prefix == DATA_PREFIX_OPCODE
+             : prefixes & PREFIX_DATA)
            {
-             if (vex.prefix == DATA_PREFIX_OPCODE)
-               *obufp++ = 'd';
-             else
-               *obufp++ = 's';
+             *obufp++ = 'd';
+             used_prefixes |= PREFIX_DATA;
            }
          else
-           {
-             if (prefixes & PREFIX_DATA)
-               *obufp++ = 'd';
-             else
-               *obufp++ = 's';
-             used_prefixes |= (prefixes & PREFIX_DATA);
-           }
+           *obufp++ = 's';
          break;
        case 'Y':
          if (l == 0 && len == 1)