diff --git a/gas/config/tc-aarch64.c b/gas/config/tc-aarch64.c
index 6d2040037c3ff2c4c5d1ff967ad3c7222d878c93..1f687fe1ca07d5436602860bbdbc58e1e02f6cc2 100644
--- a/gas/config/tc-aarch64.c
+++ b/gas/config/tc-aarch64.c
@@ -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;
 
diff --git a/gas/testsuite/gas/aarch64/gcs-1.d b/gas/testsuite/gas/aarch64/gcs-1.d
index 51f9dd6afc5cca1e69ad408849d71a6c7e3f09cf..09fa418e5eab6f27004dcdfa43486ecaa92afec5 100644
--- a/gas/testsuite/gas/aarch64/gcs-1.d
+++ b/gas/testsuite/gas/aarch64/gcs-1.d
@@ -12,6 +12,7 @@
 .*:	d50877bf 	gcspopcx
 .*:	d50877df 	gcspopx
 .*:	d52b773f 	gcspopm
+.*:	d503227f 	gcsb	dsync
 .*:	d50b7700 	gcspushm	x0
 .*:	d50b770f 	gcspushm	x15
 .*:	d50b771e 	gcspushm	x30
diff --git a/gas/testsuite/gas/aarch64/gcs-1.s b/gas/testsuite/gas/aarch64/gcs-1.s
index 9706587878d51d0c9874fdf1325d1052dd55ff57..35584a8810ea3b5e704dce6ee794664d14014e8c 100644
--- a/gas/testsuite/gas/aarch64/gcs-1.s
+++ b/gas/testsuite/gas/aarch64/gcs-1.s
@@ -3,6 +3,7 @@
 	gcspopcx
 	gcspopx
 	gcspopm
+	gcsb dsync
 
 	.irp op gcspushm, gcsss1, gcsss2, gcspopm
         .irp reg1 x0, x15, x30, xzr
diff --git a/gas/testsuite/gas/aarch64/hint-bad.d b/gas/testsuite/gas/aarch64/hint-bad.d
new file mode 100644
index 0000000000000000000000000000000000000000..e881fc9b386809123da9f956b0f1f12794490dee
--- /dev/null
+++ b/gas/testsuite/gas/aarch64/hint-bad.d
@@ -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
diff --git a/gas/testsuite/gas/aarch64/hint-bad.l b/gas/testsuite/gas/aarch64/hint-bad.l
new file mode 100644
index 0000000000000000000000000000000000000000..57caed10e9a16de8415bc1a19bf9799898b5755e
--- /dev/null
+++ b/gas/testsuite/gas/aarch64/hint-bad.l
@@ -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'
diff --git a/gas/testsuite/gas/aarch64/hint-bad.s b/gas/testsuite/gas/aarch64/hint-bad.s
new file mode 100644
index 0000000000000000000000000000000000000000..319b859f845ef37ad440eb300eac823456c470b0
--- /dev/null
+++ b/gas/testsuite/gas/aarch64/hint-bad.s
@@ -0,0 +1,8 @@
+	.text
+	gcsb
+	gcsb csync
+	psb
+	psb dsync
+	tsb
+	tsb dsync
+	bti jj
diff --git a/gas/testsuite/gas/aarch64/system.d b/gas/testsuite/gas/aarch64/system.d
index 8ad274655049dd8b7ab5253f2d8b45537e50528f..bb1a94cb0204b953ba204365c075493622d24c16 100644
--- a/gas/testsuite/gas/aarch64/system.d
+++ b/gas/testsuite/gas/aarch64/system.d
@@ -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)
diff --git a/include/opcode/aarch64.h b/include/opcode/aarch64.h
index fc6a01aefd6f957ceb4f1578d09977321ff270b6..8410a69ee24a692d340d3a5b3e82fe97dca8c7a2 100644
--- a/include/opcode/aarch64.h
+++ b/include/opcode/aarch64.h
@@ -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
diff --git a/opcodes/aarch64-opc.c b/opcodes/aarch64-opc.c
index 599bb6365374257189c3247ae0dbf0881ab6c079..6d9f3a06def7e696ffd6cd74fa8e1ffc7eeecbb7 100644
--- a/opcodes/aarch64-opc.c
+++ b/opcodes/aarch64-opc.c
@@ -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",
diff --git a/opcodes/aarch64-tbl.h b/opcodes/aarch64-tbl.h
index f281fd55070da59f3ce598115b9ab701fd754deb..463939d24ca1db8ad59c3f8e7a4f27f007f4137a 100644
--- a/opcodes/aarch64-tbl.h
+++ b/opcodes/aarch64-tbl.h
@@ -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),					\
