Index: llvm/trunk/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp =================================================================== --- llvm/trunk/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp +++ llvm/trunk/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); @@ -5033,6 +5034,8 @@ parseDirectiveCFINegateRAState(); else if (IDVal == ".cfi_b_key_frame") parseDirectiveCFIBKeyFrame(); + else if (IDVal == ".arch_extension") + parseDirectiveArchExtension(Loc); else if (IsMachO) { if (IDVal == MCLOHDirectiveName()) parseDirectiveLOH(IDVal, Loc); @@ -5153,6 +5156,50 @@ 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"); + + const AsmToken &Tok = Parser.getTok(); + StringRef Name = Tok.getString(); + SMLoc ExtLoc = Tok.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: llvm/trunk/test/MC/AArch64/directive-arch_extension-nosimd.s =================================================================== --- llvm/trunk/test/MC/AArch64/directive-arch_extension-nosimd.s +++ llvm/trunk/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: llvm/trunk/test/MC/AArch64/directive-arch_extension-simd.s =================================================================== --- llvm/trunk/test/MC/AArch64/directive-arch_extension-simd.s +++ llvm/trunk/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