[ARM] Add support for ARMV6K subtarget (LLVM)
authorRenato Golin <renato.golin@linaro.org>
Tue, 17 Mar 2015 11:55:28 +0000 (11:55 +0000)
committerRenato Golin <renato.golin@linaro.org>
Tue, 17 Mar 2015 11:55:28 +0000 (11:55 +0000)
ARMv6K is another layer between ARMV6 and ARMV6T2. This is the LLVM
side of the changes.

ARMV6 family LLVM implementation.

+-------------------------------------+
| ARMV6                               |
+----------------+--------------------+
| ARMV6M (thumb) | ARMV6K (arm,thumb) | <- From ARMV6K and ARMV6M processors
+----------------+--------------------+    have support for hint instructions
| ARMV6T2 (arm,thumb,thumb2)          |    (SEV/WFE/WFI/NOP/YIELD). They can
+-------------------------------------+    be either real or default to NOP.
| ARMV7 (arm,thumb,thumb2)            |    The two processors also use
+-------------------------------------+    different encoding for them.

Patch by Vinicius Tinti.

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

15 files changed:
include/llvm/ADT/Triple.h
include/llvm/Support/ARMBuildAttributes.h
lib/Support/Triple.cpp
lib/Target/ARM/ARM.td
lib/Target/ARM/ARMBaseInstrInfo.cpp
lib/Target/ARM/ARMInstrInfo.td
lib/Target/ARM/ARMSubtarget.cpp
lib/Target/ARM/ARMSubtarget.h
lib/Target/ARM/MCTargetDesc/ARMArchName.def
lib/Target/ARM/MCTargetDesc/ARMELFStreamer.cpp
lib/Target/ARM/MCTargetDesc/ARMMCTargetDesc.cpp
test/CodeGen/ARM/build-attributes.ll
test/MC/ARM/arm11-hint-instr.s [new file with mode: 0644]
test/MC/ARM/directive-arch-armv6k.s [new file with mode: 0644]
test/MC/ARM/thumb-diagnostics.s

index 535e0cc..b4b61fa 100644 (file)
@@ -93,6 +93,7 @@ public:
     ARMSubArch_v7s,
     ARMSubArch_v6,
     ARMSubArch_v6m,
+    ARMSubArch_v6k,
     ARMSubArch_v6t2,
     ARMSubArch_v5,
     ARMSubArch_v5te,
index 96a8219..5814ec8 100644 (file)
@@ -100,8 +100,8 @@ enum CPUArch {
   v5TEJ    = 5,   // e.g. ARM926EJ_S
   v6       = 6,   // e.g. ARM1136J_S
   v6KZ     = 7,   // e.g. ARM1176JZ_S
-  v6T2     = 8,   // e.g. ARM1156T2F_S
-  v6K      = 9,   // e.g. ARM1136J_S
+  v6T2     = 8,   // e.g. ARM1156T2_S
+  v6K      = 9,   // e.g. ARM1176JZ_S
   v7       = 10,  // e.g. Cortex A8, Cortex M3
   v6_M     = 11,  // e.g. Cortex M1
   v6S_M    = 12,  // v6_M with the System extensions
index 59a7ba1..c395571 100644 (file)
@@ -415,6 +415,7 @@ static Triple::SubArchType parseSubArch(StringRef SubArchName) {
     .EndsWith("v6", Triple::ARMSubArch_v6)
     .EndsWith("v6m", Triple::ARMSubArch_v6m)
     .EndsWith("v6sm", Triple::ARMSubArch_v6m)
+    .EndsWith("v6k", Triple::ARMSubArch_v6k)
     .EndsWith("v6t2", Triple::ARMSubArch_v6t2)
     .EndsWith("v5", Triple::ARMSubArch_v5)
     .EndsWith("v5e", Triple::ARMSubArch_v5)
@@ -1073,9 +1074,9 @@ const char *Triple::getARMCPUForArch(StringRef MArch) const {
       .Cases("v5", "v5t", "arm10tdmi")
       .Cases("v5e", "v5te", "arm1022e")
       .Case("v5tej", "arm926ej-s")
-      .Cases("v6", "v6k", "arm1136jf-s")
+      .Case("v6", "arm1136jf-s")
       .Case("v6j", "arm1136j-s")
-      .Cases("v6z", "v6zk", "arm1176jzf-s")
+      .Cases("v6k", "v6z", "v6zk", "arm1176jzf-s")
       .Case("v6t2", "arm1156t2-s")
       .Cases("v6m", "v6-m", "v6sm", "v6s-m", "cortex-m0")
       .Cases("v7", "v7a", "v7-a", "v7l", "v7-l", "cortex-a8")
index a8c4c9d..0f545ef 100644 (file)
@@ -162,9 +162,12 @@ def HasV6Ops    : SubtargetFeature<"v6", "HasV6Ops", "true",
 def HasV6MOps   : SubtargetFeature<"v6m", "HasV6MOps", "true",
                                    "Support ARM v6M instructions",
                                    [HasV6Ops]>;
+def HasV6KOps   : SubtargetFeature<"v6k", "HasV6KOps", "true",
+                                   "Support ARM v6k instructions",
+                                   [HasV6Ops]>;
 def HasV6T2Ops  : SubtargetFeature<"v6t2", "HasV6T2Ops", "true",
                                    "Support ARM v6t2 instructions",
-                                   [HasV6MOps, FeatureThumb2]>;
+                                   [HasV6MOps, HasV6KOps, FeatureThumb2]>;
 def HasV7Ops    : SubtargetFeature<"v7", "HasV7Ops", "true",
                                    "Support ARM v7 instructions",
                                    [HasV6T2Ops, FeaturePerfMon]>;
@@ -315,12 +318,6 @@ def : ProcNoItin<"iwmmxt",          [HasV5TEOps]>;
 def : Processor<"arm1136j-s",       ARMV6Itineraries, [HasV6Ops]>;
 def : Processor<"arm1136jf-s",      ARMV6Itineraries, [HasV6Ops, FeatureVFP2,
                                                        FeatureHasSlowFPVMLx]>;
-def : Processor<"arm1176jz-s",      ARMV6Itineraries, [HasV6Ops]>;
-def : Processor<"arm1176jzf-s",     ARMV6Itineraries, [HasV6Ops, FeatureVFP2,
-                                                       FeatureHasSlowFPVMLx]>;
-def : Processor<"mpcorenovfp",      ARMV6Itineraries, [HasV6Ops]>;
-def : Processor<"mpcore",           ARMV6Itineraries, [HasV6Ops, FeatureVFP2,
-                                                       FeatureHasSlowFPVMLx]>;
 
 // V6M Processors.
 def : Processor<"cortex-m0",        ARMV6Itineraries, [HasV6MOps, FeatureNoARM,
@@ -332,6 +329,14 @@ def : Processor<"cortex-m1",        ARMV6Itineraries, [HasV6MOps, FeatureNoARM,
 def : Processor<"sc000",            ARMV6Itineraries, [HasV6MOps, FeatureNoARM,
                                                        FeatureDB, FeatureMClass]>;
 
+// V6K Processors.
+def : Processor<"arm1176jz-s",      ARMV6Itineraries, [HasV6KOps]>;
+def : Processor<"arm1176jzf-s",     ARMV6Itineraries, [HasV6KOps, FeatureVFP2,
+                                                       FeatureHasSlowFPVMLx]>;
+def : Processor<"mpcorenovfp",      ARMV6Itineraries, [HasV6KOps]>;
+def : Processor<"mpcore",           ARMV6Itineraries, [HasV6KOps, FeatureVFP2,
+                                                       FeatureHasSlowFPVMLx]>;
+
 // V6T2 Processors.
 def : Processor<"arm1156t2-s",      ARMV6Itineraries, [HasV6T2Ops,
                                                        FeatureDSPThumb2]>;
index 42e37fe..f59c3fa 100644 (file)
@@ -4512,7 +4512,7 @@ breakPartialRegDependency(MachineBasicBlock::iterator MI,
 }
 
 bool ARMBaseInstrInfo::hasNOP() const {
-  return (Subtarget.getFeatureBits() & ARM::HasV6T2Ops) != 0;
+  return (Subtarget.getFeatureBits() & ARM::HasV6KOps) != 0;
 }
 
 bool ARMBaseInstrInfo::isSwiftFastImmShift(const MachineInstr *MI) const {
index 126c552..e9e8b8f 100644 (file)
@@ -199,6 +199,9 @@ def HasV6M           : Predicate<"Subtarget->hasV6MOps()">,
 def HasV6T2          : Predicate<"Subtarget->hasV6T2Ops()">,
                                  AssemblerPredicate<"HasV6T2Ops", "armv6t2">;
 def NoV6T2           : Predicate<"!Subtarget->hasV6T2Ops()">;
+def HasV6K           : Predicate<"Subtarget->hasV6KOps()">,
+                                 AssemblerPredicate<"HasV6KOps", "armv6k">;
+def NoV6K            : Predicate<"!Subtarget->hasV6KOps()">;
 def HasV7            : Predicate<"Subtarget->hasV7Ops()">,
                                  AssemblerPredicate<"HasV7Ops", "armv7">;
 def HasV8            : Predicate<"Subtarget->hasV8Ops()">,
@@ -1835,11 +1838,11 @@ def HINT : AI<(outs), (ins imm0_239:$imm), MiscFrm, NoItinerary,
   let Inst{7-0} = imm;
 }
 
-def : InstAlias<"nop$p", (HINT 0, pred:$p)>, Requires<[IsARM, HasV6T2]>;
-def : InstAlias<"yield$p", (HINT 1, pred:$p)>, Requires<[IsARM, HasV6T2]>;
-def : InstAlias<"wfe$p", (HINT 2, pred:$p)>, Requires<[IsARM, HasV6T2]>;
-def : InstAlias<"wfi$p", (HINT 3, pred:$p)>, Requires<[IsARM, HasV6T2]>;
-def : InstAlias<"sev$p", (HINT 4, pred:$p)>, Requires<[IsARM, HasV6T2]>;
+def : InstAlias<"nop$p", (HINT 0, pred:$p)>, Requires<[IsARM, HasV6K]>;
+def : InstAlias<"yield$p", (HINT 1, pred:$p)>, Requires<[IsARM, HasV6K]>;
+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 SEL : AI<(outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm), DPFrm, NoItinerary, "sel",
index a82b9f2..3b0d787 100644 (file)
@@ -129,6 +129,7 @@ void ARMSubtarget::initializeEnvironment() {
   HasV5TEOps = false;
   HasV6Ops = false;
   HasV6MOps = false;
+  HasV6KOps = false;
   HasV6T2Ops = false;
   HasV7Ops = false;
   HasV8Ops = false;
index 64d499a..fc1176d 100644 (file)
@@ -56,13 +56,14 @@ protected:
   ARMProcClassEnum ARMProcClass;
 
   /// HasV4TOps, HasV5TOps, HasV5TEOps,
-  /// HasV6Ops, HasV6MOps, HasV6T2Ops, HasV7Ops, HasV8Ops -
+  /// HasV6Ops, HasV6MOps, HasV6KOps, HasV6T2Ops, HasV7Ops, HasV8Ops -
   /// Specify whether target support specific ARM ISA variants.
   bool HasV4TOps;
   bool HasV5TOps;
   bool HasV5TEOps;
   bool HasV6Ops;
   bool HasV6MOps;
+  bool HasV6KOps;
   bool HasV6T2Ops;
   bool HasV7Ops;
   bool HasV8Ops;
@@ -284,6 +285,7 @@ public:
   bool hasV5TEOps() const { return HasV5TEOps; }
   bool hasV6Ops()   const { return HasV6Ops;   }
   bool hasV6MOps()  const { return HasV6MOps;  }
+  bool hasV6KOps()  const { return HasV6KOps; }
   bool hasV6T2Ops() const { return HasV6T2Ops; }
   bool hasV7Ops()   const { return HasV7Ops;  }
   bool hasV8Ops()   const { return HasV8Ops;  }
index 9f007a0..8f75a67 100644 (file)
@@ -30,6 +30,7 @@ ARM_ARCH_NAME("armv5t",  ARMV5T,  "5T",      v5T)
 ARM_ARCH_NAME("armv5te", ARMV5TE, "5TE",     v5TE)
 ARM_ARCH_NAME("armv6",   ARMV6,   "6",       v6)
 ARM_ARCH_NAME("armv6j",  ARMV6J,  "6J",      v6)
+ARM_ARCH_NAME("armv6k",  ARMV6K,  "6K",      v6K)
 ARM_ARCH_NAME("armv6t2", ARMV6T2, "6T2",     v6T2)
 ARM_ARCH_NAME("armv6z",  ARMV6Z,  "6Z",      v6KZ)
 ARM_ARCH_NAME("armv6zk", ARMV6ZK, "6ZK",     v6KZ)
index bc76249..4acf9fb 100644 (file)
@@ -783,6 +783,7 @@ void ARMTargetELFStreamer::emitArchDefaultAttributes() {
     setAttributeItem(THUMB_ISA_use, AllowThumb32, false);
     break;
 
+  case ARM::ARMV6K:
   case ARM::ARMV6Z:
   case ARM::ARMV6ZK:
     setAttributeItem(ARM_ISA_use, Allowed, false);
index ab40465..d294664 100644 (file)
@@ -195,6 +195,9 @@ std::string ARM_MC::ParseARMTriple(StringRef TT, StringRef CPU) {
   case Triple::ARMSubArch_v6t2:
     ARMArchFeature = "+v6t2";
     break;
+  case Triple::ARMSubArch_v6k:
+    ARMArchFeature = "+v6k";
+    break;
   case Triple::ARMSubArch_v6m:
     isThumb = true;
     if (NoCPU)
index 37c6a44..0450bbe 100644 (file)
 ; RUN: llc < %s -mtriple=armv6-none-linux-gnueabi -mcpu=arm1136j-s | FileCheck %s --check-prefix=STRICT-ALIGN
 ; RUN: llc < %s -mtriple=armv6-none-linux-gnueabi -mcpu=arm1136j-s -arm-no-strict-align | FileCheck %s --check-prefix=NO-STRICT-ALIGN
 ; RUN: llc < %s -mtriple=armv6-none-linux-gnueabi -mcpu=arm1136j-s -arm-strict-align | FileCheck %s --check-prefix=STRICT-ALIGN
+; ARMv6k
+; RUN: llc < %s -mtriple=armv6k-none-netbsd-gnueabi -mcpu=arm1176j-s | FileCheck %s --check-prefix=NO-STRICT-ALIGN
+; RUN: llc < %s -mtriple=armv6k-none-linux-gnueabi -mcpu=arm1176j-s | FileCheck %s --check-prefix=STRICT-ALIGN
+; RUN: llc < %s -mtriple=armv6k-none-linux-gnueabi -mcpu=arm1176j-s -arm-no-strict-align | FileCheck %s --check-prefix=NO-STRICT-ALIGN
+; RUN: llc < %s -mtriple=armv6k-none-linux-gnueabi -mcpu=arm1176j-s -arm-strict-align | FileCheck %s --check-prefix=STRICT-ALIGN
 ; ARMv6m
 ; RUN: llc < %s -mtriple=thumb-none-linux-gnueabi -arm-no-strict-align -mcpu=cortex-m0 | FileCheck %s --check-prefix=STRICT-ALIGN
 ; RUN: llc < %s -mtriple=thumb-none-linux-gnueabi -arm-strict-align -mcpu=cortex-m0 | FileCheck %s --check-prefix=STRICT-ALIGN
diff --git a/test/MC/ARM/arm11-hint-instr.s b/test/MC/ARM/arm11-hint-instr.s
new file mode 100644 (file)
index 0000000..6f5a374
--- /dev/null
@@ -0,0 +1,69 @@
+@ RUN: not llvm-mc -triple=armv6 -show-encoding < %s > %t1 2> %t2
+@ RUN: FileCheck --check-prefix=CHECK-V6 %s < %t1
+@ RUN: FileCheck --check-prefix=CHECK-ERROR-V6 %s < %t2
+@ RUN: llvm-mc -triple=armv6k -show-encoding < %s \
+@ RUN:     | FileCheck --check-prefix=CHECK-ARM %s
+@ RUN: llvm-mc -triple=armv6t2 -show-encoding < %s \
+@ RUN:     | FileCheck --check-prefix=CHECK-ARM %s
+@ RUN: llvm-mc -triple=thumb -mcpu=arm1156t2-s -show-encoding < %s \
+@ RUN:     | FileCheck --check-prefix=CHECK-THUMB %s
+@ RUN: llvm-mc -triple=armv6m -show-encoding < %s \
+@ RUN:     | FileCheck --check-prefix=CHECK-V6M %s
+
+  .syntax unified
+
+@------------------------------------------------------------------------------
+@ YIELD/WFE/WFI/SEV - are not supported pre v6K
+@------------------------------------------------------------------------------
+        nop
+        yield
+        wfe
+        wfi
+        sev
+
+
+@------------------------------------------------------------------------------
+@ v6 using ARM encoding
+@------------------------------------------------------------------------------
+@ CHECK-V6: mov        r0, r0                  @ encoding: [0x00,0x00,0xa0,0xe1]
+@ CHECK-ERROR-V6: error: instruction requires: armv6k
+@ CHECK-ERROR-V6: yield
+@ CHECK-ERROR-V6: ^
+@ CHECK-ERROR-V6: error: instruction requires: armv6k
+@ CHECK-ERROR-V6: wfe
+@ CHECK-ERROR-V6: ^
+@ CHECK-ERROR-V6: error: instruction requires: armv6k
+@ CHECK-ERROR-V6: wfi
+@ CHECK-ERROR-V6: error: instruction requires: armv6k
+@ CHECK-ERROR-V6: sev
+@ CHECK-ERROR-V6: ^
+
+@------------------------------------------------------------------------------
+@ v6K using ARM encoding
+@------------------------------------------------------------------------------
+@------------------------------------------------------------------------------
+@ v6T2 using ARM encoding (arm triple)
+@------------------------------------------------------------------------------
+@ CHECK-ARM: nop                             @ encoding: [0x00,0xf0,0x20,0xe3]
+@ CHECK-ARM: yield                           @ encoding: [0x01,0xf0,0x20,0xe3]
+@ CHECK-ARM: wfe                             @ encoding: [0x02,0xf0,0x20,0xe3]
+@ CHECK-ARM: wfi                             @ encoding: [0x03,0xf0,0x20,0xe3]
+@ CHECK-ARM: sev                             @ encoding: [0x04,0xf0,0x20,0xe3]
+
+@------------------------------------------------------------------------------
+@ v6T2 using THUMB encoding (thumb triple)
+@------------------------------------------------------------------------------
+@ CHECK-THUMB: nop                             @ encoding: [0x00,0xbf]
+@ CHECK-THUMB: yield                           @ encoding: [0x10,0xbf]
+@ CHECK-THUMB: wfe                             @ encoding: [0x20,0xbf]
+@ CHECK-THUMB: wfi                             @ encoding: [0x30,0xbf]
+@ CHECK-THUMB: sev                             @ encoding: [0x40,0xbf]
+
+@------------------------------------------------------------------------------
+@ v6M using THUMB encoding
+@------------------------------------------------------------------------------
+@ CHECK-V6M: nop                             @ encoding: [0x00,0xbf]
+@ CHECK-V6M: yield                           @ encoding: [0x10,0xbf]
+@ CHECK-V6M: wfe                             @ encoding: [0x20,0xbf]
+@ CHECK-V6M: wfi                             @ encoding: [0x30,0xbf]
+@ CHECK-V6M: sev                             @ encoding: [0x40,0xbf]
diff --git a/test/MC/ARM/directive-arch-armv6k.s b/test/MC/ARM/directive-arch-armv6k.s
new file mode 100644 (file)
index 0000000..ee433fa
--- /dev/null
@@ -0,0 +1,34 @@
+@ Test the .arch directive for armv6k
+
+@ This test case will check the default .ARM.attributes value for the
+@ armv6k architecture.
+
+@ RUN: llvm-mc -triple arm-eabi -filetype asm %s \
+@ RUN:   | FileCheck %s -check-prefix CHECK-ASM
+@ RUN: llvm-mc -triple arm-eabi -filetype obj %s \
+@ RUN:   | llvm-readobj -arm-attributes | FileCheck %s -check-prefix CHECK-ATTR
+
+       .syntax unified
+       .arch   armv6k
+
+@ CHECK-ASM:   .arch   armv6k
+
+@ CHECK-ATTR: FileAttributes {
+@ CHECK-ATTR:   Attribute {
+@ CHECK-ATTR:     TagName: CPU_name
+@ CHECK-ATTR:     Value: 6K
+@ CHECK-ATTR:   }
+@ CHECK-ATTR:   Attribute {
+@ CHECK-ATTR:     TagName: CPU_arch
+@ CHECK-ATTR:     Description: ARM v6K
+@ CHECK-ATTR:   }
+@ CHECK-ATTR:   Attribute {
+@ CHECK-ATTR:     TagName: ARM_ISA_use
+@ CHECK-ATTR:     Description: Permitted
+@ CHECK-ATTR:   }
+@ CHECK-ATTR:   Attribute {
+@ CHECK-ATTR:     TagName: THUMB_ISA_use
+@ CHECK-ATTR:     Description: Thumb-1
+@ CHECK-ATTR:   }
+@ CHECK-ATTR: }
+
index bd26d06..5dcac90 100644 (file)
@@ -235,12 +235,16 @@ error: invalid operand for instruction
 @ CHECK-ERRORS: error: branch target out of range
 
 @------------------------------------------------------------------------------
-@ WFE/WFI/YIELD - are not supported pre v6T2
+@ SEV/WFE/WFI/YIELD - are not supported pre v6M or v6T2
 @------------------------------------------------------------------------------
+        sev
         wfe
         wfi
         yield
 
+@ CHECK-ERRORS: error: instruction requires: armv6m or armv6t2
+@ CHECK-ERRORS: sev
+@ CHECK-ERRORS: ^
 @ CHECK-ERRORS: error: instruction requires: armv6m or armv6t2
 @ CHECK-ERRORS: wfe
 @ CHECK-ERRORS: ^