@@ -4417,12 +4417,13 @@ parse_barrier (char **str)
return o->value;
}
-/* Parse an operand for a PSB barrier. Set *HINT_OPT to the hint-option record
- return 0 if successful. Otherwise return PARSE_FAIL. */
+/* Parse an option for barrier, bti and guarded control stack data
+ synchronization instructions. Return true on matching the target
+ options else return false. */
-static int
-parse_barrier_psb (char **str,
- const struct aarch64_name_value_pair ** hint_opt)
+static bool
+parse_hint_opt (const char *name, char **str,
+ const struct aarch64_name_value_pair ** hint_opt)
{
char *p, *q;
const struct aarch64_name_value_pair *o;
@@ -4433,64 +4434,19 @@ parse_barrier_psb (char **str,
o = str_hash_find_n (aarch64_hint_opt_hsh, p, q - p);
if (!o)
- {
- set_fatal_syntax_error
- ( _("unknown or missing option to PSB/TSB"));
- return PARSE_FAIL;
- }
+ return false;
- if (o->value != 0x11)
- {
- /* PSB only accepts option name 'CSYNC'. */
- set_syntax_error
- (_("the specified option is not accepted for PSB/TSB"));
- return PARSE_FAIL;
- }
+ if ((strcmp ("gcsb", name) == 0 && o->value != HINT_OPD_DSYNC)
+ || ((strcmp ("psb", name) == 0 || strcmp ("tsb", name) == 0)
+ && o->value != HINT_OPD_CSYNC)
+ || ((strcmp ("bti", name) == 0)
+ && (o->value != HINT_OPD_C && o->value != HINT_OPD_J
+ && o->value != HINT_OPD_JC)))
+ return false;
*str = q;
*hint_opt = o;
- return 0;
-}
-
-/* Parse an operand for BTI. Set *HINT_OPT to the hint-option record
- return 0 if successful. Otherwise return PARSE_FAIL. */
-
-static int
-parse_bti_operand (char **str,
- const struct aarch64_name_value_pair ** hint_opt)
-{
- char *p, *q;
- const struct aarch64_name_value_pair *o;
-
- p = q = *str;
- while (ISALPHA (*q))
- q++;
-
- o = str_hash_find_n (aarch64_hint_opt_hsh, p, q - p);
- if (!o)
- {
- set_fatal_syntax_error
- ( _("unknown option to BTI"));
- return PARSE_FAIL;
- }
-
- switch (o->value)
- {
- /* Valid BTI operands. */
- case HINT_OPD_C:
- case HINT_OPD_J:
- case HINT_OPD_JC:
- break;
-
- default:
- set_syntax_error
- (_("unknown option to BTI"));
- return PARSE_FAIL;
- }
-
- *str = q;
- *hint_opt = o;
- return 0;
+ return true;
}
/* Parse STR for reg of REG_TYPE and following '.' and QUALIFIER.
@@ -7777,8 +7733,7 @@ parse_operands (char *str, const aarch64_opcode *opcode)
break;
case AARCH64_OPND_BARRIER_PSB:
- val = parse_barrier_psb (&str, &(info->hint_option));
- if (val == PARSE_FAIL)
+ if (!parse_hint_opt (opcode->name, &str, &(info->hint_option)))
goto failure;
break;
@@ -7833,9 +7788,13 @@ parse_operands (char *str, const aarch64_opcode *opcode)
info->qualifier = vectype_to_qualifier (&vectype);
break;
+ case AARCH64_OPND_BARRIER_GCSB:
+ if (!parse_hint_opt (opcode->name, &str, &(info->hint_option)))
+ goto failure;
+ break;
+
case AARCH64_OPND_BTI_TARGET:
- val = parse_bti_operand (&str, &(info->hint_option));
- if (val == PARSE_FAIL)
+ if (!parse_hint_opt (opcode->name, &str, &(info->hint_option)))
goto failure;
break;
@@ -12,6 +12,7 @@
.*: d50877bf gcspopcx
.*: d50877df gcspopx
.*: d52b773f gcspopm
+.*: d503227f gcsb dsync
.*: d50b7700 gcspushm x0
.*: d50b770f gcspushm x15
.*: d50b771e gcspushm x30
@@ -3,6 +3,7 @@
gcspopcx
gcspopx
gcspopm
+ gcsb dsync
.irp op gcspushm, gcsss1, gcsss2, gcspopm
.irp reg1 x0, x15, x30, xzr
new file mode 100644
@@ -0,0 +1,4 @@
+#name: Barrier and BTI instructions with wrong targets.
+#as: -march=armv8-a
+#source: hint-bad.s
+#error_output: hint-bad.l
new file mode 100644
@@ -0,0 +1,8 @@
+[^ :]+: Assembler messages:
+[^ :]+:[0-9]+: Error: operand 1 must be the GCSB option name DSYNC -- `gcsb'
+[^ :]+:[0-9]+: Error: operand 1 must be the GCSB option name DSYNC -- `gcsb csync'
+[^ :]+:[0-9]+: Error: operand 1 must be the PSB/TSB option name CSYNC -- `psb'
+[^ :]+:[0-9]+: Error: operand 1 must be the PSB/TSB option name CSYNC -- `psb dsync'
+[^ :]+:[0-9]+: Error: operand 1 must be the PSB/TSB option name CSYNC -- `tsb'
+[^ :]+:[0-9]+: Error: operand 1 must be the PSB/TSB option name CSYNC -- `tsb dsync'
+[^ :]+:[0-9]+: Error: operand 1 must be BTI targets j/c/jc -- `bti jj'
new file mode 100644
@@ -0,0 +1,8 @@
+ .text
+ gcsb
+ gcsb csync
+ psb
+ psb dsync
+ tsb
+ tsb dsync
+ bti jj
@@ -34,7 +34,7 @@ Disassembly of section \.text:
.*: d503221f (hint #0x10|esb)
.*: d503223f (hint #0x11|psb csync)
.*: d503225f (hint #0x12|tsb csync)
-.*: d503227f hint #0x13
+.*: d503227f (hint #0x13|gcsb dsync)
.*: d503229f (hint #0x14|csdb)
.*: d50322bf hint #0x15
.*: d50322df (hint #0x16|clearbhb)
@@ -520,6 +520,7 @@ enum aarch64_opnd
AARCH64_OPND_PRFOP, /* Prefetch operation. */
AARCH64_OPND_RPRFMOP, /* Range prefetch operation. */
AARCH64_OPND_BARRIER_PSB, /* Barrier operand for PSB. */
+ AARCH64_OPND_BARRIER_GCSB, /* Barrier operand for GCSB. */
AARCH64_OPND_BTI_TARGET, /* BTI {<target>}. */
AARCH64_OPND_SVE_ADDR_RI_S4x16, /* SVE [<Xn|SP>, #<simm4>*16]. */
AARCH64_OPND_SVE_ADDR_RI_S4x32, /* SVE [<Xn|SP>, #<simm4>*32]. */
@@ -1480,6 +1481,7 @@ struct aarch64_inst
/* Defining the HINT #imm values for the aarch64_hint_options. */
#define HINT_OPD_CSYNC 0x11
+#define HINT_OPD_DSYNC 0x13
#define HINT_OPD_C 0x22
#define HINT_OPD_J 0x24
#define HINT_OPD_JC 0x26
@@ -554,6 +554,7 @@ const struct aarch64_name_value_pair aarch64_hint_options[] =
/* BTI. This is also the F_DEFAULT entry for AARCH64_OPND_BTI_TARGET. */
{ " ", HINT_ENCODE (HINT_OPD_F_NOPRINT, 0x20) },
{ "csync", HINT_OPD_CSYNC }, /* PSB CSYNC. */
+ { "dsync", HINT_OPD_DSYNC }, /* GCSB DSYNC. */
{ "c", HINT_OPD_C }, /* BTI C. */
{ "j", HINT_OPD_J }, /* BTI J. */
{ "jc", HINT_OPD_JC }, /* BTI JC. */
@@ -4629,6 +4630,10 @@ aarch64_print_operand (char *buf, size_t size, bfd_vma pc,
snprintf (buf, size, "{%s}", style_reg (styler, "zt0"));
break;
+ case AARCH64_OPND_BARRIER_GCSB:
+ snprintf (buf, size, "%s", style_sub_mnem (styler, "dsync"));
+ break;
+
case AARCH64_OPND_BTI_TARGET:
if ((HINT_FLAG (opnd->hint_option->value) & HINT_OPD_F_NOPRINT) == 0)
snprintf (buf, size, "%s",
@@ -4156,6 +4156,7 @@ const struct aarch64_opcode aarch64_opcode_table[] =
GCS_INSN ("gcspopm", 0xd52b7720, 0xffffffe0, OP1 (Rt), QL_I1X, 0),
GCS_INSN ("gcsstr", 0xd91f0c00, 0xfffffc00, OP2 (Rt, Rn_SP), QL_I2SAMEX, 0),
GCS_INSN ("gcssttr", 0xd91f1c00, 0xfffffc00, OP2 (Rt, Rn_SP), QL_I2SAMEX, 0),
+ CORE_INSN ("gcsb", 0xd503227f, 0xffffffff, ic_system, 0, OP1 (BARRIER_GCSB), {}, F_ALIAS),
CORE_INSN ("sys", 0xd5080000, 0xfff80000, ic_system, 0, OP5 (UIMM3_OP1, CRn, CRm, UIMM3_OP2, Rt), QL_SYS, F_HAS_ALIAS | F_OPD4_OPT | F_DEFAULT (0x1F)),
CORE_INSN ("at", 0xd5080000, 0xfff80000, ic_system, 0, OP2 (SYSREG_AT, Rt), QL_SRC_X, F_ALIAS),
CORE_INSN ("dc", 0xd5080000, 0xfff80000, ic_system, 0, OP2 (SYSREG_DC, Rt), QL_SRC_X, F_ALIAS),
@@ -6300,7 +6301,9 @@ const struct aarch64_opcode aarch64_opcode_table[] =
"a range prefetch operation specifier") \
Y(SYSTEM, none, "BARRIER_PSB", 0, F (), \
"the PSB/TSB option name CSYNC") \
- Y(SYSTEM, hint, "BTI", 0, F (), \
+ Y(SYSTEM, none, "BARRIER_GCSB", 0, F (), \
+ "the GCSB option name DSYNC") \
+ Y(SYSTEM, hint, "BTI_TARGET", 0, F (), \
"BTI targets j/c/jc") \
Y(ADDRESS, sve_addr_ri_s4, "SVE_ADDR_RI_S4x16", \
4 << OPD_F_OD_LSB, F(FLD_Rn), \