Build arbitrary vector with more than 2 distinct scalar elements with a
[oota-llvm.git] / lib / Target / X86 / X86AsmPrinter.cpp
index 1b05691a0be181df961123ed72c0a4b689e31ef7..990951ea7b8126fdb3dcffcd1cbe2319a428d226 100644 (file)
 //
 //===----------------------------------------------------------------------===//
 
+#include "X86AsmPrinter.h"
 #include "X86ATTAsmPrinter.h"
 #include "X86IntelAsmPrinter.h"
 #include "X86Subtarget.h"
-#include "X86.h"
 #include "llvm/Constants.h"
 #include "llvm/Module.h"
 #include "llvm/Type.h"
 #include "llvm/Support/Mangler.h"
 #include "llvm/Support/CommandLine.h"
 using namespace llvm;
-using namespace x86;
 
-Statistic<> llvm::x86::EmittedInsts("asm-printer",
-                                    "Number of machine instrs printed");
+Statistic<> llvm::EmittedInsts("asm-printer",
+                               "Number of machine instrs printed");
 
 enum AsmWriterFlavorTy { att, intel };
 cl::opt<AsmWriterFlavorTy>
@@ -45,6 +44,7 @@ bool X86SharedAsmPrinter::doInitialization(Module &M) {
   const X86Subtarget *Subtarget = &TM.getSubtarget<X86Subtarget>();
   
   forDarwin = false;
+  PrivateGlobalPrefix = ".L";
   
   switch (Subtarget->TargetType) {
   case X86Subtarget::isDarwin:
@@ -60,6 +60,7 @@ bool X86SharedAsmPrinter::doInitialization(Module &M) {
     forDarwin = true;
     StaticCtorsSection = ".mod_init_func";
     StaticDtorsSection = ".mod_term_func";
+    InlineAsmStart = InlineAsmEnd = "";  // Don't use #APP/#NO_APP
     break;
   case X86Subtarget::isCygwin:
     GlobalPrefix = "_";
@@ -73,6 +74,11 @@ bool X86SharedAsmPrinter::doInitialization(Module &M) {
   default: break;
   }
   
+  if (forDarwin) {
+    // Emit initial debug information.
+    DW.BeginModule(&M);
+  }
+
   return AsmPrinter::doInitialization(M);
 }
 
@@ -85,7 +91,7 @@ bool X86SharedAsmPrinter::doFinalization(Module &M) {
     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.
-    if (I->hasAppendingLinkage() && EmitSpecialLLVMGlobal(I))
+    if (EmitSpecialLLVMGlobal(I))
       continue;
     
     std::string name = Mang->getValueName(I);
@@ -95,28 +101,38 @@ bool X86SharedAsmPrinter::doFinalization(Module &M) {
 
     if (C->isNullValue() && /* FIXME: Verify correct */
         (I->hasInternalLinkage() || I->hasWeakLinkage() ||
-         I->hasLinkOnceLinkage())) {
+         I->hasLinkOnceLinkage() ||
+         (forDarwin && I->hasExternalLinkage() && !I->hasSection()))) {
       if (Size == 0) Size = 1;   // .comm Foo, 0 is undefined, avoid it.
-      if (forDarwin) {
+      if (I->hasExternalLinkage()) {
+          O << "\t.globl\t" << name << "\n";
+          O << "\t.zerofill __DATA__, __common, " << name << ", "
+            << Size << ", " << Align;
+      } else {
         SwitchSection(".data", I);
-        if (I->hasInternalLinkage())
-          O << LCOMMDirective << name << "," << Size << "," << Align;
-        else
+        if (LCOMMDirective != NULL) {
+          if (I->hasInternalLinkage()) {
+            O << LCOMMDirective << name << "," << Size;
+            if (forDarwin)
+              O << "," << (AlignmentIsInBytes ? (1 << Align) : Align);
+          } else
+            O << COMMDirective  << name << "," << Size;
+        } else {
+          if (I->hasInternalLinkage())
+            O << "\t.local\t" << name << "\n";
           O << COMMDirective  << name << "," << Size;
-      } else {
-        SwitchSection(".local", I);
-        O << COMMDirective  << name << "," << Size;
-        if (COMMDirectiveTakesAlignment)
-          O << "," << (AlignmentIsInBytes ? (1 << Align) : Align);
+          if (COMMDirectiveTakesAlignment)
+            O << "," << (AlignmentIsInBytes ? (1 << Align) : Align);
+        }
       }
-      O << "\t\t" << CommentString << " '" << I->getName() << "'\n";
+      O << "\t\t" << CommentString << " " << I->getName() << "\n";
     } else {
       switch (I->getLinkage()) {
       case GlobalValue::LinkOnceLinkage:
       case GlobalValue::WeakLinkage:
         if (forDarwin) {
-          O << "\t.globl " << name << '\n'
-            << "\t.weak_definition " << name << '\n';
+          O << "\t.globl " << name << "\n"
+            << "\t.weak_definition " << name << "\n";
           SwitchSection(".section __DATA,__datacoal_nt,coalesced", I);
         } else {
           O << "\t.section\t.llvm.linkonce.d." << name << ",\"aw\",@progbits\n";
@@ -138,8 +154,11 @@ bool X86SharedAsmPrinter::doFinalization(Module &M) {
       }
 
       EmitAlignment(Align, I);
-      O << name << ":\t\t\t\t" << CommentString << " '" << I->getName()
-        << "'\n";
+      O << name << ":\t\t\t\t" << CommentString << " " << I->getName()
+        << "\n";
+      if (HasDotTypeDotSizeDirective)
+        O << "\t.size " << name << ", " << Size << "\n";
+
       EmitGlobalConstant(C);
       O << '\n';
     }
@@ -170,6 +189,16 @@ bool X86SharedAsmPrinter::doFinalization(Module &M) {
       O << "\t.indirect_symbol " << *i << "\n";
       O << "\t.long\t0\n";
     }
+
+    // Emit initial debug information.
+    DW.EndModule();
+
+    // Funny Darwin hack: This flag tells the linker that no global symbols
+    // contain code that falls through to other global symbols (e.g. the obvious
+    // implementation of multiple entry points).  If this doesn't occur, the
+    // 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";
   }
 
   AsmPrinter::doFinalization(M);
@@ -180,7 +209,8 @@ bool X86SharedAsmPrinter::doFinalization(Module &M) {
 /// for a MachineFunction to the given output stream, using the given target
 /// machine description.
 ///
-FunctionPass *llvm::createX86CodePrinterPass(std::ostream &o,TargetMachine &tm){
+FunctionPass *llvm::createX86CodePrinterPass(std::ostream &o,
+                                             X86TargetMachine &tm){
   switch (AsmWriterFlavor) {
   default:
     assert(0 && "Unknown asm flavor!");