[1/2] aarch64: add Branch Record Buffer extension instructions

Message ID 20240607135903.14295-2-claudio.bantaloukas@arm.com
State Committed
Headers
Series aarch64: add Branch Record Buffer extension instructions |

Checks

Context Check Description
linaro-tcwg-bot/tcwg_binutils_build--master-arm success Testing passed
linaro-tcwg-bot/tcwg_binutils_build--master-aarch64 success Testing passed
linaro-tcwg-bot/tcwg_binutils_check--master-aarch64 fail Testing failed
linaro-tcwg-bot/tcwg_binutils_check--master-arm success Testing passed

Commit Message

Claudio Bantaloukas June 7, 2024, 1:59 p.m. UTC
  The FEAT_BRBE extension provides two aliases of sys:
- brb iall (Invalidates all Branch records in the Branch Record Buffer)
- brb inj (Injects the Branch Record held in BRBINFINJ_EL1,
  BRBSRCINJ_EL1, and BRBTGTINJ_EL1 into the Branch Record Buffer)

This patch adds:
- the feature option "brbe" that must be added for the aliases to be available
- a new operand flag AARCH64_OPND_Rt_IN_SYS_ALIASES that warns in a comment
  when Rt is set to the non default value 0b11111 (it is constrained
  unpredictable whether the instruction is undefined or behaves as if the Rt
  field is set to 0b11111).
- a new operand flag AARCH64_OPND_BRBOP that encodes and decodes Op2 values
  from bit 5
- support for the two brb aliases above

See:
- https://developer.arm.com/documentation/ddi0602/2024-03/Base-Instructions/BRB--Branch-Record-Buffer--an-alias-of-SYS-?lang=en
- https://developer.arm.com/documentation/ddi0601/2024-03/AArch64-Instructions/BRB-INJ--Branch-Record-Injection-into-the-Branch-Record-Buffer?lang=en
- https://developer.arm.com/documentation/ddi0601/2024-03/AArch64-Instructions/BRB-IALL--Invalidate-the-Branch-Record-Buffer?lang=en
---
 gas/config/tc-aarch64.c                      |  8 +++++++
 gas/doc/c-aarch64.texi                       |  2 ++
 gas/testsuite/gas/aarch64/brbe-brb-bad.d     |  2 ++
 gas/testsuite/gas/aarch64/brbe-brb-bad.l     |  4 ++++
 gas/testsuite/gas/aarch64/brbe-brb-bad.s     |  6 +++++
 gas/testsuite/gas/aarch64/brbe-brb-inst.d    | 14 ++++++++++++
 gas/testsuite/gas/aarch64/brbe-brb-inst.s    |  5 ++++
 gas/testsuite/gas/aarch64/brbe-brb-invalid.d |  3 +++
 gas/testsuite/gas/aarch64/brbe-brb-invalid.l |  3 +++
 gas/testsuite/gas/aarch64/brbe-brb.d         | 12 ++++++++++
 gas/testsuite/gas/aarch64/brbe-brb.s         |  5 ++++
 include/opcode/aarch64.h                     |  7 +++++-
 opcodes/aarch64-opc.c                        | 24 ++++++++++++++++++++
 opcodes/aarch64-opc.h                        |  1 +
 opcodes/aarch64-tbl.h                        | 15 ++++++++++++
 15 files changed, 110 insertions(+), 1 deletion(-)
 create mode 100644 gas/testsuite/gas/aarch64/brbe-brb-bad.d
 create mode 100644 gas/testsuite/gas/aarch64/brbe-brb-bad.l
 create mode 100644 gas/testsuite/gas/aarch64/brbe-brb-bad.s
 create mode 100644 gas/testsuite/gas/aarch64/brbe-brb-inst.d
 create mode 100644 gas/testsuite/gas/aarch64/brbe-brb-inst.s
 create mode 100644 gas/testsuite/gas/aarch64/brbe-brb-invalid.d
 create mode 100644 gas/testsuite/gas/aarch64/brbe-brb-invalid.l
 create mode 100644 gas/testsuite/gas/aarch64/brbe-brb.d
 create mode 100644 gas/testsuite/gas/aarch64/brbe-brb.s
  

Comments

Jan Beulich June 10, 2024, 6:58 a.m. UTC | #1
On 07.06.2024 15:59, Claudio Bantaloukas wrote:
> 
> The FEAT_BRBE extension provides two aliases of sys:
> - brb iall (Invalidates all Branch records in the Branch Record Buffer)
> - brb inj (Injects the Branch Record held in BRBINFINJ_EL1,
>   BRBSRCINJ_EL1, and BRBTGTINJ_EL1 into the Branch Record Buffer)
> 
> This patch adds:
> - the feature option "brbe" that must be added for the aliases to be available
> - a new operand flag AARCH64_OPND_Rt_IN_SYS_ALIASES that warns in a comment
>   when Rt is set to the non default value 0b11111 (it is constrained
>   unpredictable whether the instruction is undefined or behaves as if the Rt
>   field is set to 0b11111).

Hmm, shouldn't gas nevertheless accept the optional operand, and shouldn't
the disassembler nevertheless print it (with said comment still there, just
perhaps with the then-redundant register number omitted)?

Jan
  
Claudio Bantaloukas June 10, 2024, 11 a.m. UTC | #2
On 10/06/2024 07:58, Jan Beulich wrote:
> On 07.06.2024 15:59, Claudio Bantaloukas wrote:
>>
>> The FEAT_BRBE extension provides two aliases of sys:
>> - brb iall (Invalidates all Branch records in the Branch Record Buffer)
>> - brb inj (Injects the Branch Record held in BRBINFINJ_EL1,
>>    BRBSRCINJ_EL1, and BRBTGTINJ_EL1 into the Branch Record Buffer)
>>
>> This patch adds:
>> - the feature option "brbe" that must be added for the aliases to be available
>> - a new operand flag AARCH64_OPND_Rt_IN_SYS_ALIASES that warns in a comment
>>    when Rt is set to the non default value 0b11111 (it is constrained
>>    unpredictable whether the instruction is undefined or behaves as if the Rt
>>    field is set to 0b11111).
> 
> Hmm, shouldn't gas nevertheless accept the optional operand, and shouldn't
> the disassembler nevertheless print it (with said comment still there, just
> perhaps with the then-redundant register number omitted)?

Hi Jan,
thank you for pushing the patch through the filter (if that was you) and 
for reviewing it.

 From an architectural perspective, brb is an alias of sys that always 
outputs the default Rt value and has no provision for setting Rt.

If a user ignores the language in the architecture docs that is about as 
close as it gets to "don't do that" and knows what they are doing, they 
can use sys with the equivalent operands, set a non-default Rt value and 
play the dice on whether the non-default Rt will be ignored or 
"something else" happens.

We had a bit of internal debate whether to:
- output brb ignoring Rt completely
- output sys
- output invalid syntax
- output brb with a comment that the instruction is not "as it should 
be" when Rt!=31

In the end, we settled with the last option as we don't expect the 
specific sys arguments that translate to brb to be used with a non 
default Rt.

> Jan

Cheers,
Claudio
  
Richard Earnshaw (lists) June 12, 2024, 1:52 p.m. UTC | #3
On 10/06/2024 07:58, Jan Beulich wrote:
> On 07.06.2024 15:59, Claudio Bantaloukas wrote:
>>
>> The FEAT_BRBE extension provides two aliases of sys:
>> - brb iall (Invalidates all Branch records in the Branch Record Buffer)
>> - brb inj (Injects the Branch Record held in BRBINFINJ_EL1,
>>   BRBSRCINJ_EL1, and BRBTGTINJ_EL1 into the Branch Record Buffer)
>>
>> This patch adds:
>> - the feature option "brbe" that must be added for the aliases to be available
>> - a new operand flag AARCH64_OPND_Rt_IN_SYS_ALIASES that warns in a comment
>>   when Rt is set to the non default value 0b11111 (it is constrained
>>   unpredictable whether the instruction is undefined or behaves as if the Rt
>>   field is set to 0b11111).
> 
> Hmm, shouldn't gas nevertheless accept the optional operand, and shouldn't
> the disassembler nevertheless print it (with said comment still there, just
> perhaps with the then-redundant register number omitted)?
> 
> Jan

No.  It's not really a legal encoding of the instruction, but because of the way the HW might do instruction decode it would be unreasonable of the architecture to require it to take an undef instruction trap.  So the architecture defines it as 'constrained unpredictable', meaning that the HW behaviour must take one of a specified list of actions for such encodings.  In this case the options are:

- undef trap
- execute the instruction as though Rt = 31

But programmers should not rely on a specific behaviour; really such encodings are the result of programmer errors.

R.
  
Richard Earnshaw (lists) June 25, 2024, 5 p.m. UTC | #4
On 10/06/2024 12:00, Claudio Bantaloukas wrote:
> 
> 
> On 10/06/2024 07:58, Jan Beulich wrote:
>> On 07.06.2024 15:59, Claudio Bantaloukas wrote:
>>>
>>> The FEAT_BRBE extension provides two aliases of sys:
>>> - brb iall (Invalidates all Branch records in the Branch Record Buffer)
>>> - brb inj (Injects the Branch Record held in BRBINFINJ_EL1,
>>>    BRBSRCINJ_EL1, and BRBTGTINJ_EL1 into the Branch Record Buffer)
>>>
>>> This patch adds:
>>> - the feature option "brbe" that must be added for the aliases to be available
>>> - a new operand flag AARCH64_OPND_Rt_IN_SYS_ALIASES that warns in a comment
>>>    when Rt is set to the non default value 0b11111 (it is constrained
>>>    unpredictable whether the instruction is undefined or behaves as if the Rt
>>>    field is set to 0b11111).
>>
>> Hmm, shouldn't gas nevertheless accept the optional operand, and shouldn't
>> the disassembler nevertheless print it (with said comment still there, just
>> perhaps with the then-redundant register number omitted)?
> 
> Hi Jan,
> thank you for pushing the patch through the filter (if that was you) and 
> for reviewing it.

Apologies, I pushed the patch, but somehow forgot to reply.

R.

> 
>  From an architectural perspective, brb is an alias of sys that always 
> outputs the default Rt value and has no provision for setting Rt.
> 
> If a user ignores the language in the architecture docs that is about as 
> close as it gets to "don't do that" and knows what they are doing, they 
> can use sys with the equivalent operands, set a non-default Rt value and 
> play the dice on whether the non-default Rt will be ignored or 
> "something else" happens.
> 
> We had a bit of internal debate whether to:
> - output brb ignoring Rt completely
> - output sys
> - output invalid syntax
> - output brb with a comment that the instruction is not "as it should 
> be" when Rt!=31
> 
> In the end, we settled with the last option as we don't expect the 
> specific sys arguments that translate to brb to be used with a non 
> default Rt.
> 
>> Jan
> 
> Cheers,
> Claudio
  

Patch

diff --git a/gas/config/tc-aarch64.c b/gas/config/tc-aarch64.c
index fec17c40a43..0beb2c875d8 100644
--- a/gas/config/tc-aarch64.c
+++ b/gas/config/tc-aarch64.c
@@ -6235,6 +6235,7 @@  process_omitted_operand (enum aarch64_opnd type, const aarch64_opcode *opcode,
     case AARCH64_OPND_Rs:
     case AARCH64_OPND_Ra:
     case AARCH64_OPND_Rt_SYS:
+    case AARCH64_OPND_Rt_IN_SYS_ALIASES:
     case AARCH64_OPND_Rd_SP:
     case AARCH64_OPND_Rn_SP:
     case AARCH64_OPND_Rm_SP:
@@ -6619,6 +6620,7 @@  parse_operands (char *str, const aarch64_opcode *opcode)
 	case AARCH64_OPND_Ra:
 	case AARCH64_OPND_Rt_LS64:
 	case AARCH64_OPND_Rt_SYS:
+	case AARCH64_OPND_Rt_IN_SYS_ALIASES:
 	case AARCH64_OPND_PAIRREG:
 	case AARCH64_OPND_PAIRREG_OR_XZR:
 	case AARCH64_OPND_SVE_Rm:
@@ -8076,6 +8078,11 @@  parse_operands (char *str, const aarch64_opcode *opcode)
 	  info->imm.value = val;
 	  break;
 
+	case AARCH64_OPND_BRBOP:
+	  po_strict_enum_or_fail (aarch64_brbop_array);
+	  info->imm.value = val;
+	  break;
+
 	case AARCH64_OPND_MOPS_ADDR_Rd:
 	case AARCH64_OPND_MOPS_ADDR_Rs:
 	  po_char_or_fail ('[');
@@ -10551,6 +10558,7 @@  static const struct aarch64_option_cpu_value_table aarch64_features[] = {
   {"faminmax",		AARCH64_FEATURE (FAMINMAX), AARCH64_FEATURE (SIMD)},
   {"fp8",		AARCH64_FEATURE (FP8), AARCH64_FEATURE (SIMD)},
   {"lut",		AARCH64_FEATURE (LUT), AARCH64_FEATURE (SIMD)},
+  {"brbe",		AARCH64_FEATURE (BRBE), AARCH64_NO_FEATURES},
   {NULL,		AARCH64_NO_FEATURES, AARCH64_NO_FEATURES},
 };
 
diff --git a/gas/doc/c-aarch64.texi b/gas/doc/c-aarch64.texi
index b622f30b146..b29da1f0e8f 100644
--- a/gas/doc/c-aarch64.texi
+++ b/gas/doc/c-aarch64.texi
@@ -165,6 +165,8 @@  automatically cause those extensions to be disabled.
  @tab Enable BFloat16 to BFloat16 arithmetic for SVE2 and SME2.
 @item @code{bf16} @tab @code{fp}
  @tab Enable BFloat16 extension.
+@item @code{brbe} @tab
+ @tab Enable the Branch Record Buffer extension.
 @item @code{chk} @tab
  @tab Enable the Check Feature Status Extension.
 @item @code{compnum} @tab @code{simd}
diff --git a/gas/testsuite/gas/aarch64/brbe-brb-bad.d b/gas/testsuite/gas/aarch64/brbe-brb-bad.d
new file mode 100644
index 00000000000..6afe74d6a1a
--- /dev/null
+++ b/gas/testsuite/gas/aarch64/brbe-brb-bad.d
@@ -0,0 +1,2 @@ 
+#as: -march=armv9.1-a+brbe
+#error_output: brbe-brb-bad.l
diff --git a/gas/testsuite/gas/aarch64/brbe-brb-bad.l b/gas/testsuite/gas/aarch64/brbe-brb-bad.l
new file mode 100644
index 00000000000..b220d9a9c8d
--- /dev/null
+++ b/gas/testsuite/gas/aarch64/brbe-brb-bad.l
@@ -0,0 +1,4 @@ 
+.*: Assembler messages:
+.*: Error: operand 1 must be Branch Record Buffer operation operand -- `brb foobar'
+.*: Error: operand 1 must be Branch Record Buffer operation operand -- `brb #123'
+.*: Error: operand 1 must be Branch Record Buffer operation operand -- `brb'
diff --git a/gas/testsuite/gas/aarch64/brbe-brb-bad.s b/gas/testsuite/gas/aarch64/brbe-brb-bad.s
new file mode 100644
index 00000000000..862290f1f56
--- /dev/null
+++ b/gas/testsuite/gas/aarch64/brbe-brb-bad.s
@@ -0,0 +1,6 @@ 
+/* brb only accepts iall and inj as arguments */
+.text
+
+brb foobar
+brb #123
+brb
diff --git a/gas/testsuite/gas/aarch64/brbe-brb-inst.d b/gas/testsuite/gas/aarch64/brbe-brb-inst.d
new file mode 100644
index 00000000000..748d36c38a9
--- /dev/null
+++ b/gas/testsuite/gas/aarch64/brbe-brb-inst.d
@@ -0,0 +1,14 @@ 
+#as: -march=armv9.1-a+brbe
+#objdump: -dr
+# This test is only valid on ELF based ports.
+#notarget: *-*-*coff *-*-pe *-*-wince *-*-*aout* *-*-netbsd
+
+.*:     file format .*
+
+Disassembly of section \.text:
+
+0+ <.*>:
+.*:	d509729f 	brb	iall
+.*:	d509729e 	brb	iall	// unpredictable encoding \(Rt!=31\): #30
+.*:	d50972bf 	brb	inj
+.*:	d50972be 	brb	inj	// unpredictable encoding \(Rt!=31\): #30
diff --git a/gas/testsuite/gas/aarch64/brbe-brb-inst.s b/gas/testsuite/gas/aarch64/brbe-brb-inst.s
new file mode 100644
index 00000000000..e05a8808ad1
--- /dev/null
+++ b/gas/testsuite/gas/aarch64/brbe-brb-inst.s
@@ -0,0 +1,5 @@ 
+	.text
+	.inst 0xd509729f // brb iall
+	.inst 0xd509729e // brb iall with non default Rt
+	.inst 0xd50972bf // brb inj
+	.inst 0xd50972be // brb inj with non default Rt
diff --git a/gas/testsuite/gas/aarch64/brbe-brb-invalid.d b/gas/testsuite/gas/aarch64/brbe-brb-invalid.d
new file mode 100644
index 00000000000..fbd2608696b
--- /dev/null
+++ b/gas/testsuite/gas/aarch64/brbe-brb-invalid.d
@@ -0,0 +1,3 @@ 
+#as: -march=armv9.1-a
+#source: brbe-brb.s
+#error_output: brbe-brb-invalid.l
diff --git a/gas/testsuite/gas/aarch64/brbe-brb-invalid.l b/gas/testsuite/gas/aarch64/brbe-brb-invalid.l
new file mode 100644
index 00000000000..98e164acab4
--- /dev/null
+++ b/gas/testsuite/gas/aarch64/brbe-brb-invalid.l
@@ -0,0 +1,3 @@ 
+.*: Assembler messages:
+.*: Error: selected processor does not support `brb iall'
+.*: Error: selected processor does not support `brb inj'
diff --git a/gas/testsuite/gas/aarch64/brbe-brb.d b/gas/testsuite/gas/aarch64/brbe-brb.d
new file mode 100644
index 00000000000..0ab23849614
--- /dev/null
+++ b/gas/testsuite/gas/aarch64/brbe-brb.d
@@ -0,0 +1,12 @@ 
+#as: -march=armv9.1-a+brbe
+#objdump: -dr
+
+.*:     file format .*
+
+Disassembly of section \.text:
+
+0+ <.*>:
+.*:	d509729f 	brb	iall
+.*:	d509729f 	brb	iall
+.*:	d50972bf 	brb	inj
+.*:	d50972bf 	brb	inj
diff --git a/gas/testsuite/gas/aarch64/brbe-brb.s b/gas/testsuite/gas/aarch64/brbe-brb.s
new file mode 100644
index 00000000000..01b684e42e3
--- /dev/null
+++ b/gas/testsuite/gas/aarch64/brbe-brb.s
@@ -0,0 +1,5 @@ 
+	.text
+	brb	iall
+	.inst	0xd509729f // brb iall
+	brb	inj
+	.inst	0xd50972bf // brb inj
diff --git a/include/opcode/aarch64.h b/include/opcode/aarch64.h
index 8a21611e3ff..c83c0a4ebb4 100644
--- a/include/opcode/aarch64.h
+++ b/include/opcode/aarch64.h
@@ -238,6 +238,8 @@  enum aarch64_feature_bit {
   AARCH64_FEATURE_FP8,
   /* LUT instructions.  */
   AARCH64_FEATURE_LUT,
+  /* Branch Record Buffer Extension */
+  AARCH64_FEATURE_BRBE,
   AARCH64_NUM_FEATURES
 };
 
@@ -625,6 +627,8 @@  enum aarch64_opnd
   AARCH64_OPND_BARRIER_PSB,	/* Barrier operand for PSB.  */
   AARCH64_OPND_BARRIER_GCSB,	/* Barrier operand for GCSB.  */
   AARCH64_OPND_BTI_TARGET,	/* BTI {<target>}.  */
+  AARCH64_OPND_BRBOP,		/* BRB operation IALL or INJ in bit 5.  */
+  AARCH64_OPND_Rt_IN_SYS_ALIASES,	/* Defaulted and omitted Rt used in SYS aliases such as brb.  */
   AARCH64_OPND_LSE128_Rt,	/* LSE128 <Xt1>.  */
   AARCH64_OPND_LSE128_Rt2,	/* LSE128 <Xt2>.  */
   AARCH64_OPND_SVE_ADDR_RI_S4x16,   /* SVE [<Xn|SP>, #<simm4>*16].  */
@@ -822,7 +826,7 @@  enum aarch64_opnd
   AARCH64_OPND_RCPC3_ADDR_OPT_PREIND_WB, /* [<Xn|SP>] or [<Xn|SP>, #<imm>]!.  */
   AARCH64_OPND_RCPC3_ADDR_POSTIND,	 /* [<Xn|SP>], #<imm>.  */
   AARCH64_OPND_RCPC3_ADDR_PREIND_WB, 	 /* [<Xn|SP>, #<imm>]!.  */
-  AARCH64_OPND_RCPC3_ADDR_OFFSET
+  AARCH64_OPND_RCPC3_ADDR_OFFSET,
 };
 
 /* Qualifier constrains an operand.  It either specifies a variant of an
@@ -1918,6 +1922,7 @@  extern const char *const aarch64_sve_pattern_array[32];
 extern const char *const aarch64_sve_prfop_array[16];
 extern const char *const aarch64_rprfmop_array[64];
 extern const char *const aarch64_sme_vlxn_array[2];
+extern const char *const aarch64_brbop_array[2];
 
 #ifdef __cplusplus
 }
diff --git a/opcodes/aarch64-opc.c b/opcodes/aarch64-opc.c
index bbe6f09808b..ea278bfdfe5 100644
--- a/opcodes/aarch64-opc.c
+++ b/opcodes/aarch64-opc.c
@@ -117,6 +117,12 @@  const char *const aarch64_sme_vlxn_array[2] = {
   "vlx4"
 };
 
+/* Values accepted by the brb alias.  */
+const char *const aarch64_brbop_array[] = {
+  "iall",
+  "inj",
+};
+
 /* Helper functions to determine which operand to be used to encode/decode
    the size:Q fields for AdvSIMD instructions.  */
 
@@ -418,6 +424,7 @@  const aarch64_field fields[] =
     {  6,  1 }, /* ZAn: name of the bit encoded ZA tile.  */
     { 12,  4 },	/* opc2: in rcpc3 ld/st inst deciding the pre/post-index.  */
     { 30,  2 },	/* rcpc3_size: in rcpc3 ld/st, field controls Rt/Rt2 width.  */
+    { 5,  1 },	/* FLD_brbop: used in BRB to mean IALL or INJ.  */
 };
 
 enum aarch64_operand_class
@@ -3958,6 +3965,7 @@  aarch64_print_operand (char *buf, size_t size, bfd_vma pc,
     case AARCH64_OPND_Rt2:
     case AARCH64_OPND_Rs:
     case AARCH64_OPND_Ra:
+    case AARCH64_OPND_Rt_IN_SYS_ALIASES:
     case AARCH64_OPND_Rt_LS64:
     case AARCH64_OPND_Rt_SYS:
     case AARCH64_OPND_PAIRREG:
@@ -3973,6 +3981,15 @@  aarch64_print_operand (char *buf, size_t size, bfd_vma pc,
 	  if (!opnd->present)
 	    break;
 	}
+      else if ((opnd->type == AARCH64_OPND_Rt_IN_SYS_ALIASES)
+	       && (opnd->reg.regno
+		   != get_optional_operand_default_value (opcode)))
+	{
+	  /* Avoid printing an invalid additional value for Rt in SYS aliases such as
+	     BRB, provide a helpful comment instead */
+	  snprintf (comment, comment_size, "unpredictable encoding (Rt!=31): #%" PRIi64, opnd->imm.value);
+	  break;
+	}
       /* Omit the operand, e.g. RET.  */
       else if (optional_operand_p (opcode, idx)
 	       && (opnd->reg.regno
@@ -4355,6 +4372,13 @@  aarch64_print_operand (char *buf, size_t size, bfd_vma pc,
 		style_sub_mnem (styler, aarch64_sme_vlxn_array[enum_value]));
       break;
 
+    case AARCH64_OPND_BRBOP:
+      enum_value = opnd->imm.value;
+      assert (enum_value < ARRAY_SIZE (aarch64_brbop_array));
+      snprintf (buf, size, "%s",
+		style_sub_mnem (styler, aarch64_brbop_array[enum_value]));
+      break;
+
     case AARCH64_OPND_CRn:
     case AARCH64_OPND_CRm:
       snprintf (buf, size, "%s",
diff --git a/opcodes/aarch64-opc.h b/opcodes/aarch64-opc.h
index 8bf3fc8b874..9b734d63a3b 100644
--- a/opcodes/aarch64-opc.h
+++ b/opcodes/aarch64-opc.h
@@ -225,6 +225,7 @@  enum aarch64_field_kind
   FLD_ZAn,
   FLD_opc2,
   FLD_rcpc3_size,
+  FLD_brbop,
 };
 
 /* Field description.  */
diff --git a/opcodes/aarch64-tbl.h b/opcodes/aarch64-tbl.h
index 1d12630273e..bffb422583a 100644
--- a/opcodes/aarch64-tbl.h
+++ b/opcodes/aarch64-tbl.h
@@ -100,6 +100,11 @@ 
   QLF1(NIL),			\
 }
 
+#define QL_IMM_NIL_NIL		\
+{				\
+  QLF2(NIL, NIL),		\
+}
+
 /* e.g. B.<cond> <label>.  */
 #define QL_PCREL_NIL		\
 {				\
@@ -2745,6 +2750,8 @@  static const aarch64_feature_set aarch64_feature_lut =
   AARCH64_FEATURE (LUT);
 static const aarch64_feature_set aarch64_feature_lut_sve2 =
   AARCH64_FEATURES (2, LUT, SVE2);
+static const aarch64_feature_set aarch64_feature_brbe =
+  AARCH64_FEATURE (BRBE);
 
 #define CORE		&aarch64_feature_v8
 #define FP		&aarch64_feature_fp
@@ -2821,6 +2828,7 @@  static const aarch64_feature_set aarch64_feature_lut_sve2 =
 #define FP8_SME2   &aarch64_feature_fp8_sme2
 #define LUT &aarch64_feature_lut
 #define LUT_SVE2 &aarch64_feature_lut_sve2
+#define BRBE		&aarch64_feature_brbe
 
 #define CORE_INSN(NAME,OPCODE,MASK,CLASS,OP,OPS,QUALS,FLAGS) \
   { NAME, OPCODE, MASK, CLASS, OP, CORE, OPS, QUALS, FLAGS, 0, 0, NULL }
@@ -3019,6 +3027,8 @@  static const aarch64_feature_set aarch64_feature_lut_sve2 =
 #define LUT_SVE2_INSN(NAME,OPCODE,MASK,OPS,QUALS,FLAGS,CONSTRAINTS) \
   { NAME, OPCODE, MASK, lut, 0, LUT_SVE2, OPS, QUALS, \
     FLAGS, CONSTRAINTS, 0, NULL }
+#define BRBE_INSN(NAME,OPCODE,MASK,OPS,QUALS,FLAGS) \
+  { NAME, OPCODE, MASK, ic_system, 0, BRBE, OPS, QUALS, FLAGS, 0, 0, NULL }
 
 #define MOPS_CPY_OP1_OP2_PME_INSN(NAME, OPCODE, MASK, FLAGS, CONSTRAINTS) \
   MOPS_INSN (NAME, OPCODE, MASK, 0, \
@@ -4443,6 +4453,7 @@  const struct aarch64_opcode aarch64_opcode_table[] =
   PREDRES_INSN ("dvp", 0xd50b73a0, 0xffffffe0, ic_system, OP2 (SYSREG_SR, Rt), QL_SRC_X, F_ALIAS),
   PREDRES_INSN ("cpp", 0xd50b73e0, 0xffffffe0, ic_system, OP2 (SYSREG_SR, Rt), QL_SRC_X, F_ALIAS),
   PREDRES2_INSN ("cosp", 0xd50b73c0, 0xffffffe0, ic_system, OP2 (SYSREG_SR, Rt), QL_SRC_X, F_ALIAS),
+  BRBE_INSN ("brb", 0xd5097280, 0xffffffc0, OP2 (BRBOP, Rt_IN_SYS_ALIASES), QL_IMM_NIL_NIL, F_ALIAS | F_OPD1_OPT | F_DEFAULT (0x1F)),
   /* Armv8.4-a flag setting instruction, However this encoding has an encoding clash with the msr
      below it.  Usually we can resolve this by setting an alias condition on the flags, however that
      depends on the disassembly masks to be able to quickly find the alias.  The problem is the
@@ -6836,6 +6847,10 @@  const struct aarch64_opcode aarch64_opcode_table[] =
       "the GCSB option name DSYNC")					\
     Y(SYSTEM, hint, "BTI_TARGET", 0, F (),				\
       "BTI targets j/c/jc")						\
+    Y(SYSTEM, imm, "BRBOP", 0, F(FLD_brbop),				\
+      "Branch Record Buffer operation operand")				\
+    Y(INT_REG, regno, "Rt_IN_SYS_ALIASES", 0, F(FLD_Rt),		\
+      "Rt register with defaults for SYS aliases")			\
     Y(INT_REG, regno, "LSE128_Rt", 0, F(FLD_LSE128_Rt), "an integer register") \
     Y(INT_REG, regno, "LSE128_Rt2", 0, F(FLD_LSE128_Rt2), "an integer register") \
     Y(ADDRESS, sve_addr_ri_s4, "SVE_ADDR_RI_S4x16",			\