[PATCH 09/10] aarch64: Add BC instruction

Richard Sandiford richard.sandiford@arm.com
Tue Nov 30 13:21:29 GMT 2021


This patch adds support for the Armv8.8-A BC instruction.
[https://developer.arm.com/documentation/ddi0596/2021-09/Base-Instructions/BC-cond--Branch-Consistent-conditionally-?lang=en]

Tested on aarch64-linux-gnu.  OK to install?

Richard


include/
	* opcode/aarch64.h (AARCH64_FEATURE_HBC): New macro.
	(AARCH64_ARCH_V8_8): Make armv8.8-a imply AARCH64_FEATURE_HBC.

opcodes/
	* aarch64-tbl.h (aarch64_feature_hbc): New variable.
	(HBC, HBC_INSN): New macros.
	(aarch64_opcode_table): Add BC.C.
	* aarch64-dis-2.c: Regenerate.

gas/
	* doc/c-aarch64.texi: Document +hbc.
	* config/tc-aarch64.c (aarch64_features): Add "hbc".
	* testsuite/gas/aarch64/hbc.s, testsuite/gas/aarch64/hbc.d: New test.
	* testsuite/gas/aarch64/hbc-invalid.s,
	testsuite/gas/aarch64/hbc-invalid.l,
	testsuite/gas/aarch64/hbc-invalid.d: New test.
---
 gas/config/tc-aarch64.c                 |   2 +
 gas/doc/c-aarch64.texi                  |   2 +
 gas/testsuite/gas/aarch64/hbc-invalid.d |   1 +
 gas/testsuite/gas/aarch64/hbc-invalid.l |   3 +
 gas/testsuite/gas/aarch64/hbc-invalid.s |   8 ++
 gas/testsuite/gas/aarch64/hbc.d         |  37 +++++++++
 gas/testsuite/gas/aarch64/hbc.s         |  37 +++++++++
 include/opcode/aarch64.h                |   4 +-
 opcodes/aarch64-dis-2.c                 | 105 +++++++++++++-----------
 opcodes/aarch64-tbl.h                   |   7 ++
 10 files changed, 158 insertions(+), 48 deletions(-)
 create mode 100644 gas/testsuite/gas/aarch64/hbc-invalid.d
 create mode 100644 gas/testsuite/gas/aarch64/hbc-invalid.l
 create mode 100644 gas/testsuite/gas/aarch64/hbc-invalid.s
 create mode 100644 gas/testsuite/gas/aarch64/hbc.d
 create mode 100644 gas/testsuite/gas/aarch64/hbc.s

diff --git a/gas/config/tc-aarch64.c b/gas/config/tc-aarch64.c
index ea65da580de..7277f38a4bb 100644
--- a/gas/config/tc-aarch64.c
+++ b/gas/config/tc-aarch64.c
@@ -9980,6 +9980,8 @@ static const struct aarch64_option_cpu_value_table aarch64_features[] = {
 			AARCH64_ARCH_NONE},
   {"mops",		AARCH64_FEATURE (AARCH64_FEATURE_MOPS, 0),
 			AARCH64_ARCH_NONE},
+  {"hbc",		AARCH64_FEATURE (AARCH64_FEATURE_HBC, 0),
+			AARCH64_ARCH_NONE},
   {NULL,		AARCH64_ARCH_NONE, AARCH64_ARCH_NONE},
 };
 
diff --git a/gas/doc/c-aarch64.texi b/gas/doc/c-aarch64.texi
index 7edcccec7eb..29bfd49207f 100644
--- a/gas/doc/c-aarch64.texi
+++ b/gas/doc/c-aarch64.texi
@@ -183,6 +183,8 @@ automatically cause those extensions to be disabled.
  @tab Enable ARMv8.2 16-bit floating-point support.  This implies @code{fp}.
 @item @code{fp} @tab ARMv8-A @tab ARMv8-A or later
  @tab Enable floating-point extensions.
+@item @code{hbc} @tab @tab Armv8.8-A or later
+ @tab Enable Armv8.8-A hinted conditional branch instructions
 @item @code{i8mm} @tab ARMv8.2-A @tab ARMv8.6-A or later
  @tab Enable Int8 Matrix Multiply extension.
 @item @code{lor} @tab ARMv8-A @tab ARMv8.1-A or later
diff --git a/gas/testsuite/gas/aarch64/hbc-invalid.d b/gas/testsuite/gas/aarch64/hbc-invalid.d
new file mode 100644
index 00000000000..f243de547f6
--- /dev/null
+++ b/gas/testsuite/gas/aarch64/hbc-invalid.d
@@ -0,0 +1 @@
+#error_output: hbc-invalid.l
diff --git a/gas/testsuite/gas/aarch64/hbc-invalid.l b/gas/testsuite/gas/aarch64/hbc-invalid.l
new file mode 100644
index 00000000000..aef7a21c1dd
--- /dev/null
+++ b/gas/testsuite/gas/aarch64/hbc-invalid.l
@@ -0,0 +1,3 @@
+[^:]*: Assembler messages:
+[^:]*:4: Error: selected processor does not support `bc.eq 1b'
+[^:]*:8: Error: selected processor does not support `bc.eq 1b'
diff --git a/gas/testsuite/gas/aarch64/hbc-invalid.s b/gas/testsuite/gas/aarch64/hbc-invalid.s
new file mode 100644
index 00000000000..bc2208755d9
--- /dev/null
+++ b/gas/testsuite/gas/aarch64/hbc-invalid.s
@@ -0,0 +1,8 @@
+	.arch	armv8.7-a
+
+1:
+	bc.eq	1b
+
+	.arch	armv8.7-a+mops
+
+	bc.eq	1b
diff --git a/gas/testsuite/gas/aarch64/hbc.d b/gas/testsuite/gas/aarch64/hbc.d
new file mode 100644
index 00000000000..baf963d4d1f
--- /dev/null
+++ b/gas/testsuite/gas/aarch64/hbc.d
@@ -0,0 +1,37 @@
+# objdump: -dr
+
+.*
+
+
+Disassembly of section \.text:
+
+0+ <\.text>:
+[^:]*:	54000010 	bc\.eq	0 <\.text>  // bc\.none
+[^:]*:	54fffff1 	bc\.ne	0 <\.text>  // bc\.any
+[^:]*:	54ffffd9 	bc\.ls	0 <\.text>  // bc\.plast
+[^:]*:	54ffffb3 	bc\.cc	0 <\.text>  // bc\.lo, bc\.ul, bc\.last
+[^:]*:	54ffff98 	bc\.hi	0 <\.text>  // bc\.pmore
+[^:]*:	54ffff72 	bc\.cs	0 <\.text>  // bc\.hs, bc\.nlast
+[^:]*:	54ffff58 	bc\.hi	0 <\.text>  // bc\.pmore
+[^:]*:	54ffff3b 	bc\.lt	0 <\.text>  // bc\.tstop
+[^:]*:	54ffff1d 	bc\.le	0 <\.text>
+[^:]*:	54fffefc 	bc\.gt	0 <\.text>
+[^:]*:	54fffeda 	bc\.ge	0 <\.text>  // bc\.tcont
+[^:]*:	54fffeb3 	bc\.cc	0 <\.text>  // bc\.lo, bc\.ul, bc\.last
+[^:]*:	54fffe92 	bc\.cs	0 <\.text>  // bc\.hs, bc\.nlast
+[^:]*:	54fffe76 	bc\.vs	0 <\.text>
+[^:]*:	54fffe57 	bc\.vc	0 <\.text>
+[^:]*:	54fffe34 	bc\.mi	0 <\.text>  // bc\.first
+[^:]*:	54fffe15 	bc\.pl	0 <\.text>  // bc\.nfrst
+[^:]*:	54fffdf3 	bc\.cc	0 <\.text>  // bc\.lo, bc\.ul, bc\.last
+[^:]*:	54fffdd1 	bc\.ne	0 <\.text>  // bc\.any
+[^:]*:	54fffdb0 	bc\.eq	0 <\.text>  // bc\.none
+[^:]*:	54fffd94 	bc\.mi	0 <\.text>  // bc\.first
+[^:]*:	54fffd75 	bc\.pl	0 <\.text>  // bc\.nfrst
+[^:]*:	54fffd53 	bc\.cc	0 <\.text>  // bc\.lo, bc\.ul, bc\.last
+[^:]*:	54fffd32 	bc\.cs	0 <\.text>  // bc\.hs, bc\.nlast
+[^:]*:	54fffd18 	bc\.hi	0 <\.text>  // bc\.pmore
+[^:]*:	54fffcf9 	bc\.ls	0 <\.text>  // bc\.plast
+[^:]*:	54fffcda 	bc\.ge	0 <\.text>  // bc\.tcont
+[^:]*:	54fffcbb 	bc\.lt	0 <\.text>  // bc\.tstop
+[^:]*:	54fffc90 	bc\.eq	0 <\.text>  // bc\.none
diff --git a/gas/testsuite/gas/aarch64/hbc.s b/gas/testsuite/gas/aarch64/hbc.s
new file mode 100644
index 00000000000..23af6ba8edd
--- /dev/null
+++ b/gas/testsuite/gas/aarch64/hbc.s
@@ -0,0 +1,37 @@
+	.arch	armv8.8-a
+
+1:
+	bc.eq	1b
+	bc.ne	1b
+	bc.ls	1b
+	bc.lo	1b
+	bc.hi	1b
+	bc.hs	1b
+	bc.hi	1b
+	bc.lt	1b
+	bc.le	1b
+	bc.gt	1b
+	bc.ge	1b
+	bc.cc	1b
+	bc.cs	1b
+	bc.vs	1b
+	bc.vc	1b
+	bc.mi	1b
+	bc.pl	1b
+
+	bc.ul	1b
+
+	bc.any   1b
+	bc.none  1b
+	bc.first 1b
+	bc.nfrst 1b
+	bc.last  1b
+	bc.nlast 1b
+	bc.pmore 1b
+	bc.plast 1b
+	bc.tcont 1b
+	bc.tstop 1b
+
+	.arch	armv8.7-a+hbc
+
+	bc.eq	1b
diff --git a/include/opcode/aarch64.h b/include/opcode/aarch64.h
index 21ba0bf0074..4d4f108f39a 100644
--- a/include/opcode/aarch64.h
+++ b/include/opcode/aarch64.h
@@ -88,6 +88,7 @@ typedef uint32_t aarch64_insn;
 #define AARCH64_FEATURE_MEMTAG       (1ULL << 48) /* Memory Tagging Extension.  */
 #define AARCH64_FEATURE_TME	     (1ULL << 49) /* Transactional Memory Extension.  */
 #define AARCH64_FEATURE_MOPS	     (1ULL << 50) /* Standardization of memory operations.  */
+#define AARCH64_FEATURE_HBC	     (1ULL << 51) /* Hinted conditional branches.  */
 #define AARCH64_FEATURE_I8MM	     (1ULL << 52) /* Matrix Multiply instructions.  */
 #define AARCH64_FEATURE_F32MM	     (1ULL << 53)
 #define AARCH64_FEATURE_F64MM	     (1ULL << 54)
@@ -145,7 +146,8 @@ typedef uint32_t aarch64_insn;
 						 | AARCH64_FEATURE_LS64)
 #define AARCH64_ARCH_V8_8	AARCH64_FEATURE (AARCH64_ARCH_V8_7,	\
 						 AARCH64_FEATURE_V8_8	\
-						 | AARCH64_FEATURE_MOPS)
+						 | AARCH64_FEATURE_MOPS	\
+						 | AARCH64_FEATURE_HBC)
 #define AARCH64_ARCH_V8_R	(AARCH64_FEATURE (AARCH64_ARCH_V8_4,	\
 						 AARCH64_FEATURE_V8_R)	\
 			      & ~(AARCH64_FEATURE_V8_A | AARCH64_FEATURE_LOR))
diff --git a/opcodes/aarch64-dis-2.c b/opcodes/aarch64-dis-2.c
index 70cbf908e81..37a0f8c80f6 100644
--- a/opcodes/aarch64-dis-2.c
+++ b/opcodes/aarch64-dis-2.c
@@ -16913,87 +16913,98 @@ aarch64_opcode_lookup_1 (uint32_t word)
                             }
                           else
                             {
-                              if (((word >> 10) & 0x1) == 0)
+                              if (((word >> 25) & 0x1) == 0)
                                 {
-                                  if (((word >> 21) & 0x1) == 0)
+                                  /* 33222222222211111111110000000000
+                                     10987654321098765432109876543210
+                                     x1010100xxxxxxxxxxxxxxxxxxx1xxxx
+                                     bc.c.  */
+                                  return 2631;
+                                }
+                              else
+                                {
+                                  if (((word >> 10) & 0x1) == 0)
                                     {
-                                      if (((word >> 22) & 0x1) == 0)
+                                      if (((word >> 21) & 0x1) == 0)
                                         {
-                                          if (((word >> 23) & 0x1) == 0)
+                                          if (((word >> 22) & 0x1) == 0)
                                             {
-                                              /* 33222222222211111111110000000000
-                                                 10987654321098765432109876543210
-                                                 x10101x0000xxxxxxxxxx0xxxxx1xxxx
-                                                 braaz.  */
-                                              return 647;
+                                              if (((word >> 23) & 0x1) == 0)
+                                                {
+                                                  /* 33222222222211111111110000000000
+                                                     10987654321098765432109876543210
+                                                     x1010110000xxxxxxxxxx0xxxxx1xxxx
+                                                     braaz.  */
+                                                  return 647;
+                                                }
+                                              else
+                                                {
+                                                  /* 33222222222211111111110000000000
+                                                     10987654321098765432109876543210
+                                                     x1010110100xxxxxxxxxx0xxxxx1xxxx
+                                                     eretaa.  */
+                                                  return 653;
+                                                }
                                             }
                                           else
                                             {
                                               /* 33222222222211111111110000000000
                                                  10987654321098765432109876543210
-                                                 x10101x0100xxxxxxxxxx0xxxxx1xxxx
-                                                 eretaa.  */
-                                              return 653;
+                                                 x1010110x10xxxxxxxxxx0xxxxx1xxxx
+                                                 retaa.  */
+                                              return 651;
                                             }
                                         }
                                       else
                                         {
                                           /* 33222222222211111111110000000000
                                              10987654321098765432109876543210
-                                             x10101x0x10xxxxxxxxxx0xxxxx1xxxx
-                                             retaa.  */
-                                          return 651;
+                                             x1010110xx1xxxxxxxxxx0xxxxx1xxxx
+                                             blraaz.  */
+                                          return 649;
                                         }
                                     }
                                   else
                                     {
-                                      /* 33222222222211111111110000000000
-                                         10987654321098765432109876543210
-                                         x10101x0xx1xxxxxxxxxx0xxxxx1xxxx
-                                         blraaz.  */
-                                      return 649;
-                                    }
-                                }
-                              else
-                                {
-                                  if (((word >> 21) & 0x1) == 0)
-                                    {
-                                      if (((word >> 22) & 0x1) == 0)
+                                      if (((word >> 21) & 0x1) == 0)
                                         {
-                                          if (((word >> 23) & 0x1) == 0)
+                                          if (((word >> 22) & 0x1) == 0)
                                             {
-                                              /* 33222222222211111111110000000000
-                                                 10987654321098765432109876543210
-                                                 x10101x0000xxxxxxxxxx1xxxxx1xxxx
-                                                 brabz.  */
-                                              return 648;
+                                              if (((word >> 23) & 0x1) == 0)
+                                                {
+                                                  /* 33222222222211111111110000000000
+                                                     10987654321098765432109876543210
+                                                     x1010110000xxxxxxxxxx1xxxxx1xxxx
+                                                     brabz.  */
+                                                  return 648;
+                                                }
+                                              else
+                                                {
+                                                  /* 33222222222211111111110000000000
+                                                     10987654321098765432109876543210
+                                                     x1010110100xxxxxxxxxx1xxxxx1xxxx
+                                                     eretab.  */
+                                                  return 654;
+                                                }
                                             }
                                           else
                                             {
                                               /* 33222222222211111111110000000000
                                                  10987654321098765432109876543210
-                                                 x10101x0100xxxxxxxxxx1xxxxx1xxxx
-                                                 eretab.  */
-                                              return 654;
+                                                 x1010110x10xxxxxxxxxx1xxxxx1xxxx
+                                                 retab.  */
+                                              return 652;
                                             }
                                         }
                                       else
                                         {
                                           /* 33222222222211111111110000000000
                                              10987654321098765432109876543210
-                                             x10101x0x10xxxxxxxxxx1xxxxx1xxxx
-                                             retab.  */
-                                          return 652;
+                                             x1010110xx1xxxxxxxxxx1xxxxx1xxxx
+                                             blrabz.  */
+                                          return 650;
                                         }
                                     }
-                                  else
-                                    {
-                                      /* 33222222222211111111110000000000
-                                         10987654321098765432109876543210
-                                         x10101x0xx1xxxxxxxxxx1xxxxx1xxxx
-                                         blrabz.  */
-                                      return 650;
-                                    }
                                 }
                             }
                         }
diff --git a/opcodes/aarch64-tbl.h b/opcodes/aarch64-tbl.h
index 67a24d21e02..b844c535843 100644
--- a/opcodes/aarch64-tbl.h
+++ b/opcodes/aarch64-tbl.h
@@ -2497,6 +2497,8 @@ static const aarch64_feature_set aarch64_feature_mops =
   AARCH64_FEATURE (AARCH64_FEATURE_MOPS, 0);
 static const aarch64_feature_set aarch64_feature_mops_memtag =
   AARCH64_FEATURE (AARCH64_FEATURE_MOPS | AARCH64_FEATURE_MEMTAG, 0);
+static const aarch64_feature_set aarch64_feature_hbc =
+  AARCH64_FEATURE (AARCH64_FEATURE_HBC, 0);
 
 #define CORE		&aarch64_feature_v8
 #define FP		&aarch64_feature_fp
@@ -2550,6 +2552,7 @@ static const aarch64_feature_set aarch64_feature_mops_memtag =
 #define FLAGM	  &aarch64_feature_flagm
 #define MOPS	  &aarch64_feature_mops
 #define MOPS_MEMTAG &aarch64_feature_mops_memtag
+#define HBC	  &aarch64_feature_hbc
 
 #define CORE_INSN(NAME,OPCODE,MASK,CLASS,OP,OPS,QUALS,FLAGS) \
   { NAME, OPCODE, MASK, CLASS, OP, CORE, OPS, QUALS, FLAGS, 0, 0, NULL }
@@ -2681,6 +2684,8 @@ static const aarch64_feature_set aarch64_feature_mops_memtag =
 #define MOPS_MEMTAG_INSN(NAME, OPCODE, MASK, CLASS, OPS, QUALS, FLAGS, CONSTRAINTS, VERIFIER) \
   { NAME, OPCODE, MASK, CLASS, 0, MOPS_MEMTAG, OPS, QUALS, FLAGS, \
     CONSTRAINTS, 0, VERIFIER }
+#define HBC_INSN(NAME,OPCODE,MASK,CLASS,OPS,QUALS,FLAGS) \
+  { NAME, OPCODE, MASK, CLASS, 0, HBC, OPS, QUALS, FLAGS, 0, 0, NULL }
 
 #define MOPS_CPY_OP1_OP2_PME_INSN(NAME, OPCODE, MASK, FLAGS, CONSTRAINTS) \
   MOPS_INSN (NAME, OPCODE, MASK, 0, \
@@ -5376,6 +5381,8 @@ const struct aarch64_opcode aarch64_opcode_table[] =
   MOPS_CPY_INSN ("cpy", 0x1d000400, 0xffe0fc00),
   MOPS_SET_INSN ("set", 0x19c00400, 0xffe0fc00, MOPS_INSN),
   MOPS_SET_INSN ("setg", 0x1dc00400, 0xffe0fc00, MOPS_MEMTAG_INSN),
+  HBC_INSN ("bc.c", 0x54000010, 0xff000010, condbranch, OP1 (ADDR_PCREL19), QL_PCREL_NIL, F_COND),
+
   {0, 0, 0, 0, 0, 0, {}, {}, 0, 0, 0, NULL},
 };
 
-- 
2.25.1



More information about the Binutils mailing list