From 28aa28bb7e61b1939926e48c84f91743a208cbc6 Mon Sep 17 00:00:00 2001 From: Renato Golin Date: Tue, 17 Mar 2015 11:55:28 +0000 Subject: [PATCH] [ARM] Add support for ARMV6K subtarget (LLVM) 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. llvm-svn: 232468 --- include/llvm/ADT/Triple.h | 1 + include/llvm/Support/ARMBuildAttributes.h | 4 +- lib/Support/Triple.cpp | 5 +- lib/Target/ARM/ARM.td | 19 +++-- lib/Target/ARM/ARMBaseInstrInfo.cpp | 2 +- lib/Target/ARM/ARMInstrInfo.td | 13 ++-- lib/Target/ARM/ARMSubtarget.cpp | 1 + lib/Target/ARM/ARMSubtarget.h | 4 +- lib/Target/ARM/MCTargetDesc/ARMArchName.def | 1 + .../ARM/MCTargetDesc/ARMELFStreamer.cpp | 1 + .../ARM/MCTargetDesc/ARMMCTargetDesc.cpp | 3 + test/CodeGen/ARM/build-attributes.ll | 5 ++ test/MC/ARM/arm11-hint-instr.s | 69 +++++++++++++++++++ test/MC/ARM/directive-arch-armv6k.s | 34 +++++++++ test/MC/ARM/thumb-diagnostics.s | 6 +- 15 files changed, 149 insertions(+), 19 deletions(-) create mode 100644 test/MC/ARM/arm11-hint-instr.s create mode 100644 test/MC/ARM/directive-arch-armv6k.s diff --git a/include/llvm/ADT/Triple.h b/include/llvm/ADT/Triple.h index 535e0cca1a4..b4b61fae731 100644 --- a/include/llvm/ADT/Triple.h +++ b/include/llvm/ADT/Triple.h @@ -93,6 +93,7 @@ public: ARMSubArch_v7s, ARMSubArch_v6, ARMSubArch_v6m, + ARMSubArch_v6k, ARMSubArch_v6t2, ARMSubArch_v5, ARMSubArch_v5te, diff --git a/include/llvm/Support/ARMBuildAttributes.h b/include/llvm/Support/ARMBuildAttributes.h index 96a8219bfb8..5814ec870ad 100644 --- a/include/llvm/Support/ARMBuildAttributes.h +++ b/include/llvm/Support/ARMBuildAttributes.h @@ -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 diff --git a/lib/Support/Triple.cpp b/lib/Support/Triple.cpp index 59a7ba14826..c3955714eb7 100644 --- a/lib/Support/Triple.cpp +++ b/lib/Support/Triple.cpp @@ -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") diff --git a/lib/Target/ARM/ARM.td b/lib/Target/ARM/ARM.td index a8c4c9d07f8..0f545ef466e 100644 --- a/lib/Target/ARM/ARM.td +++ b/lib/Target/ARM/ARM.td @@ -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]>; diff --git a/lib/Target/ARM/ARMBaseInstrInfo.cpp b/lib/Target/ARM/ARMBaseInstrInfo.cpp index 42e37fe44fc..f59c3fa8b1a 100644 --- a/lib/Target/ARM/ARMBaseInstrInfo.cpp +++ b/lib/Target/ARM/ARMBaseInstrInfo.cpp @@ -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 { diff --git a/lib/Target/ARM/ARMInstrInfo.td b/lib/Target/ARM/ARMInstrInfo.td index 126c5529c15..e9e8b8fa620 100644 --- a/lib/Target/ARM/ARMInstrInfo.td +++ b/lib/Target/ARM/ARMInstrInfo.td @@ -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", diff --git a/lib/Target/ARM/ARMSubtarget.cpp b/lib/Target/ARM/ARMSubtarget.cpp index a82b9f21aa9..3b0d787528d 100644 --- a/lib/Target/ARM/ARMSubtarget.cpp +++ b/lib/Target/ARM/ARMSubtarget.cpp @@ -129,6 +129,7 @@ void ARMSubtarget::initializeEnvironment() { HasV5TEOps = false; HasV6Ops = false; HasV6MOps = false; + HasV6KOps = false; HasV6T2Ops = false; HasV7Ops = false; HasV8Ops = false; diff --git a/lib/Target/ARM/ARMSubtarget.h b/lib/Target/ARM/ARMSubtarget.h index 64d499a4dc5..fc1176d85d1 100644 --- a/lib/Target/ARM/ARMSubtarget.h +++ b/lib/Target/ARM/ARMSubtarget.h @@ -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; } diff --git a/lib/Target/ARM/MCTargetDesc/ARMArchName.def b/lib/Target/ARM/MCTargetDesc/ARMArchName.def index 9f007a035a8..8f75a670fcc 100644 --- a/lib/Target/ARM/MCTargetDesc/ARMArchName.def +++ b/lib/Target/ARM/MCTargetDesc/ARMArchName.def @@ -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) diff --git a/lib/Target/ARM/MCTargetDesc/ARMELFStreamer.cpp b/lib/Target/ARM/MCTargetDesc/ARMELFStreamer.cpp index bc762499a35..4acf9fb1848 100644 --- a/lib/Target/ARM/MCTargetDesc/ARMELFStreamer.cpp +++ b/lib/Target/ARM/MCTargetDesc/ARMELFStreamer.cpp @@ -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); diff --git a/lib/Target/ARM/MCTargetDesc/ARMMCTargetDesc.cpp b/lib/Target/ARM/MCTargetDesc/ARMMCTargetDesc.cpp index ab40465e93c..d294664bc37 100644 --- a/lib/Target/ARM/MCTargetDesc/ARMMCTargetDesc.cpp +++ b/lib/Target/ARM/MCTargetDesc/ARMMCTargetDesc.cpp @@ -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) diff --git a/test/CodeGen/ARM/build-attributes.ll b/test/CodeGen/ARM/build-attributes.ll index 37c6a447dd3..0450bbea3ba 100644 --- a/test/CodeGen/ARM/build-attributes.ll +++ b/test/CodeGen/ARM/build-attributes.ll @@ -136,6 +136,11 @@ ; 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 index 00000000000..6f5a374e417 --- /dev/null +++ b/test/MC/ARM/arm11-hint-instr.s @@ -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 index 00000000000..ee433fa283e --- /dev/null +++ b/test/MC/ARM/directive-arch-armv6k.s @@ -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: } + diff --git a/test/MC/ARM/thumb-diagnostics.s b/test/MC/ARM/thumb-diagnostics.s index bd26d06865c..5dcac90a901 100644 --- a/test/MC/ARM/thumb-diagnostics.s +++ b/test/MC/ARM/thumb-diagnostics.s @@ -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: ^