diff options
| -rw-r--r-- | llvm/lib/Target/AArch64/AArch64.td | 6 | ||||
| -rw-r--r-- | llvm/lib/Target/AArch64/AArch64InstrFormats.td | 15 | ||||
| -rw-r--r-- | llvm/lib/Target/AArch64/AArch64InstrInfo.td | 4 | ||||
| -rw-r--r-- | llvm/lib/Target/AArch64/AArch64Subtarget.h | 2 | ||||
| -rw-r--r-- | llvm/lib/Target/AArch64/AArch64SystemOperands.td | 17 | ||||
| -rw-r--r-- | llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp | 67 | ||||
| -rw-r--r-- | llvm/lib/Target/AArch64/InstPrinter/AArch64InstPrinter.cpp | 11 | ||||
| -rw-r--r-- | llvm/lib/Target/AArch64/InstPrinter/AArch64InstPrinter.h | 3 | ||||
| -rw-r--r-- | llvm/lib/Target/AArch64/Utils/AArch64BaseInfo.cpp | 7 | ||||
| -rw-r--r-- | llvm/lib/Target/AArch64/Utils/AArch64BaseInfo.h | 8 | ||||
| -rw-r--r-- | llvm/test/MC/AArch64/armv8.5a-bti-error.s | 12 | ||||
| -rw-r--r-- | llvm/test/MC/AArch64/armv8.5a-bti.s | 37 | ||||
| -rw-r--r-- | llvm/test/MC/Disassembler/AArch64/armv8.5a-bti.txt | 18 |
13 files changed, 206 insertions, 1 deletions
diff --git a/llvm/lib/Target/AArch64/AArch64.td b/llvm/lib/Target/AArch64/AArch64.td index b522c897498..587a4e1b92a 100644 --- a/llvm/lib/Target/AArch64/AArch64.td +++ b/llvm/lib/Target/AArch64/AArch64.td @@ -223,6 +223,9 @@ def FeaturePredCtrl : SubtargetFeature<"predctrl", "HasPredCtrl", "true", def FeatureCacheDeepPersist : SubtargetFeature<"ccdp", "HasCCDP", "true", "Enable Cache Clean to Point of Deep Persistence" >; +def FeatureBranchTargetId : SubtargetFeature<"bti", "HasBTI", + "true", "Enable Branch Target Identification" >; + def FeatureRandGen : SubtargetFeature<"rand", "HasRandGen", "true", "Enable Random Number generation instructions" >; @@ -245,7 +248,8 @@ def HasV8_4aOps : SubtargetFeature<"v8.4a", "HasV8_4aOps", "true", def HasV8_5aOps : SubtargetFeature< "v8.5a", "HasV8_5aOps", "true", "Support ARM v8.5a instructions", [HasV8_4aOps, FeatureAltFPCmp, FeatureFRInt3264, FeatureSpecRestrict, - FeatureSpecCtrl, FeaturePredCtrl, FeatureCacheDeepPersist] + FeatureSpecCtrl, FeaturePredCtrl, FeatureCacheDeepPersist, + FeatureBranchTargetId] >; //===----------------------------------------------------------------------===// diff --git a/llvm/lib/Target/AArch64/AArch64InstrFormats.td b/llvm/lib/Target/AArch64/AArch64InstrFormats.td index 8a24650610e..3920cdbfbb1 100644 --- a/llvm/lib/Target/AArch64/AArch64InstrFormats.td +++ b/llvm/lib/Target/AArch64/AArch64InstrFormats.td @@ -1149,6 +1149,21 @@ def psbhint_op : Operand<i32> { }]; } +def BTIHintOperand : AsmOperandClass { + let Name = "BTIHint"; + let ParserMethod = "tryParseBTIHint"; +} +def btihint_op : Operand<i32> { + let ParserMatchClass = BTIHintOperand; + let PrintMethod = "printBTIHintOp"; + let MCOperandPredicate = [{ + // "bti" is an alias to "hint" only for certain values of CRm:Op2 fields. + if (!MCOp.isImm()) + return false; + return AArch64BTIHint::lookupBTIByEncoding((MCOp.getImm() ^ 32) >> 1) != nullptr; + }]; +} + class MRSI : RtSystemI<1, (outs GPR64:$Rt), (ins mrs_sysreg_op:$systemreg), "mrs", "\t$Rt, $systemreg"> { bits<16> systemreg; diff --git a/llvm/lib/Target/AArch64/AArch64InstrInfo.td b/llvm/lib/Target/AArch64/AArch64InstrInfo.td index 004639e0b91..f6b798724d3 100644 --- a/llvm/lib/Target/AArch64/AArch64InstrInfo.td +++ b/llvm/lib/Target/AArch64/AArch64InstrInfo.td @@ -72,6 +72,8 @@ def HasPredCtrl : Predicate<"Subtarget->hasPredCtrl()">, AssemblerPredicate<"FeaturePredCtrl", "predctrl">; def HasCCDP : Predicate<"Subtarget->hasCCDP()">, AssemblerPredicate<"FeatureCacheDeepPersist", "ccdp">; +def HasBTI : Predicate<"Subtarget->hasBTI()">, + AssemblerPredicate<"FeatureBranchTargetId", "bti">; def IsLE : Predicate<"Subtarget->isLittleEndian()">; def IsBE : Predicate<"!Subtarget->isLittleEndian()">; def UseAlternateSExtLoadCVTF32 @@ -454,6 +456,8 @@ def : InstAlias<"sev", (HINT 0b100)>; def : InstAlias<"sevl", (HINT 0b101)>; def : InstAlias<"esb", (HINT 0b10000)>, Requires<[HasRAS]>; def : InstAlias<"csdb", (HINT 20)>; +def : InstAlias<"bti", (HINT 32)>, Requires<[HasBTI]>; +def : InstAlias<"bti $op", (HINT btihint_op:$op)>, Requires<[HasBTI]>; // v8.2a Statistical Profiling extension def : InstAlias<"psb $op", (HINT psbhint_op:$op)>, Requires<[HasSPE]>; diff --git a/llvm/lib/Target/AArch64/AArch64Subtarget.h b/llvm/lib/Target/AArch64/AArch64Subtarget.h index 5e6a4ec5861..e1d970345cb 100644 --- a/llvm/lib/Target/AArch64/AArch64Subtarget.h +++ b/llvm/lib/Target/AArch64/AArch64Subtarget.h @@ -101,6 +101,7 @@ protected: bool HasSpecCtrl = false; bool HasPredCtrl = false; bool HasCCDP = false; + bool HasBTI = false; bool HasRandGen = false; // HasZeroCycleRegMove - Has zero-cycle register mov instructions. @@ -321,6 +322,7 @@ public: bool hasSpecCtrl() { return HasSpecCtrl; } bool hasPredCtrl() { return HasPredCtrl; } bool hasCCDP() { return HasCCDP; } + bool hasBTI() { return HasBTI; } bool hasRandGen() { return HasRandGen; } bool isLittleEndian() const { return IsLittle; } diff --git a/llvm/lib/Target/AArch64/AArch64SystemOperands.td b/llvm/lib/Target/AArch64/AArch64SystemOperands.td index ab7d1769137..fe8c797b216 100644 --- a/llvm/lib/Target/AArch64/AArch64SystemOperands.td +++ b/llvm/lib/Target/AArch64/AArch64SystemOperands.td @@ -321,6 +321,23 @@ class PSB<string name, bits<5> encoding> : SearchableTable { def : PSB<"csync", 0x11>; //===----------------------------------------------------------------------===// +// BTI instruction options. +//===----------------------------------------------------------------------===// + +class BTI<string name, bits<2> encoding> : SearchableTable { + let SearchableFields = ["Name", "Encoding"]; + let EnumValueField = "Encoding"; + + string Name = name; + bits<2> Encoding; + let Encoding = encoding; +} + +def : BTI<"c", 0b01>; +def : BTI<"j", 0b10>; +def : BTI<"jc", 0b11>; + +//===----------------------------------------------------------------------===// // TLBI (translation lookaside buffer invalidate) instruction options. //===----------------------------------------------------------------------===// diff --git a/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp b/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp index d028cdc3d1c..a2c060ab2f2 100644 --- a/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp +++ b/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp @@ -202,6 +202,7 @@ private: template <bool IsSVEPrefetch = false> OperandMatchResultTy tryParsePrefetch(OperandVector &Operands); OperandMatchResultTy tryParsePSBHint(OperandVector &Operands); + OperandMatchResultTy tryParseBTIHint(OperandVector &Operands); OperandMatchResultTy tryParseAdrpLabel(OperandVector &Operands); OperandMatchResultTy tryParseAdrLabel(OperandVector &Operands); template<bool AddFPZeroAsLiteral> @@ -284,6 +285,7 @@ private: k_FPImm, k_Barrier, k_PSBHint, + k_BTIHint, } Kind; SMLoc StartLoc, EndLoc; @@ -387,6 +389,12 @@ private: unsigned Val; }; + struct BTIHintOp { + const char *Data; + unsigned Length; + unsigned Val; + }; + struct ExtendOp { unsigned Val; }; @@ -405,6 +413,7 @@ private: struct SysCRImmOp SysCRImm; struct PrefetchOp Prefetch; struct PSBHintOp PSBHint; + struct BTIHintOp BTIHint; struct ShiftExtendOp ShiftExtend; }; @@ -459,6 +468,9 @@ public: case k_PSBHint: PSBHint = o.PSBHint; break; + case k_BTIHint: + BTIHint = o.BTIHint; + break; case k_ShiftExtend: ShiftExtend = o.ShiftExtend; break; @@ -570,6 +582,16 @@ public: return StringRef(PSBHint.Data, PSBHint.Length); } + unsigned getBTIHint() const { + assert(Kind == k_BTIHint && "Invalid access!"); + return BTIHint.Val; + } + + StringRef getBTIHintName() const { + assert(Kind == k_BTIHint && "Invalid access!"); + return StringRef(BTIHint.Data, BTIHint.Length); + } + StringRef getPrefetchName() const { assert(Kind == k_Prefetch && "Invalid access!"); return StringRef(Prefetch.Data, Prefetch.Length); @@ -1188,6 +1210,7 @@ public: bool isSysCR() const { return Kind == k_SysCR; } bool isPrefetch() const { return Kind == k_Prefetch; } bool isPSBHint() const { return Kind == k_PSBHint; } + bool isBTIHint() const { return Kind == k_BTIHint; } bool isShiftExtend() const { return Kind == k_ShiftExtend; } bool isShifter() const { if (!isShiftExtend()) @@ -1705,6 +1728,11 @@ public: Inst.addOperand(MCOperand::createImm(getPSBHint())); } + void addBTIHintOperands(MCInst &Inst, unsigned N) const { + assert(N == 1 && "Invalid number of operands!"); + Inst.addOperand(MCOperand::createImm(getBTIHint())); + } + void addShifterOperands(MCInst &Inst, unsigned N) const { assert(N == 1 && "Invalid number of operands!"); unsigned Imm = @@ -1953,6 +1981,19 @@ public: return Op; } + static std::unique_ptr<AArch64Operand> CreateBTIHint(unsigned Val, + StringRef Str, + SMLoc S, + MCContext &Ctx) { + auto Op = make_unique<AArch64Operand>(k_BTIHint, Ctx); + Op->BTIHint.Val = Val << 1 | 32; + Op->BTIHint.Data = Str.data(); + Op->BTIHint.Length = Str.size(); + Op->StartLoc = S; + Op->EndLoc = S; + return Op; + } + static std::unique_ptr<AArch64Operand> CreateShiftExtend(AArch64_AM::ShiftExtendType ShOp, unsigned Val, bool HasExplicitAmount, SMLoc S, SMLoc E, MCContext &Ctx) { @@ -2033,6 +2074,9 @@ void AArch64Operand::print(raw_ostream &OS) const { if (!getShiftExtendAmount() && !hasShiftExtendAmount()) break; LLVM_FALLTHROUGH; + case k_BTIHint: + OS << getBTIHintName(); + break; case k_ShiftExtend: OS << "<" << AArch64_AM::getShiftExtendName(getShiftExtendType()) << " #" << getShiftExtendAmount(); @@ -2398,6 +2442,29 @@ AArch64AsmParser::tryParsePSBHint(OperandVector &Operands) { return MatchOperand_Success; } +/// tryParseBTIHint - Try to parse a BTI operand, mapped to Hint command +OperandMatchResultTy +AArch64AsmParser::tryParseBTIHint(OperandVector &Operands) { + MCAsmParser &Parser = getParser(); + SMLoc S = getLoc(); + const AsmToken &Tok = Parser.getTok(); + if (Tok.isNot(AsmToken::Identifier)) { + TokError("invalid operand for instruction"); + return MatchOperand_ParseFail; + } + + auto BTI = AArch64BTIHint::lookupBTIByName(Tok.getString()); + if (!BTI) { + TokError("invalid operand for instruction"); + return MatchOperand_ParseFail; + } + + Parser.Lex(); // Eat identifier token. + Operands.push_back(AArch64Operand::CreateBTIHint( + BTI->Encoding, Tok.getString(), S, getContext())); + return MatchOperand_Success; +} + /// tryParseAdrpLabel - Parse and validate a source label for the ADRP /// instruction. OperandMatchResultTy diff --git a/llvm/lib/Target/AArch64/InstPrinter/AArch64InstPrinter.cpp b/llvm/lib/Target/AArch64/InstPrinter/AArch64InstPrinter.cpp index da8b2812734..dcf2dd25114 100644 --- a/llvm/lib/Target/AArch64/InstPrinter/AArch64InstPrinter.cpp +++ b/llvm/lib/Target/AArch64/InstPrinter/AArch64InstPrinter.cpp @@ -1122,6 +1122,17 @@ void AArch64InstPrinter::printPSBHintOp(const MCInst *MI, unsigned OpNum, O << '#' << formatImm(psbhintop); } +void AArch64InstPrinter::printBTIHintOp(const MCInst *MI, unsigned OpNum, + const MCSubtargetInfo &STI, + raw_ostream &O) { + unsigned btihintop = (MI->getOperand(OpNum).getImm() ^ 32) >> 1; + auto BTI = AArch64BTIHint::lookupBTIByEncoding(btihintop); + if (BTI) + O << BTI->Name; + else + O << '#' << formatImm(btihintop); +} + void AArch64InstPrinter::printFPImmOperand(const MCInst *MI, unsigned OpNum, const MCSubtargetInfo &STI, raw_ostream &O) { diff --git a/llvm/lib/Target/AArch64/InstPrinter/AArch64InstPrinter.h b/llvm/lib/Target/AArch64/InstPrinter/AArch64InstPrinter.h index 8dc9264f94a..4e9982f5b7b 100644 --- a/llvm/lib/Target/AArch64/InstPrinter/AArch64InstPrinter.h +++ b/llvm/lib/Target/AArch64/InstPrinter/AArch64InstPrinter.h @@ -131,6 +131,9 @@ protected: void printPSBHintOp(const MCInst *MI, unsigned OpNum, const MCSubtargetInfo &STI, raw_ostream &O); + void printBTIHintOp(const MCInst *MI, unsigned OpNum, + const MCSubtargetInfo &STI, raw_ostream &O); + void printFPImmOperand(const MCInst *MI, unsigned OpNum, const MCSubtargetInfo &STI, raw_ostream &O); diff --git a/llvm/lib/Target/AArch64/Utils/AArch64BaseInfo.cpp b/llvm/lib/Target/AArch64/Utils/AArch64BaseInfo.cpp index 9c415aa8496..c88155db703 100644 --- a/llvm/lib/Target/AArch64/Utils/AArch64BaseInfo.cpp +++ b/llvm/lib/Target/AArch64/Utils/AArch64BaseInfo.cpp @@ -111,6 +111,13 @@ namespace llvm { } namespace llvm { + namespace AArch64BTIHint { +#define GET_BTI_IMPL +#include "AArch64GenSystemOperands.inc" + } +} + +namespace llvm { namespace AArch64SysReg { #define GET_SYSREG_IMPL #include "AArch64GenSystemOperands.inc" diff --git a/llvm/lib/Target/AArch64/Utils/AArch64BaseInfo.h b/llvm/lib/Target/AArch64/Utils/AArch64BaseInfo.h index 675adad2a69..b8d0977ae54 100644 --- a/llvm/lib/Target/AArch64/Utils/AArch64BaseInfo.h +++ b/llvm/lib/Target/AArch64/Utils/AArch64BaseInfo.h @@ -388,6 +388,14 @@ namespace AArch64PSBHint { #include "AArch64GenSystemOperands.inc" } +namespace AArch64BTIHint { + struct BTI : SysAlias { + using SysAlias::SysAlias; + }; + #define GET_BTI_DECL + #include "AArch64GenSystemOperands.inc" +} + namespace AArch64SE { enum ShiftExtSpecifiers { Invalid = -1, diff --git a/llvm/test/MC/AArch64/armv8.5a-bti-error.s b/llvm/test/MC/AArch64/armv8.5a-bti-error.s new file mode 100644 index 00000000000..bb0dea03ec8 --- /dev/null +++ b/llvm/test/MC/AArch64/armv8.5a-bti-error.s @@ -0,0 +1,12 @@ +// RUN: not llvm-mc -triple aarch64-none-linux-gnu -show-encoding -mattr=+bti < %s 2>&1 | FileCheck %s + +bti cj +bti a +bti x0 + +// CHECK: invalid operand for instruction +// CHECK-NEXT: cj +// CHECK: invalid operand for instruction +// CHECK-NEXT: a +// CHECK: invalid operand for instruction +// CHECK-NEXT: x0 diff --git a/llvm/test/MC/AArch64/armv8.5a-bti.s b/llvm/test/MC/AArch64/armv8.5a-bti.s new file mode 100644 index 00000000000..ca55516890c --- /dev/null +++ b/llvm/test/MC/AArch64/armv8.5a-bti.s @@ -0,0 +1,37 @@ +// RUN: llvm-mc -triple aarch64-none-linux-gnu -show-encoding -mattr=+bti < %s | FileCheck %s +// RUN: llvm-mc -triple aarch64-none-linux-gnu -show-encoding -mattr=+v8.5a < %s | FileCheck %s +// RUN: not llvm-mc -triple aarch64-none-linux-gnu -show-encoding -mattr=-bti < %s 2>&1 | FileCheck %s --check-prefix=NOBTI + +bti +bti c +bti j +bti jc + +// CHECK: bti // encoding: [0x1f,0x24,0x03,0xd5] +// CHECK: bti c // encoding: [0x5f,0x24,0x03,0xd5] +// CHECK: bti j // encoding: [0x9f,0x24,0x03,0xd5] +// CHECK: bti jc // encoding: [0xdf,0x24,0x03,0xd5] + +// NOBTI: instruction requires: bti +// NOBTI-NEXT: bti +// NOBTI: instruction requires: bti +// NOBTI-NEXT: bti +// NOBTI: instruction requires: bti +// NOBTI-NEXT: bti +// NOBTI: instruction requires: bti +// NOBTI-NEXT: bti + +hint #32 +hint #34 +hint #36 +hint #38 + +// CHECK: bti // encoding: [0x1f,0x24,0x03,0xd5] +// CHECK: bti c // encoding: [0x5f,0x24,0x03,0xd5] +// CHECK: bti j // encoding: [0x9f,0x24,0x03,0xd5] +// CHECK: bti jc // encoding: [0xdf,0x24,0x03,0xd5] + +// NOBTI: hint #32 // encoding: [0x1f,0x24,0x03,0xd5] +// NOBTI: hint #34 // encoding: [0x5f,0x24,0x03,0xd5] +// NOBTI: hint #36 // encoding: [0x9f,0x24,0x03,0xd5] +// NOBTI: hint #38 // encoding: [0xdf,0x24,0x03,0xd5] diff --git a/llvm/test/MC/Disassembler/AArch64/armv8.5a-bti.txt b/llvm/test/MC/Disassembler/AArch64/armv8.5a-bti.txt new file mode 100644 index 00000000000..e15dcf5e3b7 --- /dev/null +++ b/llvm/test/MC/Disassembler/AArch64/armv8.5a-bti.txt @@ -0,0 +1,18 @@ +# RUN: llvm-mc -triple=aarch64 -mattr=+bti -disassemble < %s | FileCheck %s +# RUN: llvm-mc -triple=aarch64 -mattr=+v8.5a -disassemble < %s | FileCheck %s +# RUN: llvm-mc -triple=aarch64 -mattr=-bti -disassemble < %s 2>&1 | FileCheck %s --check-prefix=NOBTI + +[0x1f 0x24 0x03 0xd5] +[0x5f 0x24 0x03 0xd5] +[0x9f 0x24 0x03 0xd5] +[0xdf 0x24 0x03 0xd5] + +# CHECK: bti +# CHECK: bti c +# CHECK: bti j +# CHECK: bti jc + +# NOBTI: hint #32 +# NOBTI: hint #34 +# NOBTI: hint #36 +# NOBTI: hint #38 |

