aboutsummaryrefslogtreecommitdiff
path: root/gas/config/tc-aarch64.c
diff options
context:
space:
mode:
Diffstat (limited to 'gas/config/tc-aarch64.c')
-rw-r--r--gas/config/tc-aarch64.c64
1 files changed, 64 insertions, 0 deletions
diff --git a/gas/config/tc-aarch64.c b/gas/config/tc-aarch64.c
index f877262..7a3a39d 100644
--- a/gas/config/tc-aarch64.c
+++ b/gas/config/tc-aarch64.c
@@ -3584,6 +3584,52 @@ parse_adrp (char **str)
/* Miscellaneous. */
+/* Parse a symbolic operand such as "pow2" at *STR. ARRAY is an array
+ of SIZE tokens in which index I gives the token for field value I,
+ or is null if field value I is invalid. REG_TYPE says which register
+ names should be treated as registers rather than as symbolic immediates.
+
+ Return true on success, moving *STR past the operand and storing the
+ field value in *VAL. */
+
+static int
+parse_enum_string (char **str, int64_t *val, const char *const *array,
+ size_t size, aarch64_reg_type reg_type)
+{
+ expressionS exp;
+ char *p, *q;
+ size_t i;
+
+ /* Match C-like tokens. */
+ p = q = *str;
+ while (ISALNUM (*q))
+ q++;
+
+ for (i = 0; i < size; ++i)
+ if (array[i]
+ && strncasecmp (array[i], p, q - p) == 0
+ && array[i][q - p] == 0)
+ {
+ *val = i;
+ *str = q;
+ return TRUE;
+ }
+
+ if (!parse_immediate_expression (&p, &exp, reg_type))
+ return FALSE;
+
+ if (exp.X_op == O_constant
+ && (uint64_t) exp.X_add_number < size)
+ {
+ *val = exp.X_add_number;
+ *str = p;
+ return TRUE;
+ }
+
+ /* Use the default error for this operand. */
+ return FALSE;
+}
+
/* Parse an option for a preload instruction. Returns the encoding for the
option, or PARSE_FAIL. */
@@ -3793,6 +3839,12 @@ parse_sys_ins_reg (char **str, struct hash_control *sys_ins_regs)
} \
} while (0)
+#define po_enum_or_fail(array) do { \
+ if (!parse_enum_string (&str, &val, array, \
+ ARRAY_SIZE (array), imm_reg_type)) \
+ goto failure; \
+ } while (0)
+
#define po_misc_or_fail(expr) do { \
if (!expr) \
goto failure; \
@@ -4806,6 +4858,8 @@ process_omitted_operand (enum aarch64_opnd type, const aarch64_opcode *opcode,
case AARCH64_OPND_WIDTH:
case AARCH64_OPND_UIMM7:
case AARCH64_OPND_NZCV:
+ case AARCH64_OPND_SVE_PATTERN:
+ case AARCH64_OPND_SVE_PRFOP:
operand->imm.value = default_value;
break;
@@ -5314,6 +5368,16 @@ parse_operands (char *str, const aarch64_opcode *opcode)
info->imm.value = val;
break;
+ case AARCH64_OPND_SVE_PATTERN:
+ po_enum_or_fail (aarch64_sve_pattern_array);
+ info->imm.value = val;
+ break;
+
+ case AARCH64_OPND_SVE_PRFOP:
+ po_enum_or_fail (aarch64_sve_prfop_array);
+ info->imm.value = val;
+ break;
+
case AARCH64_OPND_UIMM7:
po_imm_or_fail (0, 127);
info->imm.value = val;