aarch64: Add BC instruction
authorRichard Sandiford <richard.sandiford@arm.com>
Thu, 2 Dec 2021 15:00:57 +0000 (15:00 +0000)
committerRichard Sandiford <richard.sandiford@arm.com>
Thu, 2 Dec 2021 15:00:57 +0000 (15:00 +0000)
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]

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
gas/doc/c-aarch64.texi
gas/testsuite/gas/aarch64/hbc-invalid.d [new file with mode: 0644]
gas/testsuite/gas/aarch64/hbc-invalid.l [new file with mode: 0644]
gas/testsuite/gas/aarch64/hbc-invalid.s [new file with mode: 0644]
gas/testsuite/gas/aarch64/hbc.d [new file with mode: 0644]
gas/testsuite/gas/aarch64/hbc.s [new file with mode: 0644]
include/opcode/aarch64.h
opcodes/aarch64-dis-2.c
opcodes/aarch64-tbl.h

index ea65da580deeb7091b19a885d3678d93e471ea5f..7277f38a4bb776fae01e6caf700b83e44d870170 100644 (file)
@@ -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},
 };
 
index 7edcccec7eb766ccaf85a525c52613e7297df38c..29bfd49207ffd0895153986aa9a19a6994b237c9 100644 (file)
@@ -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 (file)
index 0000000..f243de5
--- /dev/null
@@ -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 (file)
index 0000000..aef7a21
--- /dev/null
@@ -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 (file)
index 0000000..bc22087
--- /dev/null
@@ -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 (file)
index 0000000..baf963d
--- /dev/null
@@ -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 (file)
index 0000000..23af6ba
--- /dev/null
@@ -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
index 21ba0bf0074914f6664732257121a57cc688b951..4d4f108f39ae536e7c7b6bc72d83c5927a3aa431 100644 (file)
@@ -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))
index 70cbf908e812f3d5faaf19262a61f3db0214d4f4..37a0f8c80f6f7b02347b400c9905ce801b370589 100644 (file)
@@ -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;
-                                    }
                                 }
                             }
                         }
index 51d8532b8f296041b6fa4256ba6ed6806cfffe46..08721b13227851fb68f5fc393cce24cb3b26813d 100644 (file)
@@ -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, \
@@ -5417,6 +5422,8 @@ const struct aarch64_opcode aarch64_opcode_table[] =
      setge setget setgen setgetn  */
   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},
 };