summaryrefslogtreecommitdiffstats
path: root/llvm/lib
diff options
context:
space:
mode:
authorSjoerd Meijer <sjoerd.meijer@arm.com>2016-06-03 14:03:27 +0000
committerSjoerd Meijer <sjoerd.meijer@arm.com>2016-06-03 14:03:27 +0000
commitd906bf13699ca115a27d78e2d42ab71c2e851fe1 (patch)
tree4fda9bf6899ecf2156a6a57cfcbbc13452736025 /llvm/lib
parent60adb9229c2f5daad51625a4e03497b293253e5b (diff)
downloadbcm5719-llvm-d906bf13699ca115a27d78e2d42ab71c2e851fe1.tar.gz
bcm5719-llvm-d906bf13699ca115a27d78e2d42ab71c2e851fe1.zip
RAS extensions are part of ARMv8.2-A. This change enables them by introducing a
new instruction to ARM and AArch64 targets and several system registers. Patch by: Roger Ferrer Ibanez and Oliver Stannard Differential Revision: http://reviews.llvm.org/D20282 llvm-svn: 271670
Diffstat (limited to 'llvm/lib')
-rw-r--r--llvm/lib/Target/AArch64/AArch64.td5
-rw-r--r--llvm/lib/Target/AArch64/AArch64InstrInfo.td3
-rw-r--r--llvm/lib/Target/AArch64/AArch64Subtarget.h2
-rw-r--r--llvm/lib/Target/AArch64/Utils/AArch64BaseInfo.cpp15
-rw-r--r--llvm/lib/Target/AArch64/Utils/AArch64BaseInfo.h17
-rw-r--r--llvm/lib/Target/ARM/ARM.td39
-rw-r--r--llvm/lib/Target/ARM/ARMISelLowering.cpp2
-rw-r--r--llvm/lib/Target/ARM/ARMInstrInfo.td4
-rw-r--r--llvm/lib/Target/ARM/ARMInstrThumb2.td6
-rw-r--r--llvm/lib/Target/ARM/ARMSubtarget.cpp3
-rw-r--r--llvm/lib/Target/ARM/ARMSubtarget.h10
-rw-r--r--llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp18
-rw-r--r--llvm/lib/Target/ARM/Disassembler/ARMDisassembler.cpp31
13 files changed, 131 insertions, 24 deletions
diff --git a/llvm/lib/Target/AArch64/AArch64.td b/llvm/lib/Target/AArch64/AArch64.td
index 67a0556e437..2be0115d11d 100644
--- a/llvm/lib/Target/AArch64/AArch64.td
+++ b/llvm/lib/Target/AArch64/AArch64.td
@@ -32,6 +32,9 @@ def FeatureCrypto : SubtargetFeature<"crypto", "HasCrypto", "true",
def FeatureCRC : SubtargetFeature<"crc", "HasCRC", "true",
"Enable ARMv8 CRC-32 checksum instructions">;
+def FeatureRAS : SubtargetFeature<"ras", "HasRAS", "true",
+ "Enable ARMv8 Reliability, Availability and Serviceability Extensions">;
+
def FeaturePerfMon : SubtargetFeature<"perfmon", "HasPerfMon", "true",
"Enable ARMv8 PMUv3 Performance Monitors extension">;
@@ -110,7 +113,7 @@ def HasV8_1aOps : SubtargetFeature<"v8.1a", "HasV8_1aOps", "true",
"Support ARM v8.1a instructions", [FeatureCRC]>;
def HasV8_2aOps : SubtargetFeature<"v8.2a", "HasV8_2aOps", "true",
- "Support ARM v8.2a instructions", [HasV8_1aOps]>;
+ "Support ARM v8.2a instructions", [HasV8_1aOps, FeatureRAS]>;
//===----------------------------------------------------------------------===//
// Register File Description
diff --git a/llvm/lib/Target/AArch64/AArch64InstrInfo.td b/llvm/lib/Target/AArch64/AArch64InstrInfo.td
index d79d603e1c6..6fd18396d2c 100644
--- a/llvm/lib/Target/AArch64/AArch64InstrInfo.td
+++ b/llvm/lib/Target/AArch64/AArch64InstrInfo.td
@@ -26,6 +26,8 @@ def HasCrypto : Predicate<"Subtarget->hasCrypto()">,
AssemblerPredicate<"FeatureCrypto", "crypto">;
def HasCRC : Predicate<"Subtarget->hasCRC()">,
AssemblerPredicate<"FeatureCRC", "crc">;
+def HasRAS : Predicate<"Subtarget->hasRAS()">,
+ AssemblerPredicate<"FeatureRAS", "ras">;
def HasPerfMon : Predicate<"Subtarget->hasPerfMon()">;
def HasFullFP16 : Predicate<"Subtarget->hasFullFP16()">,
AssemblerPredicate<"FeatureFullFP16", "fullfp16">;
@@ -390,6 +392,7 @@ def : InstAlias<"wfe", (HINT 0b010)>;
def : InstAlias<"wfi", (HINT 0b011)>;
def : InstAlias<"sev", (HINT 0b100)>;
def : InstAlias<"sevl", (HINT 0b101)>;
+def : InstAlias<"esb", (HINT 0b10000)>, Requires<[HasRAS]>;
// 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 e4e88b35ccb..6d26fa71c79 100644
--- a/llvm/lib/Target/AArch64/AArch64Subtarget.h
+++ b/llvm/lib/Target/AArch64/AArch64Subtarget.h
@@ -55,6 +55,7 @@ protected:
bool HasNEON = false;
bool HasCrypto = false;
bool HasCRC = false;
+ bool HasRAS = false;
bool HasPerfMon = false;
bool HasFullFP16 = false;
bool HasSPE = false;
@@ -170,6 +171,7 @@ public:
bool hasNEON() const { return HasNEON; }
bool hasCrypto() const { return HasCrypto; }
bool hasCRC() const { return HasCRC; }
+ bool hasRAS() const { return HasRAS; }
bool mergeNarrowLoads() const { return MergeNarrowLoads; }
bool balanceFPOps() const { return BalanceFPOps; }
bool predictableSelectIsExpensive() const {
diff --git a/llvm/lib/Target/AArch64/Utils/AArch64BaseInfo.cpp b/llvm/lib/Target/AArch64/Utils/AArch64BaseInfo.cpp
index 274ff892565..e0f2a07db7c 100644
--- a/llvm/lib/Target/AArch64/Utils/AArch64BaseInfo.cpp
+++ b/llvm/lib/Target/AArch64/Utils/AArch64BaseInfo.cpp
@@ -263,6 +263,10 @@ const AArch64NamedImmMapper::Mapping AArch64SysReg::MRSMapper::MRSMappings[] = {
// v8.1a "Limited Ordering Regions" extension-specific system registers
{"lorid_el1", LORID_EL1, {AArch64::HasV8_1aOps}},
+
+ // v8.2a "Reliability, Availability and Serviceability" extensions registers
+ {"erridr_el1", ERRIDR_EL1, {AArch64::FeatureRAS}},
+ {"erxfr_el1", ERXFR_EL1, {AArch64::FeatureRAS}}
};
AArch64SysReg::MRSMapper::MRSMapper() {
@@ -816,6 +820,17 @@ const AArch64NamedImmMapper::Mapping AArch64SysReg::SysRegMapper::SysRegMappings
// v8.2a registers
{"uao", UAO, {AArch64::HasV8_2aOps}},
+ // v8.2a "Reliability, Availability and Serviceability" extensions registers
+ {"errselr_el1", ERRSELR_EL1, {AArch64::FeatureRAS}},
+ {"erxctlr_el1", ERXCTLR_EL1, {AArch64::FeatureRAS}},
+ {"erxstatus_el1", ERXSTATUS_EL1, {AArch64::FeatureRAS}},
+ {"erxaddr_el1", ERXADDR_EL1, {AArch64::FeatureRAS}},
+ {"erxmisc0_el1", ERXMISC0_EL1, {AArch64::FeatureRAS}},
+ {"erxmisc1_el1", ERXMISC1_EL1, {AArch64::FeatureRAS}},
+ {"disr_el1", DISR_EL1, {AArch64::FeatureRAS}},
+ {"vdisr_el2", VDISR_EL2, {AArch64::FeatureRAS}},
+ {"vsesr_el2", VSESR_EL2, {AArch64::FeatureRAS}},
+
// v8.2a "Statistical Profiling extension" registers
{"pmblimitr_el1", PMBLIMITR_EL1, {AArch64::FeatureSPE}},
{"pmbptr_el1", PMBPTR_EL1, {AArch64::FeatureSPE}},
diff --git a/llvm/lib/Target/AArch64/Utils/AArch64BaseInfo.h b/llvm/lib/Target/AArch64/Utils/AArch64BaseInfo.h
index 61bee1f45b6..98eaa388024 100644
--- a/llvm/lib/Target/AArch64/Utils/AArch64BaseInfo.h
+++ b/llvm/lib/Target/AArch64/Utils/AArch64BaseInfo.h
@@ -672,7 +672,11 @@ namespace AArch64SysReg {
ICC_RPR_EL1 = 0xc65b, // 11 000 1100 1011 011
ICH_VTR_EL2 = 0xe659, // 11 100 1100 1011 001
ICH_EISR_EL2 = 0xe65b, // 11 100 1100 1011 011
- ICH_ELSR_EL2 = 0xe65d // 11 100 1100 1011 101
+ ICH_ELSR_EL2 = 0xe65d, // 11 100 1100 1011 101
+
+ // RAS extension registers
+ ERRIDR_EL1 = 0xc298, // 11 000 0101 0011 000
+ ERXFR_EL1 = 0xc2a0 // 11 000 0101 0100 000
};
enum SysRegWOValues {
@@ -1211,6 +1215,17 @@ namespace AArch64SysReg {
SPSR_EL12 = 0xea00, // 11 101 0100 0000 000
ELR_EL12 = 0xea01, // 11 101 0100 0000 001
+ // RAS extension registers
+ ERRSELR_EL1 = 0xc299, // 11 000 0101 0011 001
+ ERXCTLR_EL1 = 0xc2a1, // 11 000 0101 0100 001
+ ERXSTATUS_EL1 = 0xc2a2, // 11 000 0101 0100 010
+ ERXADDR_EL1 = 0xc2a3, // 11 000 0101 0100 011
+ ERXMISC0_EL1 = 0xc2a8, // 11 000 0101 0101 000
+ ERXMISC1_EL1 = 0xc2a9, // 11 000 0101 0101 001
+ DISR_EL1 = 0xc609, // 11 000 1100 0001 001
+ VDISR_EL2 = 0xe609, // 11 100 1100 0001 001
+ VSESR_EL2 = 0xe293, // 11 100 0101 0010 011
+
// v8.2a registers
UAO = 0xc214, // 11 000 0100 0010 100
diff --git a/llvm/lib/Target/ARM/ARM.td b/llvm/lib/Target/ARM/ARM.td
index 2281f2c979c..a336c4f1a68 100644
--- a/llvm/lib/Target/ARM/ARM.td
+++ b/llvm/lib/Target/ARM/ARM.td
@@ -96,6 +96,10 @@ def FeatureCrypto : SubtargetFeature<"crypto", "HasCrypto", "true",
[FeatureNEON]>;
def FeatureCRC : SubtargetFeature<"crc", "HasCRC", "true",
"Enable support for CRC instructions">;
+// Not to be confused with FeatureHasRetAddrStack (return address stack)
+def FeatureRAS : SubtargetFeature<"ras", "HasRAS", "true",
+ "Enable Reliability, Availability and Serviceability extensions">;
+
// Cyclone has preferred instructions for zeroing VFP registers, which can
// execute in 0 cycles.
@@ -137,7 +141,7 @@ def FeatureAvoidMOVsShOp : SubtargetFeature<"avoid-movs-shop",
// Some processors perform return stack prediction. CodeGen should avoid issue
// "normal" call instructions to callees which do not return.
-def FeatureHasRAS : SubtargetFeature<"ras", "HasRAS", "true",
+def FeatureHasRetAddrStack : SubtargetFeature<"ret-addr-stack", "HasRetAddrStack", "true",
"Has return address stack">;
/// DSP extension.
@@ -394,7 +398,8 @@ def ARMv82a : Architecture<"armv8.2-a", "ARMv82a", [HasV8_2aOps,
FeatureMP,
FeatureVirtualization,
FeatureCrypto,
- FeatureCRC]>;
+ FeatureCRC,
+ FeatureRAS]>;
def ARMv8mBaseline : Architecture<"armv8-m.base", "ARMv8mBaseline",
[HasV8MBaselineOps,
@@ -491,7 +496,7 @@ def : Processor<"arm1156t2f-s", ARMV6Itineraries, [ARMv6t2,
// FIXME: A5 has currently the same Schedule model as A8
def : ProcessorModel<"cortex-a5", CortexA8Model, [ARMv7a, ProcA5,
- FeatureHasRAS,
+ FeatureHasRetAddrStack,
FeatureTrustZone,
FeatureSlowFPBrcc,
FeatureHasSlowFPVMLx,
@@ -501,7 +506,7 @@ def : ProcessorModel<"cortex-a5", CortexA8Model, [ARMv7a, ProcA5,
FeatureVFP4]>;
def : ProcessorModel<"cortex-a7", CortexA8Model, [ARMv7a, ProcA7,
- FeatureHasRAS,
+ FeatureHasRetAddrStack,
FeatureTrustZone,
FeatureSlowFPBrcc,
FeatureHasSlowFPVMLx,
@@ -514,7 +519,7 @@ def : ProcessorModel<"cortex-a7", CortexA8Model, [ARMv7a, ProcA7,
FeatureVirtualization]>;
def : ProcessorModel<"cortex-a8", CortexA8Model, [ARMv7a, ProcA8,
- FeatureHasRAS,
+ FeatureHasRetAddrStack,
FeatureTrustZone,
FeatureSlowFPBrcc,
FeatureHasSlowFPVMLx,
@@ -522,7 +527,7 @@ def : ProcessorModel<"cortex-a8", CortexA8Model, [ARMv7a, ProcA8,
FeatureT2XtPk]>;
def : ProcessorModel<"cortex-a9", CortexA9Model, [ARMv7a, ProcA9,
- FeatureHasRAS,
+ FeatureHasRetAddrStack,
FeatureTrustZone,
FeatureVMLxForwarding,
FeatureT2XtPk,
@@ -532,7 +537,7 @@ def : ProcessorModel<"cortex-a9", CortexA9Model, [ARMv7a, ProcA9,
// FIXME: A12 has currently the same Schedule model as A9
def : ProcessorModel<"cortex-a12", CortexA9Model, [ARMv7a, ProcA12,
- FeatureHasRAS,
+ FeatureHasRetAddrStack,
FeatureTrustZone,
FeatureVMLxForwarding,
FeatureT2XtPk,
@@ -545,7 +550,7 @@ def : ProcessorModel<"cortex-a12", CortexA9Model, [ARMv7a, ProcA12,
// FIXME: A15 has currently the same Schedule model as A9.
def : ProcessorModel<"cortex-a15", CortexA9Model, [ARMv7a, ProcA15,
- FeatureHasRAS,
+ FeatureHasRetAddrStack,
FeatureTrustZone,
FeatureT2XtPk,
FeatureVFP4,
@@ -557,7 +562,7 @@ def : ProcessorModel<"cortex-a15", CortexA9Model, [ARMv7a, ProcA15,
// FIXME: A17 has currently the same Schedule model as A9
def : ProcessorModel<"cortex-a17", CortexA9Model, [ARMv7a, ProcA17,
- FeatureHasRAS,
+ FeatureHasRetAddrStack,
FeatureTrustZone,
FeatureMP,
FeatureVMLxForwarding,
@@ -572,7 +577,7 @@ def : ProcessorModel<"cortex-a17", CortexA9Model, [ARMv7a, ProcA17,
// FIXME: krait has currently the same features as A9 plus VFP4 and hardware
// division features.
def : ProcessorModel<"krait", CortexA9Model, [ARMv7a, ProcKrait,
- FeatureHasRAS,
+ FeatureHasRetAddrStack,
FeatureVMLxForwarding,
FeatureT2XtPk,
FeatureFP16,
@@ -582,7 +587,7 @@ def : ProcessorModel<"krait", CortexA9Model, [ARMv7a, ProcKrait,
FeatureHWDivARM]>;
def : ProcessorModel<"swift", SwiftModel, [ARMv7a, ProcSwift,
- FeatureHasRAS,
+ FeatureHasRetAddrStack,
FeatureNEONForFP,
FeatureT2XtPk,
FeatureVFP4,
@@ -595,13 +600,13 @@ def : ProcessorModel<"swift", SwiftModel, [ARMv7a, ProcSwift,
// FIXME: R4 has currently the same ProcessorModel as A8.
def : ProcessorModel<"cortex-r4", CortexA8Model, [ARMv7r, ProcR4,
- FeatureHasRAS,
+ FeatureHasRetAddrStack,
FeatureAvoidPartialCPSR,
FeatureT2XtPk]>;
// FIXME: R4F has currently the same ProcessorModel as A8.
def : ProcessorModel<"cortex-r4f", CortexA8Model, [ARMv7r, ProcR4,
- FeatureHasRAS,
+ FeatureHasRetAddrStack,
FeatureSlowFPBrcc,
FeatureHasSlowFPVMLx,
FeatureVFP3,
@@ -611,7 +616,7 @@ def : ProcessorModel<"cortex-r4f", CortexA8Model, [ARMv7r, ProcR4,
// FIXME: R5 has currently the same ProcessorModel as A8.
def : ProcessorModel<"cortex-r5", CortexA8Model, [ARMv7r, ProcR5,
- FeatureHasRAS,
+ FeatureHasRetAddrStack,
FeatureVFP3,
FeatureD16,
FeatureSlowFPBrcc,
@@ -622,7 +627,7 @@ def : ProcessorModel<"cortex-r5", CortexA8Model, [ARMv7r, ProcR5,
// FIXME: R7 has currently the same ProcessorModel as A8 and is modelled as R5.
def : ProcessorModel<"cortex-r7", CortexA8Model, [ARMv7r, ProcR7,
- FeatureHasRAS,
+ FeatureHasRetAddrStack,
FeatureVFP3,
FeatureD16,
FeatureFP16,
@@ -634,7 +639,7 @@ def : ProcessorModel<"cortex-r7", CortexA8Model, [ARMv7r, ProcR7,
FeatureT2XtPk]>;
def : ProcessorModel<"cortex-r8", CortexA8Model, [ARMv7r,
- FeatureHasRAS,
+ FeatureHasRetAddrStack,
FeatureVFP3,
FeatureD16,
FeatureFP16,
@@ -701,7 +706,7 @@ def : ProcNoItin<"cortex-a73", [ARMv8a, ProcA73,
// Cyclone is very similar to swift
def : ProcessorModel<"cyclone", SwiftModel, [ARMv8a, ProcSwift,
- FeatureHasRAS,
+ FeatureHasRetAddrStack,
FeatureNEONForFP,
FeatureT2XtPk,
FeatureVFP4,
diff --git a/llvm/lib/Target/ARM/ARMISelLowering.cpp b/llvm/lib/Target/ARM/ARMISelLowering.cpp
index c88cd50f3a1..6a05e5473bb 100644
--- a/llvm/lib/Target/ARM/ARMISelLowering.cpp
+++ b/llvm/lib/Target/ARM/ARMISelLowering.cpp
@@ -1925,7 +1925,7 @@ ARMTargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI,
} else {
if (!isDirect && !Subtarget->hasV5TOps())
CallOpc = ARMISD::CALL_NOLINK;
- else if (doesNotRet && isDirect && Subtarget->hasRAS() &&
+ else if (doesNotRet && isDirect && Subtarget->hasRetAddrStack() &&
// Emit regular call when code size is the priority
!MF.getFunction()->optForMinSize())
// "mov lr, pc; b _foo" to avoid confusing the RSP
diff --git a/llvm/lib/Target/ARM/ARMInstrInfo.td b/llvm/lib/Target/ARM/ARMInstrInfo.td
index aaccb5e4934..c7f113dc178 100644
--- a/llvm/lib/Target/ARM/ARMInstrInfo.td
+++ b/llvm/lib/Target/ARM/ARMInstrInfo.td
@@ -241,6 +241,8 @@ def HasCrypto : Predicate<"Subtarget->hasCrypto()">,
AssemblerPredicate<"FeatureCrypto", "crypto">;
def HasCRC : Predicate<"Subtarget->hasCRC()">,
AssemblerPredicate<"FeatureCRC", "crc">;
+def HasRAS : Predicate<"Subtarget->hasRAS()">,
+ AssemblerPredicate<"FeatureRAS", "ras">;
def HasFP16 : Predicate<"Subtarget->hasFP16()">,
AssemblerPredicate<"FeatureFP16","half-float conversions">;
def HasFullFP16 : Predicate<"Subtarget->hasFullFP16()">,
@@ -1910,6 +1912,7 @@ def HINT : AI<(outs), (ins imm0_239:$imm), MiscFrm, NoItinerary,
bits<8> imm;
let Inst{27-8} = 0b00110010000011110000;
let Inst{7-0} = imm;
+ let DecoderMethod = "DecodeHINTInstruction";
}
def : InstAlias<"nop$p", (HINT 0, pred:$p)>, Requires<[IsARM, HasV6K]>;
@@ -1918,6 +1921,7 @@ def : InstAlias<"wfe$p", (HINT 2, pred:$p)>, Requires<[IsARM, HasV6K]>;
def : InstAlias<"wfi$p", (HINT 3, pred:$p)>, Requires<[IsARM, HasV6K]>;
def : InstAlias<"sev$p", (HINT 4, pred:$p)>, Requires<[IsARM, HasV6K]>;
def : InstAlias<"sevl$p", (HINT 5, pred:$p)>, Requires<[IsARM, HasV8]>;
+def : InstAlias<"esb$p", (HINT 16, pred:$p)>, Requires<[IsARM, HasRAS]>;
def SEL : AI<(outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm), DPFrm, NoItinerary, "sel",
"\t$Rd, $Rn, $Rm", []>, Requires<[IsARM, HasV6]> {
diff --git a/llvm/lib/Target/ARM/ARMInstrThumb2.td b/llvm/lib/Target/ARM/ARMInstrThumb2.td
index 543f7a9d01a..eac6754a1c3 100644
--- a/llvm/lib/Target/ARM/ARMInstrThumb2.td
+++ b/llvm/lib/Target/ARM/ARMInstrThumb2.td
@@ -3729,6 +3729,12 @@ def : t2InstAlias<"sev$p.w", (t2HINT 4, pred:$p), 1>;
def : t2InstAlias<"sevl$p.w", (t2HINT 5, pred:$p), 1> {
let Predicates = [IsThumb2, HasV8];
}
+def : t2InstAlias<"esb$p.w", (t2HINT 16, pred:$p), 1> {
+ let Predicates = [IsThumb2, HasRAS];
+}
+def : t2InstAlias<"esb$p", (t2HINT 16, pred:$p), 0> {
+ let Predicates = [IsThumb2, HasRAS];
+}
def t2DBG : T2I<(outs), (ins imm0_15:$opt), NoItinerary, "dbg", "\t$opt",
[(int_arm_dbg imm0_15:$opt)]> {
diff --git a/llvm/lib/Target/ARM/ARMSubtarget.cpp b/llvm/lib/Target/ARM/ARMSubtarget.cpp
index d0d625b5800..5f0a4897318 100644
--- a/llvm/lib/Target/ARM/ARMSubtarget.cpp
+++ b/llvm/lib/Target/ARM/ARMSubtarget.cpp
@@ -143,7 +143,7 @@ void ARMSubtarget::initializeEnvironment() {
Pref32BitThumb = false;
AvoidCPSRPartialUpdate = false;
AvoidMOVsShifterOperand = false;
- HasRAS = false;
+ HasRetAddrStack = false;
HasMPExtension = false;
HasVirtualization = false;
FPOnlySP = false;
@@ -152,6 +152,7 @@ void ARMSubtarget::initializeEnvironment() {
Has8MSecExt = false;
HasCrypto = false;
HasCRC = false;
+ HasRAS = false;
HasZeroCycleZeroing = false;
StrictAlign = false;
HasDSP = false;
diff --git a/llvm/lib/Target/ARM/ARMSubtarget.h b/llvm/lib/Target/ARM/ARMSubtarget.h
index 43e911e934f..1eeb6224206 100644
--- a/llvm/lib/Target/ARM/ARMSubtarget.h
+++ b/llvm/lib/Target/ARM/ARMSubtarget.h
@@ -178,9 +178,9 @@ protected:
/// movs with shifter operand (i.e. asr, lsl, lsr).
bool AvoidMOVsShifterOperand;
- /// HasRAS - Some processors perform return stack prediction. CodeGen should
+ /// HasRetAddrStack - Some processors perform return stack prediction. CodeGen should
/// avoid issue "normal" call instructions to callees which do not return.
- bool HasRAS;
+ bool HasRetAddrStack;
/// HasMPExtension - True if the subtarget supports Multiprocessing
/// extension (ARMv7 only).
@@ -211,6 +211,9 @@ protected:
/// HasCRC - if true, processor supports CRC instructions
bool HasCRC;
+ /// HasRAS - if true, the processor supports RAS extensions
+ bool HasRAS;
+
/// If true, the instructions "vmov.i32 d0, #0" and "vmov.i32 q0, #0" are
/// particularly effective at zeroing a VFP register.
bool HasZeroCycleZeroing;
@@ -349,6 +352,7 @@ public:
bool hasNEON() const { return HasNEON; }
bool hasCrypto() const { return HasCrypto; }
bool hasCRC() const { return HasCRC; }
+ bool hasRAS() const { return HasRAS; }
bool hasVirtualization() const { return HasVirtualization; }
bool useNEONForSinglePrecisionFP() const {
return hasNEON() && UseNEONForSinglePrecisionFP;
@@ -375,7 +379,7 @@ public:
bool prefers32BitThumb() const { return Pref32BitThumb; }
bool avoidCPSRPartialUpdate() const { return AvoidCPSRPartialUpdate; }
bool avoidMOVsShifterOperand() const { return AvoidMOVsShifterOperand; }
- bool hasRAS() const { return HasRAS; }
+ bool hasRetAddrStack() const { return HasRetAddrStack; }
bool hasMPExtension() const { return HasMPExtension; }
bool hasDSP() const { return HasDSP; }
bool useNaClTrap() const { return UseNaClTrap; }
diff --git a/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp b/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
index 8b231d3f7d1..b9207a02c9e 100644
--- a/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
+++ b/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
@@ -296,6 +296,9 @@ class ARMAsmParser : public MCTargetAsmParser {
bool hasV8_1aOps() const {
return getSTI().getFeatureBits()[ARM::HasV8_1aOps];
}
+ bool hasRAS() const {
+ return getSTI().getFeatureBits()[ARM::FeatureRAS];
+ }
void SwitchMode() {
MCSubtargetInfo &STI = copySTI();
@@ -6512,6 +6515,20 @@ bool ARMAsmParser::validateInstruction(MCInst &Inst,
"immediate expression for mov requires :lower16: or :upper16");
break;
}
+ case ARM::HINT:
+ case ARM::t2HINT: {
+ if (hasRAS()) {
+ // ESB is not predicable (pred must be AL)
+ unsigned Imm8 = Inst.getOperand(0).getImm();
+ unsigned Pred = Inst.getOperand(1).getImm();
+ if (Imm8 == 0x10 && Pred != ARMCC::AL)
+ return Error(Operands[1]->getStartLoc(), "instruction 'esb' is not "
+ "predicable, but condition "
+ "code specified");
+ }
+ // Without the RAS extension, this behaves as any other unallocated hint.
+ break;
+ }
}
return false;
@@ -10155,6 +10172,7 @@ static const struct {
// FIXME: Only available in A-class, isel not predicated
{ ARM::AEK_VIRT, Feature_HasV7, {ARM::FeatureVirtualization} },
{ ARM::AEK_FP16, Feature_HasV8_2a, {ARM::FeatureFPARMv8, ARM::FeatureFullFP16} },
+ { ARM::AEK_RAS, Feature_HasV8, {ARM::FeatureRAS} },
// FIXME: Unsupported extensions.
{ ARM::AEK_OS, Feature_None, {} },
{ ARM::AEK_IWMMXT, Feature_None, {} },
diff --git a/llvm/lib/Target/ARM/Disassembler/ARMDisassembler.cpp b/llvm/lib/Target/ARM/Disassembler/ARMDisassembler.cpp
index 46311bfdacb..ad1e03ae1e7 100644
--- a/llvm/lib/Target/ARM/Disassembler/ARMDisassembler.cpp
+++ b/llvm/lib/Target/ARM/Disassembler/ARMDisassembler.cpp
@@ -210,6 +210,8 @@ static DecodeStatus DecodeArmMOVTWInstruction(MCInst &Inst, unsigned Insn,
uint64_t Address, const void *Decoder);
static DecodeStatus DecodeSMLAInstruction(MCInst &Inst, unsigned Insn,
uint64_t Address, const void *Decoder);
+static DecodeStatus DecodeHINTInstruction(MCInst &Inst, unsigned Insn,
+ uint64_t Address, const void *Decoder);
static DecodeStatus DecodeCPSInstruction(MCInst &Inst, unsigned Insn,
uint64_t Address, const void *Decoder);
static DecodeStatus DecodeTSTInstruction(MCInst &Inst, unsigned Insn,
@@ -592,6 +594,8 @@ MCDisassembler::DecodeStatus
ThumbDisassembler::AddThumbPredicate(MCInst &MI) const {
MCDisassembler::DecodeStatus S = Success;
+ const FeatureBitset &FeatureBits = getSubtargetInfo().getFeatureBits();
+
// A few instructions actually have predicates encoded in them. Don't
// try to overwrite it if we're seeing one of those.
switch (MI.getOpcode()) {
@@ -612,6 +616,10 @@ ThumbDisassembler::AddThumbPredicate(MCInst &MI) const {
else
return Success;
break;
+ case ARM::t2HINT:
+ if (MI.getOperand(0).getImm() == 0x10 && (FeatureBits[ARM::FeatureRAS]) != 0)
+ S = SoftFail;
+ break;
case ARM::tB:
case ARM::t2B:
case ARM::t2TBB:
@@ -1943,6 +1951,29 @@ static DecodeStatus DecodeMemMultipleWritebackInstruction(MCInst &Inst,
return S;
}
+// Check for UNPREDICTABLE predicated ESB instruction
+static DecodeStatus DecodeHINTInstruction(MCInst &Inst, unsigned Insn,
+ uint64_t Address, const void *Decoder) {
+ unsigned pred = fieldFromInstruction(Insn, 28, 4);
+ unsigned imm8 = fieldFromInstruction(Insn, 0, 8);
+ const MCDisassembler *Dis = static_cast<const MCDisassembler*>(Decoder);
+ const FeatureBitset &FeatureBits = Dis->getSubtargetInfo().getFeatureBits();
+
+ DecodeStatus S = MCDisassembler::Success;
+
+ Inst.addOperand(MCOperand::createImm(imm8));
+
+ if (!Check(S, DecodePredicateOperand(Inst, pred, Address, Decoder)))
+ return MCDisassembler::Fail;
+
+ // ESB is unpredictable if pred != AL. Without the RAS extension, it is a NOP,
+ // so all predicates should be allowed.
+ if (imm8 == 0x10 && pred != 0xe && ((FeatureBits[ARM::FeatureRAS]) != 0))
+ S = MCDisassembler::SoftFail;
+
+ return S;
+}
+
static DecodeStatus DecodeCPSInstruction(MCInst &Inst, unsigned Insn,
uint64_t Address, const void *Decoder) {
unsigned imod = fieldFromInstruction(Insn, 18, 2);
OpenPOWER on IntegriCloud