diff options
Diffstat (limited to 'gas/config/tc-aarch64.c')
-rw-r--r-- | gas/config/tc-aarch64.c | 64 |
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; |