AARCH64_ARCH("armv8-a", AK_ARMV8A, "8-A", "v8", ARMBuildAttrs::CPUArch::v8_A,
FK_CRYPTO_NEON_FP_ARMV8,
(AArch64::AEK_CRC | AArch64::AEK_CRYPTO | AArch64::AEK_FP |
- AArch64::AEK_SIMD))
+ AArch64::AEK_SIMD | AArch64::AEK_LSE))
AARCH64_ARCH("armv8.1-a", AK_ARMV8_1A, "8.1-A", "v8.1a",
ARMBuildAttrs::CPUArch::v8_A, FK_CRYPTO_NEON_FP_ARMV8,
(AArch64::AEK_CRC | AArch64::AEK_CRYPTO | AArch64::AEK_FP |
- AArch64::AEK_SIMD))
+ AArch64::AEK_SIMD | AArch64::AEK_LSE))
AARCH64_ARCH("armv8.2-a", AK_ARMV8_2A, "8.2-A", "v8.2a",
ARMBuildAttrs::CPUArch::v8_A, FK_CRYPTO_NEON_FP_ARMV8,
(AArch64::AEK_CRC | AArch64::AEK_CRYPTO | AArch64::AEK_FP |
- AArch64::AEK_SIMD | AArch64::AEK_RAS))
+ AArch64::AEK_SIMD | AArch64::AEK_RAS | AArch64::AEK_LSE))
#undef AARCH64_ARCH
#ifndef AARCH64_ARCH_EXT_NAME
AARCH64_ARCH_EXT_NAME("invalid", AArch64::AEK_INVALID, nullptr, nullptr)
AARCH64_ARCH_EXT_NAME("none", AArch64::AEK_NONE, nullptr, nullptr)
AARCH64_ARCH_EXT_NAME("crc", AArch64::AEK_CRC, "+crc", "-crc")
+AARCH64_ARCH_EXT_NAME("lse", AArch64::AEK_LSE, "+lse", "-lse")
AARCH64_ARCH_EXT_NAME("crypto", AArch64::AEK_CRYPTO, "+crypto","-crypto")
AARCH64_ARCH_EXT_NAME("fp", AArch64::AEK_FP, "+fp-armv8", "-fp-armv8")
AARCH64_ARCH_EXT_NAME("simd", AArch64::AEK_SIMD, "+neon", "-neon")
AEK_SIMD = 0x10,
AEK_FP16 = 0x20,
AEK_PROFILE = 0x40,
- AEK_RAS = 0x80
+ AEK_RAS = 0x80,
+ AEK_LSE = 0x100
};
StringRef getCanonicalArchName(StringRef Arch);
def FeatureRAS : SubtargetFeature<"ras", "HasRAS", "true",
"Enable ARMv8 Reliability, Availability and Serviceability Extensions">;
+def FeatureLSE : SubtargetFeature<"lse", "HasLSE", "true",
+ "Enable ARMv8.1 Large System Extension (LSE) atomic instructions">;
+
def FeaturePerfMon : SubtargetFeature<"perfmon", "HasPerfMon", "true",
"Enable ARMv8 PMUv3 Performance Monitors extension">;
//
def HasV8_1aOps : SubtargetFeature<"v8.1a", "HasV8_1aOps", "true",
- "Support ARM v8.1a instructions", [FeatureCRC]>;
+ "Support ARM v8.1a instructions", [FeatureCRC, FeatureLSE]>;
def HasV8_2aOps : SubtargetFeature<"v8.2a", "HasV8_2aOps", "true",
"Support ARM v8.2a instructions", [HasV8_1aOps, FeatureRAS]>;
// ST<OP>{<order>}[<size>] <Ws>, [<Xn|SP>]
// ST<OP>{<order>} <Xs>, [<Xn|SP>]
-let Predicates = [HasV8_1a], mayLoad = 1, mayStore = 1, hasSideEffects = 1 in
+let Predicates = [HasLSE], mayLoad = 1, mayStore = 1, hasSideEffects = 1 in
class BaseCASEncoding<dag oops, dag iops, string asm, string operands,
string cstr, list<dag> pattern>
: I<oops, iops, asm, operands, cstr, pattern> {
let Inst{14-10} = 0b11111;
let Inst{9-5} = Rn;
let Inst{4-0} = Rt;
+ let Predicates = [HasLSE];
}
class BaseCAS<string order, string size, RegisterClass RC>
def d : BaseCASP<order, "", XSeqPairClassOperand>;
}
-let Predicates = [HasV8_1a] in
+let Predicates = [HasLSE] in
class BaseSWP<string order, string size, RegisterClass RC>
: I<(outs RC:$Rt),(ins RC:$Rs, GPR64sp:$Rn), "swp" # order # size,
"\t$Rs, $Rt, [$Rn]","",[]>,
let Inst{11-10} = 0b00;
let Inst{9-5} = Rn;
let Inst{4-0} = Rt;
+ let Predicates = [HasLSE];
}
multiclass Swap<bits<1> Acq, bits<1> Rel, string order> {
let Sz = 0b11, Acq = Acq, Rel = Rel in def d : BaseSWP<order, "", GPR64>;
}
-let Predicates = [HasV8_1a], mayLoad = 1, mayStore = 1, hasSideEffects = 1 in
+let Predicates = [HasLSE], mayLoad = 1, mayStore = 1, hasSideEffects = 1 in
class BaseLDOPregister<string op, string order, string size, RegisterClass RC>
: I<(outs RC:$Rt),(ins RC:$Rs, GPR64sp:$Rn), "ld" # op # order # size,
"\t$Rs, $Rt, [$Rn]","",[]>,
let Inst{11-10} = 0b00;
let Inst{9-5} = Rn;
let Inst{4-0} = Rt;
+ let Predicates = [HasLSE];
}
multiclass LDOPregister<bits<3> opc, string op, bits<1> Acq, bits<1> Rel,
def d : BaseLDOPregister<op, order, "", GPR64>;
}
-let Predicates = [HasV8_1a] in
+let Predicates = [HasLSE] in
class BaseSTOPregister<string asm, RegisterClass OP, Register Reg,
Instruction inst> :
InstAlias<asm # "\t$Rs, [$Rn]", (inst Reg, OP:$Rs, GPR64sp:$Rn)>;
AssemblerPredicate<"FeatureCrypto", "crypto">;
def HasCRC : Predicate<"Subtarget->hasCRC()">,
AssemblerPredicate<"FeatureCRC", "crc">;
+def HasLSE : Predicate<"Subtarget->hasLSE()">,
+ AssemblerPredicate<"FeatureLSE", "lse">;
def HasRAS : Predicate<"Subtarget->hasRAS()">,
AssemblerPredicate<"FeatureRAS", "ras">;
def HasPerfMon : Predicate<"Subtarget->hasPerfMon()">;
bool HasNEON = false;
bool HasCrypto = false;
bool HasCRC = false;
+ bool HasLSE = false;
bool HasRAS = false;
bool HasPerfMon = false;
bool HasFullFP16 = false;
bool hasNEON() const { return HasNEON; }
bool hasCrypto() const { return HasCrypto; }
bool hasCRC() const { return HasCRC; }
+ bool hasLSE() const { return HasLSE; }
bool hasRAS() const { return HasRAS; }
bool balanceFPOps() const { return BalanceFPOps; }
bool predictableSelectIsExpensive() const {
{ "fp", {AArch64::FeatureFPARMv8} },
{ "simd", {AArch64::FeatureNEON} },
{ "ras", {AArch64::FeatureRAS} },
+ { "lse", {AArch64::FeatureLSE} },
// FIXME: Unsupported extensions
- { "lse", {} },
{ "pan", {} },
{ "lor", {} },
{ "rdma", {} },
--- /dev/null
+// RUN: not llvm-mc -triple=arm64-linux-gnu -mattr=armv8.1a -mattr=-lse < %s 2> %t
+// RUN: FileCheck --check-prefix=CHECK-ERROR < %t %s
+
+ casa w5, w7, [x20]
+// CHECK-ERROR: error: instruction requires: lse
+// CHECK-ERROR-NEXT: casa w5, w7, [x20]
+// CHECK-ERROR-NEXT: ^
+
# CHECK: error: instruction requires: ras
# CHECK: esb
+
+ .arch armv8.1-a+nolse
+ casa w5, w7, [x20]
+
+# CHECK: error: instruction requires: lse
+# CHECK: casa w5, w7, [x20]
aesd v0.16b, v2.16b
+ .cpu generic+v8.1a+nolse
+ casa w5, w7, [x20]
+
+ .cpu generic+v8.1a+lse
+ casa w5, w7, [x20]
+
// NOTE: the errors precede the actual output! The errors appear in order
// though, so validate by hoisting them to the top and preservering relative
// ordering
// CHECK: aesd v0.16b, v2.16b
// CHECK: ^
+// CHECK: error: instruction requires: lse
+// CHECK: casa w5, w7, [x20]
+// CHECK: ^
+
// CHECK: fminnm d0, d0, d1
// CHECK: fminnm d0, d0, d1
// CHECK: addp v0.4s, v0.4s, v0.4s
// CHECK: crc32cx w0, w1, x3
// CHECK: aesd v0.16b, v2.16b
+// CHECK: casa w5, w7, [x20]