summaryrefslogtreecommitdiffstats
path: root/llvm/lib
diff options
context:
space:
mode:
authorOliver Stannard <oliver.stannard@arm.com>2018-09-27 13:47:40 +0000
committerOliver Stannard <oliver.stannard@arm.com>2018-09-27 13:47:40 +0000
commit224428c06a24303b2200aa98d719f080570fcb9f (patch)
tree25c0c4961fc15264a0047b3832c0956337f57404 /llvm/lib
parent382c935c4231eaf7b820cb207c9fbd0c50505181 (diff)
downloadbcm5719-llvm-224428c06a24303b2200aa98d719f080570fcb9f.tar.gz
bcm5719-llvm-224428c06a24303b2200aa98d719f080570fcb9f.zip
[AArch64][v8.5A] Add prediction invalidation instructions to AArch64
This adds new system instructions which act as barriers to speculative execution based on earlier execution within a particular execution context. Patch by Pablo Barrio! Differential revision: https://reviews.llvm.org/D52479 llvm-svn: 343214
Diffstat (limited to 'llvm/lib')
-rw-r--r--llvm/lib/Target/AArch64/AArch64.td6
-rw-r--r--llvm/lib/Target/AArch64/AArch64InstrInfo.td2
-rw-r--r--llvm/lib/Target/AArch64/AArch64Subtarget.h2
-rw-r--r--llvm/lib/Target/AArch64/AArch64SystemOperands.td17
-rw-r--r--llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp24
-rw-r--r--llvm/lib/Target/AArch64/InstPrinter/AArch64InstPrinter.cpp27
-rw-r--r--llvm/lib/Target/AArch64/Utils/AArch64BaseInfo.cpp7
-rw-r--r--llvm/lib/Target/AArch64/Utils/AArch64BaseInfo.h8
8 files changed, 89 insertions, 4 deletions
diff --git a/llvm/lib/Target/AArch64/AArch64.td b/llvm/lib/Target/AArch64/AArch64.td
index 79bae03b4b8..8d2085030c0 100644
--- a/llvm/lib/Target/AArch64/AArch64.td
+++ b/llvm/lib/Target/AArch64/AArch64.td
@@ -214,6 +214,9 @@ def FeatureFRInt3264 : SubtargetFeature<"fptoint", "HasFRInt3264", "true",
def FeatureSpecCtrl : SubtargetFeature<"specctrl", "HasSpecCtrl", "true",
"Enable speculation control barrier" >;
+def FeaturePredCtrl : SubtargetFeature<"predctrl", "HasPredCtrl", "true",
+ "Enable execution and data prediction invalidation instructions" >;
+
//===----------------------------------------------------------------------===//
// Architectures.
//
@@ -232,7 +235,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, FeatureSpecCtrl]
+ [HasV8_4aOps, FeatureAltFPCmp, FeatureFRInt3264, FeatureSpecCtrl,
+ FeaturePredCtrl]
>;
//===----------------------------------------------------------------------===//
diff --git a/llvm/lib/Target/AArch64/AArch64InstrInfo.td b/llvm/lib/Target/AArch64/AArch64InstrInfo.td
index 310c1b60bf7..1192fad94bd 100644
--- a/llvm/lib/Target/AArch64/AArch64InstrInfo.td
+++ b/llvm/lib/Target/AArch64/AArch64InstrInfo.td
@@ -68,6 +68,8 @@ def HasFRInt3264 : Predicate<"Subtarget->hasFRInt3264()">,
AssemblerPredicate<"FeatureFRInt3264", "frint3264">;
def HasSpecCtrl : Predicate<"Subtarget->hasSpecCtrl()">,
AssemblerPredicate<"FeatureSpecCtrl", "specctrl">;
+def HasPredCtrl : Predicate<"Subtarget->hasPredCtrl()">,
+ AssemblerPredicate<"FeaturePredCtrl", "predctrl">;
def IsLE : Predicate<"Subtarget->isLittleEndian()">;
def IsBE : Predicate<"!Subtarget->isLittleEndian()">;
def UseAlternateSExtLoadCVTF32
diff --git a/llvm/lib/Target/AArch64/AArch64Subtarget.h b/llvm/lib/Target/AArch64/AArch64Subtarget.h
index 8df6e5a6570..cc901e1c644 100644
--- a/llvm/lib/Target/AArch64/AArch64Subtarget.h
+++ b/llvm/lib/Target/AArch64/AArch64Subtarget.h
@@ -98,6 +98,7 @@ protected:
bool HasAlternativeNZCV = false;
bool HasFRInt3264 = false;
bool HasSpecCtrl = false;
+ bool HasPredCtrl = false;
// HasZeroCycleRegMove - Has zero-cycle register mov instructions.
bool HasZeroCycleRegMove = false;
@@ -314,6 +315,7 @@ public:
bool hasAlternativeNZCV() const { return HasAlternativeNZCV; }
bool hasFRInt3264() const { return HasFRInt3264; }
bool hasSpecCtrl() { return HasSpecCtrl; }
+ bool hasPredCtrl() { return HasPredCtrl; }
bool isLittleEndian() const { return IsLittle; }
diff --git a/llvm/lib/Target/AArch64/AArch64SystemOperands.td b/llvm/lib/Target/AArch64/AArch64SystemOperands.td
index dbc4deaf3f9..1b3887ed5e0 100644
--- a/llvm/lib/Target/AArch64/AArch64SystemOperands.td
+++ b/llvm/lib/Target/AArch64/AArch64SystemOperands.td
@@ -420,6 +420,23 @@ def : TLBI<"RVAE3OS", 0b110, 0b1000, 0b0101, 0b001>;
def : TLBI<"RVALE3OS", 0b110, 0b1000, 0b0101, 0b101>;
}
+// Armv8.5-A Prediction Restriction by Context instruction options:
+class PRCTX<string name, bits<4> crm> : SearchableTable {
+ let SearchableFields = ["Name", "Encoding"];
+ let EnumValueField = "Encoding";
+
+ string Name = name;
+ bits<11> Encoding;
+ let Encoding{10-4} = 0b0110111;
+ let Encoding{3-0} = crm;
+ bit NeedsReg = 1;
+ code Requires = [{ {} }];
+}
+
+let Requires = [{ {AArch64::FeaturePredCtrl} }] in {
+def : PRCTX<"RCTX", 0b0011>;
+}
+
//===----------------------------------------------------------------------===//
// MRS/MSR (system register read/write) instruction options.
//===----------------------------------------------------------------------===//
diff --git a/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp b/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp
index 0f156185387..acbea2b5dcf 100644
--- a/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp
+++ b/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp
@@ -2756,6 +2756,7 @@ static const struct Extension {
{ "simd", {AArch64::FeatureNEON} },
{ "ras", {AArch64::FeatureRAS} },
{ "lse", {AArch64::FeatureLSE} },
+ { "predctrl", {AArch64::FeaturePredCtrl} },
// FIXME: Unsupported extensions
{ "pan", {} },
@@ -2864,6 +2865,23 @@ bool AArch64AsmParser::parseSysAlias(StringRef Name, SMLoc NameLoc,
return TokError(Str.c_str());
}
createSysAlias(TLBI->Encoding, Operands, S);
+ } else if (Mnemonic == "cfp" || Mnemonic == "dvp" || Mnemonic == "cpp") {
+ const AArch64PRCTX::PRCTX *PRCTX = AArch64PRCTX::lookupPRCTXByName(Op);
+ if (!PRCTX)
+ return TokError("invalid operand for prediction restriction instruction");
+ else if (!PRCTX->haveFeatures(getSTI().getFeatureBits())) {
+ std::string Str(
+ Mnemonic.upper() + std::string(PRCTX->Name) + " requires ");
+ setRequiredFeatureString(PRCTX->getRequiredFeatures(), Str);
+ return TokError(Str.c_str());
+ }
+ uint16_t PRCTX_Op2 =
+ Mnemonic == "cfp" ? 4 :
+ Mnemonic == "dvp" ? 5 :
+ Mnemonic == "cpp" ? 7 :
+ 0;
+ assert(PRCTX_Op2 && "Invalid mnemonic for prediction restriction instruction");
+ createSysAlias(PRCTX->Encoding << 3 | PRCTX_Op2 , Operands, S);
}
Parser.Lex(); // Eat operand.
@@ -3682,8 +3700,10 @@ bool AArch64AsmParser::ParseInstruction(ParseInstructionInfo &Info,
size_t Start = 0, Next = Name.find('.');
StringRef Head = Name.slice(Start, Next);
- // IC, DC, AT, and TLBI instructions are aliases for the SYS instruction.
- if (Head == "ic" || Head == "dc" || Head == "at" || Head == "tlbi")
+ // IC, DC, AT, TLBI and Prediction invalidation instructions are aliases for
+ // the SYS instruction.
+ if (Head == "ic" || Head == "dc" || Head == "at" || Head == "tlbi" ||
+ Head == "cfp" || Head == "dvp" || Head == "cpp")
return parseSysAlias(Head, NameLoc, Operands);
Operands.push_back(
diff --git a/llvm/lib/Target/AArch64/InstPrinter/AArch64InstPrinter.cpp b/llvm/lib/Target/AArch64/InstPrinter/AArch64InstPrinter.cpp
index 26e41215afc..aa537abf6ab 100644
--- a/llvm/lib/Target/AArch64/InstPrinter/AArch64InstPrinter.cpp
+++ b/llvm/lib/Target/AArch64/InstPrinter/AArch64InstPrinter.cpp
@@ -775,8 +775,33 @@ bool AArch64InstPrinter::printSysAlias(const MCInst *MI,
if (CnVal == 7) {
switch (CmVal) {
default: return false;
+ // Maybe IC, maybe Prediction Restriction
+ case 1:
+ switch (Op1Val) {
+ default: return false;
+ case 0: goto Search_IC;
+ case 3: goto Search_PRCTX;
+ }
+ // Prediction Restriction aliases
+ case 3: {
+ Search_PRCTX:
+ const AArch64PRCTX::PRCTX *PRCTX = AArch64PRCTX::lookupPRCTXByEncoding(Encoding >> 3);
+ if (!PRCTX || !PRCTX->haveFeatures(STI.getFeatureBits()))
+ return false;
+
+ NeedsReg = PRCTX->NeedsReg;
+ switch (Op2Val) {
+ default: return false;
+ case 4: Ins = "cfp\t"; break;
+ case 5: Ins = "dvp\t"; break;
+ case 7: Ins = "cpp\t"; break;
+ }
+ Name = std::string(PRCTX->Name);
+ }
+ break;
// IC aliases
- case 1: case 5: {
+ case 5: {
+ Search_IC:
const AArch64IC::IC *IC = AArch64IC::lookupICByEncoding(Encoding);
if (!IC || !IC->haveFeatures(STI.getFeatureBits()))
return false;
diff --git a/llvm/lib/Target/AArch64/Utils/AArch64BaseInfo.cpp b/llvm/lib/Target/AArch64/Utils/AArch64BaseInfo.cpp
index 23cc21ce2e7..9c415aa8496 100644
--- a/llvm/lib/Target/AArch64/Utils/AArch64BaseInfo.cpp
+++ b/llvm/lib/Target/AArch64/Utils/AArch64BaseInfo.cpp
@@ -62,6 +62,13 @@ namespace llvm {
}
namespace llvm {
+ namespace AArch64PRCTX {
+#define GET_PRCTX_IMPL
+#include "AArch64GenSystemOperands.inc"
+ }
+}
+
+namespace llvm {
namespace AArch64PRFM {
#define GET_PRFM_IMPL
#include "AArch64GenSystemOperands.inc"
diff --git a/llvm/lib/Target/AArch64/Utils/AArch64BaseInfo.h b/llvm/lib/Target/AArch64/Utils/AArch64BaseInfo.h
index 461a7dcf090..675adad2a69 100644
--- a/llvm/lib/Target/AArch64/Utils/AArch64BaseInfo.h
+++ b/llvm/lib/Target/AArch64/Utils/AArch64BaseInfo.h
@@ -499,6 +499,14 @@ namespace AArch64TLBI {
#include "AArch64GenSystemOperands.inc"
}
+namespace AArch64PRCTX {
+ struct PRCTX : SysAliasReg {
+ using SysAliasReg::SysAliasReg;
+ };
+ #define GET_PRCTX_DECL
+ #include "AArch64GenSystemOperands.inc"
+}
+
namespace AArch64II {
/// Target Operand Flag enum.
enum TOF {
OpenPOWER on IntegriCloud