[llvm] 8c1e520 - [AArch64] Adding "armv8.8-a" BC instruction.

Tomas Matheson via llvm-commits llvm-commits at lists.llvm.org
Mon Jan 3 04:34:34 PST 2022


Author: Simon Tatham
Date: 2022-01-03T12:33:51Z
New Revision: 8c1e520c903e0b7e758f8fbf4f1c3824f0d3efad

URL: https://github.com/llvm/llvm-project/commit/8c1e520c903e0b7e758f8fbf4f1c3824f0d3efad
DIFF: https://github.com/llvm/llvm-project/commit/8c1e520c903e0b7e758f8fbf4f1c3824f0d3efad.diff

LOG: [AArch64] Adding "armv8.8-a" BC instruction.

This instruction is described in the Arm A64 Instruction Set
Architecture documentation available here:
https://developer.arm.com/documentation/ddi0596/2021-12/Base-Instructions/BC-cond--Branch-Consistent-conditionally-?lang=en

FEAT_HBC "Hinted Conditional Branches" is listed in the 2021 A-Profile Architecture Extensions:
https://developer.arm.com/architectures/cpu-architecture/a-profile/exploration-tools/feature-names-for-a-profile

'BC.cc', where 'cc' is any ordinary condition code, is an instruction
that looks exactly like B.cc (the normal conditional branch), except
that bit 4 of the encoding is 1 rather than 0, which hints something
to the branch predictor (specifically, that this branch is expected to
be highly consistent, even though _which way_ it will consistently go
is not known at compile time).

This commit introduces a special subtarget feature for HBC, which is a
dependency of the top-level 8.8-A feature, and uses that to enable the
new BC instruction.

Differential Revision: https://reviews.llvm.org/D116156

Added: 
    llvm/test/MC/AArch64/armv8.8a-hbc.s
    llvm/test/MC/Disassembler/AArch64/armv8.8a-hbc.txt

Modified: 
    llvm/lib/Target/AArch64/AArch64.td
    llvm/lib/Target/AArch64/AArch64InstrFormats.td
    llvm/lib/Target/AArch64/AArch64InstrInfo.td
    llvm/lib/Target/AArch64/AArch64Subtarget.h
    llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Target/AArch64/AArch64.td b/llvm/lib/Target/AArch64/AArch64.td
index bc5f0c090d433..7a5dd4f6ae9ca 100644
--- a/llvm/lib/Target/AArch64/AArch64.td
+++ b/llvm/lib/Target/AArch64/AArch64.td
@@ -416,6 +416,9 @@ def FeatureHCX : SubtargetFeature<
 def FeatureLS64 : SubtargetFeature<"ls64", "HasLS64",
     "true", "Enable Armv8.7-A LD64B/ST64B Accelerator Extension">;
 
+def FeatureHBC : SubtargetFeature<"hbc", "HasHBC",
+    "true", "Enable Armv8.8-A Hinted Conditional Branches Extension">;
+
 def FeatureBRBE : SubtargetFeature<"brbe", "HasBRBE",
     "true", "Enable Branch Record Buffer Extension">;
 
@@ -499,7 +502,7 @@ def HasV8_7aOps : SubtargetFeature<
 
 def HasV8_8aOps : SubtargetFeature<
   "v8.8a", "HasV8_8aOps", "true", "Support ARM v8.8a instructions",
-  [HasV8_7aOps]>;
+  [HasV8_7aOps, FeatureHBC]>;
 
 def HasV9_0aOps : SubtargetFeature<
   "v9a", "HasV9_0aOps", "true", "Support ARM v9a instructions",

diff  --git a/llvm/lib/Target/AArch64/AArch64InstrFormats.td b/llvm/lib/Target/AArch64/AArch64InstrFormats.td
index f8d4921887440..7433552f7a531 100644
--- a/llvm/lib/Target/AArch64/AArch64InstrFormats.td
+++ b/llvm/lib/Target/AArch64/AArch64InstrFormats.td
@@ -1816,10 +1816,10 @@ def am_brcond : Operand<OtherVT> {
   let OperandType = "OPERAND_PCREL";
 }
 
-class BranchCond : I<(outs), (ins ccode:$cond, am_brcond:$target),
-                     "b", ".$cond\t$target", "",
-                     [(AArch64brcond bb:$target, imm:$cond, NZCV)]>,
-                   Sched<[WriteBr]> {
+class BranchCond<bit bit4, string mnemonic>
+   : I<(outs), (ins ccode:$cond, am_brcond:$target),
+       mnemonic, ".$cond\t$target", "",
+       [(AArch64brcond bb:$target, imm:$cond, NZCV)]>, Sched<[WriteBr]> {
   let isBranch = 1;
   let isTerminator = 1;
   let Uses = [NZCV];
@@ -1828,7 +1828,7 @@ class BranchCond : I<(outs), (ins ccode:$cond, am_brcond:$target),
   bits<19> target;
   let Inst{31-24} = 0b01010100;
   let Inst{23-5} = target;
-  let Inst{4} = 0;
+  let Inst{4} = bit4;
   let Inst{3-0} = cond;
 }
 

diff  --git a/llvm/lib/Target/AArch64/AArch64InstrInfo.td b/llvm/lib/Target/AArch64/AArch64InstrInfo.td
index efdc8e6f1be83..3fc94a0114c30 100644
--- a/llvm/lib/Target/AArch64/AArch64InstrInfo.td
+++ b/llvm/lib/Target/AArch64/AArch64InstrInfo.td
@@ -198,6 +198,8 @@ def HasBRBE          : Predicate<"Subtarget->hasBRBE()">,
                        AssemblerPredicate<(all_of FeatureBRBE), "brbe">;
 def HasSPE_EEF       : Predicate<"Subtarget->hasSPE_EEF()">,
                        AssemblerPredicate<(all_of FeatureSPE_EEF), "spe-eef">;
+def HasHBC            : Predicate<"Subtarget->hasHBC()">,
+                       AssemblerPredicate<(all_of FeatureHBC), "hbc">;
 def IsLE             : Predicate<"Subtarget->isLittleEndian()">;
 def IsBE             : Predicate<"!Subtarget->isLittleEndian()">;
 def IsWindows        : Predicate<"Subtarget->isTargetWindows()">;
@@ -2362,7 +2364,12 @@ def : Pat<(AArch64tlsdesc_callseq texternalsym:$sym),
 //===----------------------------------------------------------------------===//
 // Conditional branch (immediate) instruction.
 //===----------------------------------------------------------------------===//
-def Bcc : BranchCond;
+def Bcc : BranchCond<0, "b">;
+
+// Armv8.8-A variant form which hints to the branch predictor that
+// this branch is very likely to go the same way nearly all the time
+// (even though it is not known at compile time _which_ way that is).
+def BCcc : BranchCond<1, "bc">, Requires<[HasHBC]>;
 
 //===----------------------------------------------------------------------===//
 // Compare-and-branch instructions.

diff  --git a/llvm/lib/Target/AArch64/AArch64Subtarget.h b/llvm/lib/Target/AArch64/AArch64Subtarget.h
index 336c92d73e3ee..27cc99424ec3a 100644
--- a/llvm/lib/Target/AArch64/AArch64Subtarget.h
+++ b/llvm/lib/Target/AArch64/AArch64Subtarget.h
@@ -189,6 +189,9 @@ class AArch64Subtarget final : public AArch64GenSubtargetInfo {
   bool HasHCX = false;
   bool HasLS64 = false;
 
+  // Armv8.8-A Extensions
+  bool HasHBC = false;
+
   // Arm SVE2 extensions
   bool HasSVE2 = false;
   bool HasSVE2AES = false;
@@ -573,6 +576,7 @@ class AArch64Subtarget final : public AArch64GenSubtargetInfo {
   bool hasRCPC_IMMO() const { return HasRCPC_IMMO; }
   bool hasEL2VMSA() const { return HasEL2VMSA; }
   bool hasEL3() const { return HasEL3; }
+  bool hasHBC() const { return HasHBC; }
 
   bool fixCortexA53_835769() const { return FixCortexA53_835769; }
 

diff  --git a/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp b/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp
index 4f8f8078b69d6..13ff5e5b1d7ee 100644
--- a/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp
+++ b/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp
@@ -4533,7 +4533,7 @@ bool AArch64AsmParser::ParseInstruction(ParseInstructionInfo &Info,
   Mnemonic = Head;
 
   // Handle condition codes for a branch mnemonic
-  if (Head == "b" && Next != StringRef::npos) {
+  if ((Head == "b" || Head == "bc") && Next != StringRef::npos) {
     Start = Next;
     Next = Name.find('.', Start + 1);
     Head = Name.slice(Start + 1, Next);

diff  --git a/llvm/test/MC/AArch64/armv8.8a-hbc.s b/llvm/test/MC/AArch64/armv8.8a-hbc.s
new file mode 100644
index 0000000000000..c4c8d5feb34a8
--- /dev/null
+++ b/llvm/test/MC/AArch64/armv8.8a-hbc.s
@@ -0,0 +1,75 @@
+// RUN: llvm-mc -triple aarch64-none-linux-gnu -show-encoding -mattr=+hbc < %s | FileCheck %s
+// RUN: llvm-mc -triple aarch64-none-linux-gnu -show-encoding -mattr=+v8.8a < %s | FileCheck %s
+// RUN: not llvm-mc -triple aarch64-none-linux-gnu < %s 2>&1 | FileCheck --check-prefix=CHECK-NO-HBC-ERR %s
+
+lbl:
+        bc.eq lbl
+        bc.ne lbl
+        bc.cs lbl
+        bc.hs lbl
+        bc.lo lbl
+        bc.cc lbl
+        bc.mi lbl
+        bc.pl lbl
+        bc.vs lbl
+        bc.vc lbl
+        bc.hi lbl
+        bc.ls lbl
+        bc.ge lbl
+        bc.lt lbl
+        bc.gt lbl
+        bc.le lbl
+        bc.al lbl
+
+// CHECK: bc.eq lbl                    // encoding: [0bAAA10000,A,A,0x54]
+// CHECK:                              //   fixup A - offset: 0, value: lbl, kind: fixup_aarch64_pcrel_branch19
+// CHECK: bc.ne lbl                    // encoding: [0bAAA10001,A,A,0x54]
+// CHECK:                              //   fixup A - offset: 0, value: lbl, kind: fixup_aarch64_pcrel_branch19
+// CHECK: bc.hs lbl                    // encoding: [0bAAA10010,A,A,0x54]
+// CHECK:                              //   fixup A - offset: 0, value: lbl, kind: fixup_aarch64_pcrel_branch19
+// CHECK: bc.hs lbl                    // encoding: [0bAAA10010,A,A,0x54]
+// CHECK:                              //   fixup A - offset: 0, value: lbl, kind: fixup_aarch64_pcrel_branch19
+// CHECK: bc.lo lbl                    // encoding: [0bAAA10011,A,A,0x54]
+// CHECK:                              //   fixup A - offset: 0, value: lbl, kind: fixup_aarch64_pcrel_branch19
+// CHECK: bc.lo lbl                    // encoding: [0bAAA10011,A,A,0x54]
+// CHECK:                              //   fixup A - offset: 0, value: lbl, kind: fixup_aarch64_pcrel_branch19
+// CHECK: bc.mi lbl                    // encoding: [0bAAA10100,A,A,0x54]
+// CHECK:                              //   fixup A - offset: 0, value: lbl, kind: fixup_aarch64_pcrel_branch19
+// CHECK: bc.pl lbl                    // encoding: [0bAAA10101,A,A,0x54]
+// CHECK:                              //   fixup A - offset: 0, value: lbl, kind: fixup_aarch64_pcrel_branch19
+// CHECK: bc.vs lbl                    // encoding: [0bAAA10110,A,A,0x54]
+// CHECK:                              //   fixup A - offset: 0, value: lbl, kind: fixup_aarch64_pcrel_branch19
+// CHECK: bc.vc lbl                    // encoding: [0bAAA10111,A,A,0x54]
+// CHECK:                              //   fixup A - offset: 0, value: lbl, kind: fixup_aarch64_pcrel_branch19
+// CHECK: bc.hi lbl                    // encoding: [0bAAA11000,A,A,0x54]
+// CHECK:                              //   fixup A - offset: 0, value: lbl, kind: fixup_aarch64_pcrel_branch19
+// CHECK: bc.ls lbl                    // encoding: [0bAAA11001,A,A,0x54]
+// CHECK:                              //   fixup A - offset: 0, value: lbl, kind: fixup_aarch64_pcrel_branch19
+// CHECK: bc.ge lbl                    // encoding: [0bAAA11010,A,A,0x54]
+// CHECK:                              //   fixup A - offset: 0, value: lbl, kind: fixup_aarch64_pcrel_branch19
+// CHECK: bc.lt lbl                    // encoding: [0bAAA11011,A,A,0x54]
+// CHECK:                              //   fixup A - offset: 0, value: lbl, kind: fixup_aarch64_pcrel_branch19
+// CHECK: bc.gt lbl                    // encoding: [0bAAA11100,A,A,0x54]
+// CHECK:                              //   fixup A - offset: 0, value: lbl, kind: fixup_aarch64_pcrel_branch19
+// CHECK: bc.le lbl                    // encoding: [0bAAA11101,A,A,0x54]
+// CHECK:                              //   fixup A - offset: 0, value: lbl, kind: fixup_aarch64_pcrel_branch19
+// CHECK: bc.al lbl                    // encoding: [0bAAA11110,A,A,0x54]
+// CHECK:                              //   fixup A - offset: 0, value: lbl, kind: fixup_aarch64_pcrel_branch19
+
+// CHECK-NO-HBC-ERR: [[@LINE-53]]:9: error: instruction requires: hbc
+// CHECK-NO-HBC-ERR: [[@LINE-53]]:9: error: instruction requires: hbc
+// CHECK-NO-HBC-ERR: [[@LINE-53]]:9: error: instruction requires: hbc
+// CHECK-NO-HBC-ERR: [[@LINE-53]]:9: error: instruction requires: hbc
+// CHECK-NO-HBC-ERR: [[@LINE-53]]:9: error: instruction requires: hbc
+// CHECK-NO-HBC-ERR: [[@LINE-53]]:9: error: instruction requires: hbc
+// CHECK-NO-HBC-ERR: [[@LINE-53]]:9: error: instruction requires: hbc
+// CHECK-NO-HBC-ERR: [[@LINE-53]]:9: error: instruction requires: hbc
+// CHECK-NO-HBC-ERR: [[@LINE-53]]:9: error: instruction requires: hbc
+// CHECK-NO-HBC-ERR: [[@LINE-53]]:9: error: instruction requires: hbc
+// CHECK-NO-HBC-ERR: [[@LINE-53]]:9: error: instruction requires: hbc
+// CHECK-NO-HBC-ERR: [[@LINE-53]]:9: error: instruction requires: hbc
+// CHECK-NO-HBC-ERR: [[@LINE-53]]:9: error: instruction requires: hbc
+// CHECK-NO-HBC-ERR: [[@LINE-53]]:9: error: instruction requires: hbc
+// CHECK-NO-HBC-ERR: [[@LINE-53]]:9: error: instruction requires: hbc
+// CHECK-NO-HBC-ERR: [[@LINE-53]]:9: error: instruction requires: hbc
+// CHECK-NO-HBC-ERR: [[@LINE-53]]:9: error: instruction requires: hbc

diff  --git a/llvm/test/MC/Disassembler/AArch64/armv8.8a-hbc.txt b/llvm/test/MC/Disassembler/AArch64/armv8.8a-hbc.txt
new file mode 100644
index 0000000000000..c58c292785b0b
--- /dev/null
+++ b/llvm/test/MC/Disassembler/AArch64/armv8.8a-hbc.txt
@@ -0,0 +1,49 @@
+# RUN: llvm-mc -triple=aarch64 -mattr=+hbc -disassemble %s | FileCheck %s
+# RUN: llvm-mc -triple=aarch64 -mattr=+v8.8a -disassemble %s | FileCheck %s
+# RUN: not llvm-mc -triple=aarch64 -disassemble %s 2>&1 | FileCheck --check-prefix=ERROR-NO-HBC %s
+
+[0x30,0x00,0x00,0x54]
+# CHECK: bc.eq #4
+# ERROR-NO-HBC: [[@LINE-2]]:2: warning: invalid instruction encoding
+[0x51,0x00,0x00,0x54]
+# CHECK: bc.ne #8
+# ERROR-NO-HBC: [[@LINE-2]]:2: warning: invalid instruction encoding
+[0x92,0x00,0x00,0x54]
+# CHECK: bc.hs #16
+# ERROR-NO-HBC: [[@LINE-2]]:2: warning: invalid instruction encoding
+[0x13,0x01,0x00,0x54]
+# CHECK: bc.lo #32
+# ERROR-NO-HBC: [[@LINE-2]]:2: warning: invalid instruction encoding
+[0x14,0x02,0x00,0x54]
+# CHECK: bc.mi #64
+# ERROR-NO-HBC: [[@LINE-2]]:2: warning: invalid instruction encoding
+[0x15,0x04,0x00,0x54]
+# CHECK: bc.pl #128
+# ERROR-NO-HBC: [[@LINE-2]]:2: warning: invalid instruction encoding
+[0x16,0x08,0x00,0x54]
+# CHECK: bc.vs #256
+# ERROR-NO-HBC: [[@LINE-2]]:2: warning: invalid instruction encoding
+[0x17,0x10,0x00,0x54]
+# CHECK: bc.vc #512
+# ERROR-NO-HBC: [[@LINE-2]]:2: warning: invalid instruction encoding
+[0x18,0x20,0x00,0x54]
+# CHECK: bc.hi #1024
+# ERROR-NO-HBC: [[@LINE-2]]:2: warning: invalid instruction encoding
+[0x19,0x40,0x00,0x54]
+# CHECK: bc.ls #2048
+# ERROR-NO-HBC: [[@LINE-2]]:2: warning: invalid instruction encoding
+[0x1a,0x80,0x00,0x54]
+# CHECK: bc.ge #4096
+# ERROR-NO-HBC: [[@LINE-2]]:2: warning: invalid instruction encoding
+[0x1b,0x00,0x01,0x54]
+# CHECK: bc.lt #8192
+# ERROR-NO-HBC: [[@LINE-2]]:2: warning: invalid instruction encoding
+[0x1c,0x00,0x02,0x54]
+# CHECK: bc.gt #16384
+# ERROR-NO-HBC: [[@LINE-2]]:2: warning: invalid instruction encoding
+[0x1d,0x00,0x04,0x54]
+# CHECK: bc.le #32768
+# ERROR-NO-HBC: [[@LINE-2]]:2: warning: invalid instruction encoding
+[0x1e,0x00,0x08,0x54]
+# CHECK: bc.al #65536
+# ERROR-NO-HBC: [[@LINE-2]]:2: warning: invalid instruction encoding


        


More information about the llvm-commits mailing list