gas/ChangeLog: * config/tc-i386.c (build_apx_evex_prefix): Handle ZU. * testsuite/gas/i386/x86-64.exp: Added new tests for ZU. * testsuite/gas/i386/x86-64.exp: Added new tests for ZU. * testsuite/gas/i386/x86-64-apx-zu-intel.d: New test. * testsuite/gas/i386/x86-64-apx-zu-inval.l: Ditto. * testsuite/gas/i386/x86-64-apx-zu-inval.s: Ditto. * testsuite/gas/i386/x86-64-apx-zu.d: Ditto. * testsuite/gas/i386/x86-64-apx-zu.s: Ditto.
opcodes/ChangeLog: * i386-dis-evex-prefix.h: Handle PREFIX_EVEX_MAP4_40 ~ PREFIX_EVEX_MAP4_4F. * i386-dis-evex.h: Ditto. * i386-dis.c (struct dis386): Add new micro 'ZU'. (putop): Handle %ZU. * i386-gen.c: Added ZU. * i386-opc.h: Ditto. * i386-opc.tbl: Added new templates to support ZU. --- gas/config/tc-i386.c | 5 +- gas/testsuite/gas/i386/x86-64-apx-zu-intel.d | 78 +++++++++++++ gas/testsuite/gas/i386/x86-64-apx-zu-inval.l | 25 +++++ gas/testsuite/gas/i386/x86-64-apx-zu-inval.s | 28 +++++ gas/testsuite/gas/i386/x86-64-apx-zu.d | 78 +++++++++++++ gas/testsuite/gas/i386/x86-64-apx-zu.s | 73 ++++++++++++ gas/testsuite/gas/i386/x86-64.exp | 3 + opcodes/i386-dis-evex-prefix.h | 112 +++++++++++++++++++ opcodes/i386-dis-evex.h | 36 +++--- opcodes/i386-dis.c | 35 ++++++ opcodes/i386-gen.c | 1 + opcodes/i386-opc.h | 4 + opcodes/i386-opc.tbl | 6 + 13 files changed, 464 insertions(+), 20 deletions(-) create mode 100644 gas/testsuite/gas/i386/x86-64-apx-zu-intel.d create mode 100644 gas/testsuite/gas/i386/x86-64-apx-zu-inval.l create mode 100644 gas/testsuite/gas/i386/x86-64-apx-zu-inval.s create mode 100644 gas/testsuite/gas/i386/x86-64-apx-zu.d create mode 100644 gas/testsuite/gas/i386/x86-64-apx-zu.s diff --git a/gas/config/tc-i386.c b/gas/config/tc-i386.c index 18d06371321..86d177591b3 100644 --- a/gas/config/tc-i386.c +++ b/gas/config/tc-i386.c @@ -4285,8 +4285,9 @@ build_apx_evex_prefix (void) i.vex.bytes[3] &= ~0x08; /* Encode the NDD bit of the instruction promoted from the legacy - space. */ - if (i.vex.register_specifier && i.tm.opcode_space == SPACE_EVEXMAP4) + space. ZU shares the same bit with NDD. */ + if ((i.vex.register_specifier && i.tm.opcode_space == SPACE_EVEXMAP4) + || i.tm.opcode_modifier.zu) i.vex.bytes[3] |= 0x10; /* Encode the NF bit. */ diff --git a/gas/testsuite/gas/i386/x86-64-apx-zu-intel.d b/gas/testsuite/gas/i386/x86-64-apx-zu-intel.d new file mode 100644 index 00000000000..9b61d50fd2f --- /dev/null +++ b/gas/testsuite/gas/i386/x86-64-apx-zu-intel.d @@ -0,0 +1,78 @@ +#as: +#objdump: -dw -Mintel +#name: x86-64 APX ZU instructions with evex prefix encoding(Intel disassembly) +#source: x86-64-apx-zu.s + +.*: +file format .* + + +Disassembly of section .text: + +0+ <_start>: +\s*[a-f0-9]+:\s*62 f4 7d 18 6b c3 0a[ ]+imulzu ax,bx,0xa +\s*[a-f0-9]+:\s*67 62 f4 7d 18 6b 00 0a[ ]+imulzu ax,WORD PTR \[eax\],0xa +\s*[a-f0-9]+:\s*62 ec 7d 18 6b c1 0a[ ]+imulzu r16w,r17w,0xa +\s*[a-f0-9]+:\s*67 62 6c 7d 18 6b 38 0a[ ]+imulzu r31w,WORD PTR \[r16d\],0xa +\s*[a-f0-9]+:\s*62 4c 7d 18 6b ff 0a[ ]+imulzu r31w,r31w,0xa +\s*[a-f0-9]+:\s*62 f4 7d 18 69 c3 82 23[ ]+imulzu ax,bx,0x2382 +\s*[a-f0-9]+:\s*67 62 f4 7d 18 69 00 82 23[ ]+imulzu ax,WORD PTR \[eax\],0x2382 +\s*[a-f0-9]+:\s*62 ec 7d 18 69 c1 82 23[ ]+imulzu r16w,r17w,0x2382 +\s*[a-f0-9]+:\s*67 62 6c 7d 18 69 38 82 23[ ]+imulzu r31w,WORD PTR \[r16d\],0x2382 +\s*[a-f0-9]+:\s*62 4c 7d 18 69 ff 82 23[ ]+imulzu r31w,r31w,0x2382 +\s*[a-f0-9]+:\s*62 f4 7d 1c 6b c3 0a[ ]+\{nf\} imulzu ax,bx,0xa +\s*[a-f0-9]+:\s*67 62 f4 7d 1c 6b 00 0a[ ]+\{nf\} imulzu ax,WORD PTR \[eax\],0xa +\s*[a-f0-9]+:\s*62 f4 7d 0c 6b c3 0a[ ]+\{nf\} imul ax,bx,0xa +\s*[a-f0-9]+:\s*67 62 f4 7d 0c 6b 00 0a[ ]+\{nf\} imul ax,WORD PTR \[eax\],0xa +\s*[a-f0-9]+:\s*62 f4 7d 08 6b c3 0a[ ]+\{evex\} imul ax,bx,0xa +\s*[a-f0-9]+:\s*67 62 f4 7d 08 6b 00 0a[ ]+\{evex\} imul ax,WORD PTR \[eax\],0xa +\s*[a-f0-9]+:\s*62 f4 7f 18 41 c0[ ]+setzuno al +\s*[a-f0-9]+:\s*62 f4 7f 18 42 c3[ ]+setzub bl +\s*[a-f0-9]+:\s*62 d4 7f 18 43 c0[ ]+setzuae r8b +\s*[a-f0-9]+:\s*62 d4 7f 18 44 c1[ ]+setzue r9b +\s*[a-f0-9]+:\s*62 d4 7f 18 45 c2[ ]+setzune r10b +\s*[a-f0-9]+:\s*62 fc 7f 18 46 c0[ ]+setzube r16b +\s*[a-f0-9]+:\s*62 fc 7f 18 47 c1[ ]+setzua r17b +\s*[a-f0-9]+:\s*62 fc 7f 18 48 c2[ ]+setzus r18b +\s*[a-f0-9]+:\s*62 fc 7f 18 49 c3[ ]+setzuns r19b +\s*[a-f0-9]+:\s*62 fc 7f 18 4a c4[ ]+setzup r20b +\s*[a-f0-9]+:\s*62 fc 7f 18 4b c5[ ]+setzunp r21b +\s*[a-f0-9]+:\s*62 fc 7f 18 4c c6[ ]+setzul r22b +\s*[a-f0-9]+:\s*62 fc 7f 18 4d c7[ ]+setzuge r23b +\s*[a-f0-9]+:\s*62 dc 7f 18 4e c0[ ]+setzule r24b +\s*[a-f0-9]+:\s*62 dc 7f 18 4f c1[ ]+setzug r25b +\s*[a-f0-9]+:\s*d5 91 9f c1[ ]+setg r25b +\s*[a-f0-9]+:\s*62 f4 7f 08 4f c0[ ]+\{evex\} setg al +\s*[a-f0-9]+:\s*62 f4 7d 18 6b c3 0a[ ]+imulzu ax,bx,0xa +\s*[a-f0-9]+:\s*67 62 f4 7d 18 6b 00 0a[ ]+imulzu ax,WORD PTR \[eax\],0xa +\s*[a-f0-9]+:\s*62 ec 7d 18 6b c1 0a[ ]+imulzu r16w,r17w,0xa +\s*[a-f0-9]+:\s*67 62 6c 7d 18 6b 38 0a[ ]+imulzu r31w,WORD PTR \[r16d\],0xa +\s*[a-f0-9]+:\s*62 4c 7d 18 6b ff 0a[ ]+imulzu r31w,r31w,0xa +\s*[a-f0-9]+:\s*62 f4 7d 18 69 c3 82 23[ ]+imulzu ax,bx,0x2382 +\s*[a-f0-9]+:\s*67 62 f4 7d 18 69 00 82 23[ ]+imulzu ax,WORD PTR \[eax\],0x2382 +\s*[a-f0-9]+:\s*62 ec 7d 18 69 c1 82 23[ ]+imulzu r16w,r17w,0x2382 +\s*[a-f0-9]+:\s*67 62 6c 7d 18 69 38 82 23[ ]+imulzu r31w,WORD PTR \[r16d\],0x2382 +\s*[a-f0-9]+:\s*62 4c 7d 18 69 ff 82 23[ ]+imulzu r31w,r31w,0x2382 +\s*[a-f0-9]+:\s*62 f4 7d 1c 6b c3 0a[ ]+\{nf\} imulzu ax,bx,0xa +\s*[a-f0-9]+:\s*67 62 f4 7d 1c 6b 00 0a[ ]+\{nf\} imulzu ax,WORD PTR \[eax\],0xa +\s*[a-f0-9]+:\s*62 f4 7d 0c 6b c3 0a[ ]+\{nf\} imul ax,bx,0xa +\s*[a-f0-9]+:\s*67 62 f4 7d 0c 6b 00 0a[ ]+\{nf\} imul ax,WORD PTR \[eax\],0xa +\s*[a-f0-9]+:\s*62 f4 7d 08 6b c3 0a[ ]+\{evex\} imul ax,bx,0xa +\s*[a-f0-9]+:\s*67 62 f4 7d 08 6b 00 0a[ ]+\{evex\} imul ax,WORD PTR \[eax\],0xa +\s*[a-f0-9]+:\s*62 f4 7f 18 41 c0[ ]+setzuno al +\s*[a-f0-9]+:\s*62 f4 7f 18 42 c3[ ]+setzub bl +\s*[a-f0-9]+:\s*62 d4 7f 18 43 c0[ ]+setzuae r8b +\s*[a-f0-9]+:\s*62 d4 7f 18 44 c1[ ]+setzue r9b +\s*[a-f0-9]+:\s*62 d4 7f 18 45 c2[ ]+setzune r10b +\s*[a-f0-9]+:\s*62 fc 7f 18 46 c0[ ]+setzube r16b +\s*[a-f0-9]+:\s*62 fc 7f 18 47 c1[ ]+setzua r17b +\s*[a-f0-9]+:\s*62 fc 7f 18 48 c2[ ]+setzus r18b +\s*[a-f0-9]+:\s*62 fc 7f 18 49 c3[ ]+setzuns r19b +\s*[a-f0-9]+:\s*62 fc 7f 18 4a c4[ ]+setzup r20b +\s*[a-f0-9]+:\s*62 fc 7f 18 4b c5[ ]+setzunp r21b +\s*[a-f0-9]+:\s*62 fc 7f 18 4c c6[ ]+setzul r22b +\s*[a-f0-9]+:\s*62 fc 7f 18 4d c7[ ]+setzuge r23b +\s*[a-f0-9]+:\s*62 dc 7f 18 4e c0[ ]+setzule r24b +\s*[a-f0-9]+:\s*62 dc 7f 18 4f c1[ ]+setzug r25b +\s*[a-f0-9]+:\s*d5 91 9f c1[ ]+setg r25b +\s*[a-f0-9]+:\s*62 f4 7f 08 4f c0[ ]+\{evex\} setg al +#pass diff --git a/gas/testsuite/gas/i386/x86-64-apx-zu-inval.l b/gas/testsuite/gas/i386/x86-64-apx-zu-inval.l new file mode 100644 index 00000000000..978acc1e3e9 --- /dev/null +++ b/gas/testsuite/gas/i386/x86-64-apx-zu-inval.l @@ -0,0 +1,25 @@ +.* Assembler messages: +.*:6: Error: invalid instruction suffix for `imulzu' +.*:7: Error: no such instruction: `imulzud \$0xa,%ebx,%eax' +.*:8: Error: operand size mismatch for `imulzu' +.*:9: Error: invalid instruction suffix for `imulzu' +.*:10: Error: no such instruction: `imulzud \$0xaaaa,%ebx,%eax' +.*:11: Error: operand size mismatch for `imulzu' +.*:12: Error: operand size mismatch for `imulzu' +.*:13: Error: operand size mismatch for `imulzu' +.*:14: Error: can't encode register 'ah' in an EVEX/VEX prefix instruction +.*:15: Error: operand size mismatch for `setzub' +.*:16: Error: operand size mismatch for `setzuae' +.*:17: Error: operand size mismatch for `setzue' +.*:18: Error: operand size mismatch for `setzune' +.*:19: Error: operand size mismatch for `setzube' +.*:20: Error: operand size mismatch for `setzua' +.*:21: Error: operand size mismatch for `setzus' +.*:22: Error: operand size mismatch for `setzuns' +.*:23: Error: operand size mismatch for `setzup' +.*:24: Error: operand size mismatch for `setzunp' +.*:25: Error: operand size mismatch for `setzul' +.*:26: Error: operand size mismatch for `setzuge' +.*:27: Error: operand size mismatch for `setzule' +.*:28: Error: operand size mismatch for `setzug' +#pass diff --git a/gas/testsuite/gas/i386/x86-64-apx-zu-inval.s b/gas/testsuite/gas/i386/x86-64-apx-zu-inval.s new file mode 100644 index 00000000000..bd81b41ff3f --- /dev/null +++ b/gas/testsuite/gas/i386/x86-64-apx-zu-inval.s @@ -0,0 +1,28 @@ +# Check illegal APX-ZU instructions + + .allow_index_reg + .text +_start: + imulzub $0xa,%bl,%al + imulzud $0xa,%ebx,%eax + imulzu $0xa,%rbx,%rax + imulzub $0xaaaa,%bl,%al + imulzud $0xaaaa,%ebx,%eax + imulzu $0xaaaa,%rbx,%rax + imulzu $0xaaaa,%ebx,%rax + imulzu $0xaaaa,%ebx,%rax + setzuno %ah + setzub %bx + setzuae %r8w + setzue %r9 + setzune %r10d + setzube %eax + setzua %ebx + setzus %r18w + setzuns %r19w + setzup %r20d + setzunp %r21w + setzul %r22w + setzuge %r23d + setzule %r24w + setzug %r25w diff --git a/gas/testsuite/gas/i386/x86-64-apx-zu.d b/gas/testsuite/gas/i386/x86-64-apx-zu.d new file mode 100644 index 00000000000..c6b0cc45d76 --- /dev/null +++ b/gas/testsuite/gas/i386/x86-64-apx-zu.d @@ -0,0 +1,78 @@ +#as: +#objdump: -dw +#name: x86-64 APX ZU instructions with evex prefix encoding +#source: x86-64-apx-zu.s + +.*: +file format .* + + +Disassembly of section .text: + +0+ <_start>: +\s*[a-f0-9]+:\s*62 f4 7d 18 6b c3 0a[ ]+imulzu \$0xa,%bx,%ax +\s*[a-f0-9]+:\s*67 62 f4 7d 18 6b 00 0a[ ]+imulzu \$0xa,\(%eax\),%ax +\s*[a-f0-9]+:\s*62 ec 7d 18 6b c1 0a[ ]+imulzu \$0xa,%r17w,%r16w +\s*[a-f0-9]+:\s*67 62 6c 7d 18 6b 38 0a[ ]+imulzu \$0xa,\(%r16d\),%r31w +\s*[a-f0-9]+:\s*62 4c 7d 18 6b ff 0a[ ]+imulzu \$0xa,%r31w,%r31w +\s*[a-f0-9]+:\s*62 f4 7d 18 69 c3 82 23[ ]+imulzu \$0x2382,%bx,%ax +\s*[a-f0-9]+:\s*67 62 f4 7d 18 69 00 82 23[ ]+imulzu \$0x2382,\(%eax\),%ax +\s*[a-f0-9]+:\s*62 ec 7d 18 69 c1 82 23[ ]+imulzu \$0x2382,%r17w,%r16w +\s*[a-f0-9]+:\s*67 62 6c 7d 18 69 38 82 23[ ]+imulzu \$0x2382,\(%r16d\),%r31w +\s*[a-f0-9]+:\s*62 4c 7d 18 69 ff 82 23[ ]+imulzu \$0x2382,%r31w,%r31w +\s*[a-f0-9]+:\s*62 f4 7d 1c 6b c3 0a[ ]+\{nf\} imulzu \$0xa,%bx,%ax +\s*[a-f0-9]+:\s*67 62 f4 7d 1c 6b 00 0a[ ]+\{nf\} imulzu \$0xa,\(%eax\),%ax +\s*[a-f0-9]+:\s*62 f4 7d 0c 6b c3 0a[ ]+\{nf\} imul \$0xa,%bx,%ax +\s*[a-f0-9]+:\s*67 62 f4 7d 0c 6b 00 0a[ ]+\{nf\} imul \$0xa,\(%eax\),%ax +\s*[a-f0-9]+:\s*62 f4 7d 08 6b c3 0a[ ]+\{evex\} imul \$0xa,%bx,%ax +\s*[a-f0-9]+:\s*67 62 f4 7d 08 6b 00 0a[ ]+\{evex\} imul \$0xa,\(%eax\),%ax +\s*[a-f0-9]+:\s*62 f4 7f 18 41 c0[ ]+setzuno %al +\s*[a-f0-9]+:\s*62 f4 7f 18 42 c3[ ]+setzub %bl +\s*[a-f0-9]+:\s*62 d4 7f 18 43 c0[ ]+setzuae %r8b +\s*[a-f0-9]+:\s*62 d4 7f 18 44 c1[ ]+setzue %r9b +\s*[a-f0-9]+:\s*62 d4 7f 18 45 c2[ ]+setzune %r10b +\s*[a-f0-9]+:\s*62 fc 7f 18 46 c0[ ]+setzube %r16b +\s*[a-f0-9]+:\s*62 fc 7f 18 47 c1[ ]+setzua %r17b +\s*[a-f0-9]+:\s*62 fc 7f 18 48 c2[ ]+setzus %r18b +\s*[a-f0-9]+:\s*62 fc 7f 18 49 c3[ ]+setzuns %r19b +\s*[a-f0-9]+:\s*62 fc 7f 18 4a c4[ ]+setzup %r20b +\s*[a-f0-9]+:\s*62 fc 7f 18 4b c5[ ]+setzunp %r21b +\s*[a-f0-9]+:\s*62 fc 7f 18 4c c6[ ]+setzul %r22b +\s*[a-f0-9]+:\s*62 fc 7f 18 4d c7[ ]+setzuge %r23b +\s*[a-f0-9]+:\s*62 dc 7f 18 4e c0[ ]+setzule %r24b +\s*[a-f0-9]+:\s*62 dc 7f 18 4f c1[ ]+setzug %r25b +\s*[a-f0-9]+:\s*d5 91 9f c1[ ]+setg %r25b +\s*[a-f0-9]+:\s*62 f4 7f 08 4f c0[ ]+\{evex\} setg %al +\s*[a-f0-9]+:\s*62 f4 7d 18 6b c3 0a[ ]+imulzu \$0xa,%bx,%ax +\s*[a-f0-9]+:\s*67 62 f4 7d 18 6b 00 0a[ ]+imulzu \$0xa,\(%eax\),%ax +\s*[a-f0-9]+:\s*62 ec 7d 18 6b c1 0a[ ]+imulzu \$0xa,%r17w,%r16w +\s*[a-f0-9]+:\s*67 62 6c 7d 18 6b 38 0a[ ]+imulzu \$0xa,\(%r16d\),%r31w +\s*[a-f0-9]+:\s*62 4c 7d 18 6b ff 0a[ ]+imulzu \$0xa,%r31w,%r31w +\s*[a-f0-9]+:\s*62 f4 7d 18 69 c3 82 23[ ]+imulzu \$0x2382,%bx,%ax +\s*[a-f0-9]+:\s*67 62 f4 7d 18 69 00 82 23[ ]+imulzu \$0x2382,\(%eax\),%ax +\s*[a-f0-9]+:\s*62 ec 7d 18 69 c1 82 23[ ]+imulzu \$0x2382,%r17w,%r16w +\s*[a-f0-9]+:\s*67 62 6c 7d 18 69 38 82 23[ ]+imulzu \$0x2382,\(%r16d\),%r31w +\s*[a-f0-9]+:\s*62 4c 7d 18 69 ff 82 23[ ]+imulzu \$0x2382,%r31w,%r31w +\s*[a-f0-9]+:\s*62 f4 7d 1c 6b c3 0a[ ]+\{nf\} imulzu \$0xa,%bx,%ax +\s*[a-f0-9]+:\s*67 62 f4 7d 1c 6b 00 0a[ ]+\{nf\} imulzu \$0xa,\(%eax\),%ax +\s*[a-f0-9]+:\s*62 f4 7d 0c 6b c3 0a[ ]+\{nf\} imul \$0xa,%bx,%ax +\s*[a-f0-9]+:\s*67 62 f4 7d 0c 6b 00 0a[ ]+\{nf\} imul \$0xa,\(%eax\),%ax +\s*[a-f0-9]+:\s*62 f4 7d 08 6b c3 0a[ ]+\{evex\} imul \$0xa,%bx,%ax +\s*[a-f0-9]+:\s*67 62 f4 7d 08 6b 00 0a[ ]+\{evex\} imul \$0xa,\(%eax\),%ax +\s*[a-f0-9]+:\s*62 f4 7f 18 41 c0[ ]+setzuno %al +\s*[a-f0-9]+:\s*62 f4 7f 18 42 c3[ ]+setzub %bl +\s*[a-f0-9]+:\s*62 d4 7f 18 43 c0[ ]+setzuae %r8b +\s*[a-f0-9]+:\s*62 d4 7f 18 44 c1[ ]+setzue %r9b +\s*[a-f0-9]+:\s*62 d4 7f 18 45 c2[ ]+setzune %r10b +\s*[a-f0-9]+:\s*62 fc 7f 18 46 c0[ ]+setzube %r16b +\s*[a-f0-9]+:\s*62 fc 7f 18 47 c1[ ]+setzua %r17b +\s*[a-f0-9]+:\s*62 fc 7f 18 48 c2[ ]+setzus %r18b +\s*[a-f0-9]+:\s*62 fc 7f 18 49 c3[ ]+setzuns %r19b +\s*[a-f0-9]+:\s*62 fc 7f 18 4a c4[ ]+setzup %r20b +\s*[a-f0-9]+:\s*62 fc 7f 18 4b c5[ ]+setzunp %r21b +\s*[a-f0-9]+:\s*62 fc 7f 18 4c c6[ ]+setzul %r22b +\s*[a-f0-9]+:\s*62 fc 7f 18 4d c7[ ]+setzuge %r23b +\s*[a-f0-9]+:\s*62 dc 7f 18 4e c0[ ]+setzule %r24b +\s*[a-f0-9]+:\s*62 dc 7f 18 4f c1[ ]+setzug %r25b +\s*[a-f0-9]+:\s*d5 91 9f c1[ ]+setg %r25b +\s*[a-f0-9]+:\s*62 f4 7f 08 4f c0[ ]+\{evex\} setg %al +#pass diff --git a/gas/testsuite/gas/i386/x86-64-apx-zu.s b/gas/testsuite/gas/i386/x86-64-apx-zu.s new file mode 100644 index 00000000000..0c287b8aa89 --- /dev/null +++ b/gas/testsuite/gas/i386/x86-64-apx-zu.s @@ -0,0 +1,73 @@ +# Check 64bit APX ZU instructions with evex prefix encoding + + .allow_index_reg + .text +_start: + imulzu $10, %bx, %ax + imulzu $10, (%eax), %ax + imulzu $10, %r17w, %r16w + imulzu $10, (%r16d), %r31w + imulzu $10, %r31w + imulzu $9090, %bx, %ax + imulzu $9090, (%eax), %ax + imulzu $9090, %r17w, %r16w + imulzu $9090, (%r16d), %r31w + imulzu $9090, %r31w + {nf} imulzu $10, %bx, %ax + {nf} imulzu $10, (%eax), %ax + {nf} imul $10, %bx, %ax # ZU=0 + {nf} imul $10, (%eax), %ax # ZU=0 + {evex} imul $10, %bx, %ax # ZU=0 + {evex} imul $10, (%eax), %ax # ZU=0 + setzuno %al + setzub %bl + setzuae %r8b + setzue %r9b + setzune %r10b + setzube %r16b + setzua %r17b + setzus %r18b + setzuns %r19b + setzup %r20b + setzunp %r21b + setzul %r22b + setzuge %r23b + setzule %r24b + setzug %r25b + setg %r25b + {evex} setg %al + + .intel_syntax noprefix + imulzu ax,bx, 10 + imulzu ax,WORD PTR [eax],10 + imulzu r16w,r17w,10 + imulzu r31w,WORD PTR [r16d],10 + imulzu r31w,r31w,10 + imulzu ax,bx,9090 + imulzu ax,WORD PTR [eax],9090 + imulzu r16w,r17w,9090 + imulzu r31w,WORD PTR [r16d],9090 + imulzu r31w,r31w,9090 + {nf} imulzu ax,bx, 10 + {nf} imulzu ax,WORD PTR [eax],10 + {nf} imul ax,bx, 10 # ZU=0 + {nf} imul ax,WORD PTR [eax],10 # ZU=0 + {evex} imul ax,bx, 10 # ZU=0 + {evex} imul ax,WORD PTR [eax],10 # ZU=0 + setzuno al + setzub bl + setzuae r8b + setzue r9b + setzune r10b + setzube r16b + setzua r17b + setzus r18b + setzuns r19b + setzup r20b + setzunp r21b + setzul r22b + setzuge r23b + setzule r24b + setzug r25b + setg r25b + {evex} setg al diff --git a/gas/testsuite/gas/i386/x86-64.exp b/gas/testsuite/gas/i386/x86-64.exp index a50865f6b21..ef1ad2dfe8a 100644 --- a/gas/testsuite/gas/i386/x86-64.exp +++ b/gas/testsuite/gas/i386/x86-64.exp @@ -389,6 +389,9 @@ run_dump_test "x86-64-apx-jmpabs-intel" run_dump_test "x86-64-apx-jmpabs-inval" run_dump_test "x86-64-apx-nf" run_dump_test "x86-64-apx-nf-intel" +run_dump_test "x86-64-apx-zu" +run_dump_test "x86-64-apx-zu-intel" +run_list_test "x86-64-apx-zu-inval" run_dump_test "x86-64-apx_f-evex" run_dump_test "sse2avx-apx" run_dump_test "sse2avx-evex" diff --git a/opcodes/i386-dis-evex-prefix.h b/opcodes/i386-dis-evex-prefix.h index 5e6423790b5..947fd868dd6 100644 --- a/opcodes/i386-dis-evex-prefix.h +++ b/opcodes/i386-dis-evex-prefix.h @@ -338,6 +338,118 @@ { "vcmpp%XH", { MaskG, Vex, EXxh, EXxEVexS, CMP }, 0 }, { "vcmps%XH", { MaskG, VexScalar, EXw, EXxEVexS, CMP }, 0 }, }, + /* PREFIX_EVEX_MAP4_40 */ + { + { "%CFcmovoS", { VexGv, Gv, Ev }, 0 }, + { Bad_Opcode }, + { "%CFcmovoS", { VexGv, Gv, Ev }, 0 }, + { "set%ZUo", { Eb }, 0 }, + }, + /* PREFIX_EVEX_MAP4_41 */ + { + { "%CFcmovnoS", { VexGv, Gv, Ev }, 0 }, + { Bad_Opcode }, + { "%CFcmovnoS", { VexGv, Gv, Ev }, 0 }, + { "set%ZUno", { Eb }, 0 }, + }, + /* PREFIX_EVEX_MAP4_42 */ + { + { "%CFcmovbS", { VexGv, Gv, Ev }, 0 }, + { Bad_Opcode }, + { "%CFcmovbS", { VexGv, Gv, Ev }, 0 }, + { "set%ZUb", { Eb }, 0 }, + }, + /* PREFIX_EVEX_MAP4_43 */ + { + { "%CFcmovaeS", { VexGv, Gv, Ev }, 0 }, + { Bad_Opcode }, + { "%CFcmovaeS", { VexGv, Gv, Ev }, 0 }, + { "set%ZUae", { Eb }, 0 }, + }, + /* PREFIX_EVEX_MAP4_44 */ + { + { "%CFcmoveS", { VexGv, Gv, Ev }, 0 }, + { Bad_Opcode }, + { "%CFcmoveS", { VexGv, Gv, Ev }, 0 }, + { "set%ZUe", { Eb }, 0 }, + }, + /* PREFIX_EVEX_MAP4_45 */ + { + { "%CFcmovneS", { VexGv, Gv, Ev }, 0 }, + { Bad_Opcode }, + { "%CFcmovneS", { VexGv, Gv, Ev }, 0 }, + { "set%ZUne", { Eb }, 0 }, + }, + /* PREFIX_EVEX_MAP4_46 */ + { + { "%CFcmovbeS", { VexGv, Gv, Ev }, 0 }, + { Bad_Opcode }, + { "%CFcmovbeS", { VexGv, Gv, Ev }, 0 }, + { "set%ZUbe", { Eb }, 0 }, + }, + /* PREFIX_EVEX_MAP4_47 */ + { + { "%CFcmovaS", { VexGv, Gv, Ev }, 0 }, + { Bad_Opcode }, + { "%CFcmovaS", { VexGv, Gv, Ev }, 0 }, + { "set%ZUa", { Eb }, 0 }, + }, + /* PREFIX_EVEX_MAP4_48 */ + { + { "%CFcmovsS", { VexGv, Gv, Ev }, 0 }, + { Bad_Opcode }, + { "%CFcmovsS", { VexGv, Gv, Ev }, 0 }, + { "set%ZUs", { Eb }, 0 }, + }, + /* PREFIX_EVEX_MAP4_49 */ + { + { "%CFcmovnsS", { VexGv, Gv, Ev }, 0 }, + { Bad_Opcode }, + { "%CFcmovnsS", { VexGv, Gv, Ev }, 0 }, + { "set%ZUns", { Eb }, 0 }, + }, + /* PREFIX_EVEX_MAP4_4A */ + { + { "%CFcmovpS", { VexGv, Gv, Ev }, 0 }, + { Bad_Opcode }, + { "%CFcmovpS", { VexGv, Gv, Ev }, 0 }, + { "set%ZUp", { Eb }, 0 }, + }, + /* PREFIX_EVEX_MAP4_4B */ + { + { "%CFcmovnpS", { VexGv, Gv, Ev }, 0 }, + { Bad_Opcode }, + { "%CFcmovnpS", { VexGv, Gv, Ev }, 0 }, + { "set%ZUnp", { Eb }, 0 }, + }, + /* PREFIX_EVEX_MAP4_4C */ + { + { "%CFcmovlS", { VexGv, Gv, Ev }, 0 }, + { Bad_Opcode }, + { "%CFcmovlS", { VexGv, Gv, Ev }, 0 }, + { "set%ZUl", { Eb }, 0 }, + }, + /* PREFIX_EVEX_MAP4_4D */ + { + { "%CFcmovgeS", { VexGv, Gv, Ev }, 0 }, + { Bad_Opcode }, + { "%CFcmovgeS", { VexGv, Gv, Ev }, 0 }, + { "set%ZUge", { Eb }, 0 }, + }, + /* PREFIX_EVEX_MAP4_4E */ + { + { "%CFcmovleS", { VexGv, Gv, Ev }, 0 }, + { Bad_Opcode }, + { "%CFcmovleS", { VexGv, Gv, Ev }, 0 }, + { "set%ZUle", { Eb }, 0 }, + }, + /* PREFIX_EVEX_MAP4_4F */ + { + { "%CFcmovgS", { VexGv, Gv, Ev }, 0 }, + { Bad_Opcode }, + { "%CFcmovgS", { VexGv, Gv, Ev }, 0 }, + { "set%ZUg", { Eb }, 0 }, + }, /* PREFIX_EVEX_MAP4_F0 */ { { "crc32A", { Gdq, Eb }, 0 }, diff --git a/opcodes/i386-dis-evex.h b/opcodes/i386-dis-evex.h index b158f2b0b89..ebb3cc20aea 100644 --- a/opcodes/i386-dis-evex.h +++ b/opcodes/i386-dis-evex.h @@ -947,23 +947,23 @@ static const struct dis386 evex_table[][256] = { { Bad_Opcode }, { Bad_Opcode }, /* 40 */ - { "%CFcmovoS", { VexGv, Gv, Ev }, PREFIX_NP_OR_DATA }, - { "%CFcmovnoS", { VexGv, Gv, Ev }, PREFIX_NP_OR_DATA }, - { "%CFcmovbS", { VexGv, Gv, Ev }, PREFIX_NP_OR_DATA }, - { "%CFcmovaeS", { VexGv, Gv, Ev }, PREFIX_NP_OR_DATA }, - { "%CFcmoveS", { VexGv, Gv, Ev }, PREFIX_NP_OR_DATA }, - { "%CFcmovneS", { VexGv, Gv, Ev }, PREFIX_NP_OR_DATA }, - { "%CFcmovbeS", { VexGv, Gv, Ev }, PREFIX_NP_OR_DATA }, - { "%CFcmovaS", { VexGv, Gv, Ev }, PREFIX_NP_OR_DATA }, + { PREFIX_TABLE (PREFIX_EVEX_MAP4_40) }, + { PREFIX_TABLE (PREFIX_EVEX_MAP4_41) }, + { PREFIX_TABLE (PREFIX_EVEX_MAP4_42) }, + { PREFIX_TABLE (PREFIX_EVEX_MAP4_43) }, + { PREFIX_TABLE (PREFIX_EVEX_MAP4_44) }, + { PREFIX_TABLE (PREFIX_EVEX_MAP4_45) }, + { PREFIX_TABLE (PREFIX_EVEX_MAP4_46) }, + { PREFIX_TABLE (PREFIX_EVEX_MAP4_47) }, /* 48 */ - { "%CFcmovsS", { VexGv, Gv, Ev }, PREFIX_NP_OR_DATA }, - { "%CFcmovnsS", { VexGv, Gv, Ev }, PREFIX_NP_OR_DATA }, - { "%CFcmovpS", { VexGv, Gv, Ev }, PREFIX_NP_OR_DATA }, - { "%CFcmovnpS", { VexGv, Gv, Ev }, PREFIX_NP_OR_DATA }, - { "%CFcmovlS", { VexGv, Gv, Ev }, PREFIX_NP_OR_DATA }, - { "%CFcmovgeS", { VexGv, Gv, Ev }, PREFIX_NP_OR_DATA }, - { "%CFcmovleS", { VexGv, Gv, Ev }, PREFIX_NP_OR_DATA }, - { "%CFcmovgS", { VexGv, Gv, Ev }, PREFIX_NP_OR_DATA }, + { PREFIX_TABLE (PREFIX_EVEX_MAP4_48) }, + { PREFIX_TABLE (PREFIX_EVEX_MAP4_49) }, + { PREFIX_TABLE (PREFIX_EVEX_MAP4_4A) }, + { PREFIX_TABLE (PREFIX_EVEX_MAP4_4B) }, + { PREFIX_TABLE (PREFIX_EVEX_MAP4_4C) }, + { PREFIX_TABLE (PREFIX_EVEX_MAP4_4D) }, + { PREFIX_TABLE (PREFIX_EVEX_MAP4_4E) }, + { PREFIX_TABLE (PREFIX_EVEX_MAP4_4F) }, /* 50 */ { Bad_Opcode }, { Bad_Opcode }, @@ -993,9 +993,9 @@ static const struct dis386 evex_table[][256] = { { Bad_Opcode }, /* 68 */ { Bad_Opcode }, - { "%NFimulS", { Gv, Ev, Iv }, PREFIX_NP_OR_DATA }, + { "%NFimul%ZUS", { Gv, Ev, Iv }, PREFIX_NP_OR_DATA }, { Bad_Opcode }, - { "%NFimulS", { Gv, Ev, sIb }, PREFIX_NP_OR_DATA }, + { "%NFimul%ZUS", { Gv, Ev, sIb }, PREFIX_NP_OR_DATA }, { Bad_Opcode }, { Bad_Opcode }, { Bad_Opcode }, diff --git a/opcodes/i386-dis.c b/opcodes/i386-dis.c index 53f2d6cf6d8..fad9188b259 100644 --- a/opcodes/i386-dis.c +++ b/opcodes/i386-dis.c @@ -1199,6 +1199,22 @@ enum PREFIX_EVEX_0F3A67, PREFIX_EVEX_0F3AC2, + PREFIX_EVEX_MAP4_40, + PREFIX_EVEX_MAP4_41, + PREFIX_EVEX_MAP4_42, + PREFIX_EVEX_MAP4_43, + PREFIX_EVEX_MAP4_44, + PREFIX_EVEX_MAP4_45, + PREFIX_EVEX_MAP4_46, + PREFIX_EVEX_MAP4_47, + PREFIX_EVEX_MAP4_48, + PREFIX_EVEX_MAP4_49, + PREFIX_EVEX_MAP4_4A, + PREFIX_EVEX_MAP4_4B, + PREFIX_EVEX_MAP4_4C, + PREFIX_EVEX_MAP4_4D, + PREFIX_EVEX_MAP4_4E, + PREFIX_EVEX_MAP4_4F, PREFIX_EVEX_MAP4_F0, PREFIX_EVEX_MAP4_F1, PREFIX_EVEX_MAP4_F2, @@ -1816,6 +1832,7 @@ struct dis386 { instruction. "NF" => print "{nf} " pseudo prefix when EVEX.NF = 1 and print "{evex} " pseudo prefix when instructions without NF, EGPR and VVVV, + "ZU" => print 'zu' if EVEX.ZU=1. "YK" keep unused, to avoid ambiguity with the combined use of Y and K. "YX" keep unused, to avoid ambiguity with the combined use of Y and X. "LQ" => print 'l' ('d' in Intel mode) or 'q' for memory operand, cond @@ -10877,6 +10894,24 @@ putop (instr_info *ins, const char *in_template, int sizeflag) abort (); } break; + case 'U': + if (l == 1 && (last[0] == 'Z')) + { + /* Although IMUL/SETcc does not support NDD, the EVEX.ND bit is + used to control whether its destination register has its upper + bits zeroed when OSIZE is 16b/8b. */ + if (ins->vex.nd) + { + oappend (ins, "zu"); + /* When we print zu for the EVEX instruction, we no longer + need prefix {evex}. */ + if (evex_printed == true && startswith (ins->obufp, "{evex}")) + ins->obufp += 6; + } + } + else + abort (); + break; case 'V': if (l == 0) { diff --git a/opcodes/i386-gen.c b/opcodes/i386-gen.c index 35e2f27df3b..fb4e78df3a2 100644 --- a/opcodes/i386-gen.c +++ b/opcodes/i386-gen.c @@ -491,6 +491,7 @@ static bitfield opcode_modifiers[] = BITFIELD (NoEgpr), BITFIELD (NF), BITFIELD (Rex2), + BITFIELD (ZU), }; #define CLASS(n) #n, n diff --git a/opcodes/i386-opc.h b/opcodes/i386-opc.h index fa482ca3d37..b63ad7c13f5 100644 --- a/opcodes/i386-opc.h +++ b/opcodes/i386-opc.h @@ -754,6 +754,9 @@ enum /* Instrucion requires REX2 prefix. */ Rex2, + /* Support zero upper */ + ZU, + /* The last bitfield in i386_opcode_modifier. */ Opcode_Modifier_Num }; @@ -801,6 +804,7 @@ typedef struct i386_opcode_modifier unsigned int noegpr:1; unsigned int nf:1; unsigned int rex2:1; + unsigned int zu:1; } i386_opcode_modifier; /* Operand classes. */ diff --git a/opcodes/i386-opc.tbl b/opcodes/i386-opc.tbl index 0bcda7ea8e1..faaa92c8d11 100644 --- a/opcodes/i386-opc.tbl +++ b/opcodes/i386-opc.tbl @@ -400,15 +400,19 @@ imul, 0xfaf, i386, Modrm|CheckOperandSize|No_bSuf|No_sSuf, { Reg16|Reg32|Reg64|U imul, 0xaf, APX_F, Modrm|CheckOperandSize|No_bSuf|No_sSuf|EVexMap4|NF, { Reg16|Reg32|Reg64|Unspecified|BaseIndex, Reg16|Reg32|Reg64 } imul, 0x6b, i186, Modrm|CheckOperandSize|No_bSuf|No_sSuf, { Imm8S, Reg16|Reg32|Reg64|Unspecified|BaseIndex, Reg16|Reg32|Reg64 } imul, 0x6b, APX_F, Modrm|CheckOperandSize|No_bSuf|No_sSuf|EVexMap4|NF, { Imm8S, Reg16|Reg32|Reg64|Unspecified|BaseIndex, Reg16|Reg32|Reg64 } +imulzu, 0x6b, APX_F, Modrm|No_bSuf|No_sSuf|EVexMap4|NF|ZU, { Imm8S, Reg16|Unspecified|BaseIndex, Reg16 } imul, 0x69, i186, Modrm|CheckOperandSize|No_bSuf|No_sSuf, { Imm16|Imm32|Imm32S, Reg16|Reg32|Reg64|Unspecified|BaseIndex, Reg16|Reg32|Reg64 } imul, 0x69, APX_F, Modrm|CheckOperandSize|No_bSuf|No_sSuf|EVexMap4|NF, { Imm16|Imm32|Imm32S, Reg16|Reg32|Reg64|Unspecified|BaseIndex, Reg16|Reg32|Reg64 } +imulzu, 0x69, APX_F, Modrm|No_bSuf|No_sSuf|EVexMap4|NF|ZU, { Imm16, Reg16|Unspecified|BaseIndex, Reg16 } // imul with 2 operands mimics imul with 3 by putting the register in // both i.rm.reg & i.rm.regmem fields. RegKludge enables this // transformation. imul, 0x6b, i186, Modrm|No_bSuf|No_sSuf|RegKludge, { Imm8S, Reg16|Reg32|Reg64 } imul, 0x6b, APX_F, Modrm|No_bSuf|No_sSuf|RegKludge|EVexMap4|NF, { Imm8S, Reg16|Reg32|Reg64 } +imulzu, 0x6b, APX_F, Modrm|No_bSuf|No_sSuf|RegKludge|EVexMap4|NF|ZU, { Imm8S, Reg16 } imul, 0x69, i186, Modrm|No_bSuf|No_sSuf|RegKludge, { Imm16|Imm32|Imm32S, Reg16|Reg32|Reg64 } imul, 0x69, APX_F, Modrm|No_bSuf|No_sSuf|RegKludge|EVexMap4|NF, { Imm16|Imm32|Imm32S, Reg16|Reg32|Reg64 } +imulzu, 0x69, APX_F, Modrm|No_bSuf|No_sSuf|RegKludge|EVexMap4|NF|ZU, { Imm16, Reg16 } <mul> @@ -529,6 +533,8 @@ loopne, 0xe0, x64, JumpByte|No_bSuf|No_wSuf|No_sSuf|NoRex64, { Disp8 } // Set byte on flag instructions. set<cc>, 0xf9<cc:opc>/0, i386, Modrm|No_wSuf|No_lSuf|No_sSuf|No_qSuf, { Reg8|Unspecified|BaseIndex } +set<cc>, 0xf24<cc:opc>/0, APX_F, Modrm|No_wSuf|No_lSuf|No_sSuf|No_qSuf|VexWIG|EVexMap4, { Reg8 } +setzu<cc>, 0xf24<cc:opc>/0, APX_F, Modrm|No_wSuf|No_lSuf|No_sSuf|No_qSuf|VexWIG|EVexMap4|ZU, { Reg8 } // String manipulation. cmps, 0xa6, 0, W|No_sSuf|RepPrefixOk, {} -- 2.34.1