24
24
#include " llvm/CodeGen/TargetRegisterInfo.h"
25
25
#include " llvm/CodeGen/TargetSubtargetInfo.h"
26
26
#include " llvm/IR/Mangler.h"
27
+ #include " llvm/MC/MCContext.h"
27
28
#include " llvm/MC/MCInst.h"
28
29
#include " llvm/MC/MCStreamer.h"
29
30
#include " llvm/MC/MCSymbol.h"
@@ -38,9 +39,8 @@ namespace llvm {
38
39
// / An AVR assembly code printer.
39
40
class AVRAsmPrinter : public AsmPrinter {
40
41
public:
41
- AVRAsmPrinter (TargetMachine &TM,
42
- std::unique_ptr<MCStreamer> Streamer)
43
- : AsmPrinter(TM, std::move(Streamer)), MRI(*TM.getMCRegisterInfo()) { }
42
+ AVRAsmPrinter (TargetMachine &TM, std::unique_ptr<MCStreamer> Streamer)
43
+ : AsmPrinter(TM, std::move(Streamer)), MRI(*TM.getMCRegisterInfo()) {}
44
44
45
45
StringRef getPassName () const override { return " AVR Assembly Printer" ; }
46
46
@@ -56,8 +56,13 @@ class AVRAsmPrinter : public AsmPrinter {
56
56
57
57
const MCExpr *lowerConstant (const Constant *CV) override ;
58
58
59
+ void emitXXStructor (const DataLayout &DL, const Constant *CV) override ;
60
+
61
+ bool doFinalization (Module &M) override ;
62
+
59
63
private:
60
64
const MCRegisterInfo &MRI;
65
+ bool EmittedStructorSymbolAttrs = false ;
61
66
};
62
67
63
68
void AVRAsmPrinter::printOperand (const MachineInstr *MI, unsigned OpNo,
@@ -193,9 +198,47 @@ const MCExpr *AVRAsmPrinter::lowerConstant(const Constant *CV) {
193
198
return AsmPrinter::lowerConstant (CV);
194
199
}
195
200
201
+ void AVRAsmPrinter::emitXXStructor (const DataLayout &DL, const Constant *CV) {
202
+ if (!EmittedStructorSymbolAttrs) {
203
+ OutStreamer->emitRawComment (
204
+ " Emitting these undefined symbol references causes us to link the"
205
+ " libgcc code that runs our constructors/destructors" );
206
+ OutStreamer->emitRawComment (" This matches GCC's behavior" );
207
+
208
+ MCSymbol *CtorsSym = OutContext.getOrCreateSymbol (" __do_global_ctors" );
209
+ OutStreamer->emitSymbolAttribute (CtorsSym, MCSA_Global);
210
+
211
+ MCSymbol *DtorsSym = OutContext.getOrCreateSymbol (" __do_global_dtors" );
212
+ OutStreamer->emitSymbolAttribute (DtorsSym, MCSA_Global);
213
+
214
+ EmittedStructorSymbolAttrs = true ;
215
+ }
216
+
217
+ AsmPrinter::emitXXStructor (DL, CV);
218
+ }
219
+
220
+ bool AVRAsmPrinter::doFinalization (Module &M) {
221
+ MCSymbol *DoCopyData = OutContext.getOrCreateSymbol (" __do_copy_data" );
222
+ MCSymbol *DoClearBss = OutContext.getOrCreateSymbol (" __do_clear_bss" );
223
+
224
+ // FIXME: We can disable __do_copy_data if there are no static RAM variables.
225
+
226
+ OutStreamer->emitRawComment (
227
+ " Declaring this symbol tells the CRT that it should" );
228
+ OutStreamer->emitRawComment (
229
+ " copy all variables from program memory to RAM on startup" );
230
+ OutStreamer->emitSymbolAttribute (DoCopyData, MCSA_Global);
231
+
232
+ OutStreamer->emitRawComment (
233
+ " Declaring this symbol tells the CRT that it should" );
234
+ OutStreamer->emitRawComment (" clear the zeroed data section on startup" );
235
+ OutStreamer->emitSymbolAttribute (DoClearBss, MCSA_Global);
236
+
237
+ return AsmPrinter::doFinalization (M);
238
+ }
239
+
196
240
} // end of namespace llvm
197
241
198
242
extern " C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeAVRAsmPrinter () {
199
243
llvm::RegisterAsmPrinter<llvm::AVRAsmPrinter> X (llvm::getTheAVRTarget ());
200
244
}
201
-
0 commit comments