From 1b41599cf8972abbf0d2ee7595dba78a4b158af0 Mon Sep 17 00:00:00 2001 From: Jessica Clarke Date: Sun, 18 May 2025 20:09:43 +0100 Subject: [PATCH] [MC][AArch64][ARM][X86] Push target-dependent assembler flags into targets (#139844) The .syntax unified directive and .codeX/.code X directives are, other than some simple common printing code, exclusively implemented in the targets themselves. Thus, remove the corresponding MCAF_* flags and reimplement the directives solely within the targets. This avoids exposing all targets to all other targets' flags. Since MCAF_SubsectionsViaSymbols is all that remains, convert it to its own function like other directives, simplifying its implementation. Note that, on X86, we now always need a target streamer when parsing assembly, as it's now used for directives that aren't COFF-specific. It still does not however need to do anything when producing a non-COFF object file, so this commit does not introduce any new target streamers. There is some churn in test output, and corresponding UTC regex changes, due to comments no longer being flushed by these various directives (and EmitEOL is not exposed outside MCAsmStreamer.cpp so we couldn't do so even if we wanted to), but that was a bit odd to be doing anyway. This is motivated by Morello LLVM, which adds yet another assembler flag to distinguish A64 and C64 instruction sets, but did not update every switch and so emits warnings during the build. Rather than fix those warnings it seems better to instead make the problem not exist in the first place via this change. --- llvm/include/llvm/MC/MCAsmBackend.h | 3 -- llvm/include/llvm/MC/MCAsmInfo.h | 10 ------ llvm/include/llvm/MC/MCDirectives.h | 8 ----- llvm/include/llvm/MC/MCELFStreamer.h | 1 - llvm/include/llvm/MC/MCStreamer.h | 9 +++-- llvm/include/llvm/MC/MCWasmStreamer.h | 1 - llvm/include/llvm/MC/MCWinCOFFStreamer.h | 1 - llvm/lib/MC/MCAsmInfo.cpp | 3 -- llvm/lib/MC/MCAsmStreamer.cpp | 13 ++----- llvm/lib/MC/MCELFStreamer.cpp | 5 --- llvm/lib/MC/MCMachOStreamer.cpp | 17 ++------- llvm/lib/MC/MCNullStreamer.cpp | 1 + llvm/lib/MC/MCParser/DarwinAsmParser.cpp | 2 +- llvm/lib/MC/MCStreamer.cpp | 5 ++- llvm/lib/MC/MCWasmStreamer.cpp | 8 ----- llvm/lib/MC/MCWinCOFFStreamer.cpp | 16 --------- llvm/lib/Object/RecordStreamer.h | 7 ++-- llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp | 2 +- .../AArch64/MCTargetDesc/AArch64MCAsmInfo.cpp | 1 - llvm/lib/Target/ARM/ARMAsmPrinter.cpp | 26 +++++++++----- .../lib/Target/ARM/AsmParser/ARMAsmParser.cpp | 16 +++++---- .../Target/ARM/MCTargetDesc/ARMAsmBackend.cpp | 20 ++--------- .../Target/ARM/MCTargetDesc/ARMAsmBackend.h | 10 ++---- .../ARM/MCTargetDesc/ARMAsmBackendDarwin.h | 5 ++- .../ARM/MCTargetDesc/ARMAsmBackendELF.h | 5 ++- .../ARM/MCTargetDesc/ARMAsmBackendWinCOFF.h | 4 +-- .../ARM/MCTargetDesc/ARMELFStreamer.cpp | 36 +++++++++---------- .../Target/ARM/MCTargetDesc/ARMMCAsmInfo.cpp | 6 ---- .../ARM/MCTargetDesc/ARMTargetStreamer.cpp | 3 ++ .../lib/Target/X86/AsmParser/X86AsmParser.cpp | 8 ++--- .../X86/MCTargetDesc/X86TargetStreamer.h | 4 +++ .../MCTargetDesc/X86WinCOFFTargetStreamer.cpp | 14 ++++++-- llvm/lib/Target/X86/X86AsmPrinter.cpp | 9 +++-- llvm/test/CodeGen/ARM/ldrd.ll | 12 +++---- .../ARM/thumb-function-section-reloc.ll | 4 +-- .../CodeGen/Thumb/thumb-shrink-wrapping.ll | 16 ++++----- llvm/test/DebugInfo/ARM/header.ll | 4 +-- llvm/utils/UpdateTestChecks/asm.py | 16 ++++++--- 38 files changed, 136 insertions(+), 195 deletions(-) diff --git a/llvm/include/llvm/MC/MCAsmBackend.h b/llvm/include/llvm/MC/MCAsmBackend.h index 691988ae1f1d..455812c0b10a 100644 --- a/llvm/include/llvm/MC/MCAsmBackend.h +++ b/llvm/include/llvm/MC/MCAsmBackend.h @@ -213,9 +213,6 @@ public: /// Give backend an opportunity to finish layout after relaxation virtual void finishLayout(MCAssembler const &Asm) const {} - /// Handle any target-specific assembler flags. By default, do nothing. - virtual void handleAssemblerFlag(MCAssemblerFlag Flag) {} - /// Generate the compact unwind encoding for the CFI instructions. virtual uint64_t generateCompactUnwindEncoding(const MCDwarfFrameInfo *FI, const MCContext *Ctxt) const { diff --git a/llvm/include/llvm/MC/MCAsmInfo.h b/llvm/include/llvm/MC/MCAsmInfo.h index 950dc952d0b4..3a31957f2f6b 100644 --- a/llvm/include/llvm/MC/MCAsmInfo.h +++ b/llvm/include/llvm/MC/MCAsmInfo.h @@ -166,13 +166,6 @@ protected: const char *InlineAsmStart; const char *InlineAsmEnd; - /// These are assembly directives that tells the assembler to interpret the - /// following instructions differently. Defaults to ".code16", ".code32", - /// ".code64". - const char *Code16Directive; - const char *Code32Directive; - const char *Code64Directive; - /// Which dialect of an assembler variant to use. Defaults to 0 unsigned AssemblerDialect = 0; @@ -544,9 +537,6 @@ public: const char *getInlineAsmStart() const { return InlineAsmStart; } const char *getInlineAsmEnd() const { return InlineAsmEnd; } - const char *getCode16Directive() const { return Code16Directive; } - const char *getCode32Directive() const { return Code32Directive; } - const char *getCode64Directive() const { return Code64Directive; } unsigned getAssemblerDialect() const { return AssemblerDialect; } bool doesAllowAtInName() const { return AllowAtInName; } void setAllowAtInName(bool V) { AllowAtInName = V; } diff --git a/llvm/include/llvm/MC/MCDirectives.h b/llvm/include/llvm/MC/MCDirectives.h index fcab56ff0a74..f8b7e05b3719 100644 --- a/llvm/include/llvm/MC/MCDirectives.h +++ b/llvm/include/llvm/MC/MCDirectives.h @@ -50,14 +50,6 @@ enum MCSymbolAttr { MCSA_Memtag, ///< .memtag (ELF) }; -enum MCAssemblerFlag { - MCAF_SyntaxUnified, ///< .syntax (ARM/ELF) - MCAF_SubsectionsViaSymbols, ///< .subsections_via_symbols (MachO) - MCAF_Code16, ///< .code16 (X86) / .code 16 (ARM) - MCAF_Code32, ///< .code32 (X86) / .code 32 (ARM) - MCAF_Code64 ///< .code64 (X86) -}; - enum MCDataRegionType { MCDR_DataRegion, ///< .data_region MCDR_DataRegionJT8, ///< .data_region jt8 diff --git a/llvm/include/llvm/MC/MCELFStreamer.h b/llvm/include/llvm/MC/MCELFStreamer.h index f084268aad18..f00b1645347f 100644 --- a/llvm/include/llvm/MC/MCELFStreamer.h +++ b/llvm/include/llvm/MC/MCELFStreamer.h @@ -53,7 +53,6 @@ public: void emitLabel(MCSymbol *Symbol, SMLoc Loc = SMLoc()) override; void emitLabelAtPos(MCSymbol *Symbol, SMLoc Loc, MCDataFragment &F, uint64_t Offset) override; - void emitAssemblerFlag(MCAssemblerFlag Flag) override; void emitWeakReference(MCSymbol *Alias, const MCSymbol *Symbol) override; bool emitSymbolAttribute(MCSymbol *Symbol, MCSymbolAttr Attribute) override; void emitCommonSymbol(MCSymbol *Symbol, uint64_t Size, diff --git a/llvm/include/llvm/MC/MCStreamer.h b/llvm/include/llvm/MC/MCStreamer.h index beed370858d7..1f5014843c5d 100644 --- a/llvm/include/llvm/MC/MCStreamer.h +++ b/llvm/include/llvm/MC/MCStreamer.h @@ -169,6 +169,11 @@ public: virtual void annotateTLSDescriptorSequence(const MCSymbolRefExpr *SRE); + virtual void emitSyntaxUnified(); + + virtual void emitCode16(); + virtual void emitCode32(); + // Note in the output that the specified \p Symbol is a Thumb mode function. virtual void emitThumbFunc(MCSymbol *Symbol); virtual void emitThumbSet(MCSymbol *Symbol, const MCExpr *Value); @@ -471,8 +476,8 @@ public: virtual void emitEHSymAttributes(const MCSymbol *Symbol, MCSymbol *EHSymbol); - /// Note in the output the specified \p Flag. - virtual void emitAssemblerFlag(MCAssemblerFlag Flag); + /// Emit a .subsection_via_symbols directive. + virtual void emitSubsectionsViaSymbols(); /// Emit the given list \p Options of strings as linker /// options into the output. diff --git a/llvm/include/llvm/MC/MCWasmStreamer.h b/llvm/include/llvm/MC/MCWasmStreamer.h index 02fda9635f1f..1b97e765fdf4 100644 --- a/llvm/include/llvm/MC/MCWasmStreamer.h +++ b/llvm/include/llvm/MC/MCWasmStreamer.h @@ -44,7 +44,6 @@ public: void emitLabel(MCSymbol *Symbol, SMLoc Loc = SMLoc()) override; void emitLabelAtPos(MCSymbol *Symbol, SMLoc Loc, MCDataFragment &F, uint64_t Offset) override; - void emitAssemblerFlag(MCAssemblerFlag Flag) override; void emitWeakReference(MCSymbol *Alias, const MCSymbol *Symbol) override; bool emitSymbolAttribute(MCSymbol *Symbol, MCSymbolAttr Attribute) override; void emitCommonSymbol(MCSymbol *Symbol, uint64_t Size, diff --git a/llvm/include/llvm/MC/MCWinCOFFStreamer.h b/llvm/include/llvm/MC/MCWinCOFFStreamer.h index bc01362b779b..b474ececb21d 100644 --- a/llvm/include/llvm/MC/MCWinCOFFStreamer.h +++ b/llvm/include/llvm/MC/MCWinCOFFStreamer.h @@ -45,7 +45,6 @@ public: void initSections(bool NoExecStack, const MCSubtargetInfo &STI) override; void changeSection(MCSection *Section, uint32_t Subsection = 0) override; void emitLabel(MCSymbol *Symbol, SMLoc Loc = SMLoc()) override; - void emitAssemblerFlag(MCAssemblerFlag Flag) override; bool emitSymbolAttribute(MCSymbol *Symbol, MCSymbolAttr Attribute) override; void emitSymbolDesc(MCSymbol *Symbol, unsigned DescValue) override; void beginCOFFSymbolDef(MCSymbol const *Symbol) override; diff --git a/llvm/lib/MC/MCAsmInfo.cpp b/llvm/lib/MC/MCAsmInfo.cpp index 49e8db209102..86759c32bb75 100644 --- a/llvm/lib/MC/MCAsmInfo.cpp +++ b/llvm/lib/MC/MCAsmInfo.cpp @@ -48,9 +48,6 @@ MCAsmInfo::MCAsmInfo() { LinkerPrivateGlobalPrefix = ""; InlineAsmStart = "APP"; InlineAsmEnd = "NO_APP"; - Code16Directive = ".code16"; - Code32Directive = ".code32"; - Code64Directive = ".code64"; ZeroDirective = "\t.zero\t"; AsciiDirective = "\t.ascii\t"; AscizDirective = "\t.asciz\t"; diff --git a/llvm/lib/MC/MCAsmStreamer.cpp b/llvm/lib/MC/MCAsmStreamer.cpp index 42e62459d973..f670335045cb 100644 --- a/llvm/lib/MC/MCAsmStreamer.cpp +++ b/llvm/lib/MC/MCAsmStreamer.cpp @@ -182,7 +182,7 @@ public: void emitLabel(MCSymbol *Symbol, SMLoc Loc = SMLoc()) override; - void emitAssemblerFlag(MCAssemblerFlag Flag) override; + void emitSubsectionsViaSymbols() override; void emitLinkerOptions(ArrayRef Options) override; void emitDataRegion(MCDataRegionType Kind) override; void emitVersionMin(MCVersionMinType Kind, unsigned Major, unsigned Minor, @@ -597,15 +597,8 @@ void MCAsmStreamer::emitGNUAttribute(unsigned Tag, unsigned Value) { OS << "\t.gnu_attribute " << Tag << ", " << Value << "\n"; } -void MCAsmStreamer::emitAssemblerFlag(MCAssemblerFlag Flag) { - switch (Flag) { - case MCAF_SyntaxUnified: OS << "\t.syntax unified"; break; - case MCAF_SubsectionsViaSymbols: OS << ".subsections_via_symbols"; break; - case MCAF_Code16: OS << '\t'<< MAI->getCode16Directive();break; - case MCAF_Code32: OS << '\t'<< MAI->getCode32Directive();break; - case MCAF_Code64: OS << '\t'<< MAI->getCode64Directive();break; - } - EmitEOL(); +void MCAsmStreamer::emitSubsectionsViaSymbols() { + OS << ".subsections_via_symbols\n"; } void MCAsmStreamer::emitLinkerOptions(ArrayRef Options) { diff --git a/llvm/lib/MC/MCELFStreamer.cpp b/llvm/lib/MC/MCELFStreamer.cpp index 5cf67f018b45..7006ac9dda7c 100644 --- a/llvm/lib/MC/MCELFStreamer.cpp +++ b/llvm/lib/MC/MCELFStreamer.cpp @@ -84,11 +84,6 @@ void MCELFStreamer::emitLabelAtPos(MCSymbol *S, SMLoc Loc, MCDataFragment &F, Symbol->setType(ELF::STT_TLS); } -void MCELFStreamer::emitAssemblerFlag(MCAssemblerFlag Flag) { - // Let the target do whatever target specific stuff it needs to do. - getAssembler().getBackend().handleAssemblerFlag(Flag); -} - // If bundle alignment is used and there are any instructions in the section, it // needs to be aligned to at least the bundle size. static void setSectionAlignmentForBundling(const MCAssembler &Assembler, diff --git a/llvm/lib/MC/MCMachOStreamer.cpp b/llvm/lib/MC/MCMachOStreamer.cpp index 9b7152f56117..4cf602b7e456 100644 --- a/llvm/lib/MC/MCMachOStreamer.cpp +++ b/llvm/lib/MC/MCMachOStreamer.cpp @@ -89,7 +89,7 @@ public: void emitLabel(MCSymbol *Symbol, SMLoc Loc = SMLoc()) override; void emitAssignment(MCSymbol *Symbol, const MCExpr *Value) override; void emitEHSymAttributes(const MCSymbol *Symbol, MCSymbol *EHSymbol) override; - void emitAssemblerFlag(MCAssemblerFlag Flag) override; + void emitSubsectionsViaSymbols() override; void emitLinkerOptions(ArrayRef Options) override; void emitDataRegion(MCDataRegionType Kind) override; void emitVersionMin(MCVersionMinType Kind, unsigned Major, unsigned Minor, @@ -209,19 +209,8 @@ void MCMachOStreamer::emitDataRegionEnd() { emitLabel(Data.End); } -void MCMachOStreamer::emitAssemblerFlag(MCAssemblerFlag Flag) { - // Let the target do whatever target specific stuff it needs to do. - getAssembler().getBackend().handleAssemblerFlag(Flag); - // Do any generic stuff we need to do. - switch (Flag) { - case MCAF_SyntaxUnified: return; // no-op here. - case MCAF_Code16: return; // Change parsing mode; no-op here. - case MCAF_Code32: return; // Change parsing mode; no-op here. - case MCAF_Code64: return; // Change parsing mode; no-op here. - case MCAF_SubsectionsViaSymbols: - getWriter().setSubsectionsViaSymbols(true); - return; - } +void MCMachOStreamer::emitSubsectionsViaSymbols() { + getWriter().setSubsectionsViaSymbols(true); } void MCMachOStreamer::emitLinkerOptions(ArrayRef Options) { diff --git a/llvm/lib/MC/MCNullStreamer.cpp b/llvm/lib/MC/MCNullStreamer.cpp index e84830eb20a7..f76b2f754b18 100644 --- a/llvm/lib/MC/MCNullStreamer.cpp +++ b/llvm/lib/MC/MCNullStreamer.cpp @@ -38,6 +38,7 @@ namespace { void emitCommonSymbol(MCSymbol *Symbol, uint64_t Size, Align ByteAlignment) override {} + void emitSubsectionsViaSymbols() override {}; void beginCOFFSymbolDef(const MCSymbol *Symbol) override {} void emitCOFFSymbolStorageClass(int StorageClass) override {} void emitCOFFSymbolType(int Type) override {} diff --git a/llvm/lib/MC/MCParser/DarwinAsmParser.cpp b/llvm/lib/MC/MCParser/DarwinAsmParser.cpp index 5dc9cb64c46a..de134e25e842 100644 --- a/llvm/lib/MC/MCParser/DarwinAsmParser.cpp +++ b/llvm/lib/MC/MCParser/DarwinAsmParser.cpp @@ -817,7 +817,7 @@ bool DarwinAsmParser::parseDirectiveSubsectionsViaSymbols(StringRef, SMLoc) { Lex(); - getStreamer().emitAssemblerFlag(MCAF_SubsectionsViaSymbols); + getStreamer().emitSubsectionsViaSymbols(); return false; } diff --git a/llvm/lib/MC/MCStreamer.cpp b/llvm/lib/MC/MCStreamer.cpp index a1968423a125..618a35b9596a 100644 --- a/llvm/lib/MC/MCStreamer.cpp +++ b/llvm/lib/MC/MCStreamer.cpp @@ -1245,7 +1245,10 @@ void MCStreamer::emitAbsoluteSymbolDiffAsULEB128(const MCSymbol *Hi, emitULEB128Value(Diff); } -void MCStreamer::emitAssemblerFlag(MCAssemblerFlag Flag) {} +void MCStreamer::emitSubsectionsViaSymbols() { + llvm_unreachable( + "emitSubsectionsViaSymbols only supported on Mach-O targets"); +} void MCStreamer::emitSymbolDesc(MCSymbol *Symbol, unsigned DescValue) {} void MCStreamer::beginCOFFSymbolDef(const MCSymbol *Symbol) { llvm_unreachable("this directive only supported on COFF targets"); diff --git a/llvm/lib/MC/MCWasmStreamer.cpp b/llvm/lib/MC/MCWasmStreamer.cpp index cddd250cc000..9920ff9106fc 100644 --- a/llvm/lib/MC/MCWasmStreamer.cpp +++ b/llvm/lib/MC/MCWasmStreamer.cpp @@ -59,14 +59,6 @@ void MCWasmStreamer::emitLabelAtPos(MCSymbol *S, SMLoc Loc, MCDataFragment &F, Symbol->setTLS(); } -void MCWasmStreamer::emitAssemblerFlag(MCAssemblerFlag Flag) { - // Let the target do whatever target specific stuff it needs to do. - getAssembler().getBackend().handleAssemblerFlag(Flag); - - // Do any generic stuff we need to do. - llvm_unreachable("invalid assembler flag!"); -} - void MCWasmStreamer::changeSection(MCSection *Section, uint32_t Subsection) { MCAssembler &Asm = getAssembler(); auto *SectionWasm = cast(Section); diff --git a/llvm/lib/MC/MCWinCOFFStreamer.cpp b/llvm/lib/MC/MCWinCOFFStreamer.cpp index e03f7b5b6d41..ee7a7c87eb22 100644 --- a/llvm/lib/MC/MCWinCOFFStreamer.cpp +++ b/llvm/lib/MC/MCWinCOFFStreamer.cpp @@ -184,22 +184,6 @@ void MCWinCOFFStreamer::emitLabel(MCSymbol *S, SMLoc Loc) { MCObjectStreamer::emitLabel(Symbol, Loc); } -void MCWinCOFFStreamer::emitAssemblerFlag(MCAssemblerFlag Flag) { - // Let the target do whatever target specific stuff it needs to do. - getAssembler().getBackend().handleAssemblerFlag(Flag); - - switch (Flag) { - // None of these require COFF specific handling. - case MCAF_SyntaxUnified: - case MCAF_Code16: - case MCAF_Code32: - case MCAF_Code64: - break; - case MCAF_SubsectionsViaSymbols: - llvm_unreachable("COFF doesn't support .subsections_via_symbols"); - } -} - bool MCWinCOFFStreamer::emitSymbolAttribute(MCSymbol *S, MCSymbolAttr Attribute) { auto *Symbol = cast(S); diff --git a/llvm/lib/Object/RecordStreamer.h b/llvm/lib/Object/RecordStreamer.h index d9ef27c79016..edb6e3ae118b 100644 --- a/llvm/lib/Object/RecordStreamer.h +++ b/llvm/lib/Object/RecordStreamer.h @@ -54,9 +54,10 @@ public: void emitCommonSymbol(MCSymbol *Symbol, uint64_t Size, Align ByteAlignment) override; - // Ignore COFF-specific directives; we do not need any information from them, - // but the default implementation of these methods crashes, so we override - // them with versions that do nothing. + // Ignore format-specific directives; we do not need any information from + // them, but the default implementation of these methods crashes, so we + // override them with versions that do nothing. + void emitSubsectionsViaSymbols() override {}; void beginCOFFSymbolDef(const MCSymbol *Symbol) override {} void emitCOFFSymbolStorageClass(int StorageClass) override {} void emitCOFFSymbolType(int Type) override {} diff --git a/llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp b/llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp index f55b7ef7c20b..e9ccc35f3461 100644 --- a/llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp +++ b/llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp @@ -961,7 +961,7 @@ void AArch64AsmPrinter::emitEndOfAsmFile(Module &M) { // implementation of multiple entry points). If this doesn't occur, the // linker can safely perform dead code stripping. Since LLVM never // generates code that does this, it is always safe to set. - OutStreamer->emitAssemblerFlag(MCAF_SubsectionsViaSymbols); + OutStreamer->emitSubsectionsViaSymbols(); } if (TT.isOSBinFormatELF()) { diff --git a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64MCAsmInfo.cpp b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64MCAsmInfo.cpp index 83daa836e650..e8a88f7f3140 100644 --- a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64MCAsmInfo.cpp +++ b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64MCAsmInfo.cpp @@ -108,7 +108,6 @@ AArch64MCAsmInfoELF::AArch64MCAsmInfoELF(const Triple &T) { CommentString = "//"; PrivateGlobalPrefix = ".L"; PrivateLabelPrefix = ".L"; - Code32Directive = ".code\t32"; Data16bitsDirective = "\t.hword\t"; Data32bitsDirective = "\t.word\t"; diff --git a/llvm/lib/Target/ARM/ARMAsmPrinter.cpp b/llvm/lib/Target/ARM/ARMAsmPrinter.cpp index 2505a67727aa..13efd70c0f22 100644 --- a/llvm/lib/Target/ARM/ARMAsmPrinter.cpp +++ b/llvm/lib/Target/ARM/ARMAsmPrinter.cpp @@ -66,10 +66,10 @@ void ARMAsmPrinter::emitFunctionEntryLabel() { auto &TS = static_cast(*OutStreamer->getTargetStreamer()); if (AFI->isThumbFunction()) { - OutStreamer->emitAssemblerFlag(MCAF_Code16); + TS.emitCode16(); TS.emitThumbFunc(CurrentFnSym); } else { - OutStreamer->emitAssemblerFlag(MCAF_Code32); + TS.emitCode32(); } // Emit symbol for CMSE non-secure entry point @@ -171,7 +171,9 @@ bool ARMAsmPrinter::runOnMachineFunction(MachineFunction &MF) { // These are created per function, rather than per TU, since it's // relatively easy to exceed the thumb branch range within a TU. if (! ThumbIndirectPads.empty()) { - OutStreamer->emitAssemblerFlag(MCAF_Code16); + auto &TS = + static_cast(*OutStreamer->getTargetStreamer()); + TS.emitCode16(); emitAlignment(Align(2)); for (std::pair &TIP : ThumbIndirectPads) { OutStreamer->emitLabel(TIP.second); @@ -489,24 +491,30 @@ void ARMAsmPrinter::emitInlineAsmEnd(const MCSubtargetInfo &StartInfo, // the start mode, then restore the start mode. const bool WasThumb = isThumb(StartInfo); if (!EndInfo || WasThumb != isThumb(*EndInfo)) { - OutStreamer->emitAssemblerFlag(WasThumb ? MCAF_Code16 : MCAF_Code32); + auto &TS = + static_cast(*OutStreamer->getTargetStreamer()); + if (WasThumb) + TS.emitCode16(); + else + TS.emitCode32(); } } void ARMAsmPrinter::emitStartOfAsmFile(Module &M) { const Triple &TT = TM.getTargetTriple(); + auto &TS = + static_cast(*OutStreamer->getTargetStreamer()); // Use unified assembler syntax. - OutStreamer->emitAssemblerFlag(MCAF_SyntaxUnified); + TS.emitSyntaxUnified(); // Emit ARM Build Attributes if (TT.isOSBinFormatELF()) emitAttributes(); // Use the triple's architecture and subarchitecture to determine - // if we're thumb for the purposes of the top level code16 assembler - // flag. + // if we're thumb for the purposes of the top level code16 state. if (!M.getModuleInlineAsm().empty() && TT.isThumb()) - OutStreamer->emitAssemblerFlag(MCAF_Code16); + TS.emitCode16(); } static void @@ -575,7 +583,7 @@ void ARMAsmPrinter::emitEndOfAsmFile(Module &M) { // implementation of multiple entry points). If this doesn't occur, the // linker can safely perform dead code stripping. Since LLVM never // generates code that does this, it is always safe to set. - OutStreamer->emitAssemblerFlag(MCAF_SubsectionsViaSymbols); + OutStreamer->emitSubsectionsViaSymbols(); } // The last attribute to be emitted is ABI_optimization_goals diff --git a/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp b/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp index 48ad8a8994ae..85b107c6085d 100644 --- a/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp +++ b/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp @@ -11654,7 +11654,7 @@ bool ARMAsmParser::parseDirectiveThumb(SMLoc L) { if (!isThumb()) SwitchMode(); - getParser().getStreamer().emitAssemblerFlag(MCAF_Code16); + getTargetStreamer().emitCode16(); getParser().getStreamer().emitCodeAlignment(Align(2), &getSTI(), 0); return false; } @@ -11667,7 +11667,7 @@ bool ARMAsmParser::parseDirectiveARM(SMLoc L) { if (isThumb()) SwitchMode(); - getParser().getStreamer().emitAssemblerFlag(MCAF_Code32); + getTargetStreamer().emitCode32(); getParser().getStreamer().emitCodeAlignment(Align(4), &getSTI(), 0); return false; } @@ -11715,7 +11715,7 @@ bool ARMAsmParser::parseDirectiveThumbFunc(SMLoc L) { if (!isThumb()) SwitchMode(); - getParser().getStreamer().emitAssemblerFlag(MCAF_Code16); + getTargetStreamer().emitCode16(); NextSymbolIsThumb = true; return false; @@ -11768,14 +11768,14 @@ bool ARMAsmParser::parseDirectiveCode(SMLoc L) { if (!isThumb()) SwitchMode(); - getParser().getStreamer().emitAssemblerFlag(MCAF_Code16); + getTargetStreamer().emitCode16(); } else { if (!hasARM()) return Error(L, "target does not support ARM mode"); if (isThumb()) SwitchMode(); - getParser().getStreamer().emitAssemblerFlag(MCAF_Code32); + getTargetStreamer().emitCode32(); } return false; @@ -11824,8 +11824,10 @@ void ARMAsmParser::FixModeAfterArchChange(bool WasThumb, SMLoc Loc) { SwitchMode(); } else { // Mode switch forced, because the new arch doesn't support the old mode. - getParser().getStreamer().emitAssemblerFlag(isThumb() ? MCAF_Code16 - : MCAF_Code32); + if (isThumb()) + getTargetStreamer().emitCode16(); + else + getTargetStreamer().emitCode32(); // Warn about the implcit mode switch. GAS does not switch modes here, // but instead stays in the old mode, reporting an error on any following // instructions as the mode does not exist on the target. diff --git a/llvm/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp b/llvm/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp index 266ae1ff84e6..9b0aafe620c7 100644 --- a/llvm/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp +++ b/llvm/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp @@ -206,19 +206,6 @@ MCFixupKindInfo ARMAsmBackend::getFixupKindInfo(MCFixupKind Kind) const { : InfosBE)[Kind - FirstTargetFixupKind]; } -void ARMAsmBackend::handleAssemblerFlag(MCAssemblerFlag Flag) { - switch (Flag) { - default: - break; - case MCAF_Code16: - setIsThumb(true); - break; - case MCAF_Code32: - setIsThumb(false); - break; - } -} - unsigned ARMAsmBackend::getRelaxedOpcode(unsigned Op, const MCSubtargetInfo &STI) const { bool HasThumb2 = STI.hasFeature(ARM::FeatureThumb2); @@ -405,7 +392,7 @@ bool ARMAsmBackend::writeNopData(raw_ostream &OS, uint64_t Count, const uint16_t Thumb2_16bitNopEncoding = 0xbf00; // NOP const uint32_t ARMv4_NopEncoding = 0xe1a00000; // using MOV r0,r0 const uint32_t ARMv6T2_NopEncoding = 0xe320f000; // NOP - if (isThumb()) { + if (STI->hasFeature(ARM::ModeThumb)) { const uint16_t nopEncoding = hasNOP(STI) ? Thumb2_16bitNopEncoding : Thumb1_16bitNopEncoding; uint64_t NumNops = Count / 2; @@ -1407,14 +1394,13 @@ static MCAsmBackend *createARMAsmBackend(const Target &T, return new ARMAsmBackendDarwin(T, STI, MRI); case Triple::COFF: assert(TheTriple.isOSWindows() && "non-Windows ARM COFF is not supported"); - return new ARMAsmBackendWinCOFF(T, STI.getTargetTriple().isThumb()); + return new ARMAsmBackendWinCOFF(T); case Triple::ELF: assert(TheTriple.isOSBinFormatELF() && "using ELF for non-ELF target"); uint8_t OSABI = Options.FDPIC ? static_cast(ELF::ELFOSABI_ARM_FDPIC) : MCELFObjectTargetWriter::getOSABI(TheTriple.getOS()); - return new ARMAsmBackendELF(T, STI.getTargetTriple().isThumb(), OSABI, - Endian); + return new ARMAsmBackendELF(T, OSABI, Endian); } } diff --git a/llvm/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.h b/llvm/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.h index bcf044b340da..4f017d82aa54 100644 --- a/llvm/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.h +++ b/llvm/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.h @@ -18,11 +18,9 @@ namespace llvm { class ARMAsmBackend : public MCAsmBackend { - bool isThumbMode; // Currently emitting Thumb code. public: - ARMAsmBackend(const Target &T, bool isThumb, llvm::endianness Endian) - : MCAsmBackend(Endian), isThumbMode(isThumb) {} - + ARMAsmBackend(const Target &T, llvm::endianness Endian) + : MCAsmBackend(Endian) {} bool hasNOP(const MCSubtargetInfo *STI) const { return STI->hasFeature(ARM::HasV6T2Ops); @@ -64,11 +62,7 @@ public: bool writeNopData(raw_ostream &OS, uint64_t Count, const MCSubtargetInfo *STI) const override; - void handleAssemblerFlag(MCAssemblerFlag Flag) override; - unsigned getPointerSize() const { return 4; } - bool isThumb() const { return isThumbMode; } - void setIsThumb(bool it) { isThumbMode = it; } }; } // end namespace llvm diff --git a/llvm/lib/Target/ARM/MCTargetDesc/ARMAsmBackendDarwin.h b/llvm/lib/Target/ARM/MCTargetDesc/ARMAsmBackendDarwin.h index 9c958003ca75..29cbc40f844a 100644 --- a/llvm/lib/Target/ARM/MCTargetDesc/ARMAsmBackendDarwin.h +++ b/llvm/lib/Target/ARM/MCTargetDesc/ARMAsmBackendDarwin.h @@ -22,9 +22,8 @@ public: const MachO::CPUSubTypeARM Subtype; ARMAsmBackendDarwin(const Target &T, const MCSubtargetInfo &STI, const MCRegisterInfo &MRI) - : ARMAsmBackend(T, STI.getTargetTriple().isThumb(), - llvm::endianness::little), - MRI(MRI), TT(STI.getTargetTriple()), + : ARMAsmBackend(T, llvm::endianness::little), MRI(MRI), + TT(STI.getTargetTriple()), Subtype((MachO::CPUSubTypeARM)cantFail( MachO::getCPUSubType(STI.getTargetTriple()))) {} diff --git a/llvm/lib/Target/ARM/MCTargetDesc/ARMAsmBackendELF.h b/llvm/lib/Target/ARM/MCTargetDesc/ARMAsmBackendELF.h index 17ae262c0826..d0b598dbdc9b 100644 --- a/llvm/lib/Target/ARM/MCTargetDesc/ARMAsmBackendELF.h +++ b/llvm/lib/Target/ARM/MCTargetDesc/ARMAsmBackendELF.h @@ -17,9 +17,8 @@ namespace llvm { class ARMAsmBackendELF : public ARMAsmBackend { public: uint8_t OSABI; - ARMAsmBackendELF(const Target &T, bool isThumb, uint8_t OSABI, - llvm::endianness Endian) - : ARMAsmBackend(T, isThumb, Endian), OSABI(OSABI) {} + ARMAsmBackendELF(const Target &T, uint8_t OSABI, llvm::endianness Endian) + : ARMAsmBackend(T, Endian), OSABI(OSABI) {} std::unique_ptr createObjectTargetWriter() const override { diff --git a/llvm/lib/Target/ARM/MCTargetDesc/ARMAsmBackendWinCOFF.h b/llvm/lib/Target/ARM/MCTargetDesc/ARMAsmBackendWinCOFF.h index 9b50fb7f0758..8a1137e13283 100644 --- a/llvm/lib/Target/ARM/MCTargetDesc/ARMAsmBackendWinCOFF.h +++ b/llvm/lib/Target/ARM/MCTargetDesc/ARMAsmBackendWinCOFF.h @@ -15,8 +15,8 @@ namespace llvm { class ARMAsmBackendWinCOFF : public ARMAsmBackend { public: - ARMAsmBackendWinCOFF(const Target &T, bool isThumb) - : ARMAsmBackend(T, isThumb, llvm::endianness::little) {} + ARMAsmBackendWinCOFF(const Target &T) + : ARMAsmBackend(T, llvm::endianness::little) {} std::unique_ptr createObjectTargetWriter() const override { return createARMWinCOFFObjectWriter(); diff --git a/llvm/lib/Target/ARM/MCTargetDesc/ARMELFStreamer.cpp b/llvm/lib/Target/ARM/MCTargetDesc/ARMELFStreamer.cpp index 3d45ecf72cc7..83183970a422 100644 --- a/llvm/lib/Target/ARM/MCTargetDesc/ARMELFStreamer.cpp +++ b/llvm/lib/Target/ARM/MCTargetDesc/ARMELFStreamer.cpp @@ -101,6 +101,9 @@ class ARMTargetAsmStreamer : public ARMTargetStreamer { void finishAttributeSection() override; void annotateTLSDescriptorSequence(const MCSymbolRefExpr *SRE) override; + void emitSyntaxUnified() override; + void emitCode16() override; + void emitCode32() override; void emitThumbFunc(MCSymbol *Symbol) override; void emitThumbSet(MCSymbol *Symbol, const MCExpr *Value) override; @@ -262,6 +265,12 @@ void ARMTargetAsmStreamer::annotateTLSDescriptorSequence( OS << "\t.tlsdescseq\t" << S->getSymbol().getName() << "\n"; } +void ARMTargetAsmStreamer::emitSyntaxUnified() { OS << "\t.syntax\tunified\n"; } + +void ARMTargetAsmStreamer::emitCode16() { OS << "\t.code\t16\n"; } + +void ARMTargetAsmStreamer::emitCode32() { OS << "\t.code\t32\n"; } + void ARMTargetAsmStreamer::emitThumbFunc(MCSymbol *Symbol) { const MCAsmInfo *MAI = Streamer.getContext().getAsmInfo(); OS << "\t.thumb_func"; @@ -435,6 +444,8 @@ private: void emitLabel(MCSymbol *Symbol) override; void annotateTLSDescriptorSequence(const MCSymbolRefExpr *SRE) override; + void emitCode16() override; + void emitCode32() override; void emitThumbFunc(MCSymbol *Symbol) override; void emitThumbSet(MCSymbol *Symbol, const MCExpr *Value) override; @@ -590,25 +601,6 @@ public: MCELFStreamer::emitValueImpl(Value, Size, Loc); } - void emitAssemblerFlag(MCAssemblerFlag Flag) override { - MCELFStreamer::emitAssemblerFlag(Flag); - - switch (Flag) { - case MCAF_SyntaxUnified: - return; // no-op here. - case MCAF_Code16: - IsThumb = true; - return; // Change to Thumb mode - case MCAF_Code32: - IsThumb = false; - return; // Change to ARM mode - case MCAF_Code64: - return; - case MCAF_SubsectionsViaSymbols: - return; - } - } - /// If a label is defined before the .type directive sets the label's type /// then the label can't be recorded as thumb function when the label is /// defined. We override emitSymbolAttribute() which is called as part of the @@ -631,6 +623,8 @@ public: return Val; }; + void setIsThumb(bool Val) { IsThumb = Val; } + private: enum ElfMappingSymbol { EMS_None, @@ -1107,6 +1101,10 @@ void ARMTargetELFStreamer::annotateTLSDescriptorSequence( getStreamer().EmitFixup(S, FK_Data_4); } +void ARMTargetELFStreamer::emitCode16() { getStreamer().setIsThumb(true); } + +void ARMTargetELFStreamer::emitCode32() { getStreamer().setIsThumb(false); } + void ARMTargetELFStreamer::emitThumbFunc(MCSymbol *Symbol) { getStreamer().getAssembler().setIsThumbFunc(Symbol); getStreamer().emitSymbolAttribute(Symbol, MCSA_ELF_TypeFunction); diff --git a/llvm/lib/Target/ARM/MCTargetDesc/ARMMCAsmInfo.cpp b/llvm/lib/Target/ARM/MCTargetDesc/ARMMCAsmInfo.cpp index 789f7ec09d75..92121dd5704d 100644 --- a/llvm/lib/Target/ARM/MCTargetDesc/ARMMCAsmInfo.cpp +++ b/llvm/lib/Target/ARM/MCTargetDesc/ARMMCAsmInfo.cpp @@ -53,8 +53,6 @@ ARMMCAsmInfoDarwin::ARMMCAsmInfoDarwin(const Triple &TheTriple) { Data64bitsDirective = nullptr; CommentString = "@"; - Code16Directive = ".code\t16"; - Code32Directive = ".code\t32"; UseDataRegionDirectives = true; SupportsDebugInformation = true; @@ -82,8 +80,6 @@ ARMELFMCAsmInfo::ARMELFMCAsmInfo(const Triple &TheTriple) { Data64bitsDirective = nullptr; CommentString = "@"; - Code16Directive = ".code\t16"; - Code32Directive = ".code\t32"; SupportsDebugInformation = true; @@ -141,8 +137,6 @@ ARMCOFFMCAsmInfoGNU::ARMCOFFMCAsmInfoGNU() { HasSingleParameterDotFile = true; CommentString = "@"; - Code16Directive = ".code\t16"; - Code32Directive = ".code\t32"; PrivateGlobalPrefix = ".L"; PrivateLabelPrefix = ".L"; diff --git a/llvm/lib/Target/ARM/MCTargetDesc/ARMTargetStreamer.cpp b/llvm/lib/Target/ARM/MCTargetDesc/ARMTargetStreamer.cpp index 632dbebf58f0..130b6a6ba143 100644 --- a/llvm/lib/Target/ARM/MCTargetDesc/ARMTargetStreamer.cpp +++ b/llvm/lib/Target/ARM/MCTargetDesc/ARMTargetStreamer.cpp @@ -115,6 +115,9 @@ void ARMTargetStreamer::emitFPU(ARM::FPUKind FPU) {} void ARMTargetStreamer::finishAttributeSection() {} void ARMTargetStreamer::annotateTLSDescriptorSequence( const MCSymbolRefExpr *SRE) {} +void ARMTargetStreamer::emitSyntaxUnified() {} +void ARMTargetStreamer::emitCode16() {} +void ARMTargetStreamer::emitCode32() {} void ARMTargetStreamer::emitThumbFunc(MCSymbol *Symbol) {} void ARMTargetStreamer::emitThumbSet(MCSymbol *Symbol, const MCExpr *Value) {} diff --git a/llvm/lib/Target/X86/AsmParser/X86AsmParser.cpp b/llvm/lib/Target/X86/AsmParser/X86AsmParser.cpp index 11193304a785..300f79543693 100644 --- a/llvm/lib/Target/X86/AsmParser/X86AsmParser.cpp +++ b/llvm/lib/Target/X86/AsmParser/X86AsmParser.cpp @@ -4795,7 +4795,7 @@ bool X86AsmParser::ParseDirectiveCode(StringRef IDVal, SMLoc L) { Parser.Lex(); if (!is16BitMode()) { SwitchMode(X86::Is16Bit); - getParser().getStreamer().emitAssemblerFlag(MCAF_Code16); + getTargetStreamer().emitCode16(); } } else if (IDVal == ".code16gcc") { // .code16gcc parses as if in 32-bit mode, but emits code in 16-bit mode. @@ -4803,19 +4803,19 @@ bool X86AsmParser::ParseDirectiveCode(StringRef IDVal, SMLoc L) { Code16GCC = true; if (!is16BitMode()) { SwitchMode(X86::Is16Bit); - getParser().getStreamer().emitAssemblerFlag(MCAF_Code16); + getTargetStreamer().emitCode16(); } } else if (IDVal == ".code32") { Parser.Lex(); if (!is32BitMode()) { SwitchMode(X86::Is32Bit); - getParser().getStreamer().emitAssemblerFlag(MCAF_Code32); + getTargetStreamer().emitCode32(); } } else if (IDVal == ".code64") { Parser.Lex(); if (!is64BitMode()) { SwitchMode(X86::Is64Bit); - getParser().getStreamer().emitAssemblerFlag(MCAF_Code64); + getTargetStreamer().emitCode64(); } } else { Error(L, "unknown directive " + IDVal); diff --git a/llvm/lib/Target/X86/MCTargetDesc/X86TargetStreamer.h b/llvm/lib/Target/X86/MCTargetDesc/X86TargetStreamer.h index 8cfd9388063a..486795ff7f40 100644 --- a/llvm/lib/Target/X86/MCTargetDesc/X86TargetStreamer.h +++ b/llvm/lib/Target/X86/MCTargetDesc/X86TargetStreamer.h @@ -18,6 +18,10 @@ class X86TargetStreamer : public MCTargetStreamer { public: X86TargetStreamer(MCStreamer &S) : MCTargetStreamer(S) {} + virtual void emitCode16() {} + virtual void emitCode32() {} + virtual void emitCode64() {} + virtual bool emitFPOProc(const MCSymbol *ProcSym, unsigned ParamsSize, SMLoc L = {}) { return false; diff --git a/llvm/lib/Target/X86/MCTargetDesc/X86WinCOFFTargetStreamer.cpp b/llvm/lib/Target/X86/MCTargetDesc/X86WinCOFFTargetStreamer.cpp index 0d0b43f03d41..16e878d948cf 100644 --- a/llvm/lib/Target/X86/MCTargetDesc/X86WinCOFFTargetStreamer.cpp +++ b/llvm/lib/Target/X86/MCTargetDesc/X86WinCOFFTargetStreamer.cpp @@ -32,6 +32,10 @@ public: MCInstPrinter &InstPrinter) : X86TargetStreamer(S), OS(OS), InstPrinter(InstPrinter) {} + void emitCode16() override; + void emitCode32() override; + void emitCode64() override; + bool emitFPOProc(const MCSymbol *ProcSym, unsigned ParamsSize, SMLoc L) override; bool emitFPOEndPrologue(SMLoc L) override; @@ -96,6 +100,12 @@ public: }; } // end namespace +void X86WinCOFFAsmTargetStreamer::emitCode16() { OS << "\t.code16\n"; } + +void X86WinCOFFAsmTargetStreamer::emitCode32() { OS << "\t.code32\n"; } + +void X86WinCOFFAsmTargetStreamer::emitCode64() { OS << "\t.code64\n"; } + bool X86WinCOFFAsmTargetStreamer::emitFPOProc(const MCSymbol *ProcSym, unsigned ParamsSize, SMLoc L) { OS << "\t.cv_fpo_proc\t"; @@ -452,9 +462,9 @@ MCTargetStreamer *llvm::createX86AsmTargetStreamer(MCStreamer &S, MCTargetStreamer * llvm::createX86ObjectTargetStreamer(MCStreamer &S, const MCSubtargetInfo &STI) { - // No need to register a target streamer. + // No need for a special target streamer. if (!STI.getTargetTriple().isOSBinFormatCOFF()) - return nullptr; + return new X86TargetStreamer(S); // Registers itself to the MCStreamer. return new X86WinCOFFTargetStreamer(S); } diff --git a/llvm/lib/Target/X86/X86AsmPrinter.cpp b/llvm/lib/Target/X86/X86AsmPrinter.cpp index ce9a7c42d963..247b792d16ba 100644 --- a/llvm/lib/Target/X86/X86AsmPrinter.cpp +++ b/llvm/lib/Target/X86/X86AsmPrinter.cpp @@ -918,8 +918,11 @@ void X86AsmPrinter::emitStartOfAsmFile(Module &M) { // If this is not inline asm and we're in 16-bit // mode prefix assembly with .code16. bool is16 = TT.getEnvironment() == Triple::CODE16; - if (M.getModuleInlineAsm().empty() && is16) - OutStreamer->emitAssemblerFlag(MCAF_Code16); + if (M.getModuleInlineAsm().empty() && is16) { + auto *XTS = + static_cast(OutStreamer->getTargetStreamer()); + XTS->emitCode16(); + } } static void @@ -1011,7 +1014,7 @@ void X86AsmPrinter::emitEndOfAsmFile(Module &M) { // points). If this doesn't occur, the linker can safely perform dead code // stripping. Since LLVM never generates code that does this, it is always // safe to set. - OutStreamer->emitAssemblerFlag(MCAF_SubsectionsViaSymbols); + OutStreamer->emitSubsectionsViaSymbols(); } else if (TT.isOSBinFormatCOFF()) { if (usesMSVCFloatingPoint(TT, M)) { // In Windows' libcmt.lib, there is a file which is linked in only if the diff --git a/llvm/test/CodeGen/ARM/ldrd.ll b/llvm/test/CodeGen/ARM/ldrd.ll index 3cf10f0e64b4..084abc433a47 100644 --- a/llvm/test/CodeGen/ARM/ldrd.ll +++ b/llvm/test/CodeGen/ARM/ldrd.ll @@ -16,7 +16,7 @@ declare ptr @get_ptr() declare void @use_i64(i64 %v) define void @test_ldrd(i64 %a) nounwind readonly "frame-pointer"="all" { -; CHECK-LABEL: test_ldrd: +; CHECK-LABEL: test_ldrd:{{.*$}} ; NORMAL: bl{{x?}} _get_ptr ; A8: ldrd r0, r1, [r0] ; Cortex-M3 errata 602117: LDRD with base in list may result in incorrect base @@ -138,7 +138,7 @@ define void @strd_spill_ldrd_reload(i32 %v0, i32 %v1) "frame-pointer"="all" { declare void @extfunc2(ptr, i32, i32) -; CHECK-LABEL: ldrd_postupdate_dec: +; CHECK-LABEL: ldrd_postupdate_dec:{{.*$}} ; NORMAL: ldrd r1, r2, [r0], #-8 ; CONSERVATIVE-NOT: ldrd ; CHECK: bl{{x?}} _extfunc @@ -151,7 +151,7 @@ define void @ldrd_postupdate_dec(ptr %p0) "frame-pointer"="all" { ret void } -; CHECK-LABEL: ldrd_postupdate_inc: +; CHECK-LABEL: ldrd_postupdate_inc:{{.*$}} ; NORMAL: ldrd r1, r2, [r0], #8 ; CONSERVATIVE-NOT: ldrd ; CHECK: bl{{x?}} _extfunc @@ -164,7 +164,7 @@ define void @ldrd_postupdate_inc(ptr %p0) "frame-pointer"="all" { ret void } -; CHECK-LABEL: strd_postupdate_dec: +; CHECK-LABEL: strd_postupdate_dec:{{.*$}} ; NORMAL: strd r1, r2, [r0], #-8 ; CONSERVATIVE-NOT: strd ; CHECK: bx lr @@ -176,7 +176,7 @@ define ptr @strd_postupdate_dec(ptr %p0, i32 %v0, i32 %v1) "frame-pointer"="none ret ptr %p1 } -; CHECK-LABEL: strd_postupdate_inc: +; CHECK-LABEL: strd_postupdate_inc:{{.*$}} ; NORMAL: strd r1, r2, [r0], #8 ; CONSERVATIVE-NOT: strd ; CHECK: bx lr @@ -188,7 +188,7 @@ define ptr @strd_postupdate_inc(ptr %p0, i32 %v0, i32 %v1) "frame-pointer"="none ret ptr %p1 } -; CHECK-LABEL: ldrd_strd_aa: +; CHECK-LABEL: ldrd_strd_aa:{{.*$}} ; NORMAL: ldrd [[TMP1:r[0-9]]], [[TMP2:r[0-9]]], ; NORMAL: strd [[TMP1]], [[TMP2]], ; CONSERVATIVE-NOT: ldrd diff --git a/llvm/test/CodeGen/ARM/thumb-function-section-reloc.ll b/llvm/test/CodeGen/ARM/thumb-function-section-reloc.ll index beb0d839c8d8..0cf1c62e3d8c 100644 --- a/llvm/test/CodeGen/ARM/thumb-function-section-reloc.ll +++ b/llvm/test/CodeGen/ARM/thumb-function-section-reloc.ll @@ -46,9 +46,9 @@ define dso_local void @_ZdlPv(ptr %ptr) local_unnamed_addr nounwind "target-feat ; CHECK-NEXT: .globl _ZdlPv @ -- Begin function _ZdlPv ; CHECK-NEXT: .p2align 1 ; CHECK-NEXT: .type _ZdlPv,%function -; CHECK-NEXT: .code 16 @ @_ZdlPv +; CHECK-NEXT: .code 16 ; CHECK-NEXT: .thumb_func -; CHECK-NEXT: _ZdlPv: +; CHECK-NEXT: _ZdlPv: @ @_ZdlPv ; CHECK-NEXT: .L_ZdlPv$local: ; CHECK-NEXT: .type .L_ZdlPv$local,%function ; CHECK-NEXT: .fnstart diff --git a/llvm/test/CodeGen/Thumb/thumb-shrink-wrapping.ll b/llvm/test/CodeGen/Thumb/thumb-shrink-wrapping.ll index c52a54569b3d..27720a4200b1 100644 --- a/llvm/test/CodeGen/Thumb/thumb-shrink-wrapping.ll +++ b/llvm/test/CodeGen/Thumb/thumb-shrink-wrapping.ll @@ -750,9 +750,9 @@ define i32 @loopInfoRestoreOutsideLoop(i32 %cond, i32 %N) nounwind { ; ENABLE-V4T-NEXT: @ -- End function ; ENABLE-V4T-NEXT: .globl _emptyFrame @ -- Begin function emptyFrame ; ENABLE-V4T-NEXT: .p2align 1 -; ENABLE-V4T-NEXT: .code 16 @ @emptyFrame +; ENABLE-V4T-NEXT: .code 16 ; ENABLE-V4T-NEXT: .thumb_func _emptyFrame -; ENABLE-V4T-NEXT: _emptyFrame: +; ENABLE-V4T-NEXT: _emptyFrame: @ @emptyFrame ; ENABLE-V4T-NEXT: .cfi_startproc ; ENABLE-V4T-NEXT: @ %bb.0: @ %entry ; ENABLE-V4T-NEXT: movs r0, #0 @@ -787,9 +787,9 @@ define i32 @loopInfoRestoreOutsideLoop(i32 %cond, i32 %N) nounwind { ; ENABLE-V5T-NEXT: @ -- End function ; ENABLE-V5T-NEXT: .globl _emptyFrame @ -- Begin function emptyFrame ; ENABLE-V5T-NEXT: .p2align 1 -; ENABLE-V5T-NEXT: .code 16 @ @emptyFrame +; ENABLE-V5T-NEXT: .code 16 ; ENABLE-V5T-NEXT: .thumb_func _emptyFrame -; ENABLE-V5T-NEXT: _emptyFrame: +; ENABLE-V5T-NEXT: _emptyFrame: @ @emptyFrame ; ENABLE-V5T-NEXT: .cfi_startproc ; ENABLE-V5T-NEXT: @ %bb.0: @ %entry ; ENABLE-V5T-NEXT: movs r0, #0 @@ -826,9 +826,9 @@ define i32 @loopInfoRestoreOutsideLoop(i32 %cond, i32 %N) nounwind { ; DISABLE-V4T-NEXT: @ -- End function ; DISABLE-V4T-NEXT: .globl _emptyFrame @ -- Begin function emptyFrame ; DISABLE-V4T-NEXT: .p2align 1 -; DISABLE-V4T-NEXT: .code 16 @ @emptyFrame +; DISABLE-V4T-NEXT: .code 16 ; DISABLE-V4T-NEXT: .thumb_func _emptyFrame -; DISABLE-V4T-NEXT: _emptyFrame: +; DISABLE-V4T-NEXT: _emptyFrame: @ @emptyFrame ; DISABLE-V4T-NEXT: .cfi_startproc ; DISABLE-V4T-NEXT: @ %bb.0: @ %entry ; DISABLE-V4T-NEXT: movs r0, #0 @@ -862,9 +862,9 @@ define i32 @loopInfoRestoreOutsideLoop(i32 %cond, i32 %N) nounwind { ; DISABLE-V5T-NEXT: @ -- End function ; DISABLE-V5T-NEXT: .globl _emptyFrame @ -- Begin function emptyFrame ; DISABLE-V5T-NEXT: .p2align 1 -; DISABLE-V5T-NEXT: .code 16 @ @emptyFrame +; DISABLE-V5T-NEXT: .code 16 ; DISABLE-V5T-NEXT: .thumb_func _emptyFrame -; DISABLE-V5T-NEXT: _emptyFrame: +; DISABLE-V5T-NEXT: _emptyFrame: @ @emptyFrame ; DISABLE-V5T-NEXT: .cfi_startproc ; DISABLE-V5T-NEXT: @ %bb.0: @ %entry ; DISABLE-V5T-NEXT: movs r0, #0 diff --git a/llvm/test/DebugInfo/ARM/header.ll b/llvm/test/DebugInfo/ARM/header.ll index 7582f3403315..6956d47c0212 100644 --- a/llvm/test/DebugInfo/ARM/header.ll +++ b/llvm/test/DebugInfo/ARM/header.ll @@ -8,8 +8,8 @@ ; CHECK-NEXT: .section __TEXT,__text,regular,pure_instructions ; CHECK-NEXT: .globl _f ; CHECK-NEXT: .p2align 2 -; CHECK-NEXT: .code 32 @ @f -; CHECK-NEXT: _f: +; CHECK-NEXT: .code 32 +; CHECK-NEXT: _f: @ @f ; CHECK: .section __DWARF,__debug_str,regular,debug diff --git a/llvm/utils/UpdateTestChecks/asm.py b/llvm/utils/UpdateTestChecks/asm.py index 7d4fb7d8e150..da7e7ecc24bd 100644 --- a/llvm/utils/UpdateTestChecks/asm.py +++ b/llvm/utils/UpdateTestChecks/asm.py @@ -32,7 +32,7 @@ ASM_FUNCTION_X86_RE = re.compile( ) ASM_FUNCTION_ARM_RE = re.compile( - r"^(?P[0-9a-zA-Z_$]+):\n" # f: (name of function) + r'^(?P[0-9a-zA-Z_$]+):[ \t]*@+[ \t]*@"?(?P=func)"?\n' # f: (name of function) r"(?:\.L(?P=func)\$local:\n)?" # drop .L$local: r"(?:\s*\.type\s+\.L(?P=func)\$local,@function\n)?" # drop .type .L$local r"\s+\.fnstart\n" # .fnstart @@ -175,7 +175,7 @@ ASM_FUNCTION_ARM_DARWIN_RE = re.compile( ) ASM_FUNCTION_ARM_MACHO_RE = re.compile( - r"^_(?P[^:]+):[ \t]*\n" + r'^_(?P[^:]+):[ \t]*@[ \t]@"?(?P=func)"?\n' r"([ \t]*.cfi_startproc\n[ \t]*)?" r"(?P.*?)\n" r"[ \t]*\.cfi_endproc\n", @@ -183,17 +183,23 @@ ASM_FUNCTION_ARM_MACHO_RE = re.compile( ) ASM_FUNCTION_THUMBS_DARWIN_RE = re.compile( - r"^_(?P[^:]+):\n" r"(?P.*?)\n" r"[ \t]*\.data_region\n", + r'^_(?P[^:]+):[ \t]*@[ \t]@"?(?P=func)"?\n' + r"(?P.*?)\n" + r"[ \t]*\.data_region\n", flags=(re.M | re.S), ) ASM_FUNCTION_THUMB_DARWIN_RE = re.compile( - r"^_(?P[^:]+):\n" r"(?P.*?)\n" r"^[ \t]*@[ \t]--[ \t]End[ \t]function", + r'^_(?P[^:]+):[ \t]*@[ \t]@"?(?P=func)"?\n' + r"(?P.*?)\n" + r"^[ \t]*@[ \t]--[ \t]End[ \t]function", flags=(re.M | re.S), ) ASM_FUNCTION_ARM_IOS_RE = re.compile( - r"^_(?P[^:]+):\n" r"(?P.*?)" r"^[ \t]*@[ \t]--[ \t]End[ \t]function", + r'^_(?P[^:]+):[ \t]*@[ \t]@"?(?P=func)"?\n' + r"(?P.*?)" + r"^[ \t]*@[ \t]--[ \t]End[ \t]function", flags=(re.M | re.S), )