Add completely untested support for mtcrf/mfcrf encoding
[oota-llvm.git] / lib / Target / SparcV9 / SparcV9AsmPrinter.cpp
index 0fa4c49ceb4b89a3f2aada1b53fae58bc19f57a9..c410a4baf7d08f98025579c38be989ce74e035ff 100644 (file)
@@ -1,4 +1,4 @@
-//===-- EmitAssembly.cpp - Emit SparcV9 Specific .s File ---------------------==//
+//===-- SparcV9AsmPrinter.cpp - Emit SparcV9 Specific .s File --------------==//
 // 
 //                     The LLVM Compiler Infrastructure
 //
 #include "llvm/Assembly/Writer.h"
 #include "llvm/CodeGen/MachineConstantPool.h"
 #include "llvm/CodeGen/MachineFunction.h"
-#include "llvm/CodeGen/MachineFunctionInfo.h"
 #include "llvm/CodeGen/MachineInstr.h"
 #include "llvm/Support/Mangler.h"
-#include "Support/StringExtras.h"
-#include "Support/Statistic.h"
+#include "llvm/ADT/StringExtras.h"
+#include "llvm/ADT/Statistic.h"
 #include "SparcV9Internals.h"
+#include "MachineFunctionInfo.h"
 #include <string>
 using namespace llvm;
 
@@ -74,10 +74,18 @@ namespace {
             arrayType->getElementType() == Type::SByteTy);
   }
 
+  unsigned findOptimalStorageSize(const TargetMachine &TM, const Type *Ty) {
+    // All integer types smaller than ints promote to 4 byte integers.
+    if (Ty->isIntegral() && Ty->getPrimitiveSize() < 4)
+      return 4;
+
+    return TM.getTargetData().getTypeSize(Ty);
+  }
+
+
   inline const std::string
   TypeToDataDirective(const Type* type) {
-    switch(type->getPrimitiveID())
-    {
+    switch(type->getTypeID()) {
     case Type::BoolTyID: case Type::UByteTyID: case Type::SByteTyID:
       return ".byte";
     case Type::UShortTyID: case Type::ShortTyID:
@@ -111,7 +119,7 @@ namespace {
         return 1 + CVA->getNumOperands();
     }
   
-    return target.findOptimalStorageSize(CV->getType());
+    return findOptimalStorageSize(target, CV->getType());
   }
 
   /// Align data larger than one L1 cache line on L1 cache line boundaries.
@@ -132,7 +140,7 @@ namespace {
   /// 
   inline unsigned int
   TypeToAlignment(const Type* type, const TargetMachine& target) {
-    return SizeToAlignment(target.findOptimalStorageSize(type), target);
+    return SizeToAlignment(findOptimalStorageSize(target, type), target);
   }
 
   /// Get the size of the constant and then use SizeToAlignment.
@@ -148,31 +156,27 @@ namespace {
 
 } // End anonymous namespace
 
-
-
-//===---------------------------------------------------------------------===//
-//   Code abstracted away from the AsmPrinter
-//===---------------------------------------------------------------------===//
-
 namespace {
+  enum Sections {
+    Unknown,
+    Text,
+    ReadOnlyData,
+    InitRWData,
+    ZeroInitRWData,
+  };
+
   class AsmPrinter {
     // Mangle symbol names appropriately
     Mangler *Mang;
 
   public:
-    std::ostream &toAsm;
-    const TargetMachine &Target;
-  
-    enum Sections {
-      Unknown,
-      Text,
-      ReadOnlyData,
-      InitRWData,
-      ZeroInitRWData,
-    } CurSection;
+    std::ostream &O;
+    const TargetMachine &TM;
+
+    enum Sections CurSection;
 
     AsmPrinter(std::ostream &os, const TargetMachine &T)
-      : /* idTable(0), */ toAsm(os), Target(T), CurSection(Unknown) {}
+      : /* idTable(0), */ O(os), TM(T), CurSection(Unknown) {}
   
     ~AsmPrinter() {
       delete Mang;
@@ -209,24 +213,24 @@ namespace {
       if (valID.length() == 0)
         valID = getID(CV);
   
-      toAsm << "\t.align\t" << ConstantToAlignment(CV, Target) << "\n";
+      O << "\t.align\t" << ConstantToAlignment(CV, TM) << "\n";
   
       // Print .size and .type only if it is not a string.
       if (const ConstantArray *CVA = dyn_cast<ConstantArray>(CV))
         if (CVA->isString()) {
           // print it as a string and return
-          toAsm << valID << ":\n";
-          toAsm << "\t" << ".ascii" << "\t" << getAsCString(CVA) << "\n";
+          O << valID << ":\n";
+          O << "\t" << ".ascii" << "\t" << getAsCString(CVA) << "\n";
           return;
         }
   
-      toAsm << "\t.type" << "\t" << valID << ",#object\n";
+      O << "\t.type" << "\t" << valID << ",#object\n";
 
-      unsigned int constSize = ConstantToSize(CV, Target);
+      unsigned int constSize = ConstantToSize(CV, TM);
       if (constSize)
-        toAsm << "\t.size" << "\t" << valID << "," << constSize << "\n";
+        O << "\t.size" << "\t" << valID << "," << constSize << "\n";
   
-      toAsm << valID << ":\n";
+      O << valID << ":\n";
   
       printConstantValueOnly(CV);
     }
@@ -238,16 +242,16 @@ namespace {
       if (S == CurSection) return;        // Only switch section if necessary
       CurSection = S;
 
-      toAsm << "\n\t.section ";
+      O << "\n\t.section ";
       switch (S)
       {
       default: assert(0 && "Bad section name!");
-      case Text:         toAsm << "\".text\""; break;
-      case ReadOnlyData: toAsm << "\".rodata\",#alloc"; break;
-      case InitRWData:   toAsm << "\".data\",#alloc,#write"; break;
-      case ZeroInitRWData: toAsm << "\".bss\",#alloc,#write"; break;
+      case Text:         O << "\".text\""; break;
+      case ReadOnlyData: O << "\".rodata\",#alloc"; break;
+      case InitRWData:   O << "\".data\",#alloc,#write"; break;
+      case ZeroInitRWData: O << "\".bss\",#alloc,#write"; break;
       }
-      toAsm << "\n";
+      O << "\n";
     }
 
     // getID Wrappers - Ensure consistent usage
@@ -301,49 +305,47 @@ namespace {
 ///
 void AsmPrinter::printSingleConstantValue(const Constant* CV) {
   assert(CV->getType() != Type::VoidTy &&
-         CV->getType() != Type::TypeTy &&
          CV->getType() != Type::LabelTy &&
          "Unexpected type for Constant");
   
   assert((!isa<ConstantArray>(CV) && ! isa<ConstantStruct>(CV))
          && "Aggregate types should be handled outside this function");
   
-  toAsm << "\t" << TypeToDataDirective(CV->getType()) << "\t";
+  O << "\t" << TypeToDataDirective(CV->getType()) << "\t";
   
-  if (const ConstantPointerRef* CPR = dyn_cast<ConstantPointerRef>(CV)) {
-    // This is a constant address for a global variable or method.
-    // Use the name of the variable or method as the address value.
-    assert(isa<GlobalValue>(CPR->getValue()) && "Unexpected non-global");
-    toAsm << getID(CPR->getValue()) << "\n";
-  } else if (isa<ConstantPointerNull>(CV)) {
+  if (const GlobalValue* GV = dyn_cast<GlobalValue>(CV)) {
+    O << getID(GV) << "\n";
+  } else if (isa<ConstantPointerNull>(CV) || isa<UndefValue>(CV)) {
     // Null pointer value
-    toAsm << "0\n";
+    O << "0\n";
   } else if (const ConstantExpr* CE = dyn_cast<ConstantExpr>(CV)) { 
     // Constant expression built from operators, constants, and symbolic addrs
-    toAsm << ConstantExprToString(CE, Target) << "\n";
+    O << ConstantExprToString(CE, TM) << "\n";
   } else if (CV->getType()->isPrimitiveType()) {
     // Check primitive types last
-    if (CV->getType()->isFloatingPoint()) {
+    if (isa<UndefValue>(CV)) {
+      O << "0\n";
+    } else if (CV->getType()->isFloatingPoint()) {
       // FP Constants are printed as integer constants to avoid losing
       // precision...
       double Val = cast<ConstantFP>(CV)->getValue();
       if (CV->getType() == Type::FloatTy) {
         float FVal = (float)Val;
         char *ProxyPtr = (char*)&FVal;        // Abide by C TBAA rules
-        toAsm << *(unsigned int*)ProxyPtr;            
+        O << *(unsigned int*)ProxyPtr;            
       } else if (CV->getType() == Type::DoubleTy) {
         char *ProxyPtr = (char*)&Val;         // Abide by C TBAA rules
-        toAsm << *(uint64_t*)ProxyPtr;            
+        O << *(uint64_t*)ProxyPtr;            
       } else {
         assert(0 && "Unknown floating point type!");
       }
         
-      toAsm << "\t! " << CV->getType()->getDescription()
+      O << "\t! " << CV->getType()->getDescription()
             << " value: " << Val << "\n";
     } else if (const ConstantBool *CB = dyn_cast<ConstantBool>(CV)) {
-      toAsm << (int)CB->getValue() << "\n";
+      O << (int)CB->getValue() << "\n";
     } else {
-      WriteAsOperand(toAsm, CV, false, false) << "\n";
+      WriteAsOperand(O, CV, false, false) << "\n";
     }
   } else {
     assert(0 && "Unknown elementary type for constant");
@@ -358,26 +360,24 @@ void AsmPrinter::printConstantValueOnly(const Constant* CV,
   if (const ConstantArray *CVA = dyn_cast<ConstantArray>(CV)) {
     if (CVA->isString()) {
       // print the string alone and return
-      toAsm << "\t" << ".ascii" << "\t" << getAsCString(CVA) << "\n";
+      O << "\t" << ".ascii" << "\t" << getAsCString(CVA) << "\n";
     } else {
       // Not a string.  Print the values in successive locations
-      const std::vector<Use> &constValues = CVA->getValues();
-      for (unsigned i=0; i < constValues.size(); i++)
-        printConstantValueOnly(cast<Constant>(constValues[i].get()));
+      for (unsigned i = 0, e = CVA->getNumOperands(); i != e; ++i)
+        printConstantValueOnly(CVA->getOperand(i));
     }
   } else if (const ConstantStruct *CVS = dyn_cast<ConstantStruct>(CV)) {
     // Print the fields in successive locations. Pad to align if needed!
     const StructLayout *cvsLayout =
-      Target.getTargetData().getStructLayout(CVS->getType());
-    const std::vector<Use>& constValues = CVS->getValues();
+      TM.getTargetData().getStructLayout(CVS->getType());
     unsigned sizeSoFar = 0;
-    for (unsigned i=0, N = constValues.size(); i < N; i++) {
-      const Constant* field = cast<Constant>(constValues[i].get());
+    for (unsigned i = 0, e = CVS->getNumOperands(); i != e; ++i) {
+      const Constant* field = CVS->getOperand(i);
 
       // Check if padding is needed and insert one or more 0s.
       unsigned fieldSize =
-        Target.getTargetData().getTypeSize(field->getType());
-      int padSize = ((i == N-1? cvsLayout->StructSize
+        TM.getTargetData().getTypeSize(field->getType());
+      int padSize = ((i == e-1? cvsLayout->StructSize
                       : cvsLayout->MemberOffsets[i+1])
                      - cvsLayout->MemberOffsets[i]) - fieldSize;
       sizeSoFar += (fieldSize + padSize);
@@ -387,8 +387,8 @@ void AsmPrinter::printConstantValueOnly(const Constant* CV,
     }
     assert(sizeSoFar == cvsLayout->StructSize &&
            "Layout of constant struct may be incorrect!");
-  } else if (isa<ConstantAggregateZero>(CV)) {
-    PrintZeroBytesToPad(Target.getTargetData().getTypeSize(CV->getType()));
+  } else if (isa<ConstantAggregateZero>(CV) || isa<UndefValue>(CV)) {
+    PrintZeroBytesToPad(TM.getTargetData().getTypeSize(CV->getType()));
   } else
     printSingleConstantValue(CV);
 
@@ -473,7 +473,9 @@ std::string AsmPrinter::valToExprString(const Value* V,
                                         const TargetMachine& target) {
   std::string S;
   bool failed = false;
-  if (const Constant* CV = dyn_cast<Constant>(V)) { // symbolic or known
+  if (const GlobalValue* GV = dyn_cast<GlobalValue>(V)) {
+    S += getID(GV);
+  } else if (const Constant* CV = dyn_cast<Constant>(V)) { // symbolic or known
     if (const ConstantBool *CB = dyn_cast<ConstantBool>(CV))
       S += std::string(CB == ConstantBool::True ? "1" : "0");
     else if (const ConstantSInt *CI = dyn_cast<ConstantSInt>(CV))
@@ -482,16 +484,12 @@ std::string AsmPrinter::valToExprString(const Value* V,
       S += utostr(CI->getValue());
     else if (const ConstantFP *CFP = dyn_cast<ConstantFP>(CV))
       S += ftostr(CFP->getValue());
-    else if (isa<ConstantPointerNull>(CV))
+    else if (isa<ConstantPointerNull>(CV) || isa<UndefValue>(CV))
       S += "0";
-    else if (const ConstantPointerRef *CPR = dyn_cast<ConstantPointerRef>(CV))
-      S += valToExprString(CPR->getValue(), target);
     else if (const ConstantExpr *CE = dyn_cast<ConstantExpr>(CV))
       S += ConstantExprToString(CE, target);
     else
       failed = true;
-  } else if (const GlobalValue* GV = dyn_cast<GlobalValue>(V)) {
-    S += getID(GV);
   } else
     failed = true;
 
@@ -502,11 +500,6 @@ std::string AsmPrinter::valToExprString(const Value* V,
   return S;
 }
 
-
-//===----------------------------------------------------------------------===//
-//   SparcV9AsmPrinter Code
-//===----------------------------------------------------------------------===//
-
 namespace {
 
   struct SparcV9AsmPrinter : public FunctionPass, public AsmPrinter {
@@ -581,33 +574,28 @@ SparcV9AsmPrinter::OpIsBranchTargetLabel(const MachineInstr *MI,
 inline bool
 SparcV9AsmPrinter::OpIsMemoryAddressBase(const MachineInstr *MI,
                                        unsigned int opNum) {
-  if (Target.getInstrInfo().isLoad(MI->getOpcode()))
+  if (TM.getInstrInfo()->isLoad(MI->getOpcode()))
     return (opNum == 0);
-  else if (Target.getInstrInfo().isStore(MI->getOpcode()))
+  else if (TM.getInstrInfo()->isStore(MI->getOpcode()))
     return (opNum == 1);
   else
     return false;
 }
 
-
-#define PrintOp1PlusOp2(mop1, mop2, opCode) \
-  printOneOperand(mop1, opCode); \
-  toAsm << "+"; \
-  printOneOperand(mop2, opCode);
-
 unsigned int
-SparcV9AsmPrinter::printOperands(const MachineInstr *MI,
-                               unsigned int opNum)
-{
+SparcV9AsmPrinter::printOperands(const MachineInstr *MI, unsigned opNum) {
   const MachineOperand& mop = MI->getOperand(opNum);
-  
   if (OpIsBranchTargetLabel(MI, opNum)) {
-    PrintOp1PlusOp2(mop, MI->getOperand(opNum+1), MI->getOpcode());
+    printOneOperand(mop, MI->getOpcode());
+    O << "+";
+    printOneOperand(MI->getOperand(opNum+1), MI->getOpcode());
     return 2;
   } else if (OpIsMemoryAddressBase(MI, opNum)) {
-    toAsm << "[";
-    PrintOp1PlusOp2(mop, MI->getOperand(opNum+1), MI->getOpcode());
-    toAsm << "]";
+    O << "[";
+    printOneOperand(mop, MI->getOpcode());
+    O << "+";
+    printOneOperand(MI->getOperand(opNum+1), MI->getOpcode());
+    O << "]";
     return 2;
   } else {
     printOneOperand(mop, MI->getOpcode());
@@ -617,18 +605,18 @@ SparcV9AsmPrinter::printOperands(const MachineInstr *MI,
 
 void
 SparcV9AsmPrinter::printOneOperand(const MachineOperand &mop,
-                                 MachineOpCode opCode)
+                                   MachineOpCode opCode)
 {
   bool needBitsFlag = true;
   
   if (mop.isHiBits32())
-    toAsm << "%lm(";
+    O << "%lm(";
   else if (mop.isLoBits32())
-    toAsm << "%lo(";
+    O << "%lo(";
   else if (mop.isHiBits64())
-    toAsm << "%hh(";
+    O << "%hh(";
   else if (mop.isLoBits64())
-    toAsm << "%hm(";
+    O << "%hm(";
   else
     needBitsFlag = false;
   
@@ -640,18 +628,18 @@ SparcV9AsmPrinter::printOneOperand(const MachineOperand &mop,
       {
         int regNum = (int)mop.getReg();
         
-        if (regNum == Target.getRegInfo().getInvalidRegNum()) {
+        if (regNum == TM.getRegInfo()->getInvalidRegNum()) {
           // better to print code with NULL registers than to die
-          toAsm << "<NULL VALUE>";
+          O << "<NULL VALUE>";
         } else {
-          toAsm << "%" << Target.getRegInfo().getUnifiedRegName(regNum);
+          O << "%" << TM.getRegInfo()->getUnifiedRegName(regNum);
         }
         break;
       }
     
     case MachineOperand::MO_ConstantPoolIndex:
       {
-        toAsm << ".CPI_" << currFunction->getName() 
+        O << ".CPI_" << getID(currFunction)
               << "_" << mop.getConstantPoolIndex();
         break;
       }
@@ -662,42 +650,42 @@ SparcV9AsmPrinter::printOneOperand(const MachineOperand &mop,
         assert(Val && "\tNULL Value in SparcV9AsmPrinter");
         
         if (const BasicBlock *BB = dyn_cast<BasicBlock>(Val))
-          toAsm << getID(BB);
-        else if (const Function *M = dyn_cast<Function>(Val))
-          toAsm << getID(M);
+          O << getID(BB);
+        else if (const Function *F = dyn_cast<Function>(Val))
+          O << getID(F);
         else if (const GlobalVariable *GV = dyn_cast<GlobalVariable>(Val))
-          toAsm << getID(GV);
+          O << getID(GV);
         else if (const Constant *CV = dyn_cast<Constant>(Val))
-          toAsm << getID(CV);
+          O << getID(CV);
         else
           assert(0 && "Unrecognized value in SparcV9AsmPrinter");
         break;
       }
     
     case MachineOperand::MO_SignExtendedImmed:
-      toAsm << mop.getImmedValue();
+      O << mop.getImmedValue();
       break;
 
     case MachineOperand::MO_UnextendedImmed:
-      toAsm << (uint64_t) mop.getImmedValue();
+      O << (uint64_t) mop.getImmedValue();
       break;
     
     default:
-      toAsm << mop;      // use dump field
+      O << mop;      // use dump field
       break;
     }
   
   if (needBitsFlag)
-    toAsm << ")";
+    O << ")";
 }
 
 void SparcV9AsmPrinter::emitMachineInst(const MachineInstr *MI) {
   unsigned Opcode = MI->getOpcode();
 
-  if (Target.getInstrInfo().isDummyPhiInstr(Opcode))
-    return;  // IGNORE PHI NODES
+  if (Opcode == V9::PHI)
+    return;  // Ignore Machine-PHI nodes.
 
-  toAsm << "\t" << Target.getInstrInfo().getName(Opcode) << "\t";
+  O << "\t" << TM.getInstrInfo()->getName(Opcode) << "\t";
 
   unsigned Mask = getOperandMask(Opcode);
   
@@ -705,96 +693,98 @@ void SparcV9AsmPrinter::emitMachineInst(const MachineInstr *MI) {
   unsigned N = 1;
   for (unsigned OpNum = 0; OpNum < MI->getNumOperands(); OpNum += N)
     if (! ((1 << OpNum) & Mask)) {        // Ignore this operand?
-      if (NeedComma) toAsm << ", ";         // Handle comma outputting
+      if (NeedComma) O << ", ";         // Handle comma outputting
       NeedComma = true;
       N = printOperands(MI, OpNum);
     } else
       N = 1;
   
-  toAsm << "\n";
+  O << "\n";
   ++EmittedInsts;
 }
 
 void SparcV9AsmPrinter::emitBasicBlock(const MachineBasicBlock &MBB) {
   // Emit a label for the basic block
-  toAsm << getID(MBB.getBasicBlock()) << ":\n";
+  O << getID(MBB.getBasicBlock()) << ":\n";
 
   // Loop over all of the instructions in the basic block...
   for (MachineBasicBlock::const_iterator MII = MBB.begin(), MIE = MBB.end();
        MII != MIE; ++MII)
     emitMachineInst(MII);
-  toAsm << "\n";  // Separate BB's with newlines
+  O << "\n";  // Separate BB's with newlines
 }
 
 void SparcV9AsmPrinter::emitFunction(const Function &F) {
-  std::string methName = getID(&F);
-  toAsm << "!****** Outputing Function: " << methName << " ******\n";
+  std::string CurrentFnName = getID(&F);
+  MachineFunction &MF = MachineFunction::get(&F);
+  O << "!****** Outputing Function: " << CurrentFnName << " ******\n";
 
   // Emit constant pool for this function
-  const MachineConstantPool *MCP = MachineFunction::get(&F).getConstantPool();
+  const MachineConstantPool *MCP = MF.getConstantPool();
   const std::vector<Constant*> &CP = MCP->getConstants();
 
-  enterSection(AsmPrinter::ReadOnlyData);
+  enterSection(ReadOnlyData);
   for (unsigned i = 0, e = CP.size(); i != e; ++i) {
-    std::string cpiName = ".CPI_" + F.getName() + "_" + utostr(i);
+    std::string cpiName = ".CPI_" + CurrentFnName + "_" + utostr(i);
     printConstant(CP[i], cpiName);
   }
 
-  enterSection(AsmPrinter::Text);
-  toAsm << "\t.align\t4\n\t.global\t" << methName << "\n";
-  //toAsm << "\t.type\t" << methName << ",#function\n";
-  toAsm << "\t.type\t" << methName << ", 2\n";
-  toAsm << methName << ":\n";
+  enterSection(Text);
+  O << "\t.align\t4\n\t.global\t" << CurrentFnName << "\n";
+  //O << "\t.type\t" << CurrentFnName << ",#function\n";
+  O << "\t.type\t" << CurrentFnName << ", 2\n";
+  O << CurrentFnName << ":\n";
 
   // Output code for all of the basic blocks in the function...
-  MachineFunction &MF = MachineFunction::get(&F);
   for (MachineFunction::const_iterator I = MF.begin(), E = MF.end(); I != E;++I)
     emitBasicBlock(*I);
 
   // Output a .size directive so the debugger knows the extents of the function
-  toAsm << ".EndOf_" << methName << ":\n\t.size "
-           << methName << ", .EndOf_"
-           << methName << "-" << methName << "\n";
+  O << ".EndOf_" << CurrentFnName << ":\n\t.size "
+           << CurrentFnName << ", .EndOf_"
+           << CurrentFnName << "-" << CurrentFnName << "\n";
 
   // Put some spaces between the functions
-  toAsm << "\n\n";
+  O << "\n\n";
 }
 
 void SparcV9AsmPrinter::printGlobalVariable(const GlobalVariable* GV) {
   if (GV->hasExternalLinkage())
-    toAsm << "\t.global\t" << getID(GV) << "\n";
+    O << "\t.global\t" << getID(GV) << "\n";
   
-  if (GV->hasInitializer() && ! GV->getInitializer()->isNullValue()) {
+  if (GV->hasInitializer() &&
+      !(GV->getInitializer()->isNullValue() ||
+        isa<UndefValue>(GV->getInitializer()))) {
     printConstant(GV->getInitializer(), getID(GV));
   } else {
-    toAsm << "\t.align\t" << TypeToAlignment(GV->getType()->getElementType(),
-                                                Target) << "\n";
-    toAsm << "\t.type\t" << getID(GV) << ",#object\n";
-    toAsm << "\t.reserve\t" << getID(GV) << ","
-          << Target.findOptimalStorageSize(GV->getType()->getElementType())
-          << "\n";
+    O << "\t.align\t" << TypeToAlignment(GV->getType()->getElementType(),
+                                                TM) << "\n";
+    O << "\t.type\t" << getID(GV) << ",#object\n";
+    O << "\t.reserve\t" << getID(GV) << ","
+      << findOptimalStorageSize(TM, GV->getType()->getElementType())
+      << "\n";
   }
 }
 
 void SparcV9AsmPrinter::emitGlobals(const Module &M) {
   // Output global variables...
-  for (Module::const_giterator GI = M.gbegin(), GE = M.gend(); GI != GE; ++GI)
+  for (Module::const_global_iterator GI = M.global_begin(), GE = M.global_end(); GI != GE; ++GI)
     if (! GI->isExternal()) {
       assert(GI->hasInitializer());
       if (GI->isConstant())
-        enterSection(AsmPrinter::ReadOnlyData);   // read-only, initialized data
-      else if (GI->getInitializer()->isNullValue())
-        enterSection(AsmPrinter::ZeroInitRWData); // read-write zero data
+        enterSection(ReadOnlyData);   // read-only, initialized data
+      else if (GI->getInitializer()->isNullValue() ||
+               isa<UndefValue>(GI->getInitializer()))
+        enterSection(ZeroInitRWData); // read-write zero data
       else
-        enterSection(AsmPrinter::InitRWData);     // read-write non-zero data
+        enterSection(InitRWData);     // read-write non-zero data
 
       printGlobalVariable(GI);
     }
 
-  toAsm << "\n";
+  O << "\n";
 }
 
-FunctionPass *llvm::createAsmPrinterPass(std::ostream &Out,
-                                         const TargetMachine &TM) {
+FunctionPass *llvm::createAsmPrinterPass(std::ostream &Out, TargetMachine &TM) {
   return new SparcV9AsmPrinter(Out, TM);
 }