Cleanup handling of .zerofill on darwin:
[oota-llvm.git] / lib / Target / ARM / AsmPrinter / ARMAsmPrinter.cpp
index ef2d460fab77c5bb0894df09da3c4cfa3f777665..30f9fec867ecd9a485020021282ded3cccfedbfa 100644 (file)
@@ -1196,71 +1196,76 @@ void ARMAsmPrinter::PrintGlobalVariable(const GlobalVariable* GVar) {
   if (Subtarget->isTargetELF())
     O << "\t.type " << *GVarSym << ",%object\n";
 
+  SectionKind GVKind = TargetLoweringObjectFile::getKindForGlobal(GVar, TM);
   const MCSection *TheSection =
-    getObjFileLowering().SectionForGlobal(GVar, Mang, TM);
+    getObjFileLowering().SectionForGlobal(GVar, GVKind, Mang, TM);
   OutStreamer.SwitchSection(TheSection);
 
+  // Handle the zerofill directive on darwin, which is a special form of BSS
+  // emission.
+  if (GVKind.isBSS() && MAI->hasMachoZeroFillDirective()) {
+    TargetLoweringObjectFileMachO &TLOFMacho = 
+    static_cast<TargetLoweringObjectFileMachO &>(getObjFileLowering());
+    if (TheSection == TLOFMacho.getDataCommonSection()) {
+      // .globl _foo
+      OutStreamer.EmitSymbolAttribute(GVarSym, MCStreamer::Global);
+      // .zerofill __DATA, __common, _foo, 400, 5
+      OutStreamer.EmitZerofill(TheSection, GVarSym, Size, 1 << Align);
+      return;
+    }
+  }
+  
   // FIXME: get this stuff from section kind flags.
   if (C->isNullValue() && !GVar->hasSection() && !GVar->isThreadLocal() &&
       // Don't put things that should go in the cstring section into "comm".
-      !TheSection->getKind().isMergeableCString()) {
-    if (GVar->hasExternalLinkage()) {
-      if (const char *Directive = MAI->getZeroFillDirective()) {
-        O << "\t.globl\t" << *GVarSym << "\n";
-        O << Directive << "__DATA, __common, " << *GVarSym
-          << ", " << Size << ", " << Align << "\n";
-        return;
-      }
-    }
+      !TheSection->getKind().isMergeableCString() &&
+      (GVar->hasLocalLinkage() || GVar->isWeakForLinker())) {
+    if (Size == 0) Size = 1;   // .comm Foo, 0 is undefined, avoid it.
 
-    if (GVar->hasLocalLinkage() || GVar->isWeakForLinker()) {
-      if (Size == 0) Size = 1;   // .comm Foo, 0 is undefined, avoid it.
-
-      if (isDarwin) {
-        if (GVar->hasLocalLinkage()) {
-          O << MAI->getLCOMMDirective() << *GVarSym << ',' << Size
-            << ',' << Align;
-        } else if (GVar->hasCommonLinkage()) {
-          O << MAI->getCOMMDirective() << *GVarSym << ',' << Size
-            << ',' << Align;
-        } else {
-          OutStreamer.SwitchSection(TheSection);
-          O << "\t.globl " << *GVarSym << '\n' << MAI->getWeakDefDirective();
-          O << *GVarSym << '\n';
-          EmitAlignment(Align, GVar);
-          O << *GVarSym << ":";
-          if (VerboseAsm) {
-            O.PadToColumn(MAI->getCommentColumn());
-            O << MAI->getCommentString() << ' ';
-            WriteAsOperand(O, GVar, /*PrintType=*/false, GVar->getParent());
-          }
-          O << '\n';
-          EmitGlobalConstant(C);
-          return;
-        }
-      } else if (MAI->getLCOMMDirective() != NULL) {
-        if (GVar->hasLocalLinkage()) {
-          O << MAI->getLCOMMDirective() << *GVarSym << "," << Size;
-        } else {
-          O << MAI->getCOMMDirective() << *GVarSym << "," << Size;
-          if (MAI->getCOMMDirectiveTakesAlignment())
-            O << ',' << (MAI->getAlignmentIsInBytes() ? (1 << Align) : Align);
+    if (isDarwin) {
+      if (GVar->hasLocalLinkage()) {
+        O << MAI->getLCOMMDirective() << *GVarSym << ',' << Size
+          << ',' << Align;
+      } else if (GVar->hasCommonLinkage()) {
+        O << MAI->getCOMMDirective() << *GVarSym << ',' << Size
+          << ',' << Align;
+      } else {
+        OutStreamer.SwitchSection(TheSection);
+        O << "\t.globl " << *GVarSym << '\n' << MAI->getWeakDefDirective();
+        O << *GVarSym << '\n';
+        EmitAlignment(Align, GVar);
+        O << *GVarSym << ":";
+        if (VerboseAsm) {
+          O.PadToColumn(MAI->getCommentColumn());
+          O << MAI->getCommentString() << ' ';
+          WriteAsOperand(O, GVar, /*PrintType=*/false, GVar->getParent());
         }
+        O << '\n';
+        EmitGlobalConstant(C);
+        return;
+      }
+    } else if (MAI->getLCOMMDirective() != NULL) {
+      if (GVar->hasLocalLinkage()) {
+        O << MAI->getLCOMMDirective() << *GVarSym << "," << Size;
       } else {
-        if (GVar->hasLocalLinkage())
-          O << "\t.local\t" << *GVarSym << '\n';
         O << MAI->getCOMMDirective() << *GVarSym << "," << Size;
         if (MAI->getCOMMDirectiveTakesAlignment())
-          O << "," << (MAI->getAlignmentIsInBytes() ? (1 << Align) : Align);
-      }
-      if (VerboseAsm) {
-        O.PadToColumn(MAI->getCommentColumn());
-        O << MAI->getCommentString() << ' ';
-        WriteAsOperand(O, GVar, /*PrintType=*/false, GVar->getParent());
+          O << ',' << (MAI->getAlignmentIsInBytes() ? (1 << Align) : Align);
       }
-      O << "\n";
-      return;
+    } else {
+      if (GVar->hasLocalLinkage())
+        O << "\t.local\t" << *GVarSym << '\n';
+      O << MAI->getCOMMDirective() << *GVarSym << "," << Size;
+      if (MAI->getCOMMDirectiveTakesAlignment())
+        O << "," << (MAI->getAlignmentIsInBytes() ? (1 << Align) : Align);
+    }
+    if (VerboseAsm) {
+      O.PadToColumn(MAI->getCommentColumn());
+      O << MAI->getCommentString() << ' ';
+      WriteAsOperand(O, GVar, /*PrintType=*/false, GVar->getParent());
     }
+    O << "\n";
+    return;
   }
 
   switch (GVar->getLinkage()) {