summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Target/ARM
diff options
context:
space:
mode:
authorOliver Stannard <oliver.stannard@arm.com>2018-09-28 08:27:56 +0000
committerOliver Stannard <oliver.stannard@arm.com>2018-09-28 08:27:56 +0000
commit5f34e9e265f87af4b5f1b64e885d5eaf58a904a2 (patch)
tree76eab67023aebeda9067d1f15d3a3d4e6df9a0cf /llvm/lib/Target/ARM
parent280af1c7f0cce6fe15e7074c0724ded7cca23038 (diff)
downloadbcm5719-llvm-5f34e9e265f87af4b5f1b64e885d5eaf58a904a2.tar.gz
bcm5719-llvm-5f34e9e265f87af4b5f1b64e885d5eaf58a904a2.zip
[ARM][v8.5A] Add speculation barriers SSBB and PSSBB
This adds two new barrier instructions which can be used to restrict speculative execution of load instructions. Patch by Pablo Barrio! Differential revision: https://reviews.llvm.org/D52484 llvm-svn: 343300
Diffstat (limited to 'llvm/lib/Target/ARM')
-rw-r--r--llvm/lib/Target/ARM/ARMInstrInfo.td2
-rw-r--r--llvm/lib/Target/ARM/ARMInstrThumb2.td6
-rw-r--r--llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp23
-rw-r--r--llvm/lib/Target/ARM/InstPrinter/ARMInstPrinter.cpp15
4 files changed, 45 insertions, 1 deletions
diff --git a/llvm/lib/Target/ARM/ARMInstrInfo.td b/llvm/lib/Target/ARM/ARMInstrInfo.td
index e063ffdc36b..e1a077ef166 100644
--- a/llvm/lib/Target/ARM/ARMInstrInfo.td
+++ b/llvm/lib/Target/ARM/ARMInstrInfo.td
@@ -5926,6 +5926,8 @@ include "ARMInstrNEON.td"
// Memory barriers
def : InstAlias<"dmb", (DMB 0xf), 0>, Requires<[IsARM, HasDB]>;
def : InstAlias<"dsb", (DSB 0xf), 0>, Requires<[IsARM, HasDB]>;
+def : InstAlias<"ssbb", (DSB 0x0), 1>, Requires<[IsARM, HasDB]>;
+def : InstAlias<"pssbb", (DSB 0x4), 1>, Requires<[IsARM, HasDB]>;
def : InstAlias<"isb", (ISB 0xf), 0>, Requires<[IsARM, HasDB]>;
// Armv8-R 'Data Full Barrier'
def : InstAlias<"dfb", (DSB 0xc), 1>, Requires<[IsARM, HasDFB]>;
diff --git a/llvm/lib/Target/ARM/ARMInstrThumb2.td b/llvm/lib/Target/ARM/ARMInstrThumb2.td
index 39525a3e28f..0c5720e0267 100644
--- a/llvm/lib/Target/ARM/ARMInstrThumb2.td
+++ b/llvm/lib/Target/ARM/ARMInstrThumb2.td
@@ -4554,6 +4554,12 @@ def : t2InstAlias<"tst${p} $Rn, $Rm",
def : InstAlias<"dmb${p}", (t2DMB 0xf, pred:$p), 0>, Requires<[HasDB]>;
def : InstAlias<"dsb${p}", (t2DSB 0xf, pred:$p), 0>, Requires<[HasDB]>;
def : InstAlias<"isb${p}", (t2ISB 0xf, pred:$p), 0>, Requires<[HasDB]>;
+
+// Non-predicable aliases of a predicable DSB: the predicate is (14, 0) where
+// 14 = AL (always execute) and 0 = "instruction doesn't read the CPSR".
+def : InstAlias<"ssbb", (t2DSB 0x0, 14, 0), 1>, Requires<[HasDB, IsThumb2]>;
+def : InstAlias<"pssbb", (t2DSB 0x4, 14, 0), 1>, Requires<[HasDB, IsThumb2]>;
+
// Armv8-R 'Data Full Barrier'
def : InstAlias<"dfb${p}", (t2DSB 0xc, pred:$p), 1>, Requires<[HasDFB]>;
diff --git a/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp b/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
index c5b2d2d5968..f837db56264 100644
--- a/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
+++ b/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
@@ -5721,7 +5721,8 @@ void ARMAsmParser::getMnemonicAcceptInfo(StringRef Mnemonic, StringRef FullInst,
Mnemonic == "vudot" || Mnemonic == "vsdot" ||
Mnemonic == "vcmla" || Mnemonic == "vcadd" ||
Mnemonic == "vfmal" || Mnemonic == "vfmsl" ||
- Mnemonic == "sb") {
+ Mnemonic == "sb" || Mnemonic == "ssbb" ||
+ Mnemonic == "pssbb") {
// These mnemonics are never predicable
CanAcceptPredicationCode = false;
} else if (!isThumb()) {
@@ -6824,6 +6825,26 @@ bool ARMAsmParser::validateInstruction(MCInst &Inst,
"code specified");
break;
}
+ case ARM::DSB:
+ case ARM::t2DSB: {
+
+ if (Inst.getNumOperands() < 2)
+ break;
+
+ unsigned Option = Inst.getOperand(0).getImm();
+ unsigned Pred = Inst.getOperand(1).getImm();
+
+ // SSBB and PSSBB (DSB #0|#4) are not predicable (pred must be AL).
+ if (Option == 0 && Pred != ARMCC::AL)
+ return Error(Operands[1]->getStartLoc(),
+ "instruction 'ssbb' is not predicable, but condition code "
+ "specified");
+ if (Option == 4 && Pred != ARMCC::AL)
+ return Error(Operands[1]->getStartLoc(),
+ "instruction 'pssbb' is not predicable, but condition code "
+ "specified");
+ break;
+ }
case ARM::VMOVRRS: {
// Source registers must be sequential.
const unsigned Sm = MRI->getEncodingValue(Inst.getOperand(2).getReg());
diff --git a/llvm/lib/Target/ARM/InstPrinter/ARMInstPrinter.cpp b/llvm/lib/Target/ARM/InstPrinter/ARMInstPrinter.cpp
index bfc32073ba1..2f84719c4c4 100644
--- a/llvm/lib/Target/ARM/InstPrinter/ARMInstPrinter.cpp
+++ b/llvm/lib/Target/ARM/InstPrinter/ARMInstPrinter.cpp
@@ -273,6 +273,21 @@ void ARMInstPrinter::printInst(const MCInst *MI, raw_ostream &O,
case ARM::t2TSB:
O << "\ttsb\tcsync";
return;
+ case ARM::t2DSB:
+ switch (MI->getOperand(0).getImm()) {
+ default:
+ if (!printAliasInstr(MI, STI, O))
+ printInstruction(MI, STI, O);
+ break;
+ case 0:
+ O << "\tssbb";
+ break;
+ case 4:
+ O << "\tpssbb";
+ break;
+ }
+ printAnnotation(O, Annot);
+ return;
}
if (!printAliasInstr(MI, STI, O))
OpenPOWER on IntegriCloud