x86: Print {bad} on invalid broadcast in OP_E_memory
authorCui,Lili <lili.cui@intel.com>
Tue, 28 Sep 2021 03:13:33 +0000 (11:13 +0800)
committerCui,Lili <lili.cui@intel.com>
Tue, 28 Sep 2021 03:13:50 +0000 (11:13 +0800)
Don't print broadcast for scalar_mode, and print {bad} for invalid broadcast.

gas/

PR binutils/28381
* testsuite/gas/i386/bad-bcast.s: Add a new testcase.
* testsuite/gas/i386/bad-bcast.d: Likewise.
* testsuite/gas/i386/bad-bcast-intel.d: New.

opcodes/

PR binutils/28381
* i386-dis.c (static struct): Add no_broadcast.
(OP_E_memory): Mark invalid broadcast with no_broadcast=1 and Print "{bad}"for it.
(intel_operand_size): mark invalid broadcast with no_broadcast=1.
(OP_XMM): Mark scalar_mode with no_broadcast=1.

gas/testsuite/gas/i386/bad-bcast-intel.d [new file with mode: 0644]
gas/testsuite/gas/i386/bad-bcast.d
gas/testsuite/gas/i386/bad-bcast.s
gas/testsuite/gas/i386/i386.exp
opcodes/i386-dis.c

diff --git a/gas/testsuite/gas/i386/bad-bcast-intel.d b/gas/testsuite/gas/i386/bad-bcast-intel.d
new file mode 100644 (file)
index 0000000..29de3de
--- /dev/null
@@ -0,0 +1,15 @@
+#source: bad-bcast.s
+#objdump: -dw -Mintel
+#name: Disassemble bad broadcast (Intel mode)
+
+.*: +file format .*
+
+Disassembly of section .text:
+
+0+ <.text>:
+[      ]*[a-f0-9]+:[   ]*62 c3 8c 1d 66\s*\(bad\)
+[      ]*[a-f0-9]+:[   ]*90\s*nop
+[      ]*[a-f0-9]+:[   ]*66 90\s*xchg   ax,ax
+[      ]*[a-f0-9]+:[   ]*66 90\s*xchg   ax,ax
+[      ]*[a-f0-9]+:[   ]*62 c1 ff 38 2a 20\s*vcvtsi2sd xmm4,xmm0,\[eax\]{bad}
+#pass
index 9fc474a42ff5ba016abc87066a15058fb9974485..4f829259994a11f03d9c0cc858cd1d4697ae0c68 100644 (file)
@@ -7,8 +7,8 @@
 Disassembly of section .text:
 
 0+ <.text>:
- +[a-f0-9]+:   62                      .byte 0x62
- +[a-f0-9]+:   c3                      ret    
- +[a-f0-9]+:   8c 1d 66 90 66 90       mov    %ds,0x90669066
- +[a-f0-9]+:   66 90                   xchg   %ax,%ax
-#pass
+ +[a-f0-9]+:   62 c3 8c 1d 66\s+\(bad\)
+ +[a-f0-9]+:   90\s+nop
+ +[a-f0-9]+:   66 90\s+xchg   %ax,%ax
+ +[a-f0-9]+:   66 90\s+xchg   %ax,%ax
+ +[a-f0-9]+:   62 c1 ff 38 2a 20\s+vcvtsi2sd \(%eax\){bad},%xmm0,%xmm4
index 3e49b2238ed5a86ba904f4236e3ccf4d39d7e454..6c55dcbbbd8c4f7a49e63b9e0dba82bcf74318db 100644 (file)
@@ -1,3 +1,5 @@
        .text
 # Invalid 16-bit broadcast with EVEX.W == 1.
        .byte 0x62, 0xc3, 0x8c, 0x1d, 0x66, 0x90, 0x66, 0x90, 0x66, 0x90
+# Invalid vcvtsi2sd with EVEX.b == 1.
+       .byte 0x62,0xc1,0xff,0x38,0x2a,0x20
index 80959726d0eb9606ed0c1f97326191bc899c3b65..680259b1c4e491a9d2e276639123f99792108d81 100644 (file)
@@ -646,6 +646,7 @@ if [gas_32_check] then {
        run_dump_test "dw2-compress-2"
        run_dump_test "dw2-compressed-2"
 
+       run_dump_test "bad-bcast-intel"
        run_dump_test "bad-bcast"
        run_dump_test "bad-size"
 
index aa292233d4d4c6fdc2ce47380d16988022bccbb7..926f776de88a79c1a2a90fc0d65f94c6ca08ac66 100644 (file)
@@ -2422,6 +2422,7 @@ static struct
     int zeroing;
     int ll;
     int b;
+    int no_broadcast;
   }
 vex;
 static unsigned char need_vex;
@@ -11059,23 +11060,25 @@ intel_operand_size (int bytemode, int sizeflag)
 {
   if (vex.b)
     {
-      switch (bytemode)
-       {
-       case x_mode:
-       case evex_half_bcst_xmmq_mode:
-         if (vex.w)
-           oappend ("QWORD PTR ");
-         else
-           oappend ("DWORD PTR ");
-         break;
-       case xh_mode:
-       case evex_half_bcst_xmmqh_mode:
-       case evex_half_bcst_xmmqdh_mode:
-         oappend ("WORD PTR ");
-         break;
-       default:
-         abort ();
-       }
+      if (!vex.no_broadcast)
+       switch (bytemode)
+         {
+         case x_mode:
+         case evex_half_bcst_xmmq_mode:
+           if (vex.w)
+             oappend ("QWORD PTR ");
+           else
+             oappend ("DWORD PTR ");
+           break;
+         case xh_mode:
+         case evex_half_bcst_xmmqh_mode:
+         case evex_half_bcst_xmmqdh_mode:
+           oappend ("WORD PTR ");
+           break;
+         default:
+           vex.no_broadcast = 1;
+           break;
+         }
       return;
     }
   switch (bytemode)
@@ -11908,69 +11911,71 @@ OP_E_memory (int bytemode, int sizeflag)
   if (vex.b)
     {
       evex_used |= EVEX_b_used;
-      if (bytemode == xh_mode)
-        {
-          if (vex.w)
-            {
-             oappend ("{bad}");
-            }
-          else
-            {
-              switch (vex.length)
-                {
-                case 128:
-                  oappend ("{1to8}");
-                  break;
-                case 256:
-                  oappend ("{1to16}");
-                  break;
-                case 512:
-                  oappend ("{1to32}");
-                  break;
-                default:
-                 abort ();
-                }
-            }
-        }
-      else if (vex.w
-         || bytemode == evex_half_bcst_xmmqdh_mode
-         || bytemode == evex_half_bcst_xmmq_mode)
+      if (!vex.no_broadcast)
        {
-         switch (vex.length)
+         if (bytemode == xh_mode)
            {
-           case 128:
-             oappend ("{1to2}");
-             break;
-           case 256:
-             oappend ("{1to4}");
-             break;
-           case 512:
-             oappend ("{1to8}");
-             break;
-           default:
-             abort ();
+             if (vex.w)
+               oappend ("{bad}");
+             else
+               {
+                 switch (vex.length)
+                   {
+                   case 128:
+                     oappend ("{1to8}");
+                     break;
+                   case 256:
+                     oappend ("{1to16}");
+                     break;
+                   case 512:
+                     oappend ("{1to32}");
+                     break;
+                   default:
+                     abort ();
+                   }
+               }
            }
-       }
-      else if (bytemode == x_mode
-         || bytemode == evex_half_bcst_xmmqh_mode)
-       {
-         switch (vex.length)
+         else if (vex.w
+                  || bytemode == evex_half_bcst_xmmqdh_mode
+                  || bytemode == evex_half_bcst_xmmq_mode)
            {
-           case 128:
-             oappend ("{1to4}");
-             break;
-           case 256:
-             oappend ("{1to8}");
-             break;
-           case 512:
-             oappend ("{1to16}");
-             break;
-           default:
-             abort ();
+             switch (vex.length)
+               {
+               case 128:
+                 oappend ("{1to2}");
+                 break;
+               case 256:
+                 oappend ("{1to4}");
+                 break;
+               case 512:
+                 oappend ("{1to8}");
+                 break;
+               default:
+                 abort ();
+               }
+           }
+         else if (bytemode == x_mode
+                  || bytemode == evex_half_bcst_xmmqh_mode)
+           {
+             switch (vex.length)
+               {
+               case 128:
+                 oappend ("{1to4}");
+                 break;
+               case 256:
+                 oappend ("{1to8}");
+                 break;
+               case 512:
+                 oappend ("{1to16}");
+                 break;
+               default:
+                 abort ();
+               }
            }
+         else
+           vex.no_broadcast = 1;
        }
-      else
-       /* If operand doesn't allow broadcast, vex.b should be 0.  */
+      if (vex.no_broadcast)
        oappend ("{bad}");
     }
 }
@@ -12685,6 +12690,8 @@ OP_XMM (int bytemode, int sizeflag ATTRIBUTE_UNUSED)
 
   if (bytemode == tmm_mode)
     modrm.reg = reg;
+  else if (bytemode == scalar_mode)
+    vex.no_broadcast = 1;
 
   print_vector_reg (reg, bytemode);
 }