diff --git a/llvm/include/llvm/MC/MCELFStreamer.h b/llvm/include/llvm/MC/MCELFStreamer.h index 5a1cdd9e96cad..9c86b4ecc6599 100644 --- a/llvm/include/llvm/MC/MCELFStreamer.h +++ b/llvm/include/llvm/MC/MCELFStreamer.h @@ -54,7 +54,6 @@ class MCELFStreamer : public MCObjectStreamer { void emitLabelAtPos(MCSymbol *Symbol, SMLoc Loc, MCDataFragment &F, uint64_t Offset) override; void emitAssemblerFlag(MCAssemblerFlag Flag) override; - void emitThumbFunc(MCSymbol *Func) override; void emitWeakReference(MCSymbol *Alias, const MCSymbol *Symbol) override; bool emitSymbolAttribute(MCSymbol *Symbol, MCSymbolAttr Attribute) override; void emitSymbolDesc(MCSymbol *Symbol, unsigned DescValue) override; diff --git a/llvm/include/llvm/MC/MCObjectStreamer.h b/llvm/include/llvm/MC/MCObjectStreamer.h index aaa13be6b2986..2e3ef417ce89a 100644 --- a/llvm/include/llvm/MC/MCObjectStreamer.h +++ b/llvm/include/llvm/MC/MCObjectStreamer.h @@ -63,7 +63,6 @@ class MCObjectStreamer : public MCStreamer { virtual void emitInstToData(const MCInst &Inst, const MCSubtargetInfo&) = 0; void emitCFIStartProcImpl(MCDwarfFrameInfo &Frame) override; void emitCFIEndProcImpl(MCDwarfFrameInfo &Frame) override; - MCSymbol *emitCFILabel() override; void emitInstructionImpl(const MCInst &Inst, const MCSubtargetInfo &STI); void resolvePendingFixups(); @@ -81,6 +80,7 @@ class MCObjectStreamer : public MCStreamer { bool isIntegratedAssemblerRequired() const override { return true; } void emitFrames(MCAsmBackend *MAB); + MCSymbol *emitCFILabel() override; void emitCFISections(bool EH, bool Debug) override; void insert(MCFragment *F) { diff --git a/llvm/include/llvm/MC/MCStreamer.h b/llvm/include/llvm/MC/MCStreamer.h index bf1bbd8885917..4fb2158f26e1e 100644 --- a/llvm/include/llvm/MC/MCStreamer.h +++ b/llvm/include/llvm/MC/MCStreamer.h @@ -168,6 +168,8 @@ class ARMTargetStreamer : public MCTargetStreamer { virtual void annotateTLSDescriptorSequence(const MCSymbolRefExpr *SRE); + // 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); void emitConstantPools() override; @@ -501,10 +503,6 @@ class MCStreamer { const Triple *DarwinTargetVariantTriple, const VersionTuple &DarwinTargetVariantSDKVersion); - /// Note in the output that the specified \p Func is a Thumb mode - /// function (ARM target only). - virtual void emitThumbFunc(MCSymbol *Func); - /// Emit an assignment of \p Value to \p Symbol. /// /// This corresponds to an assembler statement such as: diff --git a/llvm/include/llvm/MC/MCWasmStreamer.h b/llvm/include/llvm/MC/MCWasmStreamer.h index 77b5625efdfe8..4dffd83b12d0d 100644 --- a/llvm/include/llvm/MC/MCWasmStreamer.h +++ b/llvm/include/llvm/MC/MCWasmStreamer.h @@ -45,7 +45,6 @@ class MCWasmStreamer : public MCObjectStreamer { void emitLabelAtPos(MCSymbol *Symbol, SMLoc Loc, MCDataFragment &F, uint64_t Offset) override; void emitAssemblerFlag(MCAssemblerFlag Flag) override; - void emitThumbFunc(MCSymbol *Func) override; void emitWeakReference(MCSymbol *Alias, const MCSymbol *Symbol) override; bool emitSymbolAttribute(MCSymbol *Symbol, MCSymbolAttr Attribute) override; void emitSymbolDesc(MCSymbol *Symbol, unsigned DescValue) override; diff --git a/llvm/include/llvm/MC/MCWinCOFFStreamer.h b/llvm/include/llvm/MC/MCWinCOFFStreamer.h index 2425abe51e6dd..4e2a495480980 100644 --- a/llvm/include/llvm/MC/MCWinCOFFStreamer.h +++ b/llvm/include/llvm/MC/MCWinCOFFStreamer.h @@ -46,7 +46,6 @@ class MCWinCOFFStreamer : public MCObjectStreamer { void changeSection(MCSection *Section, uint32_t Subsection = 0) override; void emitLabel(MCSymbol *Symbol, SMLoc Loc = SMLoc()) override; void emitAssemblerFlag(MCAssemblerFlag Flag) override; - void emitThumbFunc(MCSymbol *Func) 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/MCAsmStreamer.cpp b/llvm/lib/MC/MCAsmStreamer.cpp index 5502465656627..4db405051f7f3 100644 --- a/llvm/lib/MC/MCAsmStreamer.cpp +++ b/llvm/lib/MC/MCAsmStreamer.cpp @@ -191,7 +191,6 @@ class MCAsmStreamer final : public MCStreamer { void emitDarwinTargetVariantBuildVersion(unsigned Platform, unsigned Major, unsigned Minor, unsigned Update, VersionTuple SDKVersion) override; - void emitThumbFunc(MCSymbol *Func) override; void emitAssignment(MCSymbol *Symbol, const MCExpr *Value) override; void emitConditionalAssignment(MCSymbol *Symbol, @@ -697,18 +696,6 @@ void MCAsmStreamer::emitDarwinTargetVariantBuildVersion( emitBuildVersion(Platform, Major, Minor, Update, SDKVersion); } -void MCAsmStreamer::emitThumbFunc(MCSymbol *Func) { - // This needs to emit to a temporary string to get properly quoted - // MCSymbols when they have spaces in them. - OS << "\t.thumb_func"; - // Only Mach-O hasSubsectionsViaSymbols() - if (MAI->hasSubsectionsViaSymbols()) { - OS << '\t'; - Func->print(OS, MAI); - } - EmitEOL(); -} - void MCAsmStreamer::emitAssignment(MCSymbol *Symbol, const MCExpr *Value) { // Do not emit a .set on inlined target assignments. bool EmitSet = true; diff --git a/llvm/lib/MC/MCELFStreamer.cpp b/llvm/lib/MC/MCELFStreamer.cpp index 282c82198507d..65bb88eb6f32a 100644 --- a/llvm/lib/MC/MCELFStreamer.cpp +++ b/llvm/lib/MC/MCELFStreamer.cpp @@ -616,10 +616,6 @@ void MCELFStreamer::finishImpl() { this->MCObjectStreamer::finishImpl(); } -void MCELFStreamer::emitThumbFunc(MCSymbol *Func) { - llvm_unreachable("Generic ELF doesn't support this directive"); -} - void MCELFStreamer::emitSymbolDesc(MCSymbol *Symbol, unsigned DescValue) { llvm_unreachable("ELF doesn't support this directive"); } diff --git a/llvm/lib/MC/MCMachOStreamer.cpp b/llvm/lib/MC/MCMachOStreamer.cpp index aa79d1bc5b869..25352a0e1d5c9 100644 --- a/llvm/lib/MC/MCMachOStreamer.cpp +++ b/llvm/lib/MC/MCMachOStreamer.cpp @@ -99,7 +99,6 @@ class MCMachOStreamer : public MCObjectStreamer { void emitDarwinTargetVariantBuildVersion(unsigned Platform, unsigned Major, unsigned Minor, unsigned Update, VersionTuple SDKVersion) override; - void emitThumbFunc(MCSymbol *Func) override; bool emitSymbolAttribute(MCSymbol *Symbol, MCSymbolAttr Attribute) override; void emitSymbolDesc(MCSymbol *Symbol, unsigned DescValue) override; void emitCommonSymbol(MCSymbol *Symbol, uint64_t Size, @@ -269,13 +268,6 @@ void MCMachOStreamer::emitDarwinTargetVariantBuildVersion( Minor, Update, SDKVersion); } -void MCMachOStreamer::emitThumbFunc(MCSymbol *Symbol) { - // Remember that the function is a thumb function. Fixup and relocation - // values will need adjusted. - getAssembler().setIsThumbFunc(Symbol); - cast(Symbol)->setThumbFunc(); -} - bool MCMachOStreamer::emitSymbolAttribute(MCSymbol *Sym, MCSymbolAttr Attribute) { MCSymbolMachO *Symbol = cast(Sym); diff --git a/llvm/lib/MC/MCStreamer.cpp b/llvm/lib/MC/MCStreamer.cpp index 462ebfedeba04..dd04e1e30720a 100644 --- a/llvm/lib/MC/MCStreamer.cpp +++ b/llvm/lib/MC/MCStreamer.cpp @@ -1229,7 +1229,6 @@ void MCStreamer::emitAbsoluteSymbolDiffAsULEB128(const MCSymbol *Hi, } void MCStreamer::emitAssemblerFlag(MCAssemblerFlag Flag) {} -void MCStreamer::emitThumbFunc(MCSymbol *Func) {} 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 8560f0ebeb1d8..d4806b3a5ecb6 100644 --- a/llvm/lib/MC/MCWasmStreamer.cpp +++ b/llvm/lib/MC/MCWasmStreamer.cpp @@ -238,10 +238,6 @@ void MCWasmStreamer::fixSymbolsInTLSFixups(const MCExpr *expr) { } } -void MCWasmStreamer::emitThumbFunc(MCSymbol *Func) { - llvm_unreachable("Generic Wasm doesn't support this directive"); -} - void MCWasmStreamer::emitSymbolDesc(MCSymbol *Symbol, unsigned DescValue) { llvm_unreachable("Wasm doesn't support this directive"); } diff --git a/llvm/lib/MC/MCWinCOFFStreamer.cpp b/llvm/lib/MC/MCWinCOFFStreamer.cpp index 8fd46bc8b0255..3d7eb525392e1 100644 --- a/llvm/lib/MC/MCWinCOFFStreamer.cpp +++ b/llvm/lib/MC/MCWinCOFFStreamer.cpp @@ -208,10 +208,6 @@ void MCWinCOFFStreamer::emitAssemblerFlag(MCAssemblerFlag Flag) { } } -void MCWinCOFFStreamer::emitThumbFunc(MCSymbol *Func) { - llvm_unreachable("not implemented"); -} - bool MCWinCOFFStreamer::emitSymbolAttribute(MCSymbol *S, MCSymbolAttr Attribute) { auto *Symbol = cast(S); diff --git a/llvm/lib/Target/ARM/ARMAsmPrinter.cpp b/llvm/lib/Target/ARM/ARMAsmPrinter.cpp index af47d0e176f36..b8772e1665f8a 100644 --- a/llvm/lib/Target/ARM/ARMAsmPrinter.cpp +++ b/llvm/lib/Target/ARM/ARMAsmPrinter.cpp @@ -63,9 +63,11 @@ void ARMAsmPrinter::emitFunctionBodyEnd() { } void ARMAsmPrinter::emitFunctionEntryLabel() { + auto &TS = + static_cast(*OutStreamer->getTargetStreamer()); if (AFI->isThumbFunction()) { OutStreamer->emitAssemblerFlag(MCAF_Code16); - OutStreamer->emitThumbFunc(CurrentFnSym); + TS.emitThumbFunc(CurrentFnSym); } else { OutStreamer->emitAssemblerFlag(MCAF_Code32); } diff --git a/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp b/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp index 325dfb33762a6..6cc95b7e1cd2a 100644 --- a/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp +++ b/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp @@ -11712,7 +11712,7 @@ void ARMAsmParser::doBeforeLabelEmit(MCSymbol *Symbol, SMLoc IDLoc) { void ARMAsmParser::onLabelParsed(MCSymbol *Symbol) { if (NextSymbolIsThumb) { - getParser().getStreamer().emitThumbFunc(Symbol); + getTargetStreamer().emitThumbFunc(Symbol); NextSymbolIsThumb = false; } } @@ -11732,7 +11732,7 @@ bool ARMAsmParser::parseDirectiveThumbFunc(SMLoc L) { Parser.getTok().is(AsmToken::String)) { MCSymbol *Func = getParser().getContext().getOrCreateSymbol( Parser.getTok().getIdentifier()); - getParser().getStreamer().emitThumbFunc(Func); + getTargetStreamer().emitThumbFunc(Func); Parser.Lex(); if (parseEOL()) return true; diff --git a/llvm/lib/Target/ARM/MCTargetDesc/ARMELFStreamer.cpp b/llvm/lib/Target/ARM/MCTargetDesc/ARMELFStreamer.cpp index c528526382a2b..ac30a0b7c2a01 100644 --- a/llvm/lib/Target/ARM/MCTargetDesc/ARMELFStreamer.cpp +++ b/llvm/lib/Target/ARM/MCTargetDesc/ARMELFStreamer.cpp @@ -100,6 +100,7 @@ class ARMTargetAsmStreamer : public ARMTargetStreamer { void finishAttributeSection() override; void annotateTLSDescriptorSequence(const MCSymbolRefExpr *SRE) override; + void emitThumbFunc(MCSymbol *Symbol) override; void emitThumbSet(MCSymbol *Symbol, const MCExpr *Value) override; void emitARMWinCFIAllocStack(unsigned Size, bool Wide) override; @@ -260,6 +261,17 @@ void ARMTargetAsmStreamer::annotateTLSDescriptorSequence( OS << "\t.tlsdescseq\t" << S->getSymbol().getName() << "\n"; } +void ARMTargetAsmStreamer::emitThumbFunc(MCSymbol *Symbol) { + const MCAsmInfo *MAI = Streamer.getContext().getAsmInfo(); + OS << "\t.thumb_func"; + // Only Mach-O hasSubsectionsViaSymbols() + if (MAI->hasSubsectionsViaSymbols()) { + OS << '\t'; + Symbol->print(OS, MAI); + } + OS << '\n'; +} + void ARMTargetAsmStreamer::emitThumbSet(MCSymbol *Symbol, const MCExpr *Value) { const MCAsmInfo *MAI = Streamer.getContext().getAsmInfo(); @@ -422,6 +434,7 @@ class ARMTargetELFStreamer : public ARMTargetStreamer { void emitLabel(MCSymbol *Symbol) override; void annotateTLSDescriptorSequence(const MCSymbolRefExpr *SRE) override; + void emitThumbFunc(MCSymbol *Symbol) override; void emitThumbSet(MCSymbol *Symbol, const MCExpr *Value) override; // Reset state between object emissions @@ -686,11 +699,6 @@ class ARMELFStreamer : public MCELFStreamer { Symbol->setBinding(ELF::STB_LOCAL); } - void emitThumbFunc(MCSymbol *Func) override { - getAssembler().setIsThumbFunc(Func); - emitSymbolAttribute(Func, MCSA_ELF_TypeFunction); - } - // Helper functions for ARM exception handling directives void EHReset(); @@ -1089,7 +1097,7 @@ void ARMTargetELFStreamer::emitLabel(MCSymbol *Symbol) { Streamer.getAssembler().registerSymbol(*Symbol); unsigned Type = cast(Symbol)->getType(); if (Type == ELF::STT_FUNC || Type == ELF::STT_GNU_IFUNC) - Streamer.emitThumbFunc(Symbol); + emitThumbFunc(Symbol); } void ARMTargetELFStreamer::annotateTLSDescriptorSequence( @@ -1097,6 +1105,11 @@ void ARMTargetELFStreamer::annotateTLSDescriptorSequence( getStreamer().EmitFixup(S, FK_Data_4); } +void ARMTargetELFStreamer::emitThumbFunc(MCSymbol *Symbol) { + getStreamer().getAssembler().setIsThumbFunc(Symbol); + getStreamer().emitSymbolAttribute(Symbol, MCSA_ELF_TypeFunction); +} + void ARMTargetELFStreamer::emitThumbSet(MCSymbol *Symbol, const MCExpr *Value) { if (const MCSymbolRefExpr *SRE = dyn_cast(Value)) { const MCSymbol &Sym = SRE->getSymbol(); @@ -1106,7 +1119,7 @@ void ARMTargetELFStreamer::emitThumbSet(MCSymbol *Symbol, const MCExpr *Value) { } } - getStreamer().emitThumbFunc(Symbol); + emitThumbFunc(Symbol); getStreamer().emitAssignment(Symbol, Value); } diff --git a/llvm/lib/Target/ARM/MCTargetDesc/ARMMCTargetDesc.h b/llvm/lib/Target/ARM/MCTargetDesc/ARMMCTargetDesc.h index 39b189780f1ff..5a67417351f81 100644 --- a/llvm/lib/Target/ARM/MCTargetDesc/ARMMCTargetDesc.h +++ b/llvm/lib/Target/ARM/MCTargetDesc/ARMMCTargetDesc.h @@ -71,6 +71,7 @@ MCTargetStreamer *createARMTargetAsmStreamer(MCStreamer &S, MCTargetStreamer *createARMObjectTargetStreamer(MCStreamer &S, const MCSubtargetInfo &STI); MCTargetStreamer *createARMObjectTargetELFStreamer(MCStreamer &S); +MCTargetStreamer *createARMObjectTargetMachOStreamer(MCStreamer &S); MCTargetStreamer *createARMObjectTargetWinCOFFStreamer(MCStreamer &S); MCCodeEmitter *createARMLEMCCodeEmitter(const MCInstrInfo &MCII, diff --git a/llvm/lib/Target/ARM/MCTargetDesc/ARMMachObjectWriter.cpp b/llvm/lib/Target/ARM/MCTargetDesc/ARMMachObjectWriter.cpp index 357654615e002..c37ed1198c3bb 100644 --- a/llvm/lib/Target/ARM/MCTargetDesc/ARMMachObjectWriter.cpp +++ b/llvm/lib/Target/ARM/MCTargetDesc/ARMMachObjectWriter.cpp @@ -16,8 +16,11 @@ #include "llvm/MC/MCExpr.h" #include "llvm/MC/MCFixup.h" #include "llvm/MC/MCMachObjectWriter.h" +#include "llvm/MC/MCObjectStreamer.h" #include "llvm/MC/MCSection.h" +#include "llvm/MC/MCSymbolMachO.h" #include "llvm/MC/MCValue.h" +#include "llvm/Support/Casting.h" #include "llvm/Support/ErrorHandling.h" using namespace llvm; @@ -489,3 +492,23 @@ llvm::createARMMachObjectWriter(bool Is64Bit, uint32_t CPUType, uint32_t CPUSubtype) { return std::make_unique(Is64Bit, CPUType, CPUSubtype); } + +namespace { +class ARMTargetMachOStreamer : public ARMTargetStreamer { +public: + ARMTargetMachOStreamer(MCStreamer &S) : ARMTargetStreamer(S) {} + MCObjectStreamer &getStreamer() { + return static_cast(Streamer); + } + void emitThumbFunc(MCSymbol *Symbol) override { + // Remember that the function is a thumb function. Fixup and relocation + // values will need adjusted. + getStreamer().getAssembler().setIsThumbFunc(Symbol); + cast(Symbol)->setThumbFunc(); + } +}; +} // namespace + +MCTargetStreamer *llvm::createARMObjectTargetMachOStreamer(MCStreamer &S) { + return new ARMTargetMachOStreamer(S); +} diff --git a/llvm/lib/Target/ARM/MCTargetDesc/ARMTargetStreamer.cpp b/llvm/lib/Target/ARM/MCTargetDesc/ARMTargetStreamer.cpp index 84a0fb44c9acd..1dc79438d2fc5 100644 --- a/llvm/lib/Target/ARM/MCTargetDesc/ARMTargetStreamer.cpp +++ b/llvm/lib/Target/ARM/MCTargetDesc/ARMTargetStreamer.cpp @@ -115,6 +115,7 @@ void ARMTargetStreamer::emitFPU(ARM::FPUKind FPU) {} void ARMTargetStreamer::finishAttributeSection() {} void ARMTargetStreamer::annotateTLSDescriptorSequence( const MCSymbolRefExpr *SRE) {} +void ARMTargetStreamer::emitThumbFunc(MCSymbol *Symbol) {} void ARMTargetStreamer::emitThumbSet(MCSymbol *Symbol, const MCExpr *Value) {} void ARMTargetStreamer::emitARMWinCFIAllocStack(unsigned Size, bool Wide) {} @@ -329,5 +330,7 @@ llvm::createARMObjectTargetStreamer(MCStreamer &S, const MCSubtargetInfo &STI) { return createARMObjectTargetELFStreamer(S); if (TT.isOSBinFormatCOFF()) return createARMObjectTargetWinCOFFStreamer(S); + if (TT.isOSBinFormatMachO()) + return createARMObjectTargetMachOStreamer(S); return new ARMTargetStreamer(S); } diff --git a/llvm/lib/Target/ARM/MCTargetDesc/ARMWinCOFFStreamer.cpp b/llvm/lib/Target/ARM/MCTargetDesc/ARMWinCOFFStreamer.cpp index bb51d716311b8..6566aa4c243be 100644 --- a/llvm/lib/Target/ARM/MCTargetDesc/ARMWinCOFFStreamer.cpp +++ b/llvm/lib/Target/ARM/MCTargetDesc/ARMWinCOFFStreamer.cpp @@ -31,7 +31,6 @@ class ARMWinCOFFStreamer : public MCWinCOFFStreamer { void emitWindowsUnwindTables() override; void emitWindowsUnwindTables(WinEH::FrameInfo *Frame) override; - void emitThumbFunc(MCSymbol *Symbol) override; void finishImpl() override; }; @@ -54,10 +53,6 @@ void ARMWinCOFFStreamer::emitWindowsUnwindTables() { EHStreamer.Emit(*this); } -void ARMWinCOFFStreamer::emitThumbFunc(MCSymbol *Symbol) { - getAssembler().setIsThumbFunc(Symbol); -} - void ARMWinCOFFStreamer::finishImpl() { emitFrames(nullptr); emitWindowsUnwindTables(); @@ -80,6 +75,11 @@ class ARMTargetWinCOFFStreamer : public llvm::ARMTargetStreamer { public: ARMTargetWinCOFFStreamer(llvm::MCStreamer &S) : ARMTargetStreamer(S) {} + ARMWinCOFFStreamer &getStreamer() { + return static_cast(Streamer); + } + void emitThumbFunc(MCSymbol *Symbol) override; + // The unwind codes on ARM Windows are documented at // https://docs.microsoft.com/en-us/cpp/build/arm-exception-handling void emitARMWinCFIAllocStack(unsigned Size, bool Wide) override; @@ -97,6 +97,10 @@ class ARMTargetWinCOFFStreamer : public llvm::ARMTargetStreamer { void emitARMWinUnwindCode(unsigned UnwindCode, int Reg, int Offset); }; +void ARMTargetWinCOFFStreamer::emitThumbFunc(MCSymbol *Symbol) { + getStreamer().getAssembler().setIsThumbFunc(Symbol); +} + // Helper function to common out unwind code setup for those codes that can // belong to both prolog and epilog. void ARMTargetWinCOFFStreamer::emitARMWinUnwindCode(unsigned UnwindCode,