[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