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.c47
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;