Tie dwarf generation to darwin assembler.


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@25093 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/include/llvm/CodeGen/AsmPrinter.h b/include/llvm/CodeGen/AsmPrinter.h
index 6fc48ee..4e0599e 100644
--- a/include/llvm/CodeGen/AsmPrinter.h
+++ b/include/llvm/CodeGen/AsmPrinter.h
@@ -35,7 +35,7 @@
     /// IncrementFunctionNumber().
     ///
     unsigned FunctionNumber;
-    
+
   protected:
     /// Output stream on which we're printing assembly code.
     ///
@@ -165,6 +165,7 @@
 
     AsmPrinter(std::ostream &o, TargetMachine &TM);
     
+  public:
     /// SwitchSection - Switch to the specified section of the executable if we
     /// are not already in it!  If GV is non-null and if the global has an
     /// explicitly requested section, we switch to the section indicated for the
@@ -175,6 +176,7 @@
     ///
     void SwitchSection(const char *NewSection, const GlobalValue *GV);
 
+  protected:
     /// getFunctionNumber - Return a unique ID for the current function.
     ///
     unsigned getFunctionNumber() const { return FunctionNumber; }
@@ -229,6 +231,43 @@
     
   private:
     void EmitXXStructorList(Constant *List);
+    
+  public:
+    /// getCommentString - get the comment string.
+    ///
+    const char *getCommentString() {
+      return CommentString;
+    }
+    
+    /// getData8bitsDirective - get the 8-bit data directive string.
+    ///
+    const char *getData8bitsDirective() {
+      return Data8bitsDirective;
+    }
+    
+    /// getData16bitsDirective - get the 16-bit data directive string.
+    ///
+    const char *getData16bitsDirective() {
+      return Data16bitsDirective;
+    }
+    
+    /// getData32bitsDirective - get the 32-bit data directive string.
+    ///
+    const char *getData32bitsDirective() {
+      return Data32bitsDirective;
+    }
+    
+    /// getData64bitsDirective - get the 64-bit data directive string.
+    ///
+    const char *getData64bitsDirective() {
+      return Data64bitsDirective;
+    }
+    
+    /// getPrivateGlobalPrefix - get private label prefix.
+    ///
+    const char *getPrivateGlobalPrefix() {
+      return PrivateGlobalPrefix;
+    }
   };
 }
 
diff --git a/include/llvm/CodeGen/DwarfWriter.h b/include/llvm/CodeGen/DwarfWriter.h
index 6dc83ff..effead3 100644
--- a/include/llvm/CodeGen/DwarfWriter.h
+++ b/include/llvm/CodeGen/DwarfWriter.h
@@ -14,11 +14,14 @@
 #ifndef LLVM_CODEGEN_DWARFPRINTER_H
 #define LLVM_CODEGEN_DWARFPRINTER_H
 
+#include <iostream>
+#include "llvm/CodeGen/MachineDebugInfo.h"
+
 namespace llvm {
 
-  //===----------------------------------------------------------------------===//
+  //===--------------------------------------------------------------------===//
   // Dwarf constants as gleaned from the DWARF Debugging Information Format V.3
-  // reference manual http://dwarf.freestandards.org. 
+  // reference manual http://dwarf.freestandards.org .
   //
   enum dwarf_constants {
    // Tags
@@ -422,6 +425,141 @@
     DW_CFA_lo_user = 0x1c,
     DW_CFA_hi_user = 0x3f
   };
+  
+  // Forward declarations.
+  //
+  class AsmPrinter;
+  
+  //===--------------------------------------------------------------------===//
+  // DwarfWriter - emits dwarf debug and exception handling directives.
+  //
+  class DwarfWriter {
+  
+  protected:
+  
+    /// O - Stream to .s file.
+    ///
+    std::ostream &O;
+
+    /// Asm - Target of dwarf emission.
+    ///
+    AsmPrinter *Asm;
+    
+    /// DebugInfo - Collected debug information.
+    ///
+    MachineDebugInfo &DebugInfo;
+    
+    /// hasLEB128 - True if target asm supports leb128 directives.
+    ///
+    bool hasLEB128; /// Defaults to false.
+    
+    /// needsSet - True if target asm can't compute addresses on data
+    /// directives.
+    bool needsSet; /// Defaults to false.
+    
+    /// DwarfAbbrevSection - section directive arg for dwarf abbrev.
+    ///
+    const char *DwarfAbbrevSection; /// Defaults to ".debug_abbrev".
+
+    /// DwarfInfoSection - section directive arg for dwarf info.
+    ///
+    const char *DwarfInfoSection; /// Defaults to ".debug_info".
+
+    /// DwarfLineSection - section directive arg for dwarf info.
+    ///
+    const char *DwarfLineSection; /// Defaults to ".debug_line".
+
+  public:
+    
+    // Ctor.
+    DwarfWriter(std::ostream &o, AsmPrinter *ap, MachineDebugInfo &di)
+    : O(o)
+    , Asm(ap)
+    , DebugInfo(di)
+    , hasLEB128(false)
+    , needsSet(false)
+    , DwarfAbbrevSection(".debug_abbrev")
+    , DwarfInfoSection(".debug_info")
+    , DwarfLineSection(".debug_line")
+    {}
+    
+    /// EmitHex - Emit a hexidecimal string to the output stream.
+    ///
+    void EmitHex(unsigned Value) {
+      O << "0x"
+        << std::hex
+        << Value
+        << std::dec;
+    }
+    
+    /// EmitComment - Emit a simple string comment.
+    ///
+    void EmitComment(const char *Comment) {
+      O << "\t"
+        << Asm->getCommentString()
+        << " "
+        << Comment
+        << "\n";
+    }
+
+    /// EmitULEB128 - Emit a series of hexidecimal values (separated by commas)
+    /// representing an unsigned leb128 value.
+    ///
+    void EmitULEB128(unsigned Value) {
+      do {
+        unsigned Byte = Value & 0x7f;
+        Value >>= 7;
+        if (Value) Byte |= 0x80;
+        EmitHex(Byte);
+        if (Value) O << ", ";
+      } while (Value);
+    }
+
+    /// EmitSLEB128 - Emit a series of hexidecimal values (separated by commas)
+    /// representing a signed leb128 value.
+    ///
+    void EmitSLEB128(int Value) {
+      int Sign = Value >> (8 * sizeof(Value) - 1);
+      bool IsMore;
+      
+      do {
+        unsigned Byte = Value & 0x7f;
+        Value >>= 7;
+        IsMore = Value != Sign || ((Byte ^ Sign) & 0x40) != 0;
+        if (IsMore) Byte |= 0x80;
+        EmitHex(Byte);
+        if (IsMore) O << ", ";
+      } while (IsMore);
+    }
+    
+    /// EmitLabelName - Emit label name for internal use by dwarf.
+    ///
+    void EmitLabelName(const char *Tag, int Num) {
+      O << Asm->getPrivateGlobalPrefix()
+        << "debug_"
+        << Tag
+        << Num;
+    }
+    
+    /// EmitLabel - Emit location label for internal use by dwarf.
+    ///
+    void EmitLabel(const char *Tag, int Num) {
+      EmitLabelName(Tag, Num);
+      O << ":\n";
+    }
+    
+    // Defined elsewhere
+
+    void EmitULEB128Bytes(unsigned Value, std::string Comment);
+    void EmitSLEB128Bytes(int Value, std::string Comment);
+
+    void BeginModule();
+    void EndModule();
+    
+    void BeginFunction();
+    void EndFunction();
+  };
+  
 
 } // end llvm namespace
 
diff --git a/lib/CodeGen/AsmPrinter.cpp b/lib/CodeGen/AsmPrinter.cpp
index 5fdfbfd..4759282 100644
--- a/lib/CodeGen/AsmPrinter.cpp
+++ b/lib/CodeGen/AsmPrinter.cpp
@@ -16,6 +16,7 @@
 #include "llvm/Constants.h"
 #include "llvm/Module.h"
 #include "llvm/CodeGen/MachineConstantPool.h"
+#include "llvm/CodeGen/MachineDebugInfo.h"
 #include "llvm/Support/Mangler.h"
 #include "llvm/Support/MathExtras.h"
 #include "llvm/Target/TargetMachine.h"
diff --git a/lib/CodeGen/DwarfWriter.cpp b/lib/CodeGen/DwarfWriter.cpp
index dcfb6e4..2fc65e6 100644
--- a/lib/CodeGen/DwarfWriter.cpp
+++ b/lib/CodeGen/DwarfWriter.cpp
@@ -12,4 +12,99 @@
 //===----------------------------------------------------------------------===//
 
 
+#include "llvm/CodeGen/AsmPrinter.h"
 #include "llvm/CodeGen/DwarfWriter.h"
+#include "llvm/Support/CommandLine.h"
+
+
+namespace llvm {
+
+static cl::opt<bool>
+DwarfVerbose("dwarf-verbose", cl::Hidden,
+                                cl::desc("Add comments to dwarf directives."));
+
+/// EmitULEB128Bytes - Emit an assembler byte data directive to compose an
+/// unsigned leb128 value.
+///
+void DwarfWriter::EmitULEB128Bytes(unsigned Value, std::string Comment) {
+  if (hasLEB128) {
+    O << "\t.uleb128\t"
+      << Value;
+  } else {
+    O << Asm->getData8bitsDirective();
+    EmitULEB128(Value);
+  }
+  if (DwarfVerbose) {
+    O << "\t"
+      << Asm->getCommentString()
+      << " "
+      << Comment
+      << " "
+      << Value;
+  }
+  O << "\n";
+}
+
+/// EmitSLEB128Bytes - Emit an assembler byte data directive to compose a
+/// signed leb128 value.
+///
+void DwarfWriter::EmitSLEB128Bytes(int Value, std::string Comment) {
+  if (hasLEB128) {
+    O << "\t.sleb128\t"
+      << Value;
+  } else {
+    O << Asm->getData8bitsDirective();
+    EmitSLEB128(Value);
+  }
+  if (DwarfVerbose) {
+    O << "\t"
+      << Asm->getCommentString()
+      << " "
+      << Comment
+      << " "
+      << Value;
+  }
+  O << "\n";
+}
+
+/// BeginModule - Emit all dwarf sections that should come prior to the content.
+///
+void DwarfWriter::BeginModule() {
+  EmitComment("Dwarf Begin Module");
+  
+  // define base addresses for dwarf sections
+  Asm->SwitchSection(DwarfAbbrevSection, 0);
+  EmitLabel("abbrev", 0);
+  Asm->SwitchSection(DwarfInfoSection, 0);
+  EmitLabel("info", 0);
+  Asm->SwitchSection(DwarfLineSection, 0);
+  EmitLabel("line", 0);
+}
+
+/// EndModule - Emit all dwarf sections that should come after the content.
+///
+void DwarfWriter::EndModule() {
+  EmitComment("Dwarf End Module");
+  // Print out dwarf file info
+  std::vector<std::string> Sources = DebugInfo.getSourceFiles();
+  for (unsigned i = 0, N = Sources.size(); i < N; i++) {
+    O << "\t; .file\t" << (i + 1) << "," << "\"" << Sources[i]  << "\"" << "\n";
+  }
+}
+
+
+/// BeginFunction - Emit pre-function debug information.
+///
+void DwarfWriter::BeginFunction() {
+  EmitComment("Dwarf Begin Function");
+}
+
+/// EndFunction - Emit post-function debug information.
+///
+void DwarfWriter::EndFunction() {
+  EmitComment("Dwarf End Function");
+}
+
+
+} // End llvm namespace
+
diff --git a/lib/Target/PowerPC/PPCAsmPrinter.cpp b/lib/Target/PowerPC/PPCAsmPrinter.cpp
index f75e4aa..12b5f44 100644
--- a/lib/Target/PowerPC/PPCAsmPrinter.cpp
+++ b/lib/Target/PowerPC/PPCAsmPrinter.cpp
@@ -25,6 +25,7 @@
 #include "llvm/Module.h"
 #include "llvm/Assembly/Writer.h"
 #include "llvm/CodeGen/AsmPrinter.h"
+#include "llvm/CodeGen/DwarfWriter.h"
 #include "llvm/CodeGen/MachineDebugInfo.h"
 #include "llvm/CodeGen/MachineFunctionPass.h"
 #include "llvm/CodeGen/MachineInstr.h"
@@ -205,13 +206,33 @@
     virtual bool doFinalization(Module &M) = 0;
   };
 
+  /// DarwinDwarfWriter - Dwarf debug info writer customized for Darwin/Mac OS X
+  ///
+  struct DarwinDwarfWriter : public DwarfWriter {
+    // Ctor.
+    DarwinDwarfWriter(std::ostream &o, AsmPrinter *ap, MachineDebugInfo &di)
+    : DwarfWriter(o, ap, di)
+    {
+      hasLEB128 = false;
+      needsSet = true;
+      DwarfAbbrevSection = ".section __DWARFA,__debug_abbrev,regular,debug";
+      DwarfInfoSection = ".section __DWARFA,__debug_info,regular,debug";
+      DwarfLineSection = ".section __DWARFA,__debug_line,regular,debug";
+    }
+  };
+
   /// DarwinAsmPrinter - PowerPC assembly printer, customized for Darwin/Mac OS
   /// X
   ///
   struct DarwinAsmPrinter : public PPCAsmPrinter {
+  
+    DarwinDwarfWriter DW;
 
     DarwinAsmPrinter(std::ostream &O, TargetMachine &TM)
-      : PPCAsmPrinter(O, TM) {
+      : PPCAsmPrinter(O, TM),
+        // FIXME - MachineDebugInfo needs a proper location
+        DW(O, this, getMachineDebugInfo())      
+      {
       CommentString = ";";
       GlobalPrefix = "_";
       PrivateGlobalPrefix = "L";     // Marker for constant pool idxs
@@ -397,12 +418,8 @@
   SetupMachineFunction(MF);
   O << "\n\n";
   
-  // Print out dwarf file info
-  MachineDebugInfo &DebugInfo = MF.getDebugInfo();
-  std::vector<std::string> Sources = DebugInfo.getSourceFiles();
-  for (unsigned i = 0, N = Sources.size(); i < N; i++) {
-    O << "\t; .file\t" << (i + 1) << "," << "\"" << Sources[i]  << "\"" << "\n";
-  }
+  // Emit pre-function debug information.
+  DW.BeginFunction();
 
   // Print out constants referenced by the function
   EmitConstantPool(MF.getConstantPool());
@@ -449,6 +466,9 @@
     }
   }
 
+  // Emit post-function debug information.
+  DW.EndFunction();
+
   // We didn't modify anything.
   return false;
 }
@@ -461,6 +481,9 @@
   
   // Darwin wants symbols to be quoted if they have complex names.
   Mang->setUseQuotes(true);
+  
+  // Emit initial debug information.
+  DW.BeginModule();
   return false;
 }
 
@@ -583,6 +606,9 @@
   // code that does this, it is always safe to set.
   O << "\t.subsections_via_symbols\n";
 
+  // Emit initial debug information.
+  DW.EndModule();
+
   AsmPrinter::doFinalization(M);
   return false; // success
 }
@@ -592,7 +618,7 @@
 ///
 bool AIXAsmPrinter::runOnMachineFunction(MachineFunction &MF) {
   SetupMachineFunction(MF);
-
+  
   // Print out constants referenced by the function
   EmitConstantPool(MF.getConstantPool());
 
diff --git a/lib/Target/PowerPC/PPCTargetMachine.cpp b/lib/Target/PowerPC/PPCTargetMachine.cpp
index c92122e..3115a57 100644
--- a/lib/Target/PowerPC/PPCTargetMachine.cpp
+++ b/lib/Target/PowerPC/PPCTargetMachine.cpp
@@ -80,7 +80,7 @@
                                            CodeGenFileType FileType,
                                            bool Fast) {
   if (FileType != TargetMachine::AssemblyFile) return true;
-
+  
   // Run loop strength reduction before anything else.
   if (!Fast) PM.add(createLoopStrengthReducePass());