diff --git a/gas/testsuite/gas/i386/avx512f-nondef.d b/gas/testsuite/gas/i386/avx512f-nondef.d index f19edceb6bb..07ffe60e177 100644 --- a/gas/testsuite/gas/i386/avx512f-nondef.d +++ b/gas/testsuite/gas/i386/avx512f-nondef.d @@ -10,12 +10,11 @@ Disassembly of section .text: 0+ <.text>: [ ]*[a-f0-9]+: 62 f3 d5 1f 0b f4 7b vrndscalesd \$0x7b,\{sae\},%xmm4,%xmm5,%xmm6\{%k7\} [ ]*[a-f0-9]+: 62 f3 d5 5f 0b f4 7b vrndscalesd \$0x7b,\{sae\},%xmm4,%xmm5,%xmm6\{%k7\} -[ ]*[a-f0-9]+: 62 f2 55 1f 3b f4 vpminud %zmm4,%zmm5,%zmm6\{%k7\} -[ ]*[a-f0-9]+: 62 c2 55 1f 3b f4 vpminud %zmm4,%zmm5,%zmm6\{%k7\} +[ ]*[a-f0-9]+: 62 f2 55 4f 3b f4 vpminud %zmm4,%zmm5,%zmm6\{%k7\} +[ ]*[a-f0-9]+: 62 c2 55 4f 3b f4 vpminud %zmm4,%zmm5,%zmm6\{%k7\} +[ ]*[a-f0-9]+: 62 f2 55 1f 3b f4 vpminud \{rn-bad\},%zmm4,%zmm5,%zmm6\{%k7\} [ ]*[a-f0-9]+: 62 f2 7e 48 31 72 7f vpmovdb %zmm6,0x7f0\(%edx\) -[ ]*[a-f0-9]+: 62 vpmovdb %zmm6,\(bad\) -[ ]*[a-f0-9]+: f2 7e 58 bnd jle (0x7d|7d <.text\+0x7d>) -[ ]*[a-f0-9]+: 31 72 7f xor %esi,0x7f\(%edx\) +[ ]*[a-f0-9]+: 62 f2 7e 58 31 72 7f vpmovdb %zmm6,0x7f0\(%edx\)\{bad\} [ ]*[a-f0-9]+: 62 f1 7c 88 58 \(bad\) [ ]*[a-f0-9]+: c3 ret * [ ]*[a-f0-9]+: 62 f2 7d 4f 92 01 vgatherdps \(bad\),%zmm0\{%k7\} diff --git a/gas/testsuite/gas/i386/avx512f-nondef.s b/gas/testsuite/gas/i386/avx512f-nondef.s index 676c4e0fe4b..96d04666248 100644 --- a/gas/testsuite/gas/i386/avx512f-nondef.s +++ b/gas/testsuite/gas/i386/avx512f-nondef.s @@ -5,13 +5,15 @@ .byte 0x62, 0xf3, 0xd5, 0x1f, 0x0b, 0xf4, 0x7b # vrndscalesd {sae}, $123, %xmm4, %xmm5, %xmm6{%k7} # with not-null RC .byte 0x62, 0xf3, 0xd5, 0x5f, 0x0b, 0xf4, 0x7b -# vpminud %zmm4, %zmm5, %zmm6{%k7} # with 111 REX +# vpminud %zmm4, %zmm5, %zmm6{%k7} # with 11 EVEX.{B,R'} +.byte 0x62, 0xf2, 0x55, 0x4f, 0x3b, 0xf4 +# vpminud %zmm4, %zmm5, %zmm6{%k7} # with not-11 EVEX.{B,R'} +.byte 0x62, 0xc2, 0x55, 0x4f, 0x3b, 0xf4 +# vpminud %zmm4, %zmm5, %zmm6{%k7} # with set EVEX.b bit .byte 0x62, 0xf2, 0x55, 0x1f, 0x3b, 0xf4 -# vpminud %zmm4, %zmm5, %zmm6{%k7} # with not-111 REX -.byte 0x62, 0xc2, 0x55, 0x1f, 0x3b, 0xf4 -# vpmovdb %zmm6, 2032(%rdx) # with unset EVEX.B bit +# vpmovdb %zmm6, 2032(%rdx) # with unset EVEX.b bit .byte 0x62, 0xf2, 0x7e, 0x48, 0x31, 0x72, 0x7f -# vpmovdb %zmm6, 2032(%rdx) # with set EVEX.B bit - we should get (bad) operand +# vpmovdb %zmm6, 2032(%rdx) # with set EVEX.b bit - we should get (bad) operand .byte 0x62, 0xf2, 0x7e, 0x58, 0x31, 0x72, 0x7f # vaddps xmm0, xmm0, xmm3 # with EVEX.z set .byte 0x62, 0xf1, 0x7c, 0x88, 0x58, 0xc3 diff --git a/gas/testsuite/gas/i386/evex.d b/gas/testsuite/gas/i386/evex.d index 367b2eb1321..4afcc6db728 100644 --- a/gas/testsuite/gas/i386/evex.d +++ b/gas/testsuite/gas/i386/evex.d @@ -8,14 +8,14 @@ Disassembly of section .text: 0+ <_start>: +[a-f0-9]+: 62 f1 d6 38 2a f0 vcvtsi2ssl %eax,\{rd-sae\},%xmm5,%xmm6 - +[a-f0-9]+: 62 f1 57 38 2a f0 vcvtsi2sdl %eax,\(bad\),%xmm5,%xmm6 - +[a-f0-9]+: 62 f1 d7 38 2a f0 vcvtsi2sdl %eax,\(bad\),%xmm5,%xmm6 + +[a-f0-9]+: 62 f1 57 38 2a f0 vcvtsi2sdl %eax,\{rd-bad\},%xmm5,%xmm6 + +[a-f0-9]+: 62 f1 d7 38 2a f0 vcvtsi2sdl %eax,\{rd-bad\},%xmm5,%xmm6 +[a-f0-9]+: 62 f1 d6 08 7b f0 vcvtusi2ssl %eax,%xmm5,%xmm6 +[a-f0-9]+: 62 f1 57 08 7b f0 vcvtusi2sdl %eax,%xmm5,%xmm6 +[a-f0-9]+: 62 f1 d7 08 7b f0 vcvtusi2sdl %eax,%xmm5,%xmm6 +[a-f0-9]+: 62 f1 d6 38 7b f0 vcvtusi2ssl %eax,\{rd-sae\},%xmm5,%xmm6 - +[a-f0-9]+: 62 f1 57 38 7b f0 vcvtusi2sdl %eax,\(bad\),%xmm5,%xmm6 - +[a-f0-9]+: 62 f1 d7 38 7b f0 vcvtusi2sdl %eax,\(bad\),%xmm5,%xmm6 + +[a-f0-9]+: 62 f1 57 38 7b f0 vcvtusi2sdl %eax,\{rd-bad\},%xmm5,%xmm6 + +[a-f0-9]+: 62 f1 d7 38 7b f0 vcvtusi2sdl %eax,\{rd-bad\},%xmm5,%xmm6 +[a-f0-9]+: 62 e1 7e 08 2d c0 vcvtss2si %xmm0,%eax +[a-f0-9]+: 62 e1 7c 08 c2 c0 00 vcmpeqps %xmm0,%xmm0,%k0 #pass diff --git a/gas/testsuite/gas/i386/x86-64-avx512f-nondef.d b/gas/testsuite/gas/i386/x86-64-avx512f-nondef.d index bce2d80588d..e8ddfd58870 100644 --- a/gas/testsuite/gas/i386/x86-64-avx512f-nondef.d +++ b/gas/testsuite/gas/i386/x86-64-avx512f-nondef.d @@ -10,10 +10,9 @@ Disassembly of section .text: 0+ <.text>: [ ]*[a-f0-9]+: 62 f3 d5 1f 0b f4 7b vrndscalesd \$0x7b,\{sae\},%xmm4,%xmm5,%xmm6\{%k7\} [ ]*[a-f0-9]+: 62 f3 d5 5f 0b f4 7b vrndscalesd \$0x7b,\{sae\},%xmm4,%xmm5,%xmm6\{%k7\} -[ ]*[a-f0-9]+: 62 f2 55 1f 3b f4 vpminud %zmm4,%zmm5,%zmm6\{%k7\} -[ ]*[a-f0-9]+: 62 c2 55 1f 3b f4 vpminud %zmm12,%zmm5,%zmm22\{%k7\} +[ ]*[a-f0-9]+: 62 f2 55 4f 3b f4 vpminud %zmm4,%zmm5,%zmm6\{%k7\} +[ ]*[a-f0-9]+: 62 c2 55 4f 3b f4 vpminud %zmm12,%zmm5,%zmm22\{%k7\} +[ ]*[a-f0-9]+: 62 f2 55 1f 3b f4 vpminud \{rn-bad\},%zmm4,%zmm5,%zmm6\{%k7\} [ ]*[a-f0-9]+: 62 f2 7e 48 31 72 7f vpmovdb %zmm6,0x7f0\(%rdx\) -[ ]*[a-f0-9]+: 62 vpmovdb %zmm6,\(bad\) -[ ]*[a-f0-9]+: f2 7e 58 bnd jle (0x7d|7d <.text\+0x7d>) -[ ]*[a-f0-9]+: 31 72 7f xor %esi,0x7f\(%rdx\) +[ ]*[a-f0-9]+: 62 f2 7e 58 31 72 7f vpmovdb %zmm6,0x7f0\(%rdx\)\{bad\} #pass diff --git a/gas/testsuite/gas/i386/x86-64-avx512f-nondef.s b/gas/testsuite/gas/i386/x86-64-avx512f-nondef.s index 255d2c931f1..952f2db76b3 100644 --- a/gas/testsuite/gas/i386/x86-64-avx512f-nondef.s +++ b/gas/testsuite/gas/i386/x86-64-avx512f-nondef.s @@ -5,11 +5,13 @@ .byte 0x62, 0xf3, 0xd5, 0x1f, 0x0b, 0xf4, 0x7b # vrndscalesd {sae}, $123, %xmm4, %xmm5, %xmm6{%k7} # with not-null RC .byte 0x62, 0xf3, 0xd5, 0x5f, 0x0b, 0xf4, 0x7b -# vpminud %zmm4, %zmm5, %zmm6{%k7} # with 111 REX +# vpminud %zmm4, %zmm5, %zmm6{%k7} # with 11 EVEX.{B,R'} +.byte 0x62, 0xf2, 0x55, 0x4f, 0x3b, 0xf4 +# vpminud %zmm4, %zmm5, %zmm6{%k7} # with not-11 EVEX.{B,R'} +.byte 0x62, 0xc2, 0x55, 0x4f, 0x3b, 0xf4 +# vpminud %zmm4, %zmm5, %zmm6{%k7} # with set EVEX.b bit .byte 0x62, 0xf2, 0x55, 0x1f, 0x3b, 0xf4 -# vpminud %zmm4, %zmm5, %zmm6{%k7} # with not-111 REX -.byte 0x62, 0xc2, 0x55, 0x1f, 0x3b, 0xf4 -# vpmovdb %zmm6, 2032(%rdx) # with unset EVEX.B bit +# vpmovdb %zmm6, 2032(%rdx) # with unset EVEX.b bit .byte 0x62, 0xf2, 0x7e, 0x48, 0x31, 0x72, 0x7f -# vpmovdb %zmm6, 2032(%rdx) # with set EVEX.B bit - we should get (bad) operand +# vpmovdb %zmm6, 2032(%rdx) # with set EVEX.b bit - we should get (bad) operand .byte 0x62, 0xf2, 0x7e, 0x58, 0x31, 0x72, 0x7f diff --git a/gas/testsuite/gas/i386/x86-64-evex.d b/gas/testsuite/gas/i386/x86-64-evex.d index 3a7b48e0bf9..041747db892 100644 --- a/gas/testsuite/gas/i386/x86-64-evex.d +++ b/gas/testsuite/gas/i386/x86-64-evex.d @@ -9,13 +9,13 @@ Disassembly of section .text: 0+ <_start>: +[a-f0-9]+: 62 f1 d6 38 2a f0 vcvtsi2ss %rax,\{rd-sae\},%xmm5,%xmm6 - +[a-f0-9]+: 62 f1 57 38 2a f0 vcvtsi2sd %eax,\(bad\),%xmm5,%xmm6 + +[a-f0-9]+: 62 f1 57 38 2a f0 vcvtsi2sd %eax,\{rd-bad\},%xmm5,%xmm6 +[a-f0-9]+: 62 f1 d7 38 2a f0 vcvtsi2sd %rax,\{rd-sae\},%xmm5,%xmm6 +[a-f0-9]+: 62 f1 d6 08 7b f0 vcvtusi2ss %rax,%xmm5,%xmm6 +[a-f0-9]+: 62 f1 57 08 7b f0 vcvtusi2sd %eax,%xmm5,%xmm6 +[a-f0-9]+: 62 f1 d7 08 7b f0 vcvtusi2sd %rax,%xmm5,%xmm6 +[a-f0-9]+: 62 f1 d6 38 7b f0 vcvtusi2ss %rax,\{rd-sae\},%xmm5,%xmm6 - +[a-f0-9]+: 62 f1 57 38 7b f0 vcvtusi2sd %eax,\(bad\),%xmm5,%xmm6 + +[a-f0-9]+: 62 f1 57 38 7b f0 vcvtusi2sd %eax,\{rd-bad\},%xmm5,%xmm6 +[a-f0-9]+: 62 f1 d7 38 7b f0 vcvtusi2sd %rax,\{rd-sae\},%xmm5,%xmm6 +[a-f0-9]+: 62 e1 7e 08 2d c0 vcvtss2si %xmm0,\(bad\) +[a-f0-9]+: 62 e1 7c 08 c2 c0 00 vcmpeqps %xmm0,%xmm0,\(bad\) diff --git a/opcodes/i386-dis.c b/opcodes/i386-dis.c index 521d6899338..b25a9f324c0 100644 --- a/opcodes/i386-dis.c +++ b/opcodes/i386-dis.c @@ -159,6 +159,11 @@ static int rex_used; current instruction. */ static int used_prefixes; +/* Flags for EVEX bits which we somehow handled when printing the + current instruction. */ +#define EVEX_b_used 1 +static int evex_used; + /* Flags stored in PREFIXES. */ #define PREFIX_REPZ 1 #define PREFIX_REPNZ 2 @@ -2524,12 +2529,12 @@ static const char *att_names_mask[] = { "%k0", "%k1", "%k2", "%k3", "%k4", "%k5", "%k6", "%k7" }; -static const char *names_rounding[] = +static const char *const names_rounding[] = { - "{rn-sae}", - "{rd-sae}", - "{ru-sae}", - "{rz-sae}" + "{rn-", + "{rd-", + "{ru-", + "{rz-" }; static const struct dis386 reg_table[][8] = { @@ -8578,6 +8583,7 @@ ckprefix (void) prefixes = 0; used_prefixes = 0; rex_used = 0; + evex_used = 0; last_lock_prefix = -1; last_repz_prefix = -1; last_repnz_prefix = -1; @@ -9661,6 +9667,21 @@ print_insn (bfd_vma pc, disassemble_info *info) oappend ("/(bad)"); } } + + /* Check whether rounding control was enabled for an insn not + supporting it. */ + if (modrm.mod == 3 && vex.b && !(evex_used & EVEX_b_used)) + { + for (i = 0; i < MAX_OPERANDS; ++i) + { + obufp = op_out[i]; + if (*obufp) + continue; + oappend (names_rounding[vex.ll]); + oappend ("bad}"); + break; + } + } } } @@ -11316,14 +11337,6 @@ OP_E_memory (int bytemode, int sizeflag) if (vex.evex) { - /* In EVEX, if operand doesn't allow broadcast, vex.b should be 0. */ - if (vex.b - && bytemode != x_mode - && bytemode != evex_half_bcst_xmmq_mode) - { - BadOp (); - return; - } switch (bytemode) { case dw_mode: @@ -11764,10 +11777,9 @@ OP_E_memory (int bytemode, int sizeflag) oappend (scratchbuf); } } - if (vex.b - && (bytemode == x_mode - || bytemode == evex_half_bcst_xmmq_mode)) + if (vex.b) { + evex_used |= EVEX_b_used; if (vex.w || bytemode == evex_half_bcst_xmmq_mode) { @@ -11786,7 +11798,7 @@ OP_E_memory (int bytemode, int sizeflag) abort (); } } - else + else if (bytemode == x_mode) { switch (vex.length) { @@ -11803,6 +11815,9 @@ OP_E_memory (int bytemode, int sizeflag) abort (); } } + else + /* If operand doesn't allow broadcast, vex.b should be 0. */ + oappend ("{bad}"); } } @@ -13495,24 +13510,25 @@ MOVSXD_Fixup (int bytemode, int sizeflag) static void OP_Rounding (int bytemode, int sizeflag ATTRIBUTE_UNUSED) { - if (modrm.mod == 3 && vex.b) - switch (bytemode) - { - case evex_rounding_64_mode: - if (address_mode != mode_64bit || !vex.w) - { - oappend ("(bad)"); - break; - } - /* Fall through. */ - case evex_rounding_mode: - oappend (names_rounding[vex.ll]); - break; - case evex_sae_mode: - oappend ("{sae}"); - break; - default: - abort (); - break; - } + if (modrm.mod != 3 || !vex.b) + return; + + switch (bytemode) + { + case evex_rounding_64_mode: + if (address_mode != mode_64bit || !vex.w) + return; + /* Fall through. */ + case evex_rounding_mode: + evex_used |= EVEX_b_used; + oappend (names_rounding[vex.ll]); + break; + case evex_sae_mode: + evex_used |= EVEX_b_used; + oappend ("{"); + break; + default: + abort (); + } + oappend ("sae}"); }