[PATCH 3/3] Support APX zero-upper
Cui, Lili
lili.cui@intel.com
Mon May 20 06:22:02 GMT 2024
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 | 29 +++++
opcodes/i386-gen.c | 1 +
opcodes/i386-opc.h | 4 +
opcodes/i386-opc.tbl | 6 +
13 files changed, 458 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 5606049c054..c0625fc210e 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..d58549208ab
--- /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 instruction requiring REX/REX2/EVEX prefix
+.*: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..1cbd18398c2 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,18 @@ 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");
+ }
+ 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
More information about the Binutils
mailing list