diff options
Diffstat (limited to 'llvm')
| -rw-r--r-- | llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp | 72 | ||||
| -rw-r--r-- | llvm/test/MC/AArch64/directive-cpu.s | 63 | 
2 files changed, 135 insertions, 0 deletions
diff --git a/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp b/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp index 4938b38b3b0..a00272dcb5f 100644 --- a/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp +++ b/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp @@ -70,6 +70,7 @@ private:    bool Error(SMLoc L, const Twine &Msg) { return getParser().Error(L, Msg); }    bool showMatchError(SMLoc Loc, unsigned ErrCode); +  bool parseDirectiveCPU(SMLoc L);    bool parseDirectiveWord(unsigned Size, SMLoc L);    bool parseDirectiveInst(SMLoc L); @@ -4195,6 +4196,8 @@ bool AArch64AsmParser::ParseDirective(AsmToken DirectiveID) {    StringRef IDVal = DirectiveID.getIdentifier();    SMLoc Loc = DirectiveID.getLoc(); +  if (IDVal == ".cpu") +    return parseDirectiveCPU(Loc);    if (IDVal == ".hword")      return parseDirectiveWord(2, Loc);    if (IDVal == ".word") @@ -4216,6 +4219,75 @@ bool AArch64AsmParser::ParseDirective(AsmToken DirectiveID) {    return parseDirectiveLOH(IDVal, Loc);  } +static const struct { +  const char *Name; +  const FeatureBitset Features; +} ExtensionMap[] = { +  { "crc", {AArch64::FeatureCRC} }, +  { "crypto", {AArch64::FeatureCrypto} }, +  { "fp", {AArch64::FeatureFPARMv8} }, +  { "simd", {AArch64::FeatureNEON} }, + +  // FIXME: Unsupported extensions +  { "lse", {} }, +  { "pan", {} }, +  { "lor", {} }, +  { "rdma", {} }, +  { "profile", {} }, +}; + +/// parseDirectiveCPU +///   ::= .cpu id +bool AArch64AsmParser::parseDirectiveCPU(SMLoc L) { +  SMLoc CPULoc = getLoc(); + +  StringRef CPU, ExtensionString; +  std::tie(CPU, ExtensionString) = +      getParser().parseStringToEndOfStatement().trim().split('+'); + +  SmallVector<StringRef, 4> RequestedExtensions; +  if (!ExtensionString.empty()) +    ExtensionString.split(RequestedExtensions, '+'); + +  // FIXME This is using tablegen data, but should be moved to ARMTargetParser +  // once that is tablegen'ed +  if (!getSTI().isCPUStringValid(CPU)) { +    Error(CPULoc, "unknown CPU name"); +    return false; +  } + +  MCSubtargetInfo &STI = copySTI(); +  STI.setDefaultFeatures(CPU, ""); + +  FeatureBitset Features = STI.getFeatureBits(); +  for (auto Name : RequestedExtensions) { +    bool EnableFeature = true; + +    if (Name.startswith_lower("no")) { +      EnableFeature = false; +      Name = Name.substr(2); +    } + +    for (const auto &Extension : ExtensionMap) { +      if (Extension.Name != Name) +        continue; + +      if (Extension.Features.none()) +        report_fatal_error("unsupported architectural extension: " + Name); + +      FeatureBitset ToggleFeatures = EnableFeature +                                         ? (~Features & Extension.Features) +                                         : ( Features & Extension.Features); +      uint64_t Features = +          ComputeAvailableFeatures(STI.ToggleFeature(ToggleFeatures)); +      setAvailableFeatures(Features); + +      break; +    } +  } +  return false; +} +  /// parseDirectiveWord  ///  ::= .word [ expression (, expression)* ]  bool AArch64AsmParser::parseDirectiveWord(unsigned Size, SMLoc L) { diff --git a/llvm/test/MC/AArch64/directive-cpu.s b/llvm/test/MC/AArch64/directive-cpu.s new file mode 100644 index 00000000000..8e7d4533744 --- /dev/null +++ b/llvm/test/MC/AArch64/directive-cpu.s @@ -0,0 +1,63 @@ +// RUN: not llvm-mc -triple aarch64-unknown-none-eabi -filetype asm -o - %s 2>&1 | FileCheck %s + +	.cpu generic + +	fminnm d0, d0, d1 + +	.cpu generic+fp + +	fminnm d0, d0, d1 + +	.cpu generic+nofp + +	fminnm d0, d0, d1 + +	.cpu generic+simd + +	addp v0.4s, v0.4s, v0.4s + +	.cpu generic+nosimd + +	addp v0.4s, v0.4s, v0.4s + +	.cpu generic+crc + +	crc32cx w0, w1, x3 + +	.cpu generic+nocrc + +	crc32cx w0, w1, x3 + +	.cpu generic+crypto+nocrc + +	aesd v0.16b, v2.16b + +	.cpu generic+nocrypto+crc + +	aesd v0.16b, v2.16b + +// 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: error: instruction requires: fp-armv8 +// CHECK: 	fminnm d0, d0, d1 +// CHECK: 	^ + +// CHECK: error: instruction requires: neon +// CHECK: 	addp v0.4s, v0.4s, v0.4s +// CHECK: 	^ + +// CHECK: error: instruction requires: crc +// CHECK: 	crc32cx w0, w1, x3 +// CHECK: 	^ + +// CHECK: error: instruction requires: crypto +// CHECK: 	aesd v0.16b, v2.16b +// 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  | 

