]> granicus.if.org Git - llvm/commitdiff
[AVR] Enable the '__do_copy_data' function
authorDylan McKay <me@dylanmckay.io>
Mon, 11 Sep 2017 10:32:51 +0000 (10:32 +0000)
committerDylan McKay <me@dylanmckay.io>
Mon, 11 Sep 2017 10:32:51 +0000 (10:32 +0000)
Also enables '__do_clear_bss'.

These functions are automaticalled called by the CRT if they are
declared.

We need these to be called otherwise RAM will start completely
uninitialised, even though we need to copy RAM variables from progmem to
RAM.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@312905 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Target/AVR/MCTargetDesc/AVRTargetStreamer.cpp
lib/Target/AVR/MCTargetDesc/AVRTargetStreamer.h
test/CodeGen/AVR/clear-bss.ll [new file with mode: 0644]
test/CodeGen/AVR/copy-data-to-ram.ll [new file with mode: 0644]

index a2d8c16eeb8ca25d1fa2c43bf791247b5d89d304..2b45d9adc7e903e4865ba4ff47dd638ab5d57a4b 100644 (file)
@@ -13,6 +13,8 @@
 
 #include "AVRTargetStreamer.h"
 
+#include "llvm/MC/MCContext.h"
+
 namespace llvm {
 
 AVRTargetStreamer::AVRTargetStreamer(MCStreamer &S) : MCTargetStreamer(S) {}
@@ -20,5 +22,23 @@ AVRTargetStreamer::AVRTargetStreamer(MCStreamer &S) : MCTargetStreamer(S) {}
 AVRTargetAsmStreamer::AVRTargetAsmStreamer(MCStreamer &S)
     : AVRTargetStreamer(S) {}
 
+void AVRTargetStreamer::finish() {
+  MCStreamer &OS = getStreamer();
+  MCContext &Context = OS.getContext();
+
+  MCSymbol *DoCopyData = Context.getOrCreateSymbol("__do_copy_data");
+  MCSymbol *DoClearBss = Context.getOrCreateSymbol("__do_clear_bss");
+
+  // FIXME: We can disable __do_copy_data if there are no static RAM variables.
+
+  OS.emitRawComment(" Declaring this symbol tells the CRT that it should");
+  OS.emitRawComment("copy all variables from program memory to RAM on startup");
+  OS.EmitSymbolAttribute(DoCopyData, MCSA_Global);
+
+  OS.emitRawComment(" Declaring this symbol tells the CRT that it should");
+  OS.emitRawComment("clear the zeroed data section on startup");
+  OS.EmitSymbolAttribute(DoClearBss, MCSA_Global);
+}
+
 } // end namespace llvm
 
index 99a536699ae9338c056c3bcd0d619913f5bb1f53..815088b0a5de0495312eaaa94b91506885be3fc3 100644 (file)
@@ -19,6 +19,8 @@ class MCStreamer;
 class AVRTargetStreamer : public MCTargetStreamer {
 public:
   explicit AVRTargetStreamer(MCStreamer &S);
+
+  void finish() override;
 };
 
 /// A target streamer for textual AVR assembly code.
diff --git a/test/CodeGen/AVR/clear-bss.ll b/test/CodeGen/AVR/clear-bss.ll
new file mode 100644 (file)
index 0000000..9c63815
--- /dev/null
@@ -0,0 +1,5 @@
+; RUN: llc < %s -march=avr | FileCheck %s
+
+; CHECK: .globl __do_clear_bss
+@zeroed = internal constant [3 x i8] zeroinitializer
+
diff --git a/test/CodeGen/AVR/copy-data-to-ram.ll b/test/CodeGen/AVR/copy-data-to-ram.ll
new file mode 100644 (file)
index 0000000..021cc0f
--- /dev/null
@@ -0,0 +1,5 @@
+; RUN: llc < %s -march=avr | FileCheck %s
+
+; CHECK: .globl __do_copy_data
+@str = internal global [3 x i8] c"foo"
+