Index: lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp =================================================================== --- lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp +++ lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp @@ -165,6 +165,7 @@ OperandVector &Operands); bool parseDirectiveArch(SMLoc L); + bool parseDirectiveArchExtension(SMLoc L); bool parseDirectiveCPU(SMLoc L); bool parseDirectiveInst(SMLoc L); @@ -5031,6 +5032,8 @@ parseDirectiveInst(Loc); else if (IDVal == ".cfi_negate_ra_state") parseDirectiveCFINegateRAState(); + else if (IDVal == ".arch_extension") + parseDirectiveArchExtension(Loc); else if (IsMachO) { if (IDVal == MCLOHDirectiveName()) parseDirectiveLOH(IDVal, Loc); @@ -5151,6 +5154,49 @@ return false; } +/// parseDirectiveArchExtension +/// ::= .arch_extension [no]feature +bool AArch64AsmParser::parseDirectiveArchExtension(SMLoc L) { + MCAsmParser &Parser = getParser(); + + if (getLexer().isNot(AsmToken::Identifier)) + return Error(getLexer().getLoc(), "expected architecture extension name"); + + StringRef Name = Parser.getTok().getString(); + SMLoc ExtLoc = Parser.getTok().getLoc(); + Lex(); + + if (parseToken(AsmToken::EndOfStatement, + "unexpected token in '.arch_extension' directive")) + return true; + + bool EnableFeature = true; + if (Name.startswith_lower("no")) { + EnableFeature = false; + Name = Name.substr(2); + } + + MCSubtargetInfo &STI = copySTI(); + FeatureBitset Features = STI.getFeatureBits(); + for (const auto &Extension : ExtensionMap) { + if (Extension.Name != Name) + continue; + + if (Extension.Features.none()) + return Error(ExtLoc, "unsupported architectural extension: " + Name); + + FeatureBitset ToggleFeatures = EnableFeature + ? (~Features & Extension.Features) + : (Features & Extension.Features); + uint64_t Features = + ComputeAvailableFeatures(STI.ToggleFeature(ToggleFeatures)); + setAvailableFeatures(Features); + return false; + } + + return Error(ExtLoc, "unknown architectural extension: " + Name); +} + static SMLoc incrementLoc(SMLoc L, int Offset) { return SMLoc::getFromPointer(L.getPointer() + Offset); } Index: test/MC/AArch64/directive-arch_extension-nosimd.s =================================================================== --- /dev/null +++ test/MC/AArch64/directive-arch_extension-nosimd.s @@ -0,0 +1,6 @@ +// RUN: not llvm-mc -triple aarch64 -filetype asm -o - %s 2>&1 | FileCheck %s + + .arch_extension nosimd + + add v0.8b, v0.8b, v0.8b +// CHECK: error: instruction requires: neon Index: test/MC/AArch64/directive-arch_extension-simd.s =================================================================== --- /dev/null +++ test/MC/AArch64/directive-arch_extension-simd.s @@ -0,0 +1,6 @@ +// RUN: llvm-mc -triple aarch64 -mattr=-simd -filetype asm -o - %s | FileCheck %s + + .arch_extension simd + + add v0.8b, v0.8b, v0.8b +// CHECK: add v0.8b, v0.8b, v0.8b