diff options
| author | Dimitry Andric <dim@FreeBSD.org> | 2021-11-19 20:06:13 +0000 |
|---|---|---|
| committer | Dimitry Andric <dim@FreeBSD.org> | 2021-11-19 20:06:13 +0000 |
| commit | c0981da47d5696fe36474fcf86b4ce03ae3ff818 (patch) | |
| tree | f42add1021b9f2ac6a69ac7cf6c4499962739a45 /llvm/lib/Target/AVR/AVRAsmPrinter.cpp | |
| parent | 344a3780b2e33f6ca763666c380202b18aab72a3 (diff) | |
Diffstat (limited to 'llvm/lib/Target/AVR/AVRAsmPrinter.cpp')
| -rw-r--r-- | llvm/lib/Target/AVR/AVRAsmPrinter.cpp | 58 |
1 files changed, 50 insertions, 8 deletions
diff --git a/llvm/lib/Target/AVR/AVRAsmPrinter.cpp b/llvm/lib/Target/AVR/AVRAsmPrinter.cpp index e8a13c712210..259ab1bc7aec 100644 --- a/llvm/lib/Target/AVR/AVRAsmPrinter.cpp +++ b/llvm/lib/Target/AVR/AVRAsmPrinter.cpp @@ -24,11 +24,12 @@ #include "llvm/CodeGen/TargetRegisterInfo.h" #include "llvm/CodeGen/TargetSubtargetInfo.h" #include "llvm/IR/Mangler.h" +#include "llvm/MC/MCContext.h" #include "llvm/MC/MCInst.h" #include "llvm/MC/MCStreamer.h" #include "llvm/MC/MCSymbol.h" +#include "llvm/MC/TargetRegistry.h" #include "llvm/Support/ErrorHandling.h" -#include "llvm/Support/TargetRegistry.h" #include "llvm/Support/raw_ostream.h" #define DEBUG_TYPE "avr-asm-printer" @@ -38,9 +39,8 @@ namespace llvm { /// An AVR assembly code printer. class AVRAsmPrinter : public AsmPrinter { public: - AVRAsmPrinter(TargetMachine &TM, - std::unique_ptr<MCStreamer> Streamer) - : AsmPrinter(TM, std::move(Streamer)), MRI(*TM.getMCRegisterInfo()) { } + AVRAsmPrinter(TargetMachine &TM, std::unique_ptr<MCStreamer> Streamer) + : AsmPrinter(TM, std::move(Streamer)), MRI(*TM.getMCRegisterInfo()) {} StringRef getPassName() const override { return "AVR Assembly Printer"; } @@ -56,8 +56,13 @@ public: const MCExpr *lowerConstant(const Constant *CV) override; + void emitXXStructor(const DataLayout &DL, const Constant *CV) override; + + bool doFinalization(Module &M) override; + private: const MCRegisterInfo &MRI; + bool EmittedStructorSymbolAttrs = false; }; void AVRAsmPrinter::printOperand(const MachineInstr *MI, unsigned OpNo, @@ -139,9 +144,8 @@ bool AVRAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNum, bool AVRAsmPrinter::PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNum, const char *ExtraCode, raw_ostream &O) { - if (ExtraCode && ExtraCode[0]) { - llvm_unreachable("This branch is not implemented yet"); - } + if (ExtraCode && ExtraCode[0]) + return true; // Unknown modifier const MachineOperand &MO = MI->getOperand(OpNum); (void)MO; @@ -193,9 +197,47 @@ const MCExpr *AVRAsmPrinter::lowerConstant(const Constant *CV) { return AsmPrinter::lowerConstant(CV); } +void AVRAsmPrinter::emitXXStructor(const DataLayout &DL, const Constant *CV) { + if (!EmittedStructorSymbolAttrs) { + OutStreamer->emitRawComment( + " Emitting these undefined symbol references causes us to link the" + " libgcc code that runs our constructors/destructors"); + OutStreamer->emitRawComment(" This matches GCC's behavior"); + + MCSymbol *CtorsSym = OutContext.getOrCreateSymbol("__do_global_ctors"); + OutStreamer->emitSymbolAttribute(CtorsSym, MCSA_Global); + + MCSymbol *DtorsSym = OutContext.getOrCreateSymbol("__do_global_dtors"); + OutStreamer->emitSymbolAttribute(DtorsSym, MCSA_Global); + + EmittedStructorSymbolAttrs = true; + } + + AsmPrinter::emitXXStructor(DL, CV); +} + +bool AVRAsmPrinter::doFinalization(Module &M) { + MCSymbol *DoCopyData = OutContext.getOrCreateSymbol("__do_copy_data"); + MCSymbol *DoClearBss = OutContext.getOrCreateSymbol("__do_clear_bss"); + + // FIXME: We can disable __do_copy_data if there are no static RAM variables. + + OutStreamer->emitRawComment( + " Declaring this symbol tells the CRT that it should"); + OutStreamer->emitRawComment( + "copy all variables from program memory to RAM on startup"); + OutStreamer->emitSymbolAttribute(DoCopyData, MCSA_Global); + + OutStreamer->emitRawComment( + " Declaring this symbol tells the CRT that it should"); + OutStreamer->emitRawComment("clear the zeroed data section on startup"); + OutStreamer->emitSymbolAttribute(DoClearBss, MCSA_Global); + + return AsmPrinter::doFinalization(M); +} + } // end of namespace llvm extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeAVRAsmPrinter() { llvm::RegisterAsmPrinter<llvm::AVRAsmPrinter> X(llvm::getTheAVRTarget()); } - |
