diff options
Diffstat (limited to 'gas/config/tc-aarch64.c')
-rw-r--r-- | gas/config/tc-aarch64.c | 47 |
1 files changed, 47 insertions, 0 deletions
diff --git a/gas/config/tc-aarch64.c b/gas/config/tc-aarch64.c index d17d118..2ec1af4 100644 --- a/gas/config/tc-aarch64.c +++ b/gas/config/tc-aarch64.c @@ -6686,12 +6686,49 @@ parse_operands (char *str, const aarch64_opcode *opcode) backtrack_pos = 0; goto failure; } + if (val != PARSE_FAIL + && operands[i] == AARCH64_OPND_BARRIER) + { + /* Regular barriers accept options CRm (C0-C15). + DSB nXS barrier variant accepts values > 15. */ + po_imm_or_fail (0, 15); + } /* This is an extension to accept a 0..15 immediate. */ if (val == PARSE_FAIL) po_imm_or_fail (0, 15); info->barrier = aarch64_barrier_options + val; break; + case AARCH64_OPND_BARRIER_DSB_NXS: + val = parse_barrier (&str); + if (val != PARSE_FAIL) + { + /* DSB nXS barrier variant accept only <option>nXS qualifiers. */ + if (!(val == 16 || val == 20 || val == 24 || val == 28)) + { + set_syntax_error (_("the specified option is not accepted in DSB")); + /* Turn off backtrack as this optional operand is present. */ + backtrack_pos = 0; + goto failure; + } + } + else + { + /* DSB nXS barrier variant accept 5-bit unsigned immediate, with + possible values 16, 20, 24 or 28 , encoded as val<3:2>. */ + if (! parse_constant_immediate (&str, &val, imm_reg_type)) + goto failure; + if (!(val == 16 || val == 20 || val == 24 || val == 28)) + { + set_syntax_error (_("immediate value must be 16, 20, 24, 28")); + goto failure; + } + } + /* Option index is encoded as 2-bit value in val<3:2>. */ + val = (val >> 2) - 4; + info->barrier = aarch64_barrier_dsb_nxs_options + val; + break; + case AARCH64_OPND_PRFOP: val = parse_pldop (&str); /* This is an extension to accept a 0..31 immediate. */ @@ -8782,6 +8819,16 @@ md_begin (void) (void *) (aarch64_barrier_options + i)); } + for (i = 0; i < ARRAY_SIZE (aarch64_barrier_dsb_nxs_options); i++) + { + const char *name = aarch64_barrier_dsb_nxs_options[i].name; + checked_hash_insert (aarch64_barrier_opt_hsh, name, + (void *) (aarch64_barrier_dsb_nxs_options + i)); + /* Also hash the name in the upper case. */ + checked_hash_insert (aarch64_barrier_opt_hsh, get_upper_str (name), + (void *) (aarch64_barrier_dsb_nxs_options + i)); + } + for (i = 0; i < ARRAY_SIZE (aarch64_prfops); i++) { const char* name = aarch64_prfops[i].name; |