aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorsaurabh.jha@arm.com <saurabh.jha@arm.com>2024-05-28 15:45:50 +0100
committerRichard Earnshaw <rearnsha@arm.com>2024-05-28 17:28:29 +0100
commitc3bb4211d972e681eadbdb8d800530323d98060f (patch)
tree264912c9a034da0d112001904aab13d2812bd986
parent2db17c87bd67099921ae78f90f839122041f284a (diff)
downloadbinutils-c3bb4211d972e681eadbdb8d800530323d98060f.zip
binutils-c3bb4211d972e681eadbdb8d800530323d98060f.tar.gz
binutils-c3bb4211d972e681eadbdb8d800530323d98060f.tar.bz2
gas, aarch64: Add AdvSIMD lut extension
Introduces instructions for the Advanced SIMD lut extension for AArch64. They are documented in the following links: * luti2: https://developer.arm.com/documentation/ddi0602/2024-03/SIMD-FP-Instructions/LUTI2--Lookup-table-read-with-2-bit-indices-?lang=en * luti4: https://developer.arm.com/documentation/ddi0602/2024-03/SIMD-FP-Instructions/LUTI4--Lookup-table-read-with-4-bit-indices-?lang=en These instructions needed definition of some new operands. We will first discuss operands for the third operand of the instructions and then discuss a vector register list operand needed for the second operand. The third operands are vectors with bit indices and without type qualifiers. They are called Em_INDEX1_14, Em_INDEX2_13, and Em_INDEX3_12 and they have 1 bit, 2 bit, and 3 bit indices respectively. For these new operands, we defined new parsing case branch. The lsb and width of these operands are the same as many existing but the convention is to give different names to fields that serve different purpose so we introduced new fields in aarch64-opc.c and aarch64-opc.h for these new operands. For the second operand of these instructions, we introduced a new operand called LVn_LUT. This represents a vector register list with stride 1. We defined new inserter and extractor for this new operand and it is encoded in FLD_Rn. We are enforcing the number of registers in the reglist using opcode flag rather than operand flag as this is what other SIMD vector register list operands are doing. The disassembly also uses opcode flag to print the correct number of registers.
-rw-r--r--gas/NEWS2
-rw-r--r--gas/config/tc-aarch64.c67
-rw-r--r--gas/doc/c-aarch64.texi2
-rw-r--r--gas/testsuite/gas/aarch64/advsimd-lut-bad.d3
-rw-r--r--gas/testsuite/gas/aarch64/advsimd-lut-bad.l25
-rw-r--r--gas/testsuite/gas/aarch64/advsimd-lut-illegal.d3
-rw-r--r--gas/testsuite/gas/aarch64/advsimd-lut-illegal.l208
-rw-r--r--gas/testsuite/gas/aarch64/advsimd-lut-illegal.s128
-rw-r--r--gas/testsuite/gas/aarch64/advsimd-lut.d32
-rw-r--r--gas/testsuite/gas/aarch64/advsimd-lut.s29
-rw-r--r--include/opcode/aarch64.h9
-rw-r--r--opcodes/aarch64-asm-2.c357
-rw-r--r--opcodes/aarch64-asm.c11
-rw-r--r--opcodes/aarch64-asm.h1
-rw-r--r--opcodes/aarch64-dis-2.c419
-rw-r--r--opcodes/aarch64-dis.c15
-rw-r--r--opcodes/aarch64-dis.h1
-rw-r--r--opcodes/aarch64-opc-2.c4
-rw-r--r--opcodes/aarch64-opc.c23
-rw-r--r--opcodes/aarch64-opc.h2
-rw-r--r--opcodes/aarch64-tbl.h38
21 files changed, 1016 insertions, 363 deletions
diff --git a/gas/NEWS b/gas/NEWS
index 804ef35..b6f40a3 100644
--- a/gas/NEWS
+++ b/gas/NEWS
@@ -30,6 +30,8 @@
* Add support for 'armv9.5-a' for -march in Arm GAS.
+* Add support for the AArch64 Lookup Table Extension (LUT).
+
Changes in 2.42:
* Add support for AMD znver5 processor.
diff --git a/gas/config/tc-aarch64.c b/gas/config/tc-aarch64.c
index 3f838cf..4154786 100644
--- a/gas/config/tc-aarch64.c
+++ b/gas/config/tc-aarch64.c
@@ -1513,6 +1513,54 @@ parse_vector_reg_list (char **ccp, aarch64_reg_type type,
return error ? PARSE_FAIL : (ret_val << 2) | (nb_regs - 1);
}
+/* Parse a SIMD vector register with a bit index. The SIMD vectors with
+ bit indices don't have type qualifiers.
+
+ Return null if the string pointed to by *CCP is not a valid AdvSIMD
+ vector register with a bit index.
+
+ Otherwise return the register and the bit index information
+ in *typeinfo.
+
+ The validity of the bit index itself is checked separately in encoding.
+ */
+
+static const reg_entry *
+parse_simd_vector_with_bit_index (char **ccp, struct vector_type_el *typeinfo)
+{
+ char *str = *ccp;
+ const reg_entry *reg = parse_reg (&str);
+ struct vector_type_el atype;
+
+ // Setting it here as this is the convention followed in the
+ // rest of the code with indices.
+ atype.defined = NTA_HASINDEX;
+ // This will be set to correct value in parse_index_expressions.
+ atype.index = 0;
+ // The rest of the fields are not applicable for this operand.
+ atype.type = NT_invtype;
+ atype.width = -1;
+ atype.element_size = 0;
+
+ if (reg == NULL)
+ return NULL;
+
+ if (reg->type != REG_TYPE_V)
+ return NULL;
+
+ // Parse the bit index.
+ if (!skip_past_char (&str, '['))
+ return NULL;
+ if (!parse_index_expression (&str, &atype.index))
+ return NULL;
+ if (!skip_past_char (&str, ']'))
+ return NULL;
+
+ *typeinfo = atype;
+ *ccp = str;
+ return reg;
+}
+
/* Directives: register aliases. */
static reg_entry *
@@ -6790,6 +6838,23 @@ parse_operands (char *str, const aarch64_opcode *opcode)
info->reglane.index = vectype.index;
break;
+ case AARCH64_OPND_Em_INDEX1_14:
+ case AARCH64_OPND_Em_INDEX2_13:
+ case AARCH64_OPND_Em_INDEX3_12:
+ // These are SIMD vector operands with bit indices. For example,
+ // 'V27[3]'. These operands don't have type qualifiers before
+ // indices.
+ reg = parse_simd_vector_with_bit_index(&str, &vectype);
+
+ if (!reg)
+ goto failure;
+ gas_assert (vectype.defined & NTA_HASINDEX);
+
+ info->qualifier = AARCH64_OPND_QLF_NIL;
+ info->reglane.regno = reg->number;
+ info->reglane.index = vectype.index;
+ break;
+
case AARCH64_OPND_SVE_ZnxN:
case AARCH64_OPND_SVE_ZtxN:
case AARCH64_OPND_SME_Zdnx2:
@@ -6812,6 +6877,7 @@ parse_operands (char *str, const aarch64_opcode *opcode)
goto vector_reg_list;
case AARCH64_OPND_LVn:
+ case AARCH64_OPND_LVn_LUT:
case AARCH64_OPND_LVt:
case AARCH64_OPND_LVt_AL:
case AARCH64_OPND_LEt:
@@ -10481,6 +10547,7 @@ static const struct aarch64_option_cpu_value_table aarch64_features[] = {
{"cpa", AARCH64_FEATURE (CPA), AARCH64_NO_FEATURES},
{"faminmax", AARCH64_FEATURE (FAMINMAX), AARCH64_FEATURE (SIMD)},
{"fp8", AARCH64_FEATURE (FP8), AARCH64_FEATURE (SIMD)},
+ {"lut", AARCH64_FEATURE (LUT), AARCH64_FEATURE (SIMD)},
{NULL, AARCH64_NO_FEATURES, AARCH64_NO_FEATURES},
};
diff --git a/gas/doc/c-aarch64.texi b/gas/doc/c-aarch64.texi
index 4da1807..bdfb504 100644
--- a/gas/doc/c-aarch64.texi
+++ b/gas/doc/c-aarch64.texi
@@ -293,6 +293,8 @@ automatically cause those extensions to be disabled.
@tab Enable the Checked Pointer Arithmetic extension.
@item @code{fp8} @tab
@tab Enable the Floating Point 8 (FP8) extension.
+@item @code{lut} @tab
+ @tab Enable the Lookup Table (LUT) extension.
@end multitable
@multitable @columnfractions .20 .80
diff --git a/gas/testsuite/gas/aarch64/advsimd-lut-bad.d b/gas/testsuite/gas/aarch64/advsimd-lut-bad.d
new file mode 100644
index 0000000..a3b5773
--- /dev/null
+++ b/gas/testsuite/gas/aarch64/advsimd-lut-bad.d
@@ -0,0 +1,3 @@
+#as:
+#source: advsimd-lut.s
+#error_output: advsimd-lut-bad.l \ No newline at end of file
diff --git a/gas/testsuite/gas/aarch64/advsimd-lut-bad.l b/gas/testsuite/gas/aarch64/advsimd-lut-bad.l
new file mode 100644
index 0000000..3afe4a3
--- /dev/null
+++ b/gas/testsuite/gas/aarch64/advsimd-lut-bad.l
@@ -0,0 +1,25 @@
+[^ :]+: Assembler messages:
+.*: Error: selected processor does not support `luti2 v0.16b,{v0.16b},v0\[0\]'
+.*: Error: selected processor does not support `luti2 v31.16b,{v0.16b},v0\[0\]'
+.*: Error: selected processor does not support `luti2 v0.16b,{v31.16b},v0\[0\]'
+.*: Error: selected processor does not support `luti2 v0.16b,{v0.16b},v31\[0\]'
+.*: Error: selected processor does not support `luti2 v0.16b,{v0.16b},v31\[3\]'
+.*: Error: selected processor does not support `luti2 v17.16b,{v21.16b},v27\[2\]'
+.*: Error: selected processor does not support `luti2 v0.8h,{v0.8h},v0\[0\]'
+.*: Error: selected processor does not support `luti2 v31.8h,{v0.8h},v0\[0\]'
+.*: Error: selected processor does not support `luti2 v0.8h,{v31.8h},v0\[0\]'
+.*: Error: selected processor does not support `luti2 v0.8h,{v0.8h},v31\[0\]'
+.*: Error: selected processor does not support `luti2 v0.8h,{v0.8h},v0\[7\]'
+.*: Error: selected processor does not support `luti2 v17.8h,{v21.8h},v27\[4\]'
+.*: Error: selected processor does not support `luti4 v0.16b,{v0.16b},v0\[0\]'
+.*: Error: selected processor does not support `luti4 v31.16b,{v0.16b},v0\[0\]'
+.*: Error: selected processor does not support `luti4 v0.16b,{v31.16b},v0\[0\]'
+.*: Error: selected processor does not support `luti4 v0.16b,{v0.16b},v31\[0\]'
+.*: Error: selected processor does not support `luti4 v0.16b,{v0.16b},v0\[1\]'
+.*: Error: selected processor does not support `luti4 v17.16b,{v21.16b},v27\[1\]'
+.*: Error: selected processor does not support `luti4 v0.8h,{v0.8h,v1.8h},v0\[0\]'
+.*: Error: selected processor does not support `luti4 v31.8h,{v0.8h,v1.8h},v0\[0\]'
+.*: Error: selected processor does not support `luti4 v0.8h,{v31.8h,v0.8h},v0\[0\]'
+.*: Error: selected processor does not support `luti4 v0.8h,{v0.8h,v1.8h},v31\[0\]'
+.*: Error: selected processor does not support `luti4 v0.8h,{v0.8h,v1.8h},v0\[3\]'
+.*: Error: selected processor does not support `luti4 v17.8h,{v21.8h,v22.8h},v27\[2\]'
diff --git a/gas/testsuite/gas/aarch64/advsimd-lut-illegal.d b/gas/testsuite/gas/aarch64/advsimd-lut-illegal.d
new file mode 100644
index 0000000..32ddfeb
--- /dev/null
+++ b/gas/testsuite/gas/aarch64/advsimd-lut-illegal.d
@@ -0,0 +1,3 @@
+#as: -march=armv8-a+lut
+#source: advsimd-lut-illegal.s
+#error_output: advsimd-lut-illegal.l \ No newline at end of file
diff --git a/gas/testsuite/gas/aarch64/advsimd-lut-illegal.l b/gas/testsuite/gas/aarch64/advsimd-lut-illegal.l
new file mode 100644
index 0000000..86f6a7d
--- /dev/null
+++ b/gas/testsuite/gas/aarch64/advsimd-lut-illegal.l
@@ -0,0 +1,208 @@
+[^ :]+: Assembler messages:
+[^ :]+:[0-9]+: Error: operand mismatch -- `luti2 v2.16b,\{v4.8h\},v8\[1\]'
+[^ :]+:[0-9]+: Info: did you mean this\?
+[^ :]+:[0-9]+: Info: luti2 v2.16b, \{v4.16b\}, v8\[1\]
+[^ :]+:[0-9]+: Error: operand mismatch -- `luti2 v2.8h,\{v4.16b\},v8\[1\]'
+[^ :]+:[0-9]+: Info: did you mean this\?
+[^ :]+:[0-9]+: Info: luti2 v2.16b, \{v4.16b\}, v8\[1\]
+[^ :]+:[0-9]+: Error: operand mismatch -- `luti4 v2.16b,\{v4.8h\},v8\[5\]'
+[^ :]+:[0-9]+: Info: did you mean this\?
+[^ :]+:[0-9]+: Info: luti4 v2.16b, \{v4.16b\}, v8\[5\]
+[^ :]+:[0-9]+: Error: operand mismatch -- `luti4 v2.8h,\{v4.16b\},v8\[5\]'
+[^ :]+:[0-9]+: Info: did you mean this\?
+[^ :]+:[0-9]+: Info: luti4 v2.16b, \{v4.16b\}, v8\[5\]
+[^ :]+:[0-9]+: Error: missing braces at operand 2 -- `luti2 v2.16b,v4.16b,v8\[1\]'
+[^ :]+:[0-9]+: Info: macro invoked from here
+[^ :]+:[0-9]+: Error: expected a vector register at operand 1 -- `luti2 x12,\{v4.16b\},v8\[1\]'
+[^ :]+:[0-9]+: Info: macro invoked from here
+[^ :]+:[0-9]+: Error: expected an Advanced SIMD vector register at operand 2 -- `luti2 v2.16b,\{x12\},v8\[1\]'
+[^ :]+:[0-9]+: Info: macro invoked from here
+[^ :]+:[0-9]+: Error: operand 3 must be a SIMD vector without a type qualifier encoding a bit index -- `luti2 v2.16b,\{v4.16b\},x12\[1\]'
+[^ :]+:[0-9]+: Info: macro invoked from here
+[^ :]+:[0-9]+: Error: missing braces at operand 2 -- `luti2 v2.8h,v4.8h,v8\[1\]'
+[^ :]+:[0-9]+: Info: macro invoked from here
+[^ :]+:[0-9]+: Error: expected a vector register at operand 1 -- `luti2 x12,\{v4.8h\},v8\[1\]'
+[^ :]+:[0-9]+: Info: macro invoked from here
+[^ :]+:[0-9]+: Error: expected an Advanced SIMD vector register at operand 2 -- `luti2 v2.8h,\{x12\},v8\[1\]'
+[^ :]+:[0-9]+: Info: macro invoked from here
+[^ :]+:[0-9]+: Error: operand 3 must be a SIMD vector without a type qualifier encoding a bit index -- `luti2 v2.8h,\{v4.8h\},x12\[1\]'
+[^ :]+:[0-9]+: Info: macro invoked from here
+[^ :]+:[0-9]+: Error: missing braces at operand 2 -- `luti4 v2.16b,v4.16b,v8\[1\]'
+[^ :]+:[0-9]+: Info: macro invoked from here
+[^ :]+:[0-9]+: Error: expected a vector register at operand 1 -- `luti4 x12,\{v4.16b\},v8\[1\]'
+[^ :]+:[0-9]+: Info: macro invoked from here
+[^ :]+:[0-9]+: Error: expected an Advanced SIMD vector register at operand 2 -- `luti4 v2.16b,\{x12\},v8\[1\]'
+[^ :]+:[0-9]+: Info: macro invoked from here
+[^ :]+:[0-9]+: Error: operand 3 must be a SIMD vector without a type qualifier encoding a bit index -- `luti4 v2.16b,\{v4.16b\},x12\[1\]'
+[^ :]+:[0-9]+: Info: macro invoked from here
+[^ :]+:[0-9]+: Error: missing braces at operand 2 -- `luti4 v2.8h,v4.8h,v8\[1\]'
+[^ :]+:[0-9]+: Info: macro invoked from here
+[^ :]+:[0-9]+: Error: expected a vector register at operand 1 -- `luti4 x12,\{v4.8h\},v8\[1\]'
+[^ :]+:[0-9]+: Info: macro invoked from here
+[^ :]+:[0-9]+: Error: expected an Advanced SIMD vector register at operand 2 -- `luti4 v2.8h,\{x12\},v8\[1\]'
+[^ :]+:[0-9]+: Info: macro invoked from here
+[^ :]+:[0-9]+: Error: operand 3 must be a SIMD vector without a type qualifier encoding a bit index -- `luti4 v2.8h,\{v4.8h\},x12\[1\]'
+[^ :]+:[0-9]+: Info: macro invoked from here
+[^ :]+:[0-9]+: Error: operand 2 must be a SIMD vector register list -- `luti4 v2.8h,\{v4.8h,x12\},v8\[1\]'
+[^ :]+:[0-9]+: Error: operand mismatch -- `luti2 v2.8b,\{v4.8b\},v8\[1\]'
+[^ :]+:[0-9]+: Info: did you mean this\?
+[^ :]+:[0-9]+: Info: luti2 v2.16b, \{v4.16b\}, v8\[1\]
+[^ :]+:[0-9]+: Error: operand mismatch -- `luti2 v2.4h,\{v4.4h\},v8\[1\]'
+[^ :]+:[0-9]+: Info: did you mean this\?
+[^ :]+:[0-9]+: Info: luti2 v2.16b, \{v4.16b\}, v8\[1\]
+[^ :]+:[0-9]+: Error: operand mismatch -- `luti4 v2.8b,\{v4.8b\},v8\[5\]'
+[^ :]+:[0-9]+: Info: did you mean this\?
+[^ :]+:[0-9]+: Info: luti4 v2.16b, \{v4.16b\}, v8\[5\]
+[^ :]+:[0-9]+: Error: operand mismatch -- `luti4 v2.4h,\{v4.4h,v5.4h\},v8\[5\]'
+[^ :]+:[0-9]+: Info: did you mean this\?
+[^ :]+:[0-9]+: Info: luti4 v2.16b, \{v4.16b-v5.16b\}, v8\[5\]
+[^ :]+:[0-9]+: Error: comma expected between operands at operand 2 -- `luti2 v2.16b'
+[^ :]+:[0-9]+: Info: macro invoked from here
+[^ :]+:[0-9]+: Error: expected element type rather than vector type at operand 2 -- `luti2 v2.16b,\{v4.16b\}'
+[^ :]+:[0-9]+: Info: macro invoked from here
+[^ :]+:[0-9]+: Error: unexpected characters following instruction at operand 3 -- `luti2 v2.16b,\{v4.16b\},v8\[1\],v16.16b'
+[^ :]+:[0-9]+: Info: macro invoked from here
+[^ :]+:[0-9]+: Error: unexpected characters following instruction at operand 3 -- `luti2 v2.16b,\{v4.16b\},v8\[1\],\{v16.16b\}'
+[^ :]+:[0-9]+: Info: macro invoked from here
+[^ :]+:[0-9]+: Error: comma expected between operands at operand 2 -- `luti2 v2.8h'
+[^ :]+:[0-9]+: Info: macro invoked from here
+[^ :]+:[0-9]+: Error: expected element type rather than vector type at operand 2 -- `luti2 v2.8h,\{v4.8h\}'
+[^ :]+:[0-9]+: Info: macro invoked from here
+[^ :]+:[0-9]+: Error: unexpected characters following instruction at operand 3 -- `luti2 v2.8h,\{v4.8h\},v8\[1\],v16.8h'
+[^ :]+:[0-9]+: Info: macro invoked from here
+[^ :]+:[0-9]+: Error: unexpected characters following instruction at operand 3 -- `luti2 v2.8h,\{v4.8h\},v8\[1\],\{v16.8h\}'
+[^ :]+:[0-9]+: Info: macro invoked from here
+[^ :]+:[0-9]+: Error: comma expected between operands at operand 2 -- `luti4 v2.16b'
+[^ :]+:[0-9]+: Info: macro invoked from here
+[^ :]+:[0-9]+: Error: expected element type rather than vector type at operand 2 -- `luti4 v2.16b,\{v4.16b\}'
+[^ :]+:[0-9]+: Info: macro invoked from here
+[^ :]+:[0-9]+: Error: unexpected characters following instruction at operand 3 -- `luti4 v2.16b,\{v4.16b\},v8\[1\],v16.16b'
+[^ :]+:[0-9]+: Info: macro invoked from here
+[^ :]+:[0-9]+: Error: unexpected characters following instruction at operand 3 -- `luti4 v2.16b,\{v4.16b\},v8\[1\],\{v16.16b\}'
+[^ :]+:[0-9]+: Info: macro invoked from here
+[^ :]+:[0-9]+: Error: comma expected between operands at operand 2 -- `luti4 v2.8h'
+[^ :]+:[0-9]+: Error: expected element type rather than vector type at operand 2 -- `luti4 v2.8h,\{v4.8h,v5.8h\}'
+[^ :]+:[0-9]+: Error: unexpected characters following instruction at operand 3 -- `luti4 v2.8h,\{v4.8h,v5.8h\},v8\[1\],v16.8h'
+[^ :]+:[0-9]+: Error: unexpected characters following instruction at operand 3 -- `luti4 v2.8h,\{v4.8h,v5.8h\},v8\[1\],\{v16.8h\}'
+[^ :]+:[0-9]+: Error: unexpected character `t' in element size at operand 2 -- `luti2 v2.16b,\{v4.16t\},v8\[1\]'
+[^ :]+:[0-9]+: Info: macro invoked from here
+[^ :]+:[0-9]+: Error: unexpected character `t' in element size at operand 1 -- `luti2 v2.16t,\{v4.16b\},v8\[1\]'
+[^ :]+:[0-9]+: Info: macro invoked from here
+[^ :]+:[0-9]+: Error: unexpected character `m' in element size at operand 2 -- `luti2 v2.8h,\{v4.8m\},v8\[1\]'
+[^ :]+:[0-9]+: Info: macro invoked from here
+[^ :]+:[0-9]+: Error: unexpected character `m' in element size at operand 1 -- `luti2 v2.8m,\{v4.8h\},v8\[1\]'
+[^ :]+:[0-9]+: Info: macro invoked from here
+[^ :]+:[0-9]+: Error: unexpected character `t' in element size at operand 2 -- `luti4 v2.16b,\{v4.16t\},v8\[1\]'
+[^ :]+:[0-9]+: Info: macro invoked from here
+[^ :]+:[0-9]+: Error: unexpected character `t' in element size at operand 1 -- `luti4 v2.16t,\{v4.16b\},v8\[1\]'
+[^ :]+:[0-9]+: Info: macro invoked from here
+[^ :]+:[0-9]+: Error: unexpected character `t' in element size at operand 2 -- `luti4 v2.8h,\{v4.8h,v5.8t\},v8\[1\]'
+[^ :]+:[0-9]+: Error: unexpected character `t' in element size at operand 1 -- `luti4 v2.8t,\{v4.8h,v5.8h\},v8\[1\]'
+[^ :]+:[0-9]+: Error: invalid use of vector register at operand 2 -- `luti2 v2.16b,\{v4\},v8\[1\]'
+[^ :]+:[0-9]+: Info: macro invoked from here
+[^ :]+:[0-9]+: Error: invalid use of vector register at operand 1 -- `luti2 v2,\{v4.16b\},v8\[1\]'
+[^ :]+:[0-9]+: Info: macro invoked from here
+[^ :]+:[0-9]+: Error: expected a register or register list at operand 1 -- `luti2 2.16b,\{v4.16b\},v8\[1\]'
+[^ :]+:[0-9]+: Info: macro invoked from here
+[^ :]+:[0-9]+: Error: syntax error in register list at operand 2 -- `luti2 v2.16b,\{4.16b\},v8\[1\]'
+[^ :]+:[0-9]+: Info: macro invoked from here
+[^ :]+:[0-9]+: Error: invalid use of vector register at operand 2 -- `luti2 v2.8h,\{v4\},v8\[1\]'
+[^ :]+:[0-9]+: Info: macro invoked from here
+[^ :]+:[0-9]+: Error: invalid use of vector register at operand 1 -- `luti2 v2,\{v4.8h\},v8\[1\]'
+[^ :]+:[0-9]+: Info: macro invoked from here
+[^ :]+:[0-9]+: Error: expected a register or register list at operand 1 -- `luti2 2.8h,\{v4.8h\},v8\[1\]'
+[^ :]+:[0-9]+: Info: macro invoked from here
+[^ :]+:[0-9]+: Error: syntax error in register list at operand 2 -- `luti2 v2.8h,\{4.8h\},v8\[1\]'
+[^ :]+:[0-9]+: Info: macro invoked from here
+[^ :]+:[0-9]+: Error: invalid use of vector register at operand 2 -- `luti4 v2.16b,\{v4\},v8\[1\]'
+[^ :]+:[0-9]+: Info: macro invoked from here
+[^ :]+:[0-9]+: Error: invalid use of vector register at operand 1 -- `luti4 v2,\{v4.16b\},v8\[1\]'
+[^ :]+:[0-9]+: Info: macro invoked from here
+[^ :]+:[0-9]+: Error: expected a register or register list at operand 1 -- `luti4 2.16b,\{v4.16b\},v8\[1\]'
+[^ :]+:[0-9]+: Info: macro invoked from here
+[^ :]+:[0-9]+: Error: syntax error in register list at operand 2 -- `luti4 v2.16b,\{4.16b\},v8\[1\]'
+[^ :]+:[0-9]+: Info: macro invoked from here
+[^ :]+:[0-9]+: Error: invalid use of vector register at operand 2 -- `luti4 v2.16b,\{v4,v5.16b\},v8\[1\]'
+[^ :]+:[0-9]+: Error: invalid use of vector register at operand 1 -- `luti4 v2,\{v4.16b,v5.16b\},v8\[1\]'
+[^ :]+:[0-9]+: Error: expected a register or register list at operand 1 -- `luti4 2.16b,\{v4.16b,v5.16b\},v8\[1\]'
+[^ :]+:[0-9]+: Error: syntax error in register list at operand 2 -- `luti4 v2.16b,\{v4.16b,5.16b\},v8\[1\]'
+[^ :]+:[0-9]+: Error: operand 3 must be a SIMD vector without a type qualifier encoding a bit index -- `luti2 v17.16b,\{v21.16b\},v27.16b\[3\]'
+[^ :]+:[0-9]+: Error: operand 3 must be a SIMD vector without a type qualifier encoding a bit index -- `luti2 v17.8h,\{v21.8h\},v27.8h\[4\]'
+[^ :]+:[0-9]+: Error: operand 3 must be a SIMD vector without a type qualifier encoding a bit index -- `luti4 v17.16b,\{v21.16b\},v27.16b\[1\]'
+[^ :]+:[0-9]+: Error: operand 3 must be a SIMD vector without a type qualifier encoding a bit index -- `luti4 v17.8h,\{v21.8h,v22.8h\},v27.8h\[2\]'
+[^ :]+:[0-9]+: Error: expected an SVE vector register at operand 1 -- `luti2 v17.16b\[1\],\{v0.16b\},v31.16b'
+[^ :]+:[0-9]+: Info: macro invoked from here
+[^ :]+:[0-9]+: Error: this type of register can't be indexed at operand 1 -- `luti2 v17\[1\],\{v0.16b\},v31.16b'
+[^ :]+:[0-9]+: Info: macro invoked from here
+[^ :]+:[0-9]+: Error: index not allowed inside register list at operand 2 -- `luti2 v17.16b,\{v0.16b\[1\]\},v31.16b'
+[^ :]+:[0-9]+: Info: macro invoked from here
+[^ :]+:[0-9]+: Error: this type of register can't be indexed at operand 2 -- `luti2 v17.16b,\{v0\[1\]\},v31.16b'
+[^ :]+:[0-9]+: Info: macro invoked from here
+[^ :]+:[0-9]+: Error: expected an SVE vector register at operand 1 -- `luti2 v17.8h\[1\],\{v0.8h\},v31.8h'
+[^ :]+:[0-9]+: Info: macro invoked from here
+[^ :]+:[0-9]+: Error: this type of register can't be indexed at operand 1 -- `luti2 v17\[1\],\{v0.8h\},v31.8h'
+[^ :]+:[0-9]+: Info: macro invoked from here
+[^ :]+:[0-9]+: Error: index not allowed inside register list at operand 2 -- `luti2 v17.8h,\{v0.8h\[1\]\},v31.8h'
+[^ :]+:[0-9]+: Info: macro invoked from here
+[^ :]+:[0-9]+: Error: this type of register can't be indexed at operand 2 -- `luti2 v17.8h,\{v0\[1\]\},v31.8h'
+[^ :]+:[0-9]+: Info: macro invoked from here
+[^ :]+:[0-9]+: Error: expected an SVE vector register at operand 1 -- `luti4 v17.16b\[1\],\{v0.16b\},v31.16b'
+[^ :]+:[0-9]+: Info: macro invoked from here
+[^ :]+:[0-9]+: Error: this type of register can't be indexed at operand 1 -- `luti4 v17\[1\],\{v0.16b\},v31.16b'
+[^ :]+:[0-9]+: Info: macro invoked from here
+[^ :]+:[0-9]+: Error: index not allowed inside register list at operand 2 -- `luti4 v17.16b,\{v0.16b\[1\]\},v31.16b'
+[^ :]+:[0-9]+: Info: macro invoked from here
+[^ :]+:[0-9]+: Error: this type of register can't be indexed at operand 2 -- `luti4 v17.16b,\{v0\[1\]\},v31.16b'
+[^ :]+:[0-9]+: Info: macro invoked from here
+[^ :]+:[0-9]+: Error: expected an SVE vector register at operand 1 -- `luti4 v17.8h\[1\],\{v0.8h,v1.8h\},v31.8h'
+[^ :]+:[0-9]+: Error: this type of register can't be indexed at operand 1 -- `luti4 v17\[1\],\{v0.8h,v1.8h\},v31.8h'
+[^ :]+:[0-9]+: Error: index not allowed inside register list at operand 2 -- `luti4 v17.8h,\{v0.8h\[1\],v1.8h\},v31.8h'
+[^ :]+:[0-9]+: Error: this type of register can't be indexed at operand 2 -- `luti4 v17.8h,\{v0\[1\],v1.8h\},v31.8h'
+[^ :]+:[0-9]+: Error: operand 3 must be a SIMD vector without a type qualifier encoding a bit index -- `luti2 v2.16b,\{v4.16b\},v8.16b'
+[^ :]+:[0-9]+: Error: operand 3 must be a SIMD vector without a type qualifier encoding a bit index -- `luti2 v2.16b,\{v4.16b\},v8'
+[^ :]+:[0-9]+: Error: operand 3 must be a SIMD vector without a type qualifier encoding a bit index -- `luti2 v2.8h,\{v4.8h\},v8.8h'
+[^ :]+:[0-9]+: Error: operand 3 must be a SIMD vector without a type qualifier encoding a bit index -- `luti2 v2.8h,\{v4.8h\},v8'
+[^ :]+:[0-9]+: Error: operand 3 must be a SIMD vector without a type qualifier encoding a bit index -- `luti4 v2.16b,\{v4.16b\},v8.16b'
+[^ :]+:[0-9]+: Error: operand 3 must be a SIMD vector without a type qualifier encoding a bit index -- `luti4 v2.16b,\{v4.16b\},v8'
+[^ :]+:[0-9]+: Error: operand 3 must be a SIMD vector without a type qualifier encoding a bit index -- `luti4 v2.8h,\{v4.8h,v5.8h\},v8.8h'
+[^ :]+:[0-9]+: Error: operand 3 must be a SIMD vector without a type qualifier encoding a bit index -- `luti4 v2.8h,\{v4.8h,v5.8h\},v8'
+[^ :]+:[0-9]+: Error: expected a register or register list at operand 1 -- `luti2 v32.16b,\{v4.16b\},v8\[1\]'
+[^ :]+:[0-9]+: Info: macro invoked from here
+[^ :]+:[0-9]+: Error: expected an Advanced SIMD vector register at operand 2 -- `luti2 v2.16b,\{v32.16b\},v8\[1\]'
+[^ :]+:[0-9]+: Info: macro invoked from here
+[^ :]+:[0-9]+: Error: operand 3 must be a SIMD vector without a type qualifier encoding a bit index -- `luti2 v2.16b,\{v4.16b\},v32\[1\]'
+[^ :]+:[0-9]+: Info: macro invoked from here
+[^ :]+:[0-9]+: Error: register element index out of range 0 to 3 at operand 3 -- `luti2 v2.16b,\{v4.16b\},v8\[4\]'
+[^ :]+:[0-9]+: Info: macro invoked from here
+[^ :]+:[0-9]+: Error: register element index out of range 0 to 3 at operand 3 -- `luti2 v2.16b,\{v4.16b\},v8\[-1\]'
+[^ :]+:[0-9]+: Info: macro invoked from here
+[^ :]+:[0-9]+: Error: expected a register or register list at operand 1 -- `luti2 v32.8h,\{v4.8h\},v8\[1\]'
+[^ :]+:[0-9]+: Info: macro invoked from here
+[^ :]+:[0-9]+: Error: expected an Advanced SIMD vector register at operand 2 -- `luti2 v2.8h,\{v32.8h\},v8\[1\]'
+[^ :]+:[0-9]+: Info: macro invoked from here
+[^ :]+:[0-9]+: Error: operand 3 must be a SIMD vector without a type qualifier encoding a bit index -- `luti2 v2.8h,\{v4.8h\},v32\[1\]'
+[^ :]+:[0-9]+: Info: macro invoked from here
+[^ :]+:[0-9]+: Error: register element index out of range 0 to 7 at operand 3 -- `luti2 v2.8h,\{v4.8h\},v8\[8\]'
+[^ :]+:[0-9]+: Info: macro invoked from here
+[^ :]+:[0-9]+: Error: register element index out of range 0 to 7 at operand 3 -- `luti2 v2.8h,\{v4.8h\},v8\[-1\]'
+[^ :]+:[0-9]+: Info: macro invoked from here
+[^ :]+:[0-9]+: Error: expected a register or register list at operand 1 -- `luti4 v32.16b,\{v4.16b\},v8\[1\]'
+[^ :]+:[0-9]+: Info: macro invoked from here
+[^ :]+:[0-9]+: Error: expected an Advanced SIMD vector register at operand 2 -- `luti4 v2.16b,\{v32.16b\},v8\[1\]'
+[^ :]+:[0-9]+: Info: macro invoked from here
+[^ :]+:[0-9]+: Error: operand 3 must be a SIMD vector without a type qualifier encoding a bit index -- `luti4 v2.16b,\{v4.16b\},v32\[1\]'
+[^ :]+:[0-9]+: Info: macro invoked from here
+[^ :]+:[0-9]+: Error: register element index out of range 0 to 1 at operand 3 -- `luti4 v2.16b,\{v4.16b\},v8\[2\]'
+[^ :]+:[0-9]+: Info: macro invoked from here
+[^ :]+:[0-9]+: Error: register element index out of range 0 to 1 at operand 3 -- `luti4 v2.16b,\{v4.16b\},v8\[-1\]'
+[^ :]+:[0-9]+: Info: macro invoked from here
+[^ :]+:[0-9]+: Error: expected a register or register list at operand 1 -- `luti4 v32.8h,\{v4.8h,v5.8h\},v8\[1\]'
+[^ :]+:[0-9]+: Error: operand 2 must be a SIMD vector register list -- `luti4 v2.8h,\{v31.8h,v32.8h\},v8\[1\]'
+[^ :]+:[0-9]+: Error: operand 3 must be a SIMD vector without a type qualifier encoding a bit index -- `luti4 v2.8h,\{v4.8h,v5.8h\},v32\[1\]'
+[^ :]+:[0-9]+: Error: register element index out of range 0 to 3 at operand 3 -- `luti4 v2.8h,\{v4.8h,v5.8h\},v8\[4\]'
+[^ :]+:[0-9]+: Error: register element index out of range 0 to 3 at operand 3 -- `luti4 v2.8h,\{v4.8h,v5.8h\},v8\[-1\]'
+[^ :]+:[0-9]+: Error: the register list must have a stride of 1 at operand 2 -- `luti4 v2.8h,\{v4.8h,v6.8h\},v8\[2\]'
+[^ :]+:[0-9]+: Error: expected a single-register list at operand 2 -- `luti2 v17.16b,\{v21.16b,v22.16b\},v27\[2\]'
+[^ :]+:[0-9]+: Error: expected a single-register list at operand 2 -- `luti2 v17.8h,\{v21.8h,v22.8h\},v27\[4\]'
+[^ :]+:[0-9]+: Error: expected a single-register list at operand 2 -- `luti4 v17.16b,\{v21.16b,v22.16b\},v27\[1\]'
+[^ :]+:[0-9]+: Error: expected a list of 2 registers at operand 2 -- `luti4 v17.8h,\{v21.8h\},v27\[2\]'
diff --git a/gas/testsuite/gas/aarch64/advsimd-lut-illegal.s b/gas/testsuite/gas/aarch64/advsimd-lut-illegal.s
new file mode 100644
index 0000000..24771fa
--- /dev/null
+++ b/gas/testsuite/gas/aarch64/advsimd-lut-illegal.s
@@ -0,0 +1,128 @@
+ // Operand mismatch
+ luti2 v2.16b, { v4.8h }, v8[1]
+ luti2 v2.8h, { v4.16b }, v8[1]
+ luti4 v2.16b, { v4.8h }, v8[5]
+ luti4 v2.8h, { v4.16b }, v8[5]
+
+ // Incorrect operand types
+ .macro incorrect_operand_types op, operand_type
+ \op v2\operand_type, v4\operand_type, v8[1]
+ \op x12, { v4\operand_type }, v8[1]
+ \op v2\operand_type, { x12 }, v8[1]
+ \op v2\operand_type, { v4\operand_type }, x12[1]
+ .endm
+
+ incorrect_operand_types luti2 .16b
+ incorrect_operand_types luti2 .8h
+ incorrect_operand_types luti4 .16b
+ incorrect_operand_types luti4 .8h
+ luti4 v2.8h, { v4.8h, x12 }, v8[1]
+
+ // Disallowed types
+ luti2 v2.8b, { v4.8b }, v8[1]
+ luti2 v2.4h, { v4.4h }, v8[1]
+ luti4 v2.8b, { v4.8b }, v8[5]
+ luti4 v2.4h, { v4.4h, v5.4h }, v8[5]
+
+ // Incorrect number of operands
+ .macro incorrect_operands, op, operand_type
+ \op v2\operand_type
+ \op v2\operand_type, { v4\operand_type }
+ \op v2\operand_type, { v4\operand_type }, v8[1], v16\operand_type
+ \op v2\operand_type, { v4\operand_type }, v8[1], { v16\operand_type }
+ .endm
+
+ incorrect_operands luti2 .16b
+ incorrect_operands luti2 .8h
+ incorrect_operands luti4 .16b
+ luti4 v2.8h
+ luti4 v2.8h, { v4.8h, v5.8h }
+ luti4 v2.8h, { v4.8h, v5.8h }, v8[1], v16.8h
+ luti4 v2.8h, { v4.8h, v5.8h }, v8[1], { v16.8h }
+
+ // Spelling mistakes
+ .macro spelling_mistakes, op, operand_type, incorrect_operand_type
+ \op v2\operand_type, { v4\incorrect_operand_type }, v8[1]
+ \op v2\incorrect_operand_type, { v4\operand_type }, v8[1]
+ .endm
+
+ spelling_mistakes luti2, .16b, .16t
+ spelling_mistakes luti2, .8h, .8m
+ spelling_mistakes luti4, .16b, .16t
+ luti4 v2.8h, { v4.8h, v5.8t }, v8[1]
+ luti4 v2.8t, { v4.8h, v5.8h }, v8[1]
+
+ // Missing qualifiers
+ .macro missing_qualifiers, op, operand_type
+ \op v2\operand_type, { v4 }, v8[1]
+ \op v2, { v4\operand_type }, v8[1]
+ \op 2\operand_type, { v4\operand_type }, v8[1]
+ \op v2\operand_type, { 4\operand_type }, v8[1]
+ .endm
+
+ missing_qualifiers luti2, .16b
+ missing_qualifiers luti2, .8h
+ missing_qualifiers luti4, .16b
+ luti4 v2.16b, { v4, v5.16b }, v8[1]
+ luti4 v2, { v4.16b, v5.16b }, v8[1]
+ luti4 2.16b, { v4.16b, v5.16b }, v8[1]
+ luti4 v2.16b, { v4.16b, 5.16b }, v8[1]
+
+ // Index with qualifiers
+ luti2 v17.16b, { v21.16b }, v27.16b[3]
+ luti2 v17.8h, { v21.8h }, v27.8h[4]
+ luti4 v17.16b, { v21.16b }, v27.16b[1]
+ luti4 v17.8h, { v21.8h, v22.8h }, v27.8h[2]
+
+ // Index on the wrong operand
+ .macro index_wrong_operand, op, operand_type
+ \op v17\operand_type[1], { v0\operand_type }, v31\operand_type
+ \op v17[1], { v0\operand_type }, v31\operand_type
+ \op v17\operand_type, { v0\operand_type[1] }, v31\operand_type
+ \op v17\operand_type, { v0[1] }, v31\operand_type
+ .endm
+
+ index_wrong_operand luti2, .16b
+ index_wrong_operand luti2, .8h
+ index_wrong_operand luti4, .16b
+ luti4 v17.8h[1], { v0.8h, v1.8h }, v31.8h
+ luti4 v17[1], { v0.8h, v1.8h }, v31.8h
+ luti4 v17.8h, { v0.8h[1], v1.8h }, v31.8h
+ luti4 v17.8h, { v0[1], v1.8h }, v31.8h
+
+ // Missing index
+ luti2 v2.16b, { v4.16b }, v8.16b
+ luti2 v2.16b, { v4.16b }, v8
+ luti2 v2.8h, { v4.8h }, v8.8h
+ luti2 v2.8h, { v4.8h }, v8
+ luti4 v2.16b, { v4.16b }, v8.16b
+ luti4 v2.16b, { v4.16b }, v8
+ luti4 v2.8h, { v4.8h, v5.8h }, v8.8h
+ luti4 v2.8h, { v4.8h, v5.8h }, v8
+
+ // Out of range operands
+ .macro out_of_range, op, operand_type, max_index_plus_one
+ \op v32\operand_type, { v4\operand_type }, v8[1]
+ \op v2\operand_type, { v32\operand_type }, v8[1]
+ \op v2\operand_type, { v4\operand_type }, v32[1]
+ \op v2\operand_type, { v4\operand_type }, v8[\max_index_plus_one]
+ \op v2\operand_type, { v4\operand_type }, v8[-1]
+ .endm
+
+ out_of_range luti2, .16b, 4
+ out_of_range luti2, .8h, 8
+ out_of_range luti4, .16b, 2
+ luti4 v32.8h, { v4.8h, v5.8h }, v8[1]
+ luti4 v2.8h, { v31.8h, v32.8h }, v8[1]
+ luti4 v2.8h, { v4.8h, v5.8h }, v32[1]
+ luti4 v2.8h, { v4.8h, v5.8h }, v8[4]
+ luti4 v2.8h, { v4.8h, v5.8h }, v8[-1]
+
+ // Incorrect stride of operand
+ luti4 v2.8h, { v4.8h, v6.8h }, v8[2]
+
+ // Incorrect operands
+ luti2 v17.16b, { v21.16b, v22.16b }, v27[2]
+ luti2 v17.8h, { v21.8h, v22.8h }, v27[4]
+ luti4 v17.16b, { v21.16b, v22.16b }, v27[1]
+ luti4 v17.8h, { v21.8h }, v27[2]
diff --git a/gas/testsuite/gas/aarch64/advsimd-lut.d b/gas/testsuite/gas/aarch64/advsimd-lut.d
new file mode 100644
index 0000000..0240d0d
--- /dev/null
+++ b/gas/testsuite/gas/aarch64/advsimd-lut.d
@@ -0,0 +1,32 @@
+#objdump: -dr
+#as: -march=armv8-a+lut
+
+.*: file format .*
+
+Disassembly of section \.text:
+
+0+ <.*>:
+[^:]+: 4e801000 luti2 v0.16b, \{v0.16b\}, v0\[0\]
+[^:]+: 4e80101f luti2 v31.16b, \{v0.16b\}, v0\[0\]
+[^:]+: 4e8013e0 luti2 v0.16b, \{v31.16b\}, v0\[0\]
+[^:]+: 4e9f1000 luti2 v0.16b, \{v0.16b\}, v31\[0\]
+[^:]+: 4e9f7000 luti2 v0.16b, \{v0.16b\}, v31\[3\]
+[^:]+: 4e9b52b1 luti2 v17.16b, \{v21.16b\}, v27\[2\]
+[^:]+: 4ec00000 luti2 v0.8h, \{v0.8h\}, v0\[0\]
+[^:]+: 4ec0001f luti2 v31.8h, \{v0.8h\}, v0\[0\]
+[^:]+: 4ec003e0 luti2 v0.8h, \{v31.8h\}, v0\[0\]
+[^:]+: 4edf0000 luti2 v0.8h, \{v0.8h\}, v31\[0\]
+[^:]+: 4ec07000 luti2 v0.8h, \{v0.8h\}, v0\[7\]
+[^:]+: 4edb42b1 luti2 v17.8h, \{v21.8h\}, v27\[4\]
+[^:]+: 4e402000 luti4 v0.16b, \{v0.16b\}, v0\[0\]
+[^:]+: 4e40201f luti4 v31.16b, \{v0.16b\}, v0\[0\]
+[^:]+: 4e4023e0 luti4 v0.16b, \{v31.16b\}, v0\[0\]
+[^:]+: 4e5f2000 luti4 v0.16b, \{v0.16b\}, v31\[0\]
+[^:]+: 4e406000 luti4 v0.16b, \{v0.16b\}, v0\[1\]
+[^:]+: 4e5b62b1 luti4 v17.16b, \{v21.16b\}, v27\[1\]
+[^:]+: 4e401000 luti4 v0.8h, \{v0.8h-v1.8h\}, v0\[0\]
+[^:]+: 4e40101f luti4 v31.8h, \{v0.8h-v1.8h\}, v0\[0\]
+[^:]+: 4e4013e0 luti4 v0.8h, \{v31.8h-v0.8h\}, v0\[0\]
+[^:]+: 4e5f1000 luti4 v0.8h, \{v0.8h-v1.8h\}, v31\[0\]
+[^:]+: 4e407000 luti4 v0.8h, \{v0.8h-v1.8h\}, v0\[3\]
+[^:]+: 4e5b52b1 luti4 v17.8h, \{v21.8h-v22.8h\}, v27\[2\]
diff --git a/gas/testsuite/gas/aarch64/advsimd-lut.s b/gas/testsuite/gas/aarch64/advsimd-lut.s
new file mode 100644
index 0000000..03bc27a
--- /dev/null
+++ b/gas/testsuite/gas/aarch64/advsimd-lut.s
@@ -0,0 +1,29 @@
+ // Valid luti2 instructions
+ luti2 v0.16b, { v0.16b }, v0[0]
+ luti2 v31.16b, { v0.16b }, v0[0]
+ luti2 v0.16b, { v31.16b }, v0[0]
+ luti2 v0.16b, { v0.16b }, v31[0]
+ luti2 v0.16b, { v0.16b }, v31[3]
+ luti2 v17.16b, { v21.16b }, v27[2]
+
+ luti2 v0.8h, { v0.8h }, v0[0]
+ luti2 v31.8h, { v0.8h }, v0[0]
+ luti2 v0.8h, { v31.8h }, v0[0]
+ luti2 v0.8h, { v0.8h }, v31[0]
+ luti2 v0.8h, { v0.8h }, v0[7]
+ luti2 v17.8h, { v21.8h }, v27[4]
+
+ // Valid luti4 instructions
+ luti4 v0.16b, { v0.16b }, v0[0]
+ luti4 v31.16b, { v0.16b }, v0[0]
+ luti4 v0.16b, { v31.16b }, v0[0]
+ luti4 v0.16b, { v0.16b }, v31[0]
+ luti4 v0.16b, { v0.16b }, v0[1]
+ luti4 v17.16b, { v21.16b }, v27[1]
+
+ luti4 v0.8h, { v0.8h, v1.8h }, v0[0]
+ luti4 v31.8h, { v0.8h, v1.8h }, v0[0]
+ luti4 v0.8h, { v31.8h, v0.8h }, v0[0]
+ luti4 v0.8h, { v0.8h, v1.8h }, v31[0]
+ luti4 v0.8h, { v0.8h, v1.8h }, v0[3]
+ luti4 v17.8h, { v21.8h, v22.8h }, v27[2]
diff --git a/include/opcode/aarch64.h b/include/opcode/aarch64.h
index ef4a3ff..95448b5 100644
--- a/include/opcode/aarch64.h
+++ b/include/opcode/aarch64.h
@@ -236,6 +236,8 @@ enum aarch64_feature_bit {
AARCH64_FEATURE_FAMINMAX,
/* FP8 instructions. */
AARCH64_FEATURE_FP8,
+ /* LUT instructions. */
+ AARCH64_FEATURE_LUT,
AARCH64_NUM_FEATURES
};
@@ -523,10 +525,14 @@ enum aarch64_opnd
AARCH64_OPND_Em, /* AdvSIMD Vector Element Vm. */
AARCH64_OPND_Em16, /* AdvSIMD Vector Element Vm restricted to V0 - V15 when
qualifier is S_H. */
+ AARCH64_OPND_Em_INDEX1_14, /* AdvSIMD 1-bit encoded index in Vm at [14] */
+ AARCH64_OPND_Em_INDEX2_13, /* AdvSIMD 2-bit encoded index in Vm at [14:13] */
+ AARCH64_OPND_Em_INDEX3_12, /* AdvSIMD 3-bit encoded index in Vm at [14:12] */
AARCH64_OPND_LVn, /* AdvSIMD Vector register list used in e.g. TBL. */
AARCH64_OPND_LVt, /* AdvSIMD Vector register list used in ld/st. */
AARCH64_OPND_LVt_AL, /* AdvSIMD Vector register list for loading single
structure to all lanes. */
+ AARCH64_OPND_LVn_LUT, /* AdvSIMD Vector register list used in lut. */
AARCH64_OPND_LEt, /* AdvSIMD Vector Element list. */
AARCH64_OPND_CRn, /* Co-processor register in CRn field. */
@@ -1026,7 +1032,8 @@ enum aarch64_insn_class
the,
sve2_urqvs,
sve_index1,
- rcpc3
+ rcpc3,
+ lut
};
/* Opcode enumerators. */
diff --git a/opcodes/aarch64-asm-2.c b/opcodes/aarch64-asm-2.c
index 53eb8c6..77dcc9a 100644
--- a/opcodes/aarch64-asm-2.c
+++ b/opcodes/aarch64-asm-2.c
@@ -650,12 +650,8 @@ aarch64_insert_operand (const aarch64_operand *self,
case 32:
case 33:
case 34:
- case 117:
- case 118:
- case 176:
- case 177:
- case 178:
- case 179:
+ case 121:
+ case 122:
case 180:
case 181:
case 182:
@@ -666,30 +662,34 @@ aarch64_insert_operand (const aarch64_operand *self,
case 187:
case 188:
case 189:
- case 204:
- case 205:
- case 206:
- case 207:
- case 216:
- case 217:
- case 218:
- case 219:
+ case 190:
+ case 191:
+ case 192:
+ case 193:
+ case 208:
+ case 209:
+ case 210:
+ case 211:
case 220:
- case 228:
+ case 221:
+ case 222:
+ case 223:
+ case 224:
case 232:
case 236:
- case 243:
- case 244:
- case 251:
- case 252:
- case 253:
- case 254:
+ case 240:
+ case 247:
+ case 248:
+ case 255:
+ case 256:
+ case 257:
+ case 258:
return aarch64_ins_regno (self, info, code, inst, errors);
case 6:
- case 114:
- case 115:
- case 286:
- case 288:
+ case 118:
+ case 119:
+ case 290:
+ case 292:
return aarch64_ins_none (self, info, code, inst, errors);
case 17:
return aarch64_ins_reg_extended (self, info, code, inst, errors);
@@ -703,24 +703,41 @@ aarch64_insert_operand (const aarch64_operand *self,
case 36:
case 37:
case 38:
- case 290:
+ case 294:
return aarch64_ins_reglane (self, info, code, inst, errors);
case 39:
- return aarch64_ins_reglist (self, info, code, inst, errors);
case 40:
- return aarch64_ins_ldst_reglist (self, info, code, inst, errors);
case 41:
- return aarch64_ins_ldst_reglist_r (self, info, code, inst, errors);
+ case 259:
+ case 260:
+ case 275:
+ case 276:
+ case 277:
+ case 278:
+ case 279:
+ case 280:
+ case 281:
+ case 282:
+ case 283:
+ case 284:
+ case 285:
+ case 286:
+ case 287:
+ return aarch64_ins_simple_index (self, info, code, inst, errors);
case 42:
- return aarch64_ins_ldst_elemlist (self, info, code, inst, errors);
+ return aarch64_ins_reglist (self, info, code, inst, errors);
case 43:
+ return aarch64_ins_ldst_reglist (self, info, code, inst, errors);
case 44:
+ return aarch64_ins_ldst_reglist_r (self, info, code, inst, errors);
case 45:
+ return aarch64_ins_lut_reglist (self, info, code, inst, errors);
case 46:
- case 56:
- case 57:
- case 58:
- case 59:
+ return aarch64_ins_ldst_elemlist (self, info, code, inst, errors);
+ case 47:
+ case 48:
+ case 49:
+ case 50:
case 60:
case 61:
case 62:
@@ -734,120 +751,120 @@ aarch64_insert_operand (const aarch64_operand *self,
case 70:
case 71:
case 72:
- case 84:
- case 85:
- case 86:
- case 87:
- case 113:
- case 173:
- case 175:
- case 196:
- case 197:
- case 198:
- case 199:
+ case 73:
+ case 74:
+ case 75:
+ case 76:
+ case 88:
+ case 89:
+ case 90:
+ case 91:
+ case 117:
+ case 177:
+ case 179:
case 200:
case 201:
case 202:
case 203:
- case 257:
- case 284:
- case 285:
- case 287:
+ case 204:
+ case 205:
+ case 206:
+ case 207:
+ case 261:
+ case 288:
case 289:
- case 294:
- case 295:
+ case 291:
+ case 293:
+ case 298:
+ case 299:
return aarch64_ins_imm (self, info, code, inst, errors);
- case 47:
- case 48:
- return aarch64_ins_advsimd_imm_shift (self, info, code, inst, errors);
- case 49:
- case 50:
case 51:
- return aarch64_ins_advsimd_imm_modified (self, info, code, inst, errors);
+ case 52:
+ return aarch64_ins_advsimd_imm_shift (self, info, code, inst, errors);
+ case 53:
+ case 54:
case 55:
- case 163:
+ return aarch64_ins_advsimd_imm_modified (self, info, code, inst, errors);
+ case 59:
+ case 167:
return aarch64_ins_fpimm (self, info, code, inst, errors);
- case 73:
- case 171:
+ case 77:
+ case 175:
return aarch64_ins_limm (self, info, code, inst, errors);
- case 74:
+ case 78:
return aarch64_ins_aimm (self, info, code, inst, errors);
- case 75:
+ case 79:
return aarch64_ins_imm_half (self, info, code, inst, errors);
- case 76:
+ case 80:
return aarch64_ins_fbits (self, info, code, inst, errors);
- case 78:
- case 79:
- case 168:
+ case 82:
+ case 83:
+ case 172:
return aarch64_ins_imm_rotate2 (self, info, code, inst, errors);
- case 80:
- case 167:
- case 169:
+ case 84:
+ case 171:
+ case 173:
return aarch64_ins_imm_rotate1 (self, info, code, inst, errors);
- case 81:
- case 82:
+ case 85:
+ case 86:
return aarch64_ins_cond (self, info, code, inst, errors);
- case 88:
- case 97:
+ case 92:
+ case 101:
return aarch64_ins_addr_simple (self, info, code, inst, errors);
- case 89:
+ case 93:
return aarch64_ins_addr_regoff (self, info, code, inst, errors);
- case 90:
- case 91:
- case 92:
case 94:
+ case 95:
case 96:
+ case 98:
+ case 100:
return aarch64_ins_addr_simm (self, info, code, inst, errors);
- case 93:
+ case 97:
return aarch64_ins_addr_simm10 (self, info, code, inst, errors);
- case 95:
- return aarch64_ins_addr_uimm12 (self, info, code, inst, errors);
- case 98:
- return aarch64_ins_addr_offset (self, info, code, inst, errors);
case 99:
- return aarch64_ins_simd_addr_post (self, info, code, inst, errors);
- case 100:
- case 101:
- return aarch64_ins_sysreg (self, info, code, inst, errors);
+ return aarch64_ins_addr_uimm12 (self, info, code, inst, errors);
case 102:
- return aarch64_ins_pstatefield (self, info, code, inst, errors);
+ return aarch64_ins_addr_offset (self, info, code, inst, errors);
case 103:
+ return aarch64_ins_simd_addr_post (self, info, code, inst, errors);
case 104:
case 105:
+ return aarch64_ins_sysreg (self, info, code, inst, errors);
case 106:
+ return aarch64_ins_pstatefield (self, info, code, inst, errors);
case 107:
case 108:
- return aarch64_ins_sysins_op (self, info, code, inst, errors);
case 109:
+ case 110:
case 111:
+ case 112:
+ return aarch64_ins_sysins_op (self, info, code, inst, errors);
+ case 113:
+ case 115:
return aarch64_ins_barrier (self, info, code, inst, errors);
- case 110:
+ case 114:
return aarch64_ins_barrier_dsb_nxs (self, info, code, inst, errors);
- case 112:
- return aarch64_ins_prfop (self, info, code, inst, errors);
case 116:
- return aarch64_ins_hint (self, info, code, inst, errors);
- case 119:
+ return aarch64_ins_prfop (self, info, code, inst, errors);
case 120:
- return aarch64_ins_sve_addr_ri_s4 (self, info, code, inst, errors);
- case 121:
- case 122:
+ return aarch64_ins_hint (self, info, code, inst, errors);
case 123:
case 124:
- return aarch64_ins_sve_addr_ri_s4xvl (self, info, code, inst, errors);
+ return aarch64_ins_sve_addr_ri_s4 (self, info, code, inst, errors);
case 125:
- return aarch64_ins_sve_addr_ri_s6xvl (self, info, code, inst, errors);
case 126:
- return aarch64_ins_sve_addr_ri_s9xvl (self, info, code, inst, errors);
case 127:
case 128:
+ return aarch64_ins_sve_addr_ri_s4xvl (self, info, code, inst, errors);
case 129:
+ return aarch64_ins_sve_addr_ri_s6xvl (self, info, code, inst, errors);
case 130:
- return aarch64_ins_sve_addr_ri_u6 (self, info, code, inst, errors);
+ return aarch64_ins_sve_addr_ri_s9xvl (self, info, code, inst, errors);
case 131:
case 132:
case 133:
case 134:
+ return aarch64_ins_sve_addr_ri_u6 (self, info, code, inst, errors);
case 135:
case 136:
case 137:
@@ -859,141 +876,129 @@ aarch64_insert_operand (const aarch64_operand *self,
case 143:
case 144:
case 145:
- return aarch64_ins_sve_addr_rr_lsl (self, info, code, inst, errors);
case 146:
case 147:
case 148:
case 149:
+ return aarch64_ins_sve_addr_rr_lsl (self, info, code, inst, errors);
case 150:
case 151:
case 152:
case 153:
- return aarch64_ins_sve_addr_rz_xtw (self, info, code, inst, errors);
case 154:
case 155:
case 156:
case 157:
- return aarch64_ins_sve_addr_zi_u5 (self, info, code, inst, errors);
+ return aarch64_ins_sve_addr_rz_xtw (self, info, code, inst, errors);
case 158:
- return aarch64_ins_sve_addr_zz_lsl (self, info, code, inst, errors);
case 159:
- return aarch64_ins_sve_addr_zz_sxtw (self, info, code, inst, errors);
case 160:
- return aarch64_ins_sve_addr_zz_uxtw (self, info, code, inst, errors);
case 161:
- return aarch64_ins_sve_aimm (self, info, code, inst, errors);
+ return aarch64_ins_sve_addr_zi_u5 (self, info, code, inst, errors);
case 162:
- return aarch64_ins_sve_asimm (self, info, code, inst, errors);
+ return aarch64_ins_sve_addr_zz_lsl (self, info, code, inst, errors);
+ case 163:
+ return aarch64_ins_sve_addr_zz_sxtw (self, info, code, inst, errors);
case 164:
- return aarch64_ins_sve_float_half_one (self, info, code, inst, errors);
+ return aarch64_ins_sve_addr_zz_uxtw (self, info, code, inst, errors);
case 165:
- return aarch64_ins_sve_float_half_two (self, info, code, inst, errors);
+ return aarch64_ins_sve_aimm (self, info, code, inst, errors);
case 166:
- return aarch64_ins_sve_float_zero_one (self, info, code, inst, errors);
+ return aarch64_ins_sve_asimm (self, info, code, inst, errors);
+ case 168:
+ return aarch64_ins_sve_float_half_one (self, info, code, inst, errors);
+ case 169:
+ return aarch64_ins_sve_float_half_two (self, info, code, inst, errors);
case 170:
+ return aarch64_ins_sve_float_zero_one (self, info, code, inst, errors);
+ case 174:
return aarch64_ins_inv_limm (self, info, code, inst, errors);
- case 172:
+ case 176:
return aarch64_ins_sve_limm_mov (self, info, code, inst, errors);
- case 174:
+ case 178:
return aarch64_ins_sve_scale (self, info, code, inst, errors);
- case 190:
- case 191:
- case 192:
- return aarch64_ins_sve_shlimm (self, info, code, inst, errors);
- case 193:
case 194:
case 195:
- case 270:
+ case 196:
+ return aarch64_ins_sve_shlimm (self, info, code, inst, errors);
+ case 197:
+ case 198:
+ case 199:
+ case 274:
return aarch64_ins_sve_shrimm (self, info, code, inst, errors);
- case 208:
- case 209:
- case 210:
- case 211:
- return aarch64_ins_sme_za_vrs1 (self, info, code, inst, errors);
case 212:
case 213:
case 214:
case 215:
+ return aarch64_ins_sme_za_vrs1 (self, info, code, inst, errors);
+ case 216:
+ case 217:
+ case 218:
+ case 219:
return aarch64_ins_sme_za_vrs2 (self, info, code, inst, errors);
- case 221:
- case 222:
- case 223:
- case 224:
case 225:
case 226:
case 227:
- return aarch64_ins_sve_quad_index (self, info, code, inst, errors);
+ case 228:
case 229:
- return aarch64_ins_sve_index_imm (self, info, code, inst, errors);
case 230:
- return aarch64_ins_sve_index (self, info, code, inst, errors);
case 231:
+ return aarch64_ins_sve_quad_index (self, info, code, inst, errors);
case 233:
- case 250:
- case 296:
- case 297:
- case 298:
- return aarch64_ins_sve_reglist (self, info, code, inst, errors);
+ return aarch64_ins_sve_index_imm (self, info, code, inst, errors);
case 234:
+ return aarch64_ins_sve_index (self, info, code, inst, errors);
case 235:
case 237:
+ case 254:
+ case 300:
+ case 301:
+ case 302:
+ return aarch64_ins_sve_reglist (self, info, code, inst, errors);
case 238:
case 239:
- case 240:
- case 249:
- return aarch64_ins_sve_aligned_reglist (self, info, code, inst, errors);
case 241:
case 242:
- return aarch64_ins_sve_strided_reglist (self, info, code, inst, errors);
+ case 243:
+ case 244:
+ case 253:
+ return aarch64_ins_sve_aligned_reglist (self, info, code, inst, errors);
case 245:
- case 247:
- case 258:
- return aarch64_ins_sme_za_hv_tiles (self, info, code, inst, errors);
case 246:
- case 248:
- return aarch64_ins_sme_za_hv_tiles_range (self, info, code, inst, errors);
- case 255:
- case 256:
- case 271:
- case 272:
- case 273:
- case 274:
- case 275:
- case 276:
- case 277:
- case 278:
- case 279:
- case 280:
- case 281:
- case 282:
- case 283:
- return aarch64_ins_simple_index (self, info, code, inst, errors);
- case 259:
- case 260:
- case 261:
+ return aarch64_ins_sve_strided_reglist (self, info, code, inst, errors);
+ case 249:
+ case 251:
case 262:
+ return aarch64_ins_sme_za_hv_tiles (self, info, code, inst, errors);
+ case 250:
+ case 252:
+ return aarch64_ins_sme_za_hv_tiles_range (self, info, code, inst, errors);
case 263:
case 264:
case 265:
- return aarch64_ins_sme_za_array (self, info, code, inst, errors);
case 266:
- return aarch64_ins_sme_addr_ri_u4xvl (self, info, code, inst, errors);
case 267:
- return aarch64_ins_sme_sm_za (self, info, code, inst, errors);
case 268:
- return aarch64_ins_sme_pred_reg_with_index (self, info, code, inst, errors);
case 269:
+ return aarch64_ins_sme_za_array (self, info, code, inst, errors);
+ case 270:
+ return aarch64_ins_sme_addr_ri_u4xvl (self, info, code, inst, errors);
+ case 271:
+ return aarch64_ins_sme_sm_za (self, info, code, inst, errors);
+ case 272:
+ return aarch64_ins_sme_pred_reg_with_index (self, info, code, inst, errors);
+ case 273:
return aarch64_ins_plain_shrimm (self, info, code, inst, errors);
- case 291:
- case 292:
- case 293:
+ case 295:
+ case 296:
+ case 297:
return aarch64_ins_x0_to_x30 (self, info, code, inst, errors);
- case 299:
- case 300:
- case 301:
- case 302:
- return aarch64_ins_rcpc3_addr_opt_offset (self, info, code, inst, errors);
case 303:
+ case 304:
+ case 305:
+ case 306:
+ return aarch64_ins_rcpc3_addr_opt_offset (self, info, code, inst, errors);
+ case 307:
return aarch64_ins_rcpc3_addr_offset (self, info, code, inst, errors);
default: assert (0); abort ();
}
diff --git a/opcodes/aarch64-asm.c b/opcodes/aarch64-asm.c
index 5a55ca2..5c6a311 100644
--- a/opcodes/aarch64-asm.c
+++ b/opcodes/aarch64-asm.c
@@ -286,6 +286,17 @@ aarch64_ins_ldst_reglist_r (const aarch64_operand *self ATTRIBUTE_UNUSED,
return true;
}
+/* Insert regnos of register list operand for AdvSIMD lut instructions. */
+bool
+aarch64_ins_lut_reglist (const aarch64_operand *self, const aarch64_opnd_info *info,
+ aarch64_insn *code,
+ const aarch64_inst *inst ATTRIBUTE_UNUSED,
+ aarch64_operand_error *errors ATTRIBUTE_UNUSED)
+{
+ insert_field (self->fields[0], code, info->reglist.first_regno, 0);
+ return true;
+}
+
/* Insert Q, opcode<2:1>, S, size and Rt fields for a register element list
operand e.g. Vt in AdvSIMD load/store single element instructions. */
bool
diff --git a/opcodes/aarch64-asm.h b/opcodes/aarch64-asm.h
index 88e389b..edeb6d8 100644
--- a/opcodes/aarch64-asm.h
+++ b/opcodes/aarch64-asm.h
@@ -47,6 +47,7 @@ AARCH64_DECL_OPD_INSERTER (ins_reglane);
AARCH64_DECL_OPD_INSERTER (ins_reglist);
AARCH64_DECL_OPD_INSERTER (ins_ldst_reglist);
AARCH64_DECL_OPD_INSERTER (ins_ldst_reglist_r);
+AARCH64_DECL_OPD_INSERTER (ins_lut_reglist);
AARCH64_DECL_OPD_INSERTER (ins_ldst_elemlist);
AARCH64_DECL_OPD_INSERTER (ins_advsimd_imm_shift);
AARCH64_DECL_OPD_INSERTER (ins_imm);
diff --git a/opcodes/aarch64-dis-2.c b/opcodes/aarch64-dis-2.c
index 36fd047..ef51a9b 100644
--- a/opcodes/aarch64-dis-2.c
+++ b/opcodes/aarch64-dis-2.c
@@ -25755,21 +25755,65 @@ aarch64_opcode_lookup_1 (uint32_t word)
{
if (((word >> 11) & 0x1) == 0)
{
- if (((word >> 12) & 0x1) == 0)
+ if (((word >> 22) & 0x1) == 0)
{
- /* 33222222222211111111110000000000
- 10987654321098765432109876543210
- 0x001110xx0xxxxxxxx000xxxxxxxxxx
- tbl. */
- return 420;
+ if (((word >> 12) & 0x1) == 0)
+ {
+ /* 33222222222211111111110000000000
+ 10987654321098765432109876543210
+ 0x001110x00xxxxxxxx000xxxxxxxxxx
+ tbl. */
+ return 420;
+ }
+ else
+ {
+ if (((word >> 23) & 0x1) == 0)
+ {
+ /* 33222222222211111111110000000000
+ 10987654321098765432109876543210
+ 0x001110000xxxxxxxx100xxxxxxxxxx
+ tbx. */
+ return 421;
+ }
+ else
+ {
+ /* 33222222222211111111110000000000
+ 10987654321098765432109876543210
+ 0x001110100xxxxxxxx100xxxxxxxxxx
+ luti2. */
+ return 3384;
+ }
+ }
}
else
{
- /* 33222222222211111111110000000000
- 10987654321098765432109876543210
- 0x001110xx0xxxxxxxx100xxxxxxxxxx
- tbx. */
- return 421;
+ if (((word >> 23) & 0x1) == 0)
+ {
+ if (((word >> 12) & 0x1) == 0)
+ {
+ /* 33222222222211111111110000000000
+ 10987654321098765432109876543210
+ 0x001110010xxxxxxxx000xxxxxxxxxx
+ luti4. */
+ return 3386;
+ }
+ else
+ {
+ /* 33222222222211111111110000000000
+ 10987654321098765432109876543210
+ 0x001110010xxxxxxxx100xxxxxxxxxx
+ luti4. */
+ return 3387;
+ }
+ }
+ else
+ {
+ /* 33222222222211111111110000000000
+ 10987654321098765432109876543210
+ 0x001110110xxxxxxxxx00xxxxxxxxxx
+ luti2. */
+ return 3385;
+ }
}
}
else
@@ -33548,12 +33592,8 @@ aarch64_extract_operand (const aarch64_operand *self,
case 32:
case 33:
case 34:
- case 117:
- case 118:
- case 176:
- case 177:
- case 178:
- case 179:
+ case 121:
+ case 122:
case 180:
case 181:
case 182:
@@ -33564,30 +33604,34 @@ aarch64_extract_operand (const aarch64_operand *self,
case 187:
case 188:
case 189:
- case 204:
- case 205:
- case 206:
- case 207:
- case 216:
- case 217:
- case 218:
- case 219:
+ case 190:
+ case 191:
+ case 192:
+ case 193:
+ case 208:
+ case 209:
+ case 210:
+ case 211:
case 220:
- case 228:
+ case 221:
+ case 222:
+ case 223:
+ case 224:
case 232:
case 236:
- case 243:
- case 244:
- case 251:
- case 252:
- case 253:
- case 254:
+ case 240:
+ case 247:
+ case 248:
+ case 255:
+ case 256:
+ case 257:
+ case 258:
return aarch64_ext_regno (self, info, code, inst, errors);
case 6:
- case 114:
- case 115:
- case 286:
- case 288:
+ case 118:
+ case 119:
+ case 290:
+ case 292:
return aarch64_ext_none (self, info, code, inst, errors);
case 11:
return aarch64_ext_regrt_sysins (self, info, code, inst, errors);
@@ -33606,24 +33650,41 @@ aarch64_extract_operand (const aarch64_operand *self,
case 36:
case 37:
case 38:
- case 290:
+ case 294:
return aarch64_ext_reglane (self, info, code, inst, errors);
case 39:
- return aarch64_ext_reglist (self, info, code, inst, errors);
case 40:
- return aarch64_ext_ldst_reglist (self, info, code, inst, errors);
case 41:
- return aarch64_ext_ldst_reglist_r (self, info, code, inst, errors);
+ case 259:
+ case 260:
+ case 275:
+ case 276:
+ case 277:
+ case 278:
+ case 279:
+ case 280:
+ case 281:
+ case 282:
+ case 283:
+ case 284:
+ case 285:
+ case 286:
+ case 287:
+ return aarch64_ext_simple_index (self, info, code, inst, errors);
case 42:
- return aarch64_ext_ldst_elemlist (self, info, code, inst, errors);
+ return aarch64_ext_reglist (self, info, code, inst, errors);
case 43:
+ return aarch64_ext_ldst_reglist (self, info, code, inst, errors);
case 44:
+ return aarch64_ext_ldst_reglist_r (self, info, code, inst, errors);
case 45:
+ return aarch64_ext_lut_reglist (self, info, code, inst, errors);
case 46:
- case 56:
- case 57:
- case 58:
- case 59:
+ return aarch64_ext_ldst_elemlist (self, info, code, inst, errors);
+ case 47:
+ case 48:
+ case 49:
+ case 50:
case 60:
case 61:
case 62:
@@ -33637,123 +33698,123 @@ aarch64_extract_operand (const aarch64_operand *self,
case 70:
case 71:
case 72:
- case 83:
- case 84:
- case 85:
- case 86:
+ case 73:
+ case 74:
+ case 75:
+ case 76:
case 87:
- case 113:
- case 173:
- case 175:
- case 196:
- case 197:
- case 198:
- case 199:
+ case 88:
+ case 89:
+ case 90:
+ case 91:
+ case 117:
+ case 177:
+ case 179:
case 200:
case 201:
case 202:
case 203:
- case 257:
- case 284:
- case 285:
- case 287:
+ case 204:
+ case 205:
+ case 206:
+ case 207:
+ case 261:
+ case 288:
case 289:
- case 294:
- case 295:
+ case 291:
+ case 293:
+ case 298:
+ case 299:
return aarch64_ext_imm (self, info, code, inst, errors);
- case 47:
- case 48:
- return aarch64_ext_advsimd_imm_shift (self, info, code, inst, errors);
- case 49:
- case 50:
case 51:
- return aarch64_ext_advsimd_imm_modified (self, info, code, inst, errors);
case 52:
- return aarch64_ext_shll_imm (self, info, code, inst, errors);
+ return aarch64_ext_advsimd_imm_shift (self, info, code, inst, errors);
+ case 53:
+ case 54:
case 55:
- case 163:
+ return aarch64_ext_advsimd_imm_modified (self, info, code, inst, errors);
+ case 56:
+ return aarch64_ext_shll_imm (self, info, code, inst, errors);
+ case 59:
+ case 167:
return aarch64_ext_fpimm (self, info, code, inst, errors);
- case 73:
- case 171:
+ case 77:
+ case 175:
return aarch64_ext_limm (self, info, code, inst, errors);
- case 74:
+ case 78:
return aarch64_ext_aimm (self, info, code, inst, errors);
- case 75:
+ case 79:
return aarch64_ext_imm_half (self, info, code, inst, errors);
- case 76:
+ case 80:
return aarch64_ext_fbits (self, info, code, inst, errors);
- case 78:
- case 79:
- case 168:
+ case 82:
+ case 83:
+ case 172:
return aarch64_ext_imm_rotate2 (self, info, code, inst, errors);
- case 80:
- case 167:
- case 169:
+ case 84:
+ case 171:
+ case 173:
return aarch64_ext_imm_rotate1 (self, info, code, inst, errors);
- case 81:
- case 82:
+ case 85:
+ case 86:
return aarch64_ext_cond (self, info, code, inst, errors);
- case 88:
- case 97:
+ case 92:
+ case 101:
return aarch64_ext_addr_simple (self, info, code, inst, errors);
- case 89:
+ case 93:
return aarch64_ext_addr_regoff (self, info, code, inst, errors);
- case 90:
- case 91:
- case 92:
case 94:
+ case 95:
case 96:
+ case 98:
+ case 100:
return aarch64_ext_addr_simm (self, info, code, inst, errors);
- case 93:
+ case 97:
return aarch64_ext_addr_simm10 (self, info, code, inst, errors);
- case 95:
- return aarch64_ext_addr_uimm12 (self, info, code, inst, errors);
- case 98:
- return aarch64_ext_addr_offset (self, info, code, inst, errors);
case 99:
- return aarch64_ext_simd_addr_post (self, info, code, inst, errors);
- case 100:
- case 101:
- return aarch64_ext_sysreg (self, info, code, inst, errors);
+ return aarch64_ext_addr_uimm12 (self, info, code, inst, errors);
case 102:
- return aarch64_ext_pstatefield (self, info, code, inst, errors);
+ return aarch64_ext_addr_offset (self, info, code, inst, errors);
case 103:
+ return aarch64_ext_simd_addr_post (self, info, code, inst, errors);
case 104:
case 105:
+ return aarch64_ext_sysreg (self, info, code, inst, errors);
case 106:
+ return aarch64_ext_pstatefield (self, info, code, inst, errors);
case 107:
case 108:
- return aarch64_ext_sysins_op (self, info, code, inst, errors);
case 109:
+ case 110:
case 111:
+ case 112:
+ return aarch64_ext_sysins_op (self, info, code, inst, errors);
+ case 113:
+ case 115:
return aarch64_ext_barrier (self, info, code, inst, errors);
- case 110:
+ case 114:
return aarch64_ext_barrier_dsb_nxs (self, info, code, inst, errors);
- case 112:
- return aarch64_ext_prfop (self, info, code, inst, errors);
case 116:
- return aarch64_ext_hint (self, info, code, inst, errors);
- case 119:
+ return aarch64_ext_prfop (self, info, code, inst, errors);
case 120:
- return aarch64_ext_sve_addr_ri_s4 (self, info, code, inst, errors);
- case 121:
- case 122:
+ return aarch64_ext_hint (self, info, code, inst, errors);
case 123:
case 124:
- return aarch64_ext_sve_addr_ri_s4xvl (self, info, code, inst, errors);
+ return aarch64_ext_sve_addr_ri_s4 (self, info, code, inst, errors);
case 125:
- return aarch64_ext_sve_addr_ri_s6xvl (self, info, code, inst, errors);
case 126:
- return aarch64_ext_sve_addr_ri_s9xvl (self, info, code, inst, errors);
case 127:
case 128:
+ return aarch64_ext_sve_addr_ri_s4xvl (self, info, code, inst, errors);
case 129:
+ return aarch64_ext_sve_addr_ri_s6xvl (self, info, code, inst, errors);
case 130:
- return aarch64_ext_sve_addr_ri_u6 (self, info, code, inst, errors);
+ return aarch64_ext_sve_addr_ri_s9xvl (self, info, code, inst, errors);
case 131:
case 132:
case 133:
case 134:
+ return aarch64_ext_sve_addr_ri_u6 (self, info, code, inst, errors);
case 135:
case 136:
case 137:
@@ -33765,142 +33826,130 @@ aarch64_extract_operand (const aarch64_operand *self,
case 143:
case 144:
case 145:
- return aarch64_ext_sve_addr_rr_lsl (self, info, code, inst, errors);
case 146:
case 147:
case 148:
case 149:
+ return aarch64_ext_sve_addr_rr_lsl (self, info, code, inst, errors);
case 150:
case 151:
case 152:
case 153:
- return aarch64_ext_sve_addr_rz_xtw (self, info, code, inst, errors);
case 154:
case 155:
case 156:
case 157:
- return aarch64_ext_sve_addr_zi_u5 (self, info, code, inst, errors);
+ return aarch64_ext_sve_addr_rz_xtw (self, info, code, inst, errors);
case 158:
- return aarch64_ext_sve_addr_zz_lsl (self, info, code, inst, errors);
case 159:
- return aarch64_ext_sve_addr_zz_sxtw (self, info, code, inst, errors);
case 160:
- return aarch64_ext_sve_addr_zz_uxtw (self, info, code, inst, errors);
case 161:
- return aarch64_ext_sve_aimm (self, info, code, inst, errors);
+ return aarch64_ext_sve_addr_zi_u5 (self, info, code, inst, errors);
case 162:
- return aarch64_ext_sve_asimm (self, info, code, inst, errors);
+ return aarch64_ext_sve_addr_zz_lsl (self, info, code, inst, errors);
+ case 163:
+ return aarch64_ext_sve_addr_zz_sxtw (self, info, code, inst, errors);
case 164:
- return aarch64_ext_sve_float_half_one (self, info, code, inst, errors);
+ return aarch64_ext_sve_addr_zz_uxtw (self, info, code, inst, errors);
case 165:
- return aarch64_ext_sve_float_half_two (self, info, code, inst, errors);
+ return aarch64_ext_sve_aimm (self, info, code, inst, errors);
case 166:
- return aarch64_ext_sve_float_zero_one (self, info, code, inst, errors);
+ return aarch64_ext_sve_asimm (self, info, code, inst, errors);
+ case 168:
+ return aarch64_ext_sve_float_half_one (self, info, code, inst, errors);
+ case 169:
+ return aarch64_ext_sve_float_half_two (self, info, code, inst, errors);
case 170:
+ return aarch64_ext_sve_float_zero_one (self, info, code, inst, errors);
+ case 174:
return aarch64_ext_inv_limm (self, info, code, inst, errors);
- case 172:
+ case 176:
return aarch64_ext_sve_limm_mov (self, info, code, inst, errors);
- case 174:
+ case 178:
return aarch64_ext_sve_scale (self, info, code, inst, errors);
- case 190:
- case 191:
- case 192:
- return aarch64_ext_sve_shlimm (self, info, code, inst, errors);
- case 193:
case 194:
case 195:
- case 270:
+ case 196:
+ return aarch64_ext_sve_shlimm (self, info, code, inst, errors);
+ case 197:
+ case 198:
+ case 199:
+ case 274:
return aarch64_ext_sve_shrimm (self, info, code, inst, errors);
- case 208:
- case 209:
- case 210:
- case 211:
- return aarch64_ext_sme_za_vrs1 (self, info, code, inst, errors);
case 212:
case 213:
case 214:
case 215:
+ return aarch64_ext_sme_za_vrs1 (self, info, code, inst, errors);
+ case 216:
+ case 217:
+ case 218:
+ case 219:
return aarch64_ext_sme_za_vrs2 (self, info, code, inst, errors);
- case 221:
- case 222:
- case 223:
- case 224:
case 225:
case 226:
case 227:
- return aarch64_ext_sve_quad_index (self, info, code, inst, errors);
+ case 228:
case 229:
- return aarch64_ext_sve_index_imm (self, info, code, inst, errors);
case 230:
- return aarch64_ext_sve_index (self, info, code, inst, errors);
case 231:
+ return aarch64_ext_sve_quad_index (self, info, code, inst, errors);
case 233:
- case 250:
- return aarch64_ext_sve_reglist (self, info, code, inst, errors);
+ return aarch64_ext_sve_index_imm (self, info, code, inst, errors);
case 234:
+ return aarch64_ext_sve_index (self, info, code, inst, errors);
case 235:
case 237:
+ case 254:
+ return aarch64_ext_sve_reglist (self, info, code, inst, errors);
case 238:
case 239:
- case 240:
- case 249:
- return aarch64_ext_sve_aligned_reglist (self, info, code, inst, errors);
case 241:
case 242:
- return aarch64_ext_sve_strided_reglist (self, info, code, inst, errors);
+ case 243:
+ case 244:
+ case 253:
+ return aarch64_ext_sve_aligned_reglist (self, info, code, inst, errors);
case 245:
- case 247:
- case 258:
- return aarch64_ext_sme_za_hv_tiles (self, info, code, inst, errors);
case 246:
- case 248:
- return aarch64_ext_sme_za_hv_tiles_range (self, info, code, inst, errors);
- case 255:
- case 256:
- case 271:
- case 272:
- case 273:
- case 274:
- case 275:
- case 276:
- case 277:
- case 278:
- case 279:
- case 280:
- case 281:
- case 282:
- case 283:
- return aarch64_ext_simple_index (self, info, code, inst, errors);
- case 259:
- case 260:
- case 261:
+ return aarch64_ext_sve_strided_reglist (self, info, code, inst, errors);
+ case 249:
+ case 251:
case 262:
+ return aarch64_ext_sme_za_hv_tiles (self, info, code, inst, errors);
+ case 250:
+ case 252:
+ return aarch64_ext_sme_za_hv_tiles_range (self, info, code, inst, errors);
case 263:
case 264:
case 265:
- return aarch64_ext_sme_za_array (self, info, code, inst, errors);
case 266:
- return aarch64_ext_sme_addr_ri_u4xvl (self, info, code, inst, errors);
case 267:
- return aarch64_ext_sme_sm_za (self, info, code, inst, errors);
case 268:
- return aarch64_ext_sme_pred_reg_with_index (self, info, code, inst, errors);
case 269:
+ return aarch64_ext_sme_za_array (self, info, code, inst, errors);
+ case 270:
+ return aarch64_ext_sme_addr_ri_u4xvl (self, info, code, inst, errors);
+ case 271:
+ return aarch64_ext_sme_sm_za (self, info, code, inst, errors);
+ case 272:
+ return aarch64_ext_sme_pred_reg_with_index (self, info, code, inst, errors);
+ case 273:
return aarch64_ext_plain_shrimm (self, info, code, inst, errors);
- case 291:
- case 292:
- case 293:
- return aarch64_ext_x0_to_x30 (self, info, code, inst, errors);
+ case 295:
case 296:
case 297:
- case 298:
- return aarch64_ext_sve_reglist_zt (self, info, code, inst, errors);
- case 299:
+ return aarch64_ext_x0_to_x30 (self, info, code, inst, errors);
case 300:
case 301:
case 302:
- return aarch64_ext_rcpc3_addr_opt_offset (self, info, code, inst, errors);
+ return aarch64_ext_sve_reglist_zt (self, info, code, inst, errors);
case 303:
+ case 304:
+ case 305:
+ case 306:
+ return aarch64_ext_rcpc3_addr_opt_offset (self, info, code, inst, errors);
+ case 307:
return aarch64_ext_rcpc3_addr_offset (self, info, code, inst, errors);
default: assert (0); abort ();
}
diff --git a/opcodes/aarch64-dis.c b/opcodes/aarch64-dis.c
index e1c3f55..213df61 100644
--- a/opcodes/aarch64-dis.c
+++ b/opcodes/aarch64-dis.c
@@ -548,6 +548,21 @@ aarch64_ext_ldst_reglist_r (const aarch64_operand *self ATTRIBUTE_UNUSED,
return true;
}
+/* Decode AdvSIMD vector register list for AdvSIMD lut instructions.
+ The number of of registers in the list is determined by the opcode
+ flag. */
+bool
+aarch64_ext_lut_reglist (const aarch64_operand *self, aarch64_opnd_info *info,
+ const aarch64_insn code,
+ const aarch64_inst *inst ATTRIBUTE_UNUSED,
+ aarch64_operand_error *errors ATTRIBUTE_UNUSED)
+{
+ info->reglist.first_regno = extract_field (self->fields[0], code, 0);
+ info->reglist.num_regs = get_opcode_dependent_value (inst->opcode);
+ info->reglist.stride = 1;
+ return true;
+}
+
/* Decode Q, opcode<2:1>, S, size and Rt fields of Vt in AdvSIMD
load/store single element instructions. */
bool
diff --git a/opcodes/aarch64-dis.h b/opcodes/aarch64-dis.h
index 86494cc..9e8f7c2 100644
--- a/opcodes/aarch64-dis.h
+++ b/opcodes/aarch64-dis.h
@@ -70,6 +70,7 @@ AARCH64_DECL_OPD_EXTRACTOR (ext_reglane);
AARCH64_DECL_OPD_EXTRACTOR (ext_reglist);
AARCH64_DECL_OPD_EXTRACTOR (ext_ldst_reglist);
AARCH64_DECL_OPD_EXTRACTOR (ext_ldst_reglist_r);
+AARCH64_DECL_OPD_EXTRACTOR (ext_lut_reglist);
AARCH64_DECL_OPD_EXTRACTOR (ext_ldst_elemlist);
AARCH64_DECL_OPD_EXTRACTOR (ext_advsimd_imm_shift);
AARCH64_DECL_OPD_EXTRACTOR (ext_shll_imm);
diff --git a/opcodes/aarch64-opc-2.c b/opcodes/aarch64-opc-2.c
index 034436b..7962b0f 100644
--- a/opcodes/aarch64-opc-2.c
+++ b/opcodes/aarch64-opc-2.c
@@ -63,9 +63,13 @@ const struct aarch64_operand aarch64_operands[] =
{AARCH64_OPND_CLASS_SIMD_ELEMENT, "En", OPD_F_HAS_INSERTER | OPD_F_HAS_EXTRACTOR, {FLD_Rn}, "a SIMD vector element"},
{AARCH64_OPND_CLASS_SIMD_ELEMENT, "Em", OPD_F_HAS_INSERTER | OPD_F_HAS_EXTRACTOR, {FLD_Rm}, "a SIMD vector element"},
{AARCH64_OPND_CLASS_SIMD_ELEMENT, "Em16", OPD_F_HAS_INSERTER | OPD_F_HAS_EXTRACTOR, {FLD_Rm}, "a SIMD vector element limited to V0-V15"},
+ {AARCH64_OPND_CLASS_SIMD_ELEMENT, "Em_INDEX1_14", OPD_F_HAS_INSERTER | OPD_F_HAS_EXTRACTOR, {FLD_Rm, FLD_imm1_14}, "a SIMD vector without a type qualifier encoding a bit index"},
+ {AARCH64_OPND_CLASS_SIMD_ELEMENT, "Em_INDEX2_13", OPD_F_HAS_INSERTER | OPD_F_HAS_EXTRACTOR, {FLD_Rm, FLD_imm2_13}, "a SIMD vector without a type qualifier encoding a bit index"},
+ {AARCH64_OPND_CLASS_SIMD_ELEMENT, "Em_INDEX3_12", OPD_F_HAS_INSERTER | OPD_F_HAS_EXTRACTOR, {FLD_Rm, FLD_imm3_12}, "a SIMD vector without a type qualifier encoding a bit index"},
{AARCH64_OPND_CLASS_SIMD_REGLIST, "LVn", OPD_F_HAS_INSERTER | OPD_F_HAS_EXTRACTOR, {FLD_Rn}, "a SIMD vector register list"},
{AARCH64_OPND_CLASS_SIMD_REGLIST, "LVt", OPD_F_HAS_INSERTER | OPD_F_HAS_EXTRACTOR, {}, "a SIMD vector register list"},
{AARCH64_OPND_CLASS_SIMD_REGLIST, "LVt_AL", OPD_F_HAS_INSERTER | OPD_F_HAS_EXTRACTOR, {}, "a SIMD vector register list"},
+ {AARCH64_OPND_CLASS_SIMD_REGLIST, "LVn_LUT", OPD_F_HAS_INSERTER | OPD_F_HAS_EXTRACTOR, {FLD_Rn}, "a SIMD vector register list"},
{AARCH64_OPND_CLASS_SIMD_REGLIST, "LEt", OPD_F_HAS_INSERTER | OPD_F_HAS_EXTRACTOR, {}, "a SIMD vector element list"},
{AARCH64_OPND_CLASS_IMMEDIATE, "CRn", OPD_F_HAS_INSERTER | OPD_F_HAS_EXTRACTOR, {FLD_CRn}, "a 4-bit opcode field named for historical reasons C0 - C15"},
{AARCH64_OPND_CLASS_IMMEDIATE, "CRm", OPD_F_HAS_INSERTER | OPD_F_HAS_EXTRACTOR, {FLD_CRm}, "a 4-bit opcode field named for historical reasons C0 - C15"},
diff --git a/opcodes/aarch64-opc.c b/opcodes/aarch64-opc.c
index 032ab17..84a3955 100644
--- a/opcodes/aarch64-opc.c
+++ b/opcodes/aarch64-opc.c
@@ -337,6 +337,7 @@ const aarch64_field fields[] =
{ 2, 1 }, /* imm1_2: general immediate in bits [2]. */
{ 8, 1 }, /* imm1_8: general immediate in bits [8]. */
{ 10, 1 }, /* imm1_10: general immediate in bits [10]. */
+ { 14, 1 }, /* imm1_14: general immediate in bits [14]. */
{ 15, 1 }, /* imm1_15: general immediate in bits [15]. */
{ 16, 1 }, /* imm1_16: general immediate in bits [16]. */
{ 0, 2 }, /* imm2_0: general immediate in bits [1:0]. */
@@ -344,6 +345,7 @@ const aarch64_field fields[] =
{ 8, 2 }, /* imm2_8: general immediate in bits [9:8]. */
{ 10, 2 }, /* imm2_10: 2-bit immediate, bits [11:10] */
{ 12, 2 }, /* imm2_12: 2-bit immediate, bits [13:12] */
+ { 13, 2 }, /* imm2_13: 2-bit immediate, bits [14:13] */
{ 15, 2 }, /* imm2_15: 2-bit immediate, bits [16:15] */
{ 16, 2 }, /* imm2_16: 2-bit immediate, bits [17:16] */
{ 19, 2 }, /* imm2_19: 2-bit immediate, bits [20:19] */
@@ -2554,6 +2556,10 @@ operand_general_constraint_met_p (const aarch64_opnd_info *opnds, int idx,
num = get_opcode_dependent_value (opcode);
switch (type)
{
+ case AARCH64_OPND_LVn_LUT:
+ if (!check_reglist (opnd, mismatch_detail, idx, num, 1))
+ return 0;
+ break;
case AARCH64_OPND_LVt:
assert (num >= 1 && num <= 4);
/* Unless LD1/ST1, the number of registers should be equal to that
@@ -3165,6 +3171,14 @@ operand_general_constraint_met_p (const aarch64_opnd_info *opnds, int idx,
and is halfed because complex numbers take two elements. */
num = aarch64_get_qualifier_nelem (opnds[0].qualifier)
* aarch64_get_qualifier_esize (opnds[0].qualifier) / 2;
+ else if (opcode->iclass == lut)
+ {
+ size = get_operand_fields_width (get_operand_from_code (type)) - 5;
+ if (!check_reglane (opnd, mismatch_detail, idx, "v", 0, 31,
+ 0, (1 << size) - 1))
+ return 0;
+ break;
+ }
else
num = 16;
num = num / aarch64_get_qualifier_esize (qualifier) - 1;
@@ -4069,6 +4083,14 @@ aarch64_print_operand (char *buf, size_t size, bfd_vma pc,
style_imm (styler, "%" PRIi64, opnd->reglane.index));
break;
+ case AARCH64_OPND_Em_INDEX1_14:
+ case AARCH64_OPND_Em_INDEX2_13:
+ case AARCH64_OPND_Em_INDEX3_12:
+ snprintf (buf, size, "%s[%s]",
+ style_reg (styler, "v%d", opnd->reglane.regno),
+ style_imm (styler, "%" PRIi64, opnd->reglane.index));
+ break;
+
case AARCH64_OPND_VdD1:
case AARCH64_OPND_VnD1:
snprintf (buf, size, "%s[%s]",
@@ -4077,6 +4099,7 @@ aarch64_print_operand (char *buf, size_t size, bfd_vma pc,
break;
case AARCH64_OPND_LVn:
+ case AARCH64_OPND_LVn_LUT:
case AARCH64_OPND_LVt:
case AARCH64_OPND_LVt_AL:
case AARCH64_OPND_LEt:
diff --git a/opcodes/aarch64-opc.h b/opcodes/aarch64-opc.h
index 4e781f0..23e634f 100644
--- a/opcodes/aarch64-opc.h
+++ b/opcodes/aarch64-opc.h
@@ -147,6 +147,7 @@ enum aarch64_field_kind
FLD_imm1_2,
FLD_imm1_8,
FLD_imm1_10,
+ FLD_imm1_14,
FLD_imm1_15,
FLD_imm1_16,
FLD_imm2_0,
@@ -154,6 +155,7 @@ enum aarch64_field_kind
FLD_imm2_8,
FLD_imm2_10,
FLD_imm2_12,
+ FLD_imm2_13,
FLD_imm2_15,
FLD_imm2_16,
FLD_imm2_19,
diff --git a/opcodes/aarch64-tbl.h b/opcodes/aarch64-tbl.h
index 063343d..6b98a1b 100644
--- a/opcodes/aarch64-tbl.h
+++ b/opcodes/aarch64-tbl.h
@@ -1004,6 +1004,24 @@
QLF3(V_16B, V_16B, V_16B), \
}
+/* e.g. luti2 <Vd>.16B, { <Vn>.16B }, <Vm>[index]. */
+/* The third operand is an AdvSIMD vector with a bit index
+ and without a type qualifier and is checked separately
+ based on operand enum. */
+#define QL_VVUB \
+{ \
+ QLF3(V_16B , V_16B , NIL), \
+}
+
+/* e.g. luti2 <Vd>.8H, { <Vn>.8H }, <Vm>[index]. */
+/* The third operand is an AdvSIMD vector with a bit index
+ and without a type qualifier and is checked separately
+ based on operand enum. */
+#define QL_VVUH \
+{ \
+ QLF3(V_8H , V_8H , NIL), \
+}
+
/* e.g. EXT <Vd>.<T>, <Vn>.<T>, <Vm>.<T>, #<index>. */
#define QL_VEXT \
{ \
@@ -2711,7 +2729,8 @@ static const aarch64_feature_set aarch64_feature_fp8_sve2 =
AARCH64_FEATURES (2, FP8, SVE2);
static const aarch64_feature_set aarch64_feature_fp8_sme2 =
AARCH64_FEATURES (2, FP8, SME2);
-
+static const aarch64_feature_set aarch64_feature_lut =
+ AARCH64_FEATURE (LUT);
#define CORE &aarch64_feature_v8
#define FP &aarch64_feature_fp
@@ -2786,6 +2805,7 @@ static const aarch64_feature_set aarch64_feature_fp8_sme2 =
#define FP8 &aarch64_feature_fp8
#define FP8_SVE2 &aarch64_feature_fp8_sve2
#define FP8_SME2 &aarch64_feature_fp8_sme2
+#define LUT &aarch64_feature_lut
#define CORE_INSN(NAME,OPCODE,MASK,CLASS,OP,OPS,QUALS,FLAGS) \
{ NAME, OPCODE, MASK, CLASS, OP, CORE, OPS, QUALS, FLAGS, 0, 0, NULL }
@@ -2979,6 +2999,8 @@ static const aarch64_feature_set aarch64_feature_fp8_sme2 =
#define FP8_SME2_INSN(NAME,OPCODE,MASK,CLASS,OP,OPS,QUALS,FLAGS,TIED) \
{ NAME, OPCODE, MASK, CLASS, OP, FP8_SME2, OPS, QUALS, \
F_STRICT | FLAGS, 0, TIED, NULL }
+#define LUT_INSN(NAME,OPCODE,MASK,OPS,QUALS,FLAGS) \
+ { NAME, OPCODE, MASK, lut, 0, LUT, OPS, QUALS, FLAGS, 0, 0, NULL }
#define MOPS_CPY_OP1_OP2_PME_INSN(NAME, OPCODE, MASK, FLAGS, CONSTRAINTS) \
MOPS_INSN (NAME, OPCODE, MASK, 0, \
@@ -6551,6 +6573,12 @@ const struct aarch64_opcode aarch64_opcode_table[] =
CPA_SVE_INSNC ("madpt", 0x44c0d800, 0xffe0fc00, sve_misc, OP3 (SVE_Zd, SVE_Zm_16, SVE_Za_5), OP_SVE_VVV_D, C_SCAN_MOVPRFX, 0),
CPA_SVE_INSNC ("mlapt", 0x44c0d000, 0xffe0fc00, sve_misc, OP3 (SVE_Zd, SVE_Zn, SVE_Zm_16), OP_SVE_VVV_D, C_SCAN_MOVPRFX, 0),
+ /* AdvSIMD lut. */
+ LUT_INSN ("luti2", 0x4e801000, 0xffe09c00, OP3 (Vd, LVn_LUT, Em_INDEX2_13), QL_VVUB, F_OD(1)),
+ LUT_INSN ("luti2", 0x4ec00000, 0xffe08c00, OP3 (Vd, LVn_LUT, Em_INDEX3_12), QL_VVUH, F_OD(1)),
+ LUT_INSN ("luti4", 0x4e402000, 0xffe0bc00, OP3 (Vd, LVn_LUT, Em_INDEX1_14), QL_VVUB, F_OD(1)),
+ LUT_INSN ("luti4", 0x4e401000, 0xffe09c00, OP3 (Vd, LVn_LUT, Em_INDEX2_13), QL_VVUH, F_OD(2)),
+
{0, 0, 0, 0, 0, 0, {}, {}, 0, 0, 0, NULL},
};
@@ -6626,12 +6654,20 @@ const struct aarch64_opcode aarch64_opcode_table[] =
"a SIMD vector element") \
Y(SIMD_ELEMENT, reglane, "Em16", 0, F(FLD_Rm), \
"a SIMD vector element limited to V0-V15") \
+ Y(SIMD_ELEMENT, simple_index, "Em_INDEX1_14", 0, F(FLD_Rm, FLD_imm1_14), \
+ "a SIMD vector without a type qualifier encoding a bit index") \
+ Y(SIMD_ELEMENT, simple_index, "Em_INDEX2_13", 0, F(FLD_Rm, FLD_imm2_13), \
+ "a SIMD vector without a type qualifier encoding a bit index") \
+ Y(SIMD_ELEMENT, simple_index, "Em_INDEX3_12", 0, F(FLD_Rm, FLD_imm3_12), \
+ "a SIMD vector without a type qualifier encoding a bit index") \
Y(SIMD_REGLIST, reglist, "LVn", 0, F(FLD_Rn), \
"a SIMD vector register list") \
Y(SIMD_REGLIST, ldst_reglist, "LVt", 0, F(), \
"a SIMD vector register list") \
Y(SIMD_REGLIST, ldst_reglist_r, "LVt_AL", 0, F(), \
"a SIMD vector register list") \
+ Y(SIMD_REGLIST, lut_reglist, "LVn_LUT", 0, F(FLD_Rn), \
+ "a SIMD vector register list") \
Y(SIMD_REGLIST, ldst_elemlist, "LEt", 0, F(), \
"a SIMD vector element list") \
Y(IMMEDIATE, imm, "CRn", 0, F(FLD_CRn), \