ARM: allow cortex-m0 to use hint instructions

The hint instructions ("nop", "yield", etc) are mostly Thumb2-only, but have
been ported across to the v6M architecture. Fortunately, v6M seems to sit
nicely between v6 (thumb-1 only) and v6T2, so we can add a feature for it
fairly easily.

rdar://problem/15144406

llvm-svn: 192097
This commit is contained in:
Tim Northover 2013-10-07 11:10:47 +00:00
parent 17a44966be
commit f86d1f0b77
8 changed files with 59 additions and 21 deletions

View File

@ -146,9 +146,12 @@ def HasV5TEOps : SubtargetFeature<"v5te", "HasV5TEOps", "true",
def HasV6Ops : SubtargetFeature<"v6", "HasV6Ops", "true",
"Support ARM v6 instructions",
[HasV5TEOps]>;
def HasV6MOps : SubtargetFeature<"v6m", "HasV6MOps", "true",
"Support ARM v6M instructions",
[HasV6Ops]>;
def HasV6T2Ops : SubtargetFeature<"v6t2", "HasV6T2Ops", "true",
"Support ARM v6t2 instructions",
[HasV6Ops, FeatureThumb2]>;
[HasV6MOps, FeatureThumb2]>;
def HasV7Ops : SubtargetFeature<"v7", "HasV7Ops", "true",
"Support ARM v7 instructions",
[HasV6T2Ops, FeaturePerfMon]>;
@ -254,7 +257,7 @@ def : Processor<"mpcore", ARMV6Itineraries, [HasV6Ops, FeatureVFP2,
FeatureHasSlowFPVMLx]>;
// V6M Processors.
def : Processor<"cortex-m0", ARMV6Itineraries, [HasV6Ops, FeatureNoARM,
def : Processor<"cortex-m0", ARMV6Itineraries, [HasV6MOps, FeatureNoARM,
FeatureDB, FeatureMClass]>;
// V6T2 Processors.

View File

@ -193,6 +193,9 @@ def HasV5TE : Predicate<"Subtarget->hasV5TEOps()">,
def HasV6 : Predicate<"Subtarget->hasV6Ops()">,
AssemblerPredicate<"HasV6Ops", "armv6">;
def NoV6 : Predicate<"!Subtarget->hasV6Ops()">;
def HasV6M : Predicate<"Subtarget->hasV6MOps()">,
AssemblerPredicate<"HasV6MOps",
"armv6m or armv6t2">;
def HasV6T2 : Predicate<"Subtarget->hasV6T2Ops()">,
AssemblerPredicate<"HasV6T2Ops", "armv6t2">;
def NoV6T2 : Predicate<"!Subtarget->hasV6T2Ops()">;

View File

@ -271,23 +271,23 @@ class T1SystemEncoding<bits<8> opc>
def tNOP : T1pI<(outs), (ins), NoItinerary, "nop", "", []>,
T1SystemEncoding<0x00>, // A8.6.110
Requires<[IsThumb2]>;
Requires<[IsThumb, HasV6M]>;
def tYIELD : T1pI<(outs), (ins), NoItinerary, "yield", "", []>,
T1SystemEncoding<0x10>, // A8.6.410
Requires<[IsThumb2]>;
Requires<[IsThumb, HasV6M]>;
def tWFE : T1pI<(outs), (ins), NoItinerary, "wfe", "", []>,
T1SystemEncoding<0x20>, // A8.6.408
Requires<[IsThumb2]>;
Requires<[IsThumb, HasV6M]>;
def tWFI : T1pI<(outs), (ins), NoItinerary, "wfi", "", []>,
T1SystemEncoding<0x30>, // A8.6.409
Requires<[IsThumb2]>;
Requires<[IsThumb, HasV6M]>;
def tSEV : T1pI<(outs), (ins), NoItinerary, "sev", "", []>,
T1SystemEncoding<0x40>, // A8.6.157
Requires<[IsThumb2]>;
Requires<[IsThumb, HasV6M]>;
def tSEVL : T1pI<(outs), (ins), NoItinerary, "sevl", "", [(int_arm_sevl)]>,
T1SystemEncoding<0x50>,

View File

@ -44,12 +44,13 @@ protected:
ARMProcClassEnum ARMProcClass;
/// HasV4TOps, HasV5TOps, HasV5TEOps,
/// HasV6Ops, HasV6T2Ops, HasV7Ops, HasV8Ops -
/// HasV6Ops, HasV6MOps, HasV6T2Ops, HasV7Ops, HasV8Ops -
/// Specify whether target support specific ARM ISA variants.
bool HasV4TOps;
bool HasV5TOps;
bool HasV5TEOps;
bool HasV6Ops;
bool HasV6MOps;
bool HasV6T2Ops;
bool HasV7Ops;
bool HasV8Ops;

View File

@ -162,6 +162,9 @@ class ARMAsmParser : public MCTargetAsmParser {
bool hasV6Ops() const {
return STI.getFeatureBits() & ARM::HasV6Ops;
}
bool hasV6MOps() const {
return STI.getFeatureBits() & ARM::HasV6MOps;
}
bool hasV7Ops() const {
return STI.getFeatureBits() & ARM::HasV7Ops;
}
@ -4812,7 +4815,10 @@ getMnemonicAcceptInfo(StringRef Mnemonic, StringRef FullInst,
Mnemonic != "stc2" && Mnemonic != "stc2l" &&
!Mnemonic.startswith("rfe") && !Mnemonic.startswith("srs");
} else if (isThumbOne()) {
CanAcceptPredicationCode = Mnemonic != "nop" && Mnemonic != "movs";
if (hasV6MOps())
CanAcceptPredicationCode = Mnemonic != "movs";
else
CanAcceptPredicationCode = Mnemonic != "nop" && Mnemonic != "movs";
} else
CanAcceptPredicationCode = true;
}

View File

@ -179,13 +179,13 @@ error: invalid operand for instruction
wfi
yield
@ CHECK-ERRORS: error: instruction requires: thumb2
@ CHECK-ERRORS: error: instruction requires: armv6m or armv6t2
@ CHECK-ERRORS: wfe
@ CHECK-ERRORS: ^
@ CHECK-ERRORS: error: instruction requires: thumb2
@ CHECK-ERRORS: error: instruction requires: armv6m or armv6t2
@ CHECK-ERRORS: wfi
@ CHECK-ERRORS: ^
@ CHECK-ERRORS: error: instruction requires: thumb2
@ CHECK-ERRORS: error: instruction requires: armv6m or armv6t2
@ CHECK-ERRORS: yield
@ CHECK-ERRORS: ^

View File

@ -0,0 +1,34 @@
@ RUN: llvm-mc -triple=thumbv7-apple-darwin -show-encoding < %s | FileCheck %s
@ RUN: llvm-mc -triple=thumbv6-apple-darwin -mcpu=cortex-m0 -show-encoding < %s | FileCheck %s
@ RUN: not llvm-mc -triple=thumbv6-apple-darwin -show-encoding < %s > %t 2> %t2
@ RUN: FileCheck %s --check-prefix=CHECK-EVIL-PRE-UAL < %t
@ RUN: FileCheck %s --check-prefix CHECK-ERROR < %t2
.syntax unified
nop
yield
wfe
wfi
sev
@ CHECK: nop @ encoding: [0x00,0xbf]
@ CHECK: yield @ encoding: [0x10,0xbf]
@ CHECK: wfe @ encoding: [0x20,0xbf]
@ CHECK: wfi @ encoding: [0x30,0xbf]
@ CHECK: sev @ encoding: [0x40,0xbf]
@ CHECK-EVIL-PRE-UAL: mov r8, r8 @ encoding: [0xc0,0x46]
@ CHECK-ERROR: error: instruction requires: armv6m or armv6t2
@ CHECK-ERROR-NEXT: yield
@ CHECK-ERROR: error: instruction requires: armv6m or armv6t2
@ CHECK-ERROR-NEXT: wfe
@ CHECK-ERROR: error: instruction requires: armv6m or armv6t2
@ CHECK-ERROR-NEXT: wfi
@ CHECK-ERROR: error: instruction requires: armv6m or armv6t2
@ CHECK-ERROR-NEXT: sev

View File

@ -1,9 +0,0 @@
@ RUN: llvm-mc -triple=thumbv6-apple-darwin -show-encoding < %s | FileCheck %s -check-prefix=CHECK-V6
@ RUN: llvm-mc -triple=thumbv7-apple-darwin -show-encoding < %s | FileCheck %s -check-prefix=CHECK-V7
.syntax unified
nop
@ CHECK-V6: mov r8, r8 @ encoding: [0xc0,0x46]
@ CHECK-V7: nop @ encoding: [0x00,0xbf]