]> granicus.if.org Git - llvm/commitdiff
[AArch64] Refactor LSE support as feature separate from V8.1a support.
authorJoel Jones <joelkevinjones@gmail.com>
Wed, 30 Nov 2016 22:25:24 +0000 (22:25 +0000)
committerJoel Jones <joelkevinjones@gmail.com>
Wed, 30 Nov 2016 22:25:24 +0000 (22:25 +0000)
Summary:
This is preparation for ThunderX processors that have Large
System Extension (LSE) atomic instructions, but not the
other instructions introduced by V8.1a.
This will mimic changes to GCC as described here:
https://gcc.gnu.org/ml/gcc-patches/2015-06/msg00388.html

LSE instructions are: LD/ST<op>, CAS*, SWP

Reviewers: t.p.northover, echristo, jmolloy, rengolin

Subscribers: aemerson, mehdi_amini

Differential Revision: https://reviews.llvm.org/D26621

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@288279 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/Support/AArch64TargetParser.def
include/llvm/Support/TargetParser.h
lib/Target/AArch64/AArch64.td
lib/Target/AArch64/AArch64InstrFormats.td
lib/Target/AArch64/AArch64InstrInfo.td
lib/Target/AArch64/AArch64Subtarget.h
lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp
test/MC/AArch64/arm64v8.1-diagno-predicate.s [new file with mode: 0644]
test/MC/AArch64/directive-arch-negative.s
test/MC/AArch64/directive-cpu.s

index 1171bb29f110e778f8ce5e0101a0cdd904444ee9..52fc39d40beab22128dc2e6e2795910dc0f22008 100644 (file)
@@ -21,15 +21,15 @@ AARCH64_ARCH("invalid", AK_INVALID, nullptr, nullptr,
 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
@@ -39,6 +39,7 @@ AARCH64_ARCH("armv8.2-a", AK_ARMV8_2A, "8.2-A", "v8.2a",
 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")
index ebe276a4d1a8e38a08a6bfcc6e40ae1d05ae3f6e..63aeca7f4e1eaa98589af5bf3f160408d45889d1 100644 (file)
@@ -162,7 +162,8 @@ enum ArchExtKind : unsigned {
   AEK_SIMD = 0x10,
   AEK_FP16 = 0x20,
   AEK_PROFILE = 0x40,
-  AEK_RAS = 0x80
+  AEK_RAS = 0x80,
+  AEK_LSE = 0x100
 };
 
 StringRef getCanonicalArchName(StringRef Arch);
index c6afa552ecf96be26fa79d8066f3bfec9e127ed3..65d5e8fe1f264c5de219f272f5922b836b33c65f 100644 (file)
@@ -35,6 +35,9 @@ def FeatureCRC : SubtargetFeature<"crc", "HasCRC", "true",
 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">;
 
@@ -111,7 +114,7 @@ def FeatureUseRSqrt : SubtargetFeature<
 //
 
 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]>;
index d6617617381ea56960607805aefbc5ab74074db8..cefdf51b50d2397d38f736c815a79ff41cd19c6a 100644 (file)
@@ -9348,7 +9348,7 @@ class SHAInstSS<bits<4> opc, string asm, Intrinsic OpNode>
 // 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> {
@@ -9369,6 +9369,7 @@ class BaseCASEncoding<dag oops, dag iops, string asm, string operands,
   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>
@@ -9401,7 +9402,7 @@ multiclass CompareAndSwapPair<bits<1> Acq, bits<1> Rel, string order> {
     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]","",[]>,
@@ -9424,6 +9425,7 @@ class BaseSWP<string order, string size, RegisterClass RC>
   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> {
@@ -9433,7 +9435,7 @@ 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]","",[]>,
@@ -9456,6 +9458,7 @@ class BaseLDOPregister<string op, string order, string size, RegisterClass RC>
   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, 
@@ -9470,7 +9473,7 @@ 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)>;
index 3bed50016b4056ee132f14ebe783e0cb3c97ac91..c5b95f282ea87478d4b68a27c985c46940744e57 100644 (file)
@@ -26,6 +26,8 @@ def HasCrypto        : Predicate<"Subtarget->hasCrypto()">,
                                  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()">;
index 5428c453d581d5474c18bce8664e43100d1d9dc8..73f63b8b9f67900620f129974a7d968d33a7105b 100644 (file)
@@ -59,6 +59,7 @@ protected:
   bool HasNEON = false;
   bool HasCrypto = false;
   bool HasCRC = false;
+  bool HasLSE = false;
   bool HasRAS = false;
   bool HasPerfMon = false;
   bool HasFullFP16 = false;
@@ -180,6 +181,7 @@ public:
   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 {
index 36d3abbd44d69d49fd993ca6335094c94c8eeba1..402b1e3e2236d9dce2c921deb63d957c2094e16c 100644 (file)
@@ -4137,9 +4137,9 @@ static const struct {
   { "fp", {AArch64::FeatureFPARMv8} },
   { "simd", {AArch64::FeatureNEON} },
   { "ras", {AArch64::FeatureRAS} },
+  { "lse", {AArch64::FeatureLSE} },
 
   // FIXME: Unsupported extensions
-  { "lse", {} },
   { "pan", {} },
   { "lor", {} },
   { "rdma", {} },
diff --git a/test/MC/AArch64/arm64v8.1-diagno-predicate.s b/test/MC/AArch64/arm64v8.1-diagno-predicate.s
new file mode 100644 (file)
index 0000000..9540d29
--- /dev/null
@@ -0,0 +1,8 @@
+// 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:        ^
+
index 327389de024961fc2403725a3c892669baf01d0d..43ccd7927252d40b32fac7bc07db98d1104e33fa 100644 (file)
@@ -35,3 +35,9 @@
 
 # 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]
index 8e7d453374458894b65d25f5974ab41b99192449..d645e54e470e0903646f020bce0ea9302d2fa292 100644 (file)
 
        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]