From 2c02075a8ec5223bc4cbcc9561eb91e28d46a9e5 Mon Sep 17 00:00:00 2001 From: "Cui,Lili" Date: Tue, 28 Sep 2021 11:13:33 +0800 Subject: [PATCH] x86: Print {bad} on invalid broadcast in OP_E_memory 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 | 15 +++ gas/testsuite/gas/i386/bad-bcast.d | 10 +- gas/testsuite/gas/i386/bad-bcast.s | 2 + gas/testsuite/gas/i386/i386.exp | 1 + opcodes/i386-dis.c | 155 ++++++++++++----------- 5 files changed, 104 insertions(+), 79 deletions(-) create mode 100644 gas/testsuite/gas/i386/bad-bcast-intel.d diff --git a/gas/testsuite/gas/i386/bad-bcast-intel.d b/gas/testsuite/gas/i386/bad-bcast-intel.d new file mode 100644 index 00000000000..29de3de299c --- /dev/null +++ b/gas/testsuite/gas/i386/bad-bcast-intel.d @@ -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 diff --git a/gas/testsuite/gas/i386/bad-bcast.d b/gas/testsuite/gas/i386/bad-bcast.d index 9fc474a42ff..4f829259994 100644 --- a/gas/testsuite/gas/i386/bad-bcast.d +++ b/gas/testsuite/gas/i386/bad-bcast.d @@ -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 diff --git a/gas/testsuite/gas/i386/bad-bcast.s b/gas/testsuite/gas/i386/bad-bcast.s index 3e49b2238ed..6c55dcbbbd8 100644 --- a/gas/testsuite/gas/i386/bad-bcast.s +++ b/gas/testsuite/gas/i386/bad-bcast.s @@ -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 diff --git a/gas/testsuite/gas/i386/i386.exp b/gas/testsuite/gas/i386/i386.exp index 80959726d0e..680259b1c4e 100644 --- a/gas/testsuite/gas/i386/i386.exp +++ b/gas/testsuite/gas/i386/i386.exp @@ -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" diff --git a/opcodes/i386-dis.c b/opcodes/i386-dis.c index aa292233d4d..926f776de88 100644 --- a/opcodes/i386-dis.c +++ b/opcodes/i386-dis.c @@ -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); } -- 2.30.2