* Fix one more bug in PIC codegen: extra load is needed for *all*
[oota-llvm.git] / lib / Target / X86 / X86AsmPrinter.cpp
index a37cbb5406b1b03e71158eb94a8bb5ecc2daf404..bea3914fe649be3752c28655937186af58546e7d 100644 (file)
@@ -16,6 +16,7 @@
 
 #include "X86AsmPrinter.h"
 #include "X86ATTAsmPrinter.h"
+#include "X86COFF.h"
 #include "X86IntelAsmPrinter.h"
 #include "X86MachineFunctionInfo.h"
 #include "X86Subtarget.h"
 #include "llvm/Assembly/Writer.h"
 #include "llvm/Support/Mangler.h"
 #include "llvm/Target/TargetAsmInfo.h"
-
+#include "llvm/Target/TargetOptions.h"
 using namespace llvm;
 
-Statistic<> llvm::EmittedInsts("asm-printer",
-                               "Number of machine instrs printed");
-
 static X86FunctionInfo calculateFunctionInfo(const Function *F,
                                              const TargetData *TD) {
   X86FunctionInfo Info;
@@ -109,13 +107,9 @@ void X86SharedAsmPrinter::decorateName(std::string &Name,
 
 /// doInitialization
 bool X86SharedAsmPrinter::doInitialization(Module &M) {
-  if (Subtarget->isTargetDarwin()) {
-    if (!Subtarget->is64Bit())
-      X86PICStyle = PICStyle::Stub;
-
-    // Emit initial debug information.
-    DW.BeginModule(&M);
-  } else if (Subtarget->isTargetELF() || Subtarget->isTargetCygwin()) {
+  if (Subtarget->isTargetELF() ||
+      Subtarget->isTargetCygMing() ||
+      Subtarget->isTargetDarwin()) {
     // Emit initial debug information.
     DW.BeginModule(&M);
   }
@@ -132,7 +126,7 @@ bool X86SharedAsmPrinter::doFinalization(Module &M) {
   // Print out module-level global variables here.
   for (Module::const_global_iterator I = M.global_begin(), E = M.global_end();
        I != E; ++I) {
-    if (!I->hasInitializer() && !I->hasExternalWeakLinkage())
+    if (!I->hasInitializer())
       continue;   // External global require no code
     
     // Check to see if this is a special global used by LLVM, if so, emit it.
@@ -156,7 +150,10 @@ bool X86SharedAsmPrinter::doFinalization(Module &M) {
           O << "\t.zerofill __DATA__, __common, " << name << ", "
             << Size << ", " << Align;
       } else {
-        SwitchToDataSection(TAI->getDataSection(), I);
+        if (!NoZerosInBSS && TAI->getBSSSection())
+          SwitchToDataSection(TAI->getBSSSection(), I);
+        else
+          SwitchToDataSection(TAI->getDataSection(), I);
         if (TAI->getLCOMMDirective() != NULL) {
           if (I->hasInternalLinkage()) {
             O << TAI->getLCOMMDirective() << name << "," << Size;
@@ -165,7 +162,7 @@ bool X86SharedAsmPrinter::doFinalization(Module &M) {
           } else
             O << TAI->getCOMMDirective()  << name << "," << Size;
         } else {
-          if (!Subtarget->isTargetCygwin()) {
+          if (!Subtarget->isTargetCygMing()) {
             if (I->hasInternalLinkage())
               O << "\t.local\t" << name << "\n";
           }
@@ -177,24 +174,13 @@ bool X86SharedAsmPrinter::doFinalization(Module &M) {
       O << "\t\t" << TAI->getCommentString() << " " << I->getName() << "\n";
     } else {
       switch (I->getLinkage()) {
-      case GlobalValue::ExternalWeakLinkage:
-       if (Subtarget->isTargetDarwin()) {
-         assert(0 && "External weak linkage for Darwin not implemented yet");
-       } else if (Subtarget->isTargetCygwin()) {
-         // There is no external weak linkage on Mingw32 platform.
-         // Defaulting just to external
-         O << "\t.globl " << name << "\n";
-       } else {
-         O << "\t.weak " << name << "\n";
-         break;
-       }
       case GlobalValue::LinkOnceLinkage:
       case GlobalValue::WeakLinkage:
         if (Subtarget->isTargetDarwin()) {
           O << "\t.globl " << name << "\n"
             << "\t.weak_definition " << name << "\n";
           SwitchToDataSection(".section __DATA,__const_coal,coalesced", I);
-        } else if (Subtarget->isTargetCygwin()) {
+        } else if (Subtarget->isTargetCygMing()) {
           std::string SectionName(".section\t.data$linkonce." +
                                   name +
                                   ",\"aw\"");
@@ -233,7 +219,7 @@ bool X86SharedAsmPrinter::doFinalization(Module &M) {
              I->getSection() == ".dtors")) {
           std::string SectionName = ".section " + I->getSection();
           
-          if (Subtarget->isTargetCygwin()) {
+          if (Subtarget->isTargetCygMing()) {
             SectionName += ",\"aw\"";
           } else {
             assert(!Subtarget->isTargetDarwin());
@@ -242,7 +228,10 @@ bool X86SharedAsmPrinter::doFinalization(Module &M) {
 
           SwitchToDataSection(SectionName.c_str());
         } else {
-          SwitchToDataSection(TAI->getDataSection(), I);
+          if (C->isNullValue() && !NoZerosInBSS && TAI->getBSSSection())
+            SwitchToDataSection(TAI->getBSSSection(), I);
+          else
+            SwitchToDataSection(TAI->getDataSection(), I);
         }
         
         break;
@@ -256,10 +245,21 @@ bool X86SharedAsmPrinter::doFinalization(Module &M) {
         << "\n";
       if (TAI->hasDotTypeDotSizeDirective())
         O << "\t.size " << name << ", " << Size << "\n";
+      // If the initializer is a extern weak symbol, remember to emit the weak
+      // reference!
+      if (const GlobalValue *GV = dyn_cast<GlobalValue>(C))
+        if (GV->hasExternalWeakLinkage())
+          ExtWeakSymbols.insert(GV);
 
       EmitGlobalConstant(C);
       O << '\n';
     }
+    if (I->hasHiddenVisibility())
+      if (const char *Directive = TAI->getHiddenDirective())
+        O << Directive << name << "\n";
+    
+    if (Subtarget->isTargetELF())
+      O << "\t.type " << name << ",@object\n";
   }
   
   // Output linker support code for dllexported globals
@@ -283,19 +283,6 @@ bool X86SharedAsmPrinter::doFinalization(Module &M) {
     O << "\t.ascii \" -export:" << *i << "\"\n";
   }    
 
-  if (!Subtarget->isTargetCygwin()) {
-    // There is no external weak linkage on Mingw32 platform.
-    // Defaulting to external
-    if (ExtWeakSymbols.begin() != ExtWeakSymbols.end())
-      SwitchToDataSection("");
-
-    for (std::set<std::string>::iterator i = ExtWeakSymbols.begin(),
-         e = ExtWeakSymbols.end(); i != e; ++i) {
-      O << (Subtarget->isTargetDarwin() ? "\t.weak_reference" : "\t.weak")
-        << " " << *i << "\n";
-    }
-  }
-  
   if (Subtarget->isTargetDarwin()) {
     SwitchToDataSection("");
 
@@ -332,7 +319,19 @@ bool X86SharedAsmPrinter::doFinalization(Module &M) {
     // linker can safely perform dead code stripping.  Since LLVM never
     // generates code that does this, it is always safe to set.
     O << "\t.subsections_via_symbols\n";
-  } else if (Subtarget->isTargetELF() || Subtarget->isTargetCygwin()) {
+  } else if (Subtarget->isTargetCygMing()) {
+    // Emit type information for external functions
+    for (std::set<std::string>::iterator i = FnStubs.begin(), e = FnStubs.end();
+         i != e; ++i) {
+      O << "\t.def\t " << *i
+        << ";\t.scl\t" << COFF::C_EXT
+        << ";\t.type\t" << (COFF::DT_FCN << COFF::N_BTSHFT)
+        << ";\t.endef\n";
+    }
+    
+    // Emit final debug information.
+    DW.EndModule();    
+  } else if (Subtarget->isTargetELF()) {
     // Emit final debug information.
     DW.EndModule();
   }