diff --git a/llvm/lib/Target/Sparc/EmitAssembly.cpp b/llvm/lib/Target/Sparc/EmitAssembly.cpp
index 6af9836..1e75aca 100644
--- a/llvm/lib/Target/Sparc/EmitAssembly.cpp
+++ b/llvm/lib/Target/Sparc/EmitAssembly.cpp
@@ -33,91 +33,88 @@
 #include "SparcInternals.h"
 #include <string>
 
+using namespace llvm;
+
 namespace llvm {
 
 namespace {
 
-Statistic<> EmittedInsts("asm-printer", "Number of machine instrs printed");
+  Statistic<> EmittedInsts("asm-printer", "Number of machine instrs printed");
 
-class GlobalIdTable: public Annotation {
-  static AnnotationID AnnotId;
-  friend class AsmPrinter;              // give access to AnnotId
+  class GlobalIdTable: public Annotation {
+    static AnnotationID AnnotId;
+    friend class AsmPrinter;              // give access to AnnotId
   
-  typedef hash_map<const Value*, int> ValIdMap;
-  typedef ValIdMap::const_iterator ValIdMapConstIterator;
-  typedef ValIdMap::      iterator ValIdMapIterator;
-public:
-  SlotCalculator Table;    // map anonymous values to unique integer IDs
-  ValIdMap valToIdMap;     // used for values not handled by SlotCalculator 
-  
-  GlobalIdTable(Module* M) : Annotation(AnnotId), Table(M, true) {}
-};
+    typedef hash_map<const Value*, int> ValIdMap;
+    typedef ValIdMap::const_iterator ValIdMapConstIterator;
+    typedef ValIdMap::      iterator ValIdMapIterator;
+  public:
+    SlotCalculator Table;    // map anonymous values to unique integer IDs
+    ValIdMap valToIdMap;     // used for values not handled by SlotCalculator 
+    
+    GlobalIdTable(Module* M) : Annotation(AnnotId), Table(M, true) {}
+  };
 
-AnnotationID GlobalIdTable::AnnotId =
+  AnnotationID GlobalIdTable::AnnotId = 
   AnnotationManager::getID("ASM PRINTER GLOBAL TABLE ANNOT");
+  
+  //===--------------------------------------------------------------------===//
+  // Utility functions
 
-// Can we treat the specified array as a string?  Only if it is an array of
-// ubytes or non-negative sbytes.
-//
-static bool isStringCompatible(const ConstantArray *CVA) {
-  const Type *ETy = cast<ArrayType>(CVA->getType())->getElementType();
-  if (ETy == Type::UByteTy) return true;
-  if (ETy != Type::SByteTy) return false;
+  /// Can we treat the specified array as a string?  Only if it is an array of
+  /// ubytes or non-negative sbytes.
+  ///
+  bool isStringCompatible(const ConstantArray *CVA) {
+    const Type *ETy = cast<ArrayType>(CVA->getType())->getElementType();
+    if (ETy == Type::UByteTy) return true;
+    if (ETy != Type::SByteTy) return false;
 
-  for (unsigned i = 0; i < CVA->getNumOperands(); ++i)
-    if (cast<ConstantSInt>(CVA->getOperand(i))->getValue() < 0)
-      return false;
+    for (unsigned i = 0; i < CVA->getNumOperands(); ++i)
+      if (cast<ConstantSInt>(CVA->getOperand(i))->getValue() < 0)
+        return false;
 
-  return true;
-}
-
-// toOctal - Convert the low order bits of X into an octal letter
-static inline char toOctal(int X) {
-  return (X&7)+'0';
-}
-
-// getAsCString - Return the specified array as a C compatible string, only if
-// the predicate isStringCompatible is true.
-//
-static std::string getAsCString(const ConstantArray *CVA) {
-  assert(isStringCompatible(CVA) && "Array is not string compatible!");
-
-  std::string Result;
-  const Type *ETy = cast<ArrayType>(CVA->getType())->getElementType();
-  Result = "\"";
-  for (unsigned i = 0; i < CVA->getNumOperands(); ++i) {
-    unsigned char C = cast<ConstantInt>(CVA->getOperand(i))->getRawValue();
-
-    if (C == '"') {
-      Result += "\\\"";
-    } else if (C == '\\') {
-      Result += "\\\\";
-    } else if (isprint(C)) {
-      Result += C;
-    } else {
-      Result += '\\';                   // print all other chars as octal value
-      Result += toOctal(C >> 6);
-      Result += toOctal(C >> 3);
-      Result += toOctal(C >> 0);
-    }
+    return true;
   }
-  Result += "\"";
 
-  return Result;
-}
+  /// getAsCString - Return the specified array as a C compatible string, only
+  /// if the predicate isStringCompatible is true.
+  ///
+  std::string getAsCString(const ConstantArray *CVA) {
+    assert(isStringCompatible(CVA) && "Array is not string compatible!");
 
-inline bool
-ArrayTypeIsString(const ArrayType* arrayType)
-{
-  return (arrayType->getElementType() == Type::UByteTy ||
-          arrayType->getElementType() == Type::SByteTy);
-}
+    std::string Result;
+    const Type *ETy = cast<ArrayType>(CVA->getType())->getElementType();
+    Result = "\"";
+    for (unsigned i = 0; i < CVA->getNumOperands(); ++i) {
+      unsigned char C = cast<ConstantInt>(CVA->getOperand(i))->getRawValue();
 
+      if (C == '"') {
+        Result += "\\\"";
+      } else if (C == '\\') {
+        Result += "\\\\";
+      } else if (isprint(C)) {
+        Result += C;
+      } else {
+        Result += '\\';    // print all other chars as octal value
+        // Convert C to octal representation
+        Result += ((C >> 6) & 7) + '0';
+        Result += ((C >> 3) & 7) + '0';
+        Result += ((C >> 0) & 7) + '0';
+      }
+    }
+    Result += "\"";
 
-inline const std::string
-TypeToDataDirective(const Type* type)
-{
-  switch(type->getPrimitiveID())
+    return Result;
+  }
+
+  inline bool ArrayTypeIsString(const ArrayType* arrayType) {
+    return (arrayType->getElementType() == Type::UByteTy ||
+            arrayType->getElementType() == Type::SByteTy);
+  }
+
+  inline const std::string
+  TypeToDataDirective(const Type* type) {
+    switch(type->getPrimitiveID())
     {
     case Type::BoolTyID: case Type::UByteTyID: case Type::SByteTyID:
       return ".byte";
@@ -139,274 +136,169 @@
     default:
       return "<InvaliDataTypeForPrinting>";
     }
-}
+  }
 
-// Get the size of the type
-// 
-inline unsigned int
-TypeToSize(const Type* type, const TargetMachine& target)
-{
-  return target.findOptimalStorageSize(type);
-}
-
-// Get the size of the constant for the given target.
-// If this is an unsized array, return 0.
-// 
-inline unsigned int
-ConstantToSize(const Constant* CV, const TargetMachine& target)
-{
-  if (const ConstantArray* CVA = dyn_cast<ConstantArray>(CV))
-    {
+  /// Get the size of the constant for the given target.
+  /// If this is an unsized array, return 0.
+  /// 
+  inline unsigned int
+  ConstantToSize(const Constant* CV, const TargetMachine& target) {
+    if (const ConstantArray* CVA = dyn_cast<ConstantArray>(CV)) {
       const ArrayType *aty = cast<ArrayType>(CVA->getType());
       if (ArrayTypeIsString(aty))
         return 1 + CVA->getNumOperands();
     }
   
-  return TypeToSize(CV->getType(), target);
-}
+    return target.findOptimalStorageSize(CV->getType());
+  }
 
-// Align data larger than one L1 cache line on L1 cache line boundaries.
-// Align all smaller data on the next higher 2^x boundary (4, 8, ...).
-// 
-inline unsigned int
-SizeToAlignment(unsigned int size, const TargetMachine& target)
-{
-  unsigned short cacheLineSize = target.getCacheInfo().getCacheLineSize(1); 
-  if (size > (unsigned) cacheLineSize / 2)
-    return cacheLineSize;
-  else
-    for (unsigned sz=1; /*no condition*/; sz *= 2)
-      if (sz >= size)
-        return sz;
-}
+  /// Align data larger than one L1 cache line on L1 cache line boundaries.
+  /// Align all smaller data on the next higher 2^x boundary (4, 8, ...).
+  /// 
+  inline unsigned int
+  SizeToAlignment(unsigned int size, const TargetMachine& target) {
+    unsigned short cacheLineSize = target.getCacheInfo().getCacheLineSize(1); 
+    if (size > (unsigned) cacheLineSize / 2)
+      return cacheLineSize;
+    else
+      for (unsigned sz=1; /*no condition*/; sz *= 2)
+        if (sz >= size)
+          return sz;
+  }
 
-// Get the size of the type and then use SizeToAlignment.
-// 
-inline unsigned int
-TypeToAlignment(const Type* type, const TargetMachine& target)
-{
-  return SizeToAlignment(TypeToSize(type, target), target);
-}
+  /// Get the size of the type and then use SizeToAlignment.
+  /// 
+  inline unsigned int
+  TypeToAlignment(const Type* type, const TargetMachine& target) {
+    return SizeToAlignment(target.findOptimalStorageSize(type), target);
+  }
 
-// Get the size of the constant and then use SizeToAlignment.
-// Handles strings as a special case;
-inline unsigned int
-ConstantToAlignment(const Constant* CV, const TargetMachine& target)
-{
-  if (const ConstantArray* CVA = dyn_cast<ConstantArray>(CV))
-    if (ArrayTypeIsString(cast<ArrayType>(CVA->getType())))
-      return SizeToAlignment(1 + CVA->getNumOperands(), target);
+  /// Get the size of the constant and then use SizeToAlignment.
+  /// Handles strings as a special case;
+  inline unsigned int
+  ConstantToAlignment(const Constant* CV, const TargetMachine& target) {
+    if (const ConstantArray* CVA = dyn_cast<ConstantArray>(CV))
+      if (ArrayTypeIsString(cast<ArrayType>(CVA->getType())))
+        return SizeToAlignment(1 + CVA->getNumOperands(), target);
   
-  return TypeToAlignment(CV->getType(), target);
-}
-  
+    return TypeToAlignment(CV->getType(), target);
+  }
+
+} // End anonymous namespace
+
+} // End namespace llvm
+
+
+
 //===---------------------------------------------------------------------===//
-//   Code Shared By the two printer passes, as a mixin
+//   Code abstracted away from the AsmPrinter
 //===---------------------------------------------------------------------===//
 
-class AsmPrinter {
-  GlobalIdTable* idTable;
-public:
-  std::ostream &toAsm;
-  const TargetMachine &Target;
-  
-  enum Sections {
-    Unknown,
-    Text,
-    ReadOnlyData,
-    InitRWData,
-    ZeroInitRWData,
-  } CurSection;
+namespace llvm {
 
-  AsmPrinter(std::ostream &os, const TargetMachine &T)
-    : idTable(0), toAsm(os), Target(T), CurSection(Unknown) {}
-  
-  // (start|end)(Module|Function) - Callback methods to be invoked by subclasses
-  void startModule(Module &M) {
-    // Create the global id table if it does not already exist
-    idTable = (GlobalIdTable*)M.getAnnotation(GlobalIdTable::AnnotId);
-    if (idTable == NULL) {
-      idTable = new GlobalIdTable(&M);
-      M.addAnnotation(idTable);
-    }
-  }
+namespace {
 
-  void
-  PrintZeroBytesToPad(int numBytes)
-  {
-    for ( ; numBytes >= 8; numBytes -= 8)
-      printSingleConstantValue(Constant::getNullValue(Type::ULongTy));
-
-    if (numBytes >= 4)
-    {
-      printSingleConstantValue(Constant::getNullValue(Type::UIntTy));
-      numBytes -= 4;
-    }
-
-    while (numBytes--)
-      printSingleConstantValue(Constant::getNullValue(Type::UByteTy));
-  }
-
-  // Print a single constant value.
-  void printSingleConstantValue(const Constant* CV)
-  {
-    assert(CV->getType() != Type::VoidTy &&
-           CV->getType() != Type::TypeTy &&
-           CV->getType() != Type::LabelTy &&
-           "Unexpected type for Constant");
+  class AsmPrinter {
+    GlobalIdTable* idTable;
+  public:
+    std::ostream &toAsm;
+    const TargetMachine &Target;
   
-    assert((!isa<ConstantArray>(CV) && ! isa<ConstantStruct>(CV))
-           && "Aggregate types should be handled outside this function");
+    enum Sections {
+      Unknown,
+      Text,
+      ReadOnlyData,
+      InitRWData,
+      ZeroInitRWData,
+    } CurSection;
+
+    AsmPrinter(std::ostream &os, const TargetMachine &T)
+      : idTable(0), toAsm(os), Target(T), CurSection(Unknown) {}
   
-    toAsm << "\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))
-    { // Null pointer value
-      toAsm << "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";
-    }
-    else if (CV->getType()->isPrimitiveType())     // Check primitive types last
-    {
-      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;            
-        } else if (CV->getType() == Type::DoubleTy) {
-          char *ProxyPtr = (char*)&Val;         // Abide by C TBAA rules
-          toAsm << *(uint64_t*)ProxyPtr;            
-        } else {
-          assert(0 && "Unknown floating point type!");
-        }
-        
-        toAsm << "\t! " << CV->getType()->getDescription()
-              << " value: " << Val << "\n";
-      } else {
-        WriteAsOperand(toAsm, CV, false, false) << "\n";
+    // (start|end)(Module|Function) - Callback methods invoked by subclasses
+    void startModule(Module &M) {
+      // Create the global id table if it does not already exist
+      idTable = (GlobalIdTable*)M.getAnnotation(GlobalIdTable::AnnotId);
+      if (idTable == NULL) {
+        idTable = new GlobalIdTable(&M);
+        M.addAnnotation(idTable);
       }
     }
-    else
-    {
-      assert(0 && "Unknown elementary type for constant");
-    }
-  }
 
-  // Print a constant value or values (it may be an aggregate).
-  // Uses printSingleConstantValue() to print each individual value.
-  void
-  printConstantValueOnly(const Constant* CV,
-                         int numPadBytesAfter = 0)
-  {
-    const ConstantArray *CVA = dyn_cast<ConstantArray>(CV);
+    void PrintZeroBytesToPad(int numBytes) {
+      for (/* no init */; numBytes >= 8; numBytes -= 8)
+        printSingleConstantValue(Constant::getNullValue(Type::ULongTy));
 
-    if (CVA && isStringCompatible(CVA))
-    { // print the string alone and return
-      toAsm << "\t" << ".ascii" << "\t" << getAsCString(CVA) << "\n";
-    }
-    else if (CVA)
-    { // 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()));
-    }
-    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();
-      unsigned sizeSoFar = 0;
-      for (unsigned i=0, N = constValues.size(); i < N; i++)
-      {
-        const Constant* field = cast<Constant>(constValues[i].get());
-
-        // 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
-                        : cvsLayout->MemberOffsets[i+1])
-                       - cvsLayout->MemberOffsets[i]) - fieldSize;
-        sizeSoFar += (fieldSize + padSize);
-
-        // Now print the actual field value
-        printConstantValueOnly(field, padSize);
+      if (numBytes >= 4) {
+        printSingleConstantValue(Constant::getNullValue(Type::UIntTy));
+        numBytes -= 4;
       }
-      assert(sizeSoFar == cvsLayout->StructSize &&
-             "Layout of constant struct may be incorrect!");
+
+      while (numBytes--)
+        printSingleConstantValue(Constant::getNullValue(Type::UByteTy));
     }
-    else
-      printSingleConstantValue(CV);
 
-    if (numPadBytesAfter)
-      PrintZeroBytesToPad(numPadBytesAfter);
-  }
+    /// Print a single constant value.
+    ///
+    void printSingleConstantValue(const Constant* CV);
 
-  // Print a constant (which may be an aggregate) prefixed by all the
-  // appropriate directives.  Uses printConstantValueOnly() to print the
-  // value or values.
-  void printConstant(const Constant* CV, std::string valID = "")
-  {
-    if (valID.length() == 0)
-      valID = getID(CV);
+    /// Print a constant value or values (it may be an aggregate).
+    /// Uses printSingleConstantValue() to print each individual value.
+    ///
+    void printConstantValueOnly(const Constant* CV, int numPadBytesAfter = 0);
+
+    // Print a constant (which may be an aggregate) prefixed by all the
+    // appropriate directives.  Uses printConstantValueOnly() to print the
+    // value or values.
+    void printConstant(const Constant* CV, std::string valID = "") {
+      if (valID.length() == 0)
+        valID = getID(CV);
   
-    toAsm << "\t.align\t" << ConstantToAlignment(CV, Target) << "\n";
+      toAsm << "\t.align\t" << ConstantToAlignment(CV, Target) << "\n";
   
-    // Print .size and .type only if it is not a string.
-    const ConstantArray *CVA = dyn_cast<ConstantArray>(CV);
-    if (CVA && isStringCompatible(CVA))
-    { // print it as a string and return
+      // Print .size and .type only if it is not a string.
+      const ConstantArray *CVA = dyn_cast<ConstantArray>(CV);
+      if (CVA && isStringCompatible(CVA)) {
+        // print it as a string and return
+        toAsm << valID << ":\n";
+        toAsm << "\t" << ".ascii" << "\t" << getAsCString(CVA) << "\n";
+        return;
+      }
+  
+      toAsm << "\t.type" << "\t" << valID << ",#object\n";
+
+      unsigned int constSize = ConstantToSize(CV, Target);
+      if (constSize)
+        toAsm << "\t.size" << "\t" << valID << "," << constSize << "\n";
+  
       toAsm << valID << ":\n";
-      toAsm << "\t" << ".ascii" << "\t" << getAsCString(CVA) << "\n";
-      return;
+  
+      printConstantValueOnly(CV);
+    }
+
+    void startFunction(Function &F) {
+      // Make sure the slot table has information about this function...
+      idTable->Table.incorporateFunction(&F);
+    }
+    void endFunction(Function &) {
+      idTable->Table.purgeFunction();  // Forget all about F
+    }
+
+    // Check if a value is external or accessible from external code.
+    bool isExternal(const Value* V) {
+      const GlobalValue *GV = dyn_cast<GlobalValue>(V);
+      return GV && GV->hasExternalLinkage();
     }
   
-    toAsm << "\t.type" << "\t" << valID << ",#object\n";
+    // enterSection - Use this method to enter a different section of the output
+    // executable.  This is used to only output necessary section transitions.
+    //
+    void enterSection(enum Sections S) {
+      if (S == CurSection) return;        // Only switch section if necessary
+      CurSection = S;
 
-    unsigned int constSize = ConstantToSize(CV, Target);
-    if (constSize)
-      toAsm << "\t.size" << "\t" << valID << "," << constSize << "\n";
-  
-    toAsm << valID << ":\n";
-  
-    printConstantValueOnly(CV);
-  }
-
-  void startFunction(Function &F) {
-    // Make sure the slot table has information about this function...
-    idTable->Table.incorporateFunction(&F);
-  }
-  void endFunction(Function &) {
-    idTable->Table.purgeFunction();  // Forget all about F
-  }
-  void endModule() {
-  }
-
-  // Check if a value is external or accessible from external code.
-  bool isExternal(const Value* V) {
-    const GlobalValue *GV = dyn_cast<GlobalValue>(V);
-    return GV && GV->hasExternalLinkage();
-  }
-  
-  // enterSection - Use this method to enter a different section of the output
-  // executable.  This is used to only output necessary section transitions.
-  //
-  void enterSection(enum Sections S) {
-    if (S == CurSection) return;        // Only switch section if necessary
-    CurSection = S;
-
-    toAsm << "\n\t.section ";
-    switch (S)
+      toAsm << "\n\t.section ";
+      switch (S)
       {
       default: assert(0 && "Bad section name!");
       case Text:         toAsm << "\".text\""; break;
@@ -414,264 +306,381 @@
       case InitRWData:   toAsm << "\".data\",#alloc,#write"; break;
       case ZeroInitRWData: toAsm << "\".bss\",#alloc,#write"; break;
       }
-    toAsm << "\n";
-  }
+      toAsm << "\n";
+    }
 
-  static std::string getValidSymbolName(const std::string &S) {
-    std::string Result;
+    static std::string getValidSymbolName(const std::string &S) {
+      std::string Result;
     
-    // Symbol names in Sparc assembly language have these rules:
-    // (a) Must match { letter | _ | . | $ } { letter | _ | . | $ | digit }*
-    // (b) A name beginning in "." is treated as a local name.
-    // 
-    if (isdigit(S[0]))
-      Result = "ll";
+      // Symbol names in Sparc assembly language have these rules:
+      // (a) Must match { letter | _ | . | $ } { letter | _ | . | $ | digit }*
+      // (b) A name beginning in "." is treated as a local name.
+      // 
+      if (isdigit(S[0]))
+        Result = "ll";
     
-    for (unsigned i = 0; i < S.size(); ++i)
-      {
+      for (unsigned i = 0; i < S.size(); ++i) {
         char C = S[i];
         if (C == '_' || C == '.' || C == '$' || isalpha(C) || isdigit(C))
           Result += C;
-        else
-          {
-            Result += '_';
-            Result += char('0' + ((unsigned char)C >> 4));
-            Result += char('0' + (C & 0xF));
-          }
+        else {
+          Result += '_';
+          Result += char('0' + ((unsigned char)C >> 4));
+          Result += char('0' + (C & 0xF));
+        }
       }
-    return Result;
-  }
-
-  // getID - Return a valid identifier for the specified value.  Base it on
-  // the name of the identifier if possible (qualified by the type), and
-  // use a numbered value based on prefix otherwise.
-  // FPrefix is always prepended to the output identifier.
-  //
-  std::string getID(const Value *V, const char *Prefix, const char *FPrefix = 0) {
-    std::string Result = FPrefix ? FPrefix : "";  // "Forced prefix"
-
-    Result += V->hasName() ? V->getName() : std::string(Prefix);
-
-    // Qualify all internal names with a unique id.
-    if (!isExternal(V)) {
-      int valId = idTable->Table.getSlot(V);
-      if (valId == -1) {
-        GlobalIdTable::ValIdMapConstIterator I = idTable->valToIdMap.find(V);
-        if (I == idTable->valToIdMap.end())
-          valId = idTable->valToIdMap[V] = idTable->valToIdMap.size();
-        else
-          valId = I->second;
-      }
-      Result = Result + "_" + itostr(valId);
-
-      // Replace or prefix problem characters in the name
-      Result = getValidSymbolName(Result);
+      return Result;
     }
 
-    return Result;
-  }
+    // getID - Return a valid identifier for the specified value.  Base it on
+    // the name of the identifier if possible (qualified by the type), and
+    // use a numbered value based on prefix otherwise.
+    // FPrefix is always prepended to the output identifier.
+    //
+    std::string getID(const Value *V, const char *Prefix,
+                      const char *FPrefix = 0)
+    {
+      std::string Result = FPrefix ? FPrefix : "";  // "Forced prefix"
+
+      Result += V->hasName() ? V->getName() : std::string(Prefix);
+
+      // Qualify all internal names with a unique id.
+      if (!isExternal(V)) {
+        int valId = idTable->Table.getSlot(V);
+        if (valId == -1) {
+          GlobalIdTable::ValIdMapConstIterator I = idTable->valToIdMap.find(V);
+          if (I == idTable->valToIdMap.end())
+            valId = idTable->valToIdMap[V] = idTable->valToIdMap.size();
+          else
+            valId = I->second;
+        }
+        Result = Result + "_" + itostr(valId);
+
+        // Replace or prefix problem characters in the name
+        Result = getValidSymbolName(Result);
+      }
+
+      return Result;
+    }
   
-  // getID Wrappers - Ensure consistent usage...
-  std::string getID(const Function *F) {
-    return getID(F, "LLVMFunction_");
-  }
-  std::string getID(const BasicBlock *BB) {
-    return getID(BB, "LL", (".L_"+getID(BB->getParent())+"_").c_str());
-  }
-  std::string getID(const GlobalVariable *GV) {
-    return getID(GV, "LLVMGlobal_");
-  }
-  std::string getID(const Constant *CV) {
-    return getID(CV, "LLVMConst_", ".C_");
-  }
-  std::string getID(const GlobalValue *GV) {
-    if (const GlobalVariable *V = dyn_cast<GlobalVariable>(GV))
-      return getID(V);
-    else if (const Function *F = dyn_cast<Function>(GV))
-      return getID(F);
-    assert(0 && "Unexpected type of GlobalValue!");
-    return "";
-  }
+    // getID Wrappers - Ensure consistent usage...
+    std::string getID(const Function *F) {
+      return getID(F, "LLVMFunction_");
+    }
+    std::string getID(const BasicBlock *BB) {
+      return getID(BB, "LL", (".L_"+getID(BB->getParent())+"_").c_str());
+    }
+    std::string getID(const GlobalVariable *GV) {
+      return getID(GV, "LLVMGlobal_");
+    }
+    std::string getID(const Constant *CV) {
+      return getID(CV, "LLVMConst_", ".C_");
+    }
+    std::string getID(const GlobalValue *GV) {
+      if (const GlobalVariable *V = dyn_cast<GlobalVariable>(GV))
+        return getID(V);
+      else if (const Function *F = dyn_cast<Function>(GV))
+        return getID(F);
+      assert(0 && "Unexpected type of GlobalValue!");
+      return "";
+    }
 
-  // Combines expressions 
-  inline std::string ConstantArithExprToString(const ConstantExpr* CE,
-                                               const TargetMachine &TM,
-                                               const std::string &op) {
-    return "(" + valToExprString(CE->getOperand(0), TM) + op
-               + valToExprString(CE->getOperand(1), TM) + ")";
-  }
+    // Combines expressions 
+    inline std::string ConstantArithExprToString(const ConstantExpr* CE,
+                                                 const TargetMachine &TM,
+                                                 const std::string &op) {
+      return "(" + valToExprString(CE->getOperand(0), TM) + op
+        + valToExprString(CE->getOperand(1), TM) + ")";
+    }
 
-  // ConstantExprToString() - Convert a ConstantExpr to an asm expression
-  // and return this as a string.
-  std::string ConstantExprToString(const ConstantExpr* CE,
-                                   const TargetMachine& target) {
-    std::string S;
-    switch(CE->getOpcode()) {
-    case Instruction::GetElementPtr:
-      { // generate a symbolic expression for the byte address
-        const Value* ptrVal = CE->getOperand(0);
-        std::vector<Value*> idxVec(CE->op_begin()+1, CE->op_end());
-        const TargetData &TD = target.getTargetData();
-        S += "(" + valToExprString(ptrVal, target) + ") + ("
-          + utostr(TD.getIndexedOffset(ptrVal->getType(),idxVec)) + ")";
-        break;
+    /// ConstantExprToString() - Convert a ConstantExpr to an asm expression
+    /// and return this as a string.
+    ///
+    std::string ConstantExprToString(const ConstantExpr* CE,
+                                     const TargetMachine& target);
+
+    /// valToExprString - Helper function for ConstantExprToString().
+    /// Appends result to argument string S.
+    /// 
+    std::string valToExprString(const Value* V, const TargetMachine& target);
+  };
+
+} // End anonymous namespace
+
+} // End namespace llvm
+
+/// Print a single constant value.
+///
+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";
+  
+  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)) {
+    // Null pointer value
+    toAsm << "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";
+  } else if (CV->getType()->isPrimitiveType()) {
+    // Check primitive types last
+    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;            
+      } else if (CV->getType() == Type::DoubleTy) {
+        char *ProxyPtr = (char*)&Val;         // Abide by C TBAA rules
+        toAsm << *(uint64_t*)ProxyPtr;            
+      } else {
+        assert(0 && "Unknown floating point type!");
       }
+        
+      toAsm << "\t! " << CV->getType()->getDescription()
+            << " value: " << Val << "\n";
+    } else {
+      WriteAsOperand(toAsm, CV, false, false) << "\n";
+    }
+  } else {
+    assert(0 && "Unknown elementary type for constant");
+  }
+}
 
-    case Instruction::Cast:
-      // Support only non-converting casts for now, i.e., a no-op.
-      // This assertion is not a complete check.
-      assert(target.getTargetData().getTypeSize(CE->getType()) ==
-             target.getTargetData().getTypeSize(CE->getOperand(0)->getType()));
-      S += "(" + valToExprString(CE->getOperand(0), target) + ")";
-      break;
+/// Print a constant value or values (it may be an aggregate).
+/// Uses printSingleConstantValue() to print each individual value.
+///
+void AsmPrinter::printConstantValueOnly(const Constant* CV,
+                                        int numPadBytesAfter)
+{
+  const ConstantArray *CVA = dyn_cast<ConstantArray>(CV);
 
-    case Instruction::Add:
-      S += ConstantArithExprToString(CE, target, ") + (");
-      break;
+  if (CVA && isStringCompatible(CVA)) {
+    // print the string alone and return
+    toAsm << "\t" << ".ascii" << "\t" << getAsCString(CVA) << "\n";
+  } else if (CVA) { 
+    // 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()));
+  } 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();
+    unsigned sizeSoFar = 0;
+    for (unsigned i=0, N = constValues.size(); i < N; i++) {
+      const Constant* field = cast<Constant>(constValues[i].get());
 
-    case Instruction::Sub:
-      S += ConstantArithExprToString(CE, target, ") - (");
-      break;
+      // 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
+                      : cvsLayout->MemberOffsets[i+1])
+                     - cvsLayout->MemberOffsets[i]) - fieldSize;
+      sizeSoFar += (fieldSize + padSize);
 
-    case Instruction::Mul:
-      S += ConstantArithExprToString(CE, target, ") * (");
-      break;
+      // Now print the actual field value
+      printConstantValueOnly(field, padSize);
+    }
+    assert(sizeSoFar == cvsLayout->StructSize &&
+           "Layout of constant struct may be incorrect!");
+  }
+  else
+    printSingleConstantValue(CV);
 
-    case Instruction::Div:
-      S += ConstantArithExprToString(CE, target, ") / (");
-      break;
+  if (numPadBytesAfter)
+    PrintZeroBytesToPad(numPadBytesAfter);
+}
 
-    case Instruction::Rem:
-      S += ConstantArithExprToString(CE, target, ") % (");
-      break;
-
-    case Instruction::And:
-      // Logical && for booleans; bitwise & otherwise
-      S += ConstantArithExprToString(CE, target,
-               ((CE->getType() == Type::BoolTy)? ") && (" : ") & ("));
-      break;
-
-    case Instruction::Or:
-      // Logical || for booleans; bitwise | otherwise
-      S += ConstantArithExprToString(CE, target,
-               ((CE->getType() == Type::BoolTy)? ") || (" : ") | ("));
-      break;
-
-    case Instruction::Xor:
-      // Bitwise ^ for all types
-      S += ConstantArithExprToString(CE, target, ") ^ (");
-      break;
-
-    default:
-      assert(0 && "Unsupported operator in ConstantExprToString()");
+/// ConstantExprToString() - Convert a ConstantExpr to an asm expression
+/// and return this as a string.
+///
+std::string AsmPrinter::ConstantExprToString(const ConstantExpr* CE,
+                                             const TargetMachine& target) {
+  std::string S;
+  switch(CE->getOpcode()) {
+  case Instruction::GetElementPtr:
+    { // generate a symbolic expression for the byte address
+      const Value* ptrVal = CE->getOperand(0);
+      std::vector<Value*> idxVec(CE->op_begin()+1, CE->op_end());
+      const TargetData &TD = target.getTargetData();
+      S += "(" + valToExprString(ptrVal, target) + ") + ("
+        + utostr(TD.getIndexedOffset(ptrVal->getType(),idxVec)) + ")";
       break;
     }
 
-    return S;
+  case Instruction::Cast:
+    // Support only non-converting casts for now, i.e., a no-op.
+    // This assertion is not a complete check.
+    assert(target.getTargetData().getTypeSize(CE->getType()) ==
+           target.getTargetData().getTypeSize(CE->getOperand(0)->getType()));
+    S += "(" + valToExprString(CE->getOperand(0), target) + ")";
+    break;
+
+  case Instruction::Add:
+    S += ConstantArithExprToString(CE, target, ") + (");
+    break;
+
+  case Instruction::Sub:
+    S += ConstantArithExprToString(CE, target, ") - (");
+    break;
+
+  case Instruction::Mul:
+    S += ConstantArithExprToString(CE, target, ") * (");
+    break;
+
+  case Instruction::Div:
+    S += ConstantArithExprToString(CE, target, ") / (");
+    break;
+
+  case Instruction::Rem:
+    S += ConstantArithExprToString(CE, target, ") % (");
+    break;
+
+  case Instruction::And:
+    // Logical && for booleans; bitwise & otherwise
+    S += ConstantArithExprToString(CE, target,
+                                   ((CE->getType() == Type::BoolTy)? ") && (" : ") & ("));
+    break;
+
+  case Instruction::Or:
+    // Logical || for booleans; bitwise | otherwise
+    S += ConstantArithExprToString(CE, target,
+                                   ((CE->getType() == Type::BoolTy)? ") || (" : ") | ("));
+    break;
+
+  case Instruction::Xor:
+    // Bitwise ^ for all types
+    S += ConstantArithExprToString(CE, target, ") ^ (");
+    break;
+
+  default:
+    assert(0 && "Unsupported operator in ConstantExprToString()");
+    break;
   }
 
-  // valToExprString - Helper function for ConstantExprToString().
-  // Appends result to argument string S.
-  // 
-  std::string valToExprString(const Value* V, const TargetMachine& target) {
-    std::string S;
-    bool failed = false;
-    if (const Constant* CV = dyn_cast<Constant>(V)) { // symbolic or known
+  return S;
+}
 
-      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))
-        S += itostr(CI->getValue());
-      else if (const ConstantUInt *CI = dyn_cast<ConstantUInt>(CV))
-        S += utostr(CI->getValue());
-      else if (const ConstantFP *CFP = dyn_cast<ConstantFP>(CV))
-        S += ftostr(CFP->getValue());
-      else if (isa<ConstantPointerNull>(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);
-    }
+/// valToExprString - Helper function for ConstantExprToString().
+/// Appends result to argument string S.
+/// 
+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 ConstantBool *CB = dyn_cast<ConstantBool>(CV))
+      S += std::string(CB == ConstantBool::True ? "1" : "0");
+    else if (const ConstantSInt *CI = dyn_cast<ConstantSInt>(CV))
+      S += itostr(CI->getValue());
+    else if (const ConstantUInt *CI = dyn_cast<ConstantUInt>(CV))
+      S += utostr(CI->getValue());
+    else if (const ConstantFP *CFP = dyn_cast<ConstantFP>(CV))
+      S += ftostr(CFP->getValue());
+    else if (isa<ConstantPointerNull>(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;
 
-    if (failed) {
-      assert(0 && "Cannot convert value to string");
-      S += "<illegal-value>";
-    }
-    return S;
+  if (failed) {
+    assert(0 && "Cannot convert value to string");
+    S += "<illegal-value>";
   }
-
-};
-
+  return S;
+}
 
 
 //===----------------------------------------------------------------------===//
-//   SparcFunctionAsmPrinter Code
+//   SparcAsmPrinter Code
 //===----------------------------------------------------------------------===//
 
-struct SparcFunctionAsmPrinter : public FunctionPass, public AsmPrinter {
-  inline SparcFunctionAsmPrinter(std::ostream &os, const TargetMachine &t)
-    : AsmPrinter(os, t) {}
+namespace llvm {
 
-  const Function *currFunction;
+namespace {
 
-  const char *getPassName() const {
-    return "Output Sparc Assembly for Functions";
-  }
+  struct SparcAsmPrinter : public FunctionPass, public AsmPrinter {
+    inline SparcAsmPrinter(std::ostream &os, const TargetMachine &t)
+      : AsmPrinter(os, t) {}
 
-  virtual bool doInitialization(Module &M) {
-    startModule(M);
-    return false;
-  }
+    const Function *currFunction;
 
-  virtual bool runOnFunction(Function &F) {
-    currFunction = &F;
-    startFunction(F);
-    emitFunction(F);
-    endFunction(F);
-    return false;
-  }
-
-  virtual bool doFinalization(Module &M) {
-    endModule();
-    return false;
-  }
-
-  virtual void getAnalysisUsage(AnalysisUsage &AU) const {
-    AU.setPreservesAll();
-  }
-
-  void emitFunction(const Function &F);
-private :
-  void emitBasicBlock(const MachineBasicBlock &MBB);
-  void emitMachineInst(const MachineInstr *MI);
-  
-  unsigned int printOperands(const MachineInstr *MI, unsigned int opNum);
-  void printOneOperand(const MachineOperand &Op, MachineOpCode opCode);
-
-  bool OpIsBranchTargetLabel(const MachineInstr *MI, unsigned int opNum);
-  bool OpIsMemoryAddressBase(const MachineInstr *MI, unsigned int opNum);
-  
-  unsigned getOperandMask(unsigned Opcode) {
-    switch (Opcode) {
-    case V9::SUBccr:
-    case V9::SUBcci:   return 1 << 3;  // Remove CC argument
-  //case BA:      return 1 << 0;  // Remove Arg #0, which is always null or xcc
-    default:      return 0;       // By default, don't hack operands...
+    const char *getPassName() const {
+      return "Output Sparc Assembly for Functions";
     }
-  }
-};
+
+    virtual bool doInitialization(Module &M) {
+      startModule(M);
+      return false;
+    }
+
+    virtual bool runOnFunction(Function &F) {
+      currFunction = &F;
+      startFunction(F);
+      emitFunction(F);
+      endFunction(F);
+      return false;
+    }
+
+    virtual bool doFinalization(Module &M) {
+      emitGlobals(M);
+      return false;
+    }
+
+    virtual void getAnalysisUsage(AnalysisUsage &AU) const {
+      AU.setPreservesAll();
+    }
+
+    void emitFunction(const Function &F);
+  private :
+    void emitBasicBlock(const MachineBasicBlock &MBB);
+    void emitMachineInst(const MachineInstr *MI);
+  
+    unsigned int printOperands(const MachineInstr *MI, unsigned int opNum);
+    void printOneOperand(const MachineOperand &Op, MachineOpCode opCode);
+
+    bool OpIsBranchTargetLabel(const MachineInstr *MI, unsigned int opNum);
+    bool OpIsMemoryAddressBase(const MachineInstr *MI, unsigned int opNum);
+  
+    unsigned getOperandMask(unsigned Opcode) {
+      switch (Opcode) {
+      case V9::SUBccr:
+      case V9::SUBcci:   return 1 << 3;  // Remove CC argument
+      default:      return 0;       // By default, don't hack operands...
+      }
+    }
+
+    void emitGlobals(const Module &M);
+    void printGlobalVariable(const GlobalVariable *GV);
+  };
+
+} // End anonymous namespace
 
 inline bool
-SparcFunctionAsmPrinter::OpIsBranchTargetLabel(const MachineInstr *MI,
-                                               unsigned int opNum) {
+SparcAsmPrinter::OpIsBranchTargetLabel(const MachineInstr *MI,
+                                       unsigned int opNum) {
   switch (MI->getOpCode()) {
   case V9::JMPLCALLr:
   case V9::JMPLCALLi:
@@ -683,10 +692,9 @@
   }
 }
 
-
 inline bool
-SparcFunctionAsmPrinter::OpIsMemoryAddressBase(const MachineInstr *MI,
-                                               unsigned int opNum) {
+SparcAsmPrinter::OpIsMemoryAddressBase(const MachineInstr *MI,
+                                       unsigned int opNum) {
   if (Target.getInstrInfo().isLoad(MI->getOpCode()))
     return (opNum == 0);
   else if (Target.getInstrInfo().isStore(MI->getOpCode()))
@@ -702,33 +710,28 @@
   printOneOperand(mop2, opCode);
 
 unsigned int
-SparcFunctionAsmPrinter::printOperands(const MachineInstr *MI,
+SparcAsmPrinter::printOperands(const MachineInstr *MI,
                                unsigned int opNum)
 {
   const MachineOperand& mop = MI->getOperand(opNum);
   
-  if (OpIsBranchTargetLabel(MI, opNum))
-    {
-      PrintOp1PlusOp2(mop, MI->getOperand(opNum+1), MI->getOpCode());
-      return 2;
-    }
-  else if (OpIsMemoryAddressBase(MI, opNum))
-    {
-      toAsm << "[";
-      PrintOp1PlusOp2(mop, MI->getOperand(opNum+1), MI->getOpCode());
-      toAsm << "]";
-      return 2;
-    }
-  else
-    {
-      printOneOperand(mop, MI->getOpCode());
-      return 1;
-    }
+  if (OpIsBranchTargetLabel(MI, opNum)) {
+    PrintOp1PlusOp2(mop, MI->getOperand(opNum+1), MI->getOpCode());
+    return 2;
+  } else if (OpIsMemoryAddressBase(MI, opNum)) {
+    toAsm << "[";
+    PrintOp1PlusOp2(mop, MI->getOperand(opNum+1), MI->getOpCode());
+    toAsm << "]";
+    return 2;
+  } else {
+    printOneOperand(mop, MI->getOpCode());
+    return 1;
+  }
 }
 
 void
-SparcFunctionAsmPrinter::printOneOperand(const MachineOperand &mop,
-                                         MachineOpCode opCode)
+SparcAsmPrinter::printOneOperand(const MachineOperand &mop,
+                                 MachineOpCode opCode)
 {
   bool needBitsFlag = true;
   
@@ -770,7 +773,7 @@
     case MachineOperand::MO_PCRelativeDisp:
       {
         const Value *Val = mop.getVRegValue();
-        assert(Val && "\tNULL Value in SparcFunctionAsmPrinter");
+        assert(Val && "\tNULL Value in SparcAsmPrinter");
         
         if (const BasicBlock *BB = dyn_cast<BasicBlock>(Val))
           toAsm << getID(BB);
@@ -781,7 +784,7 @@
         else if (const Constant *CV = dyn_cast<Constant>(Val))
           toAsm << getID(CV);
         else
-          assert(0 && "Unrecognized value in SparcFunctionAsmPrinter");
+          assert(0 && "Unrecognized value in SparcAsmPrinter");
         break;
       }
     
@@ -802,9 +805,7 @@
     toAsm << ")";
 }
 
-void
-SparcFunctionAsmPrinter::emitMachineInst(const MachineInstr *MI)
-{
+void SparcAsmPrinter::emitMachineInst(const MachineInstr *MI) {
   unsigned Opcode = MI->getOpCode();
 
   if (Target.getInstrInfo().isDummyPhiInstr(Opcode))
@@ -828,9 +829,7 @@
   ++EmittedInsts;
 }
 
-void
-SparcFunctionAsmPrinter::emitBasicBlock(const MachineBasicBlock &MBB)
-{
+void SparcAsmPrinter::emitBasicBlock(const MachineBasicBlock &MBB) {
   // Emit a label for the basic block
   toAsm << getID(MBB.getBasicBlock()) << ":\n";
 
@@ -841,9 +840,7 @@
   toAsm << "\n";  // Separate BB's with newlines
 }
 
-void
-SparcFunctionAsmPrinter::emitFunction(const Function &F)
-{
+void SparcAsmPrinter::emitFunction(const Function &F) {
   std::string methName = getID(&F);
   toAsm << "!****** Outputing Function: " << methName << " ******\n";
 
@@ -877,64 +874,23 @@
   toAsm << "\n\n";
 }
 
-}  // End anonymous namespace
-
-namespace llvm {
-
-Pass *UltraSparc::getFunctionAsmPrinterPass(std::ostream &Out) {
-  return new SparcFunctionAsmPrinter(Out, *this);
-}
-
-} // End llvm namespace
-
-
-//===----------------------------------------------------------------------===//
-//   SparcFunctionAsmPrinter Code
-//===----------------------------------------------------------------------===//
-
-namespace {
-
-class SparcModuleAsmPrinter : public Pass, public AsmPrinter {
-public:
-  SparcModuleAsmPrinter(std::ostream &os, TargetMachine &t)
-    : AsmPrinter(os, t) {}
-
-  const char *getPassName() const { return "Output Sparc Assembly for Module"; }
-
-  virtual bool run(Module &M) {
-    startModule(M);
-    emitGlobals(M);
-    endModule();
-    return false;
-  }
-
-  virtual void getAnalysisUsage(AnalysisUsage &AU) const {
-    AU.setPreservesAll();
-  }
-
-private:
-  void emitGlobals(const Module &M);
-  void printGlobalVariable(const GlobalVariable *GV);
-};
-
-void SparcModuleAsmPrinter::printGlobalVariable(const GlobalVariable* GV)
-{
+void SparcAsmPrinter::printGlobalVariable(const GlobalVariable* GV) {
   if (GV->hasExternalLinkage())
     toAsm << "\t.global\t" << getID(GV) << "\n";
   
-  if (GV->hasInitializer() && ! GV->getInitializer()->isNullValue())
+  if (GV->hasInitializer() && ! GV->getInitializer()->isNullValue()) {
     printConstant(GV->getInitializer(), getID(GV));
-  else {
+  } 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) << ","
-          << TypeToSize(GV->getType()->getElementType(), Target)
+          << Target.findOptimalStorageSize(GV->getType()->getElementType())
           << "\n";
   }
 }
 
-void SparcModuleAsmPrinter::emitGlobals(const Module &M) {
+void SparcAsmPrinter::emitGlobals(const Module &M) {
   // Output global variables...
   for (Module::const_giterator GI = M.gbegin(), GE = M.gend(); GI != GE; ++GI)
     if (! GI->isExternal()) {
@@ -952,10 +908,8 @@
   toAsm << "\n";
 }
 
-}  // End anonymous namespace
-
-Pass *UltraSparc::getModuleAsmPrinterPass(std::ostream &Out) {
-  return new SparcModuleAsmPrinter(Out, *this);
+FunctionPass *createAsmPrinterPass(std::ostream &Out, const TargetMachine &TM) {
+  return new SparcAsmPrinter(Out, TM);
 }
 
 } // End llvm namespace
