Support Cygwin assembly generation. The cygwin version of Gnu ASsembler
doesn't support certain directives and symbols on cygwin are prefixed with
an underscore. This patch makes the necessary adjustments to the output.


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@19775 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Target/X86/X86AsmPrinter.cpp b/lib/Target/X86/X86AsmPrinter.cpp
index b0d2788..ce6d26e 100644
--- a/lib/Target/X86/X86AsmPrinter.cpp
+++ b/lib/Target/X86/X86AsmPrinter.cpp
@@ -43,10 +43,12 @@
 
   struct X86SharedAsmPrinter : public AsmPrinter {
     X86SharedAsmPrinter(std::ostream &O, TargetMachine &TM)
-      : AsmPrinter(O, TM) { }
+      : AsmPrinter(O, TM), forCygwin(false) { }
 
+    bool doInitialization(Module &M);
     void printConstantPool(MachineConstantPool *MCP);
     bool doFinalization(Module &M);
+    bool forCygwin;
   };
 }
 
@@ -77,6 +79,24 @@
   }
 }
 
+/// doInitialization - determine
+bool X86SharedAsmPrinter::doInitialization(Module& M) {
+  forCygwin = false;
+  const std::string& TT = M.getTargetTriple();
+  if (TT.length() > 5)
+    forCygwin = TT.find("cygwin") != std::string::npos;
+  else if (TT.empty()) {
+#ifdef __CYGWIN__
+    forCygwin = true;
+#else
+    forCygwin = false;
+#endif
+  }
+  if (forCygwin)
+    GlobalPrefix = "_";
+  return AsmPrinter::doInitialization(M);
+}
+
 /// printConstantPool - Print to the current output stream assembly
 /// representations of the constants in the constant pool MCP. This is
 /// used to print out constants which have been "spilled to memory" by
@@ -114,11 +134,12 @@
           (I->hasLinkOnceLinkage() || I->hasInternalLinkage() ||
            I->hasWeakLinkage() /* FIXME: Verify correct */)) {
         SwitchSection(O, CurSection, ".data");
-        if (I->hasInternalLinkage())
+        if (!forCygwin && I->hasInternalLinkage())
           O << "\t.local " << name << "\n";
         
-        O << "\t.comm " << name << "," << TD.getTypeSize(C->getType())
-          << "," << (1 << Align);
+        O << "\t.comm " << name << "," << TD.getTypeSize(C->getType());
+        if (!forCygwin)
+          O << "," << (1 << Align);
         O << "\t\t# ";
         WriteAsOperand(O, I, true, true, &M);
         O << "\n";
@@ -150,8 +171,10 @@
         }
 
         emitAlignment(Align);
-        O << "\t.type " << name << ",@object\n";
-        O << "\t.size " << name << "," << Size << "\n";
+	if (!forCygwin) {
+	  O << "\t.type " << name << ",@object\n";
+	  O << "\t.size " << name << "," << Size << "\n";
+        }
         O << name << ":\t\t\t\t# ";
         WriteAsOperand(O, I, true, true, &M);
         O << " = ";
@@ -239,7 +262,8 @@
   O << "\t.text\n";
   emitAlignment(4);
   O << "\t.globl\t" << CurrentFnName << "\n";
-  O << "\t.type\t" << CurrentFnName << ", @function\n";
+  if (!forCygwin)
+    O << "\t.type\t" << CurrentFnName << ", @function\n";
   O << CurrentFnName << ":\n";
 
   // Print out code for the function.
@@ -306,7 +330,7 @@
     return;
   }
   case MachineOperand::MO_ExternalSymbol:
-    O << MO.getSymbolName();
+    O << GlobalPrefix << MO.getSymbolName();
     return;
   default:
     O << "<unknown operand type>"; return;    
@@ -462,7 +486,8 @@
   O << "\t.text\n";
   emitAlignment(4);
   O << "\t.globl\t" << CurrentFnName << "\n";
-  O << "\t.type\t" << CurrentFnName << ", @function\n";
+  if (!forCygwin)
+    O << "\t.type\t" << CurrentFnName << ", @function\n";
   O << CurrentFnName << ":\n";
 
   // Print out code for the function.
@@ -523,7 +548,7 @@
   }
   case MachineOperand::MO_ExternalSymbol:
     if (!isCallOp) O << '$';
-    O << MO.getSymbolName();
+    O << GlobalPrefix << MO.getSymbolName();
     return;
   default:
     O << "<unknown operand type>"; return;    
@@ -600,7 +625,8 @@
 ///
 FunctionPass *llvm::createX86CodePrinterPass(std::ostream &o,TargetMachine &tm){
   switch (AsmWriterFlavor) {
-  default: assert(0 && "Unknown asm flavor!");
+  default: 
+    assert(0 && "Unknown asm flavor!");
   case intel:
     return new X86IntelAsmPrinter(o, tm);
   case att: