diff options
-rw-r--r-- | gas/NEWS | 2 | ||||
-rw-r--r-- | gas/config/tc-aarch64.c | 67 | ||||
-rw-r--r-- | gas/doc/c-aarch64.texi | 2 | ||||
-rw-r--r-- | gas/testsuite/gas/aarch64/advsimd-lut-bad.d | 3 | ||||
-rw-r--r-- | gas/testsuite/gas/aarch64/advsimd-lut-bad.l | 25 | ||||
-rw-r--r-- | gas/testsuite/gas/aarch64/advsimd-lut-illegal.d | 3 | ||||
-rw-r--r-- | gas/testsuite/gas/aarch64/advsimd-lut-illegal.l | 208 | ||||
-rw-r--r-- | gas/testsuite/gas/aarch64/advsimd-lut-illegal.s | 128 | ||||
-rw-r--r-- | gas/testsuite/gas/aarch64/advsimd-lut.d | 32 | ||||
-rw-r--r-- | gas/testsuite/gas/aarch64/advsimd-lut.s | 29 | ||||
-rw-r--r-- | include/opcode/aarch64.h | 9 | ||||
-rw-r--r-- | opcodes/aarch64-asm-2.c | 357 | ||||
-rw-r--r-- | opcodes/aarch64-asm.c | 11 | ||||
-rw-r--r-- | opcodes/aarch64-asm.h | 1 | ||||
-rw-r--r-- | opcodes/aarch64-dis-2.c | 419 | ||||
-rw-r--r-- | opcodes/aarch64-dis.c | 15 | ||||
-rw-r--r-- | opcodes/aarch64-dis.h | 1 | ||||
-rw-r--r-- | opcodes/aarch64-opc-2.c | 4 | ||||
-rw-r--r-- | opcodes/aarch64-opc.c | 23 | ||||
-rw-r--r-- | opcodes/aarch64-opc.h | 2 | ||||
-rw-r--r-- | opcodes/aarch64-tbl.h | 38 |
21 files changed, 1016 insertions, 363 deletions
@@ -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), \ |