Convert assembly emission over to a two pass approach.
[oota-llvm.git] / lib / Target / SparcV9 / SparcV9AsmPrinter.cpp
1 //===-- EmitAssembly.cpp - Emit Sparc Specific .s File ---------------------==//
2 //
3 // This file implements all of the stuff neccesary to output a .s file from
4 // LLVM.  The code in this file assumes that the specified module has already
5 // been compiled into the internal data structures of the Module.
6 //
7 // This code largely consists of two LLVM Pass's: a MethodPass and a Pass.  The
8 // MethodPass is pipelined together with all of the rest of the code generation
9 // stages, and the Pass runs at the end to emit code for global variables and
10 // such.
11 //
12 //===----------------------------------------------------------------------===//
13
14 #include "SparcInternals.h"
15 #include "llvm/Analysis/SlotCalculator.h"
16 #include "llvm/CodeGen/MachineInstr.h"
17 #include "llvm/CodeGen/MachineCodeForMethod.h"
18 #include "llvm/GlobalVariable.h"
19 #include "llvm/ConstantVals.h"
20 #include "llvm/DerivedTypes.h"
21 #include "llvm/BasicBlock.h"
22 #include "llvm/Method.h"
23 #include "llvm/Module.h"
24 #include "Support/StringExtras.h"
25 #include "Support/HashExtras.h"
26 using std::string;
27
28 namespace {
29
30 //===----------------------------------------------------------------------===//
31 //   Code Shared By the two printer passes, as a mixin
32 //===----------------------------------------------------------------------===//
33
34 class AsmPrinter {
35   typedef std::hash_map<const Value*, int> ValIdMap;
36   typedef ValIdMap::      iterator ValIdMapIterator;
37   typedef ValIdMap::const_iterator ValIdMapConstIterator;
38   
39   SlotCalculator *Table;   // map anonymous values to unique integer IDs
40   ValIdMap valToIdMap;     // used for values not handled by SlotCalculator 
41 public:
42   std::ostream &toAsm;
43   const UltraSparc &Target;
44
45   enum Sections {
46     Unknown,
47     Text,
48     ReadOnlyData,
49     InitRWData,
50     UninitRWData,
51   } CurSection;
52
53   AsmPrinter(std::ostream &os, const UltraSparc &T)
54     : Table(0), toAsm(os), Target(T), CurSection(Unknown) {}
55
56
57   // (start|end)(Module|Method) - Callback methods to be invoked by subclasses
58   void startModule(Module *M) {
59     Table = new SlotCalculator(M, true);
60   }
61   void startMethod(Method *M) {
62     // Make sure the slot table has information about this method...
63     Table->incorporateMethod(M);
64   }
65   void endMethod(Method *M) {
66     Table->purgeMethod();  // Forget all about M.
67   }
68   void endModule() {
69     delete Table; Table = 0;
70     valToIdMap.clear();
71   }
72
73   
74   // enterSection - Use this method to enter a different section of the output
75   // executable.  This is used to only output neccesary section transitions.
76   //
77   void enterSection(enum Sections S) {
78     if (S == CurSection) return;        // Only switch section if neccesary
79     CurSection = S;
80
81     toAsm << "\n\t.section ";
82     switch (S)
83       {
84       default: assert(0 && "Bad section name!");
85       case Text:         toAsm << "\".text\""; break;
86       case ReadOnlyData: toAsm << "\".rodata\",#alloc"; break;
87       case InitRWData:   toAsm << "\".data\",#alloc,#write"; break;
88       case UninitRWData: toAsm << "\".bss\",#alloc,#write\nBbss.bss:"; break;
89       }
90     toAsm << "\n";
91   }
92
93   static std::string getValidSymbolName(const string &S) {
94     string Result;
95     
96     // Symbol names in Sparc assembly language have these rules:
97     // (a) Must match { letter | _ | . | $ } { letter | _ | . | $ | digit }*
98     // (b) A name beginning in "." is treated as a local name.
99     // (c) Names beginning with "_" are reserved by ANSI C and shd not be used.
100     // 
101     if (S[0] == '_' || isdigit(S[0]))
102       Result += "ll";
103     
104     for (unsigned i = 0; i < S.size(); ++i)
105       {
106         char C = S[i];
107         if (C == '_' || C == '.' || C == '$' || isalpha(C) || isdigit(C))
108           Result += C;
109         else
110           {
111             Result += '_';
112             Result += char('0' + ((unsigned char)C >> 4));
113             Result += char('0' + (C & 0xF));
114           }
115       }
116     return Result;
117   }
118
119   // getID - Return a valid identifier for the specified value.  Base it on
120   // the name of the identifier if possible, use a numbered value based on
121   // prefix otherwise.  FPrefix is always prepended to the output identifier.
122   //
123   string getID(const Value *V, const char *Prefix, const char *FPrefix = 0) {
124     string Result;
125     string FP(FPrefix ? FPrefix : "");  // "Forced prefix"
126     if (V->hasName()) {
127       Result = FP + V->getName();
128     } else {
129       int valId = Table->getValSlot(V);
130       if (valId == -1) {
131         ValIdMapConstIterator I = valToIdMap.find(V);
132         if (I == valToIdMap.end())
133           valId = valToIdMap[V] = valToIdMap.size();
134         else
135           valId = I->second;
136       }
137       Result = FP + string(Prefix) + itostr(valId);
138     }
139     return getValidSymbolName(Result);
140   }
141   
142   // getID Wrappers - Ensure consistent usage...
143   string getID(const Module *M) {
144     return getID(M, "LLVMModule_");
145   }
146   string getID(const Method *M) {
147     return getID(M, "LLVMMethod_");
148   }
149   string getID(const BasicBlock *BB) {
150     return getID(BB, "LL", (".L_"+getID(BB->getParent())+"_").c_str());
151   }
152   string getID(const GlobalVariable *GV) {
153     return getID(GV, "LLVMGlobal_", ".G_");
154   }
155   string getID(const Constant *CV) {
156     return getID(CV, "LLVMConst_", ".C_");
157   }
158 };
159
160
161
162 //===----------------------------------------------------------------------===//
163 //   SparcMethodAsmPrinter Code
164 //===----------------------------------------------------------------------===//
165
166 struct SparcMethodAsmPrinter : public MethodPass, public AsmPrinter {
167   inline SparcMethodAsmPrinter(std::ostream &os, const UltraSparc &t)
168     : AsmPrinter(os, t) {}
169
170   virtual bool doInitialization(Module *M) {
171     startModule(M);
172     return false;
173   }
174
175   virtual bool runOnMethod(Method *M) {
176     startMethod(M);
177     emitMethod(M);
178     endMethod(M);
179     return false;
180   }
181
182   virtual bool doFinalization(Module *M) {
183     endModule();
184     return false;
185   }
186
187   void emitMethod(const Method *M);
188 private :
189   void emitBasicBlock(const BasicBlock *BB);
190   void emitMachineInst(const MachineInstr *MI);
191   
192   unsigned int printOperands(const MachineInstr *MI, unsigned int opNum);
193   void printOneOperand(const MachineOperand &Op);
194
195   bool OpIsBranchTargetLabel(const MachineInstr *MI, unsigned int opNum);
196   bool OpIsMemoryAddressBase(const MachineInstr *MI, unsigned int opNum);
197   
198   unsigned getOperandMask(unsigned Opcode) {
199     switch (Opcode) {
200     case SUBcc:   return 1 << 3;  // Remove CC argument
201     case BA:      return 1 << 0;  // Remove Arg #0, which is always null or xcc
202     default:      return 0;       // By default, don't hack operands...
203     }
204   }
205 };
206
207 inline bool
208 SparcMethodAsmPrinter::OpIsBranchTargetLabel(const MachineInstr *MI,
209                                        unsigned int opNum) {
210   switch (MI->getOpCode()) {
211   case JMPLCALL:
212   case JMPLRET: return (opNum == 0);
213   default:      return false;
214   }
215 }
216
217
218 inline bool
219 SparcMethodAsmPrinter::OpIsMemoryAddressBase(const MachineInstr *MI,
220                                        unsigned int opNum) {
221   if (Target.getInstrInfo().isLoad(MI->getOpCode()))
222     return (opNum == 0);
223   else if (Target.getInstrInfo().isStore(MI->getOpCode()))
224     return (opNum == 1);
225   else
226     return false;
227 }
228
229
230 #define PrintOp1PlusOp2(Op1, Op2) \
231   printOneOperand(Op1); \
232   toAsm << "+"; \
233   printOneOperand(Op2);
234
235 unsigned int
236 SparcMethodAsmPrinter::printOperands(const MachineInstr *MI,
237                                unsigned int opNum)
238 {
239   const MachineOperand& Op = MI->getOperand(opNum);
240   
241   if (OpIsBranchTargetLabel(MI, opNum))
242     {
243       PrintOp1PlusOp2(Op, MI->getOperand(opNum+1));
244       return 2;
245     }
246   else if (OpIsMemoryAddressBase(MI, opNum))
247     {
248       toAsm << "[";
249       PrintOp1PlusOp2(Op, MI->getOperand(opNum+1));
250       toAsm << "]";
251       return 2;
252     }
253   else
254     {
255       printOneOperand(Op);
256       return 1;
257     }
258 }
259
260
261 void
262 SparcMethodAsmPrinter::printOneOperand(const MachineOperand &op)
263 {
264   switch (op.getOperandType())
265     {
266     case MachineOperand::MO_VirtualRegister:
267     case MachineOperand::MO_CCRegister:
268     case MachineOperand::MO_MachineRegister:
269       {
270         int RegNum = (int)op.getAllocatedRegNum();
271         
272         // ****this code is temporary till NULL Values are fixed
273         if (RegNum == Target.getRegInfo().getInvalidRegNum()) {
274           toAsm << "<NULL VALUE>";
275         } else {
276           toAsm << "%" << Target.getRegInfo().getUnifiedRegName(RegNum);
277         }
278         break;
279       }
280     
281     case MachineOperand::MO_PCRelativeDisp:
282       {
283         const Value *Val = op.getVRegValue();
284         if (!Val)
285           toAsm << "\t<*NULL Value*>";
286         else if (const BasicBlock *BB = dyn_cast<const BasicBlock>(Val))
287           toAsm << getID(BB);
288         else if (const Method *M = dyn_cast<const Method>(Val))
289           toAsm << getID(M);
290         else if (const GlobalVariable *GV=dyn_cast<const GlobalVariable>(Val))
291           toAsm << getID(GV);
292         else if (const Constant *CV = dyn_cast<const Constant>(Val))
293           toAsm << getID(CV);
294         else
295           toAsm << "<unknown value=" << Val << ">";
296         break;
297       }
298     
299     case MachineOperand::MO_SignExtendedImmed:
300     case MachineOperand::MO_UnextendedImmed:
301       toAsm << (long)op.getImmedValue();
302       break;
303     
304     default:
305       toAsm << op;      // use dump field
306       break;
307     }
308 }
309
310
311 void
312 SparcMethodAsmPrinter::emitMachineInst(const MachineInstr *MI)
313 {
314   unsigned Opcode = MI->getOpCode();
315
316   if (TargetInstrDescriptors[Opcode].iclass & M_DUMMY_PHI_FLAG)
317     return;  // IGNORE PHI NODES
318
319   toAsm << "\t" << TargetInstrDescriptors[Opcode].opCodeString << "\t";
320
321   unsigned Mask = getOperandMask(Opcode);
322   
323   bool NeedComma = false;
324   unsigned N = 1;
325   for (unsigned OpNum = 0; OpNum < MI->getNumOperands(); OpNum += N)
326     if (! ((1 << OpNum) & Mask)) {        // Ignore this operand?
327       if (NeedComma) toAsm << ", ";         // Handle comma outputing
328       NeedComma = true;
329       N = printOperands(MI, OpNum);
330     }
331   else
332     N = 1;
333   
334   toAsm << "\n";
335 }
336
337 void
338 SparcMethodAsmPrinter::emitBasicBlock(const BasicBlock *BB)
339 {
340   // Emit a label for the basic block
341   toAsm << getID(BB) << ":\n";
342
343   // Get the vector of machine instructions corresponding to this bb.
344   const MachineCodeForBasicBlock &MIs = BB->getMachineInstrVec();
345   MachineCodeForBasicBlock::const_iterator MII = MIs.begin(), MIE = MIs.end();
346
347   // Loop over all of the instructions in the basic block...
348   for (; MII != MIE; ++MII)
349     emitMachineInst(*MII);
350   toAsm << "\n";  // Seperate BB's with newlines
351 }
352
353 void
354 SparcMethodAsmPrinter::emitMethod(const Method *M)
355 {
356   string methName = getID(M);
357   toAsm << "!****** Outputing Method: " << methName << " ******\n";
358   enterSection(AsmPrinter::Text);
359   toAsm << "\t.align\t4\n\t.global\t" << methName << "\n";
360   //toAsm << "\t.type\t" << methName << ",#function\n";
361   toAsm << "\t.type\t" << methName << ", 2\n";
362   toAsm << methName << ":\n";
363
364   // Output code for all of the basic blocks in the method...
365   for (Method::const_iterator I = M->begin(), E = M->end(); I != E; ++I)
366     emitBasicBlock(*I);
367
368   // Output a .size directive so the debugger knows the extents of the function
369   toAsm << ".EndOf_" << methName << ":\n\t.size "
370            << methName << ", .EndOf_"
371            << methName << "-" << methName << "\n";
372
373   // Put some spaces between the methods
374   toAsm << "\n\n";
375 }
376
377 }  // End anonymous namespace
378
379 Pass *UltraSparc::getMethodAsmPrinterPass(PassManager &PM, std::ostream &Out) {
380   return new SparcMethodAsmPrinter(Out, *this);
381 }
382
383
384
385
386
387 //===----------------------------------------------------------------------===//
388 //   SparcMethodAsmPrinter Code
389 //===----------------------------------------------------------------------===//
390
391 namespace {
392
393 class SparcModuleAsmPrinter : public Pass, public AsmPrinter {
394 public:
395   SparcModuleAsmPrinter(ostream &os, UltraSparc &t) : AsmPrinter(os, t) {}
396
397   virtual bool run(Module *M) {
398     startModule(M);
399     emitGlobalsAndConstants(M);
400     endModule();
401     return false;
402   }
403
404   void emitGlobalsAndConstants(const Module *M);
405
406   void printGlobalVariable(const GlobalVariable *GV);
407   void printSingleConstant(   const Constant* CV);
408   void printConstantValueOnly(const Constant* CV);
409   void printConstant(         const Constant* CV, std::string valID = "");
410
411   static void FoldConstants(const Module *M,
412                             std::hash_set<const Constant*> &moduleConstants);
413
414 };
415
416
417 // Can we treat the specified array as a string?  Only if it is an array of
418 // ubytes or non-negative sbytes.
419 //
420 static bool isStringCompatible(ConstantArray *CPA) {
421   const Type *ETy = cast<ArrayType>(CPA->getType())->getElementType();
422   if (ETy == Type::UByteTy) return true;
423   if (ETy != Type::SByteTy) return false;
424
425   for (unsigned i = 0; i < CPA->getNumOperands(); ++i)
426     if (cast<ConstantSInt>(CPA->getOperand(i))->getValue() < 0)
427       return false;
428
429   return true;
430 }
431
432 // toOctal - Convert the low order bits of X into an octal letter
433 static inline char toOctal(int X) {
434   return (X&7)+'0';
435 }
436
437 // getAsCString - Return the specified array as a C compatible string, only if
438 // the predicate isStringCompatible is true.
439 //
440 static string getAsCString(ConstantArray *CPA) {
441   if (isStringCompatible(CPA)) {
442     string Result;
443     const Type *ETy = cast<ArrayType>(CPA->getType())->getElementType();
444     Result = "\"";
445     for (unsigned i = 0; i < CPA->getNumOperands(); ++i) {
446       unsigned char C = (ETy == Type::SByteTy) ?
447         (unsigned char)cast<ConstantSInt>(CPA->getOperand(i))->getValue() :
448         (unsigned char)cast<ConstantUInt>(CPA->getOperand(i))->getValue();
449
450       if (isprint(C)) {
451         Result += C;
452       } else {
453         switch(C) {
454         case '\a': Result += "\\a"; break;
455         case '\b': Result += "\\b"; break;
456         case '\f': Result += "\\f"; break;
457         case '\n': Result += "\\n"; break;
458         case '\r': Result += "\\r"; break;
459         case '\t': Result += "\\t"; break;
460         case '\v': Result += "\\v"; break;
461         default:
462           Result += '\\';
463           Result += toOctal(C >> 6);
464           Result += toOctal(C >> 3);
465           Result += toOctal(C >> 0);
466           break;
467         }
468       }
469     }
470     Result += "\"";
471
472     return Result;
473   } else {
474     return CPA->getStrValue();
475   }
476 }
477
478 inline bool
479 ArrayTypeIsString(ArrayType* arrayType)
480 {
481   return (arrayType->getElementType() == Type::UByteTy ||
482           arrayType->getElementType() == Type::SByteTy);
483 }
484
485 inline const string
486 TypeToDataDirective(const Type* type)
487 {
488   switch(type->getPrimitiveID())
489     {
490     case Type::BoolTyID: case Type::UByteTyID: case Type::SByteTyID:
491       return ".byte";
492     case Type::UShortTyID: case Type::ShortTyID:
493       return ".half";
494     case Type::UIntTyID: case Type::IntTyID:
495       return ".word";
496     case Type::ULongTyID: case Type::LongTyID: case Type::PointerTyID:
497       return ".xword";
498     case Type::FloatTyID:
499       return ".single";
500     case Type::DoubleTyID:
501       return ".double";
502     case Type::ArrayTyID:
503       if (ArrayTypeIsString((ArrayType*) type))
504         return ".ascii";
505       else
506         return "<InvaliDataTypeForPrinting>";
507     default:
508       return "<InvaliDataTypeForPrinting>";
509     }
510 }
511
512 // Get the size of the constant for the given target.
513 // If this is an unsized array, return 0.
514 // 
515 inline unsigned int
516 ConstantToSize(const Constant* CV, const TargetMachine& target)
517 {
518   if (ConstantArray* CPA = dyn_cast<ConstantArray>(CV))
519     {
520       ArrayType *aty = cast<ArrayType>(CPA->getType());
521       if (ArrayTypeIsString(aty))
522         return 1 + CPA->getNumOperands();
523     }
524   
525   return target.findOptimalStorageSize(CV->getType());
526 }
527
528
529
530 // Align data larger than one L1 cache line on L1 cache line boundaries.
531 // Align all smaller data on the next higher 2^x boundary (4, 8, ...).
532 // 
533 inline unsigned int
534 SizeToAlignment(unsigned int size, const TargetMachine& target)
535 {
536   unsigned short cacheLineSize = target.getCacheInfo().getCacheLineSize(1); 
537   if (size > (unsigned) cacheLineSize / 2)
538     return cacheLineSize;
539   else
540     for (unsigned sz=1; /*no condition*/; sz *= 2)
541       if (sz >= size)
542         return sz;
543 }
544
545 // Get the size of the type and then use SizeToAlignment.
546 // 
547 inline unsigned int
548 TypeToAlignment(const Type* type, const TargetMachine& target)
549 {
550   return SizeToAlignment(target.findOptimalStorageSize(type), target);
551 }
552
553 // Get the size of the constant and then use SizeToAlignment.
554 // Handles strings as a special case;
555 inline unsigned int
556 ConstantToAlignment(const Constant* CV, const TargetMachine& target)
557 {
558   if (ConstantArray* CPA = dyn_cast<ConstantArray>(CV))
559     if (ArrayTypeIsString(cast<ArrayType>(CPA->getType())))
560       return SizeToAlignment(1 + CPA->getNumOperands(), target);
561   
562   return TypeToAlignment(CV->getType(), target);
563 }
564
565
566 // Print a single constant value.
567 void
568 SparcModuleAsmPrinter::printSingleConstant(const Constant* CV)
569 {
570   assert(CV->getType() != Type::VoidTy &&
571          CV->getType() != Type::TypeTy &&
572          CV->getType() != Type::LabelTy &&
573          "Unexpected type for Constant");
574   
575   assert((! isa<ConstantArray>( CV) && ! isa<ConstantStruct>(CV))
576          && "Collective types should be handled outside this function");
577   
578   toAsm << "\t" << TypeToDataDirective(CV->getType()) << "\t";
579   
580   if (CV->getType()->isPrimitiveType())
581     {
582       if (CV->getType() == Type::FloatTy || CV->getType() == Type::DoubleTy)
583         toAsm << "0r";                  // FP constants must have this prefix
584       toAsm << CV->getStrValue() << "\n";
585     }
586   else if (ConstantPointer* CPP = dyn_cast<ConstantPointer>(CV))
587     {
588       assert(CPP->isNullValue() &&
589              "Cannot yet print non-null pointer constants to assembly");
590       toAsm << "0\n";
591     }
592   else if (isa<ConstantPointerRef>(CV))
593     {
594       assert(0 && "Cannot yet initialize pointer refs in assembly");
595     }
596   else
597     {
598       assert(0 && "Unknown elementary type for constant");
599     }
600 }
601
602 // Print a constant value or values (it may be an aggregate).
603 // Uses printSingleConstant() to print each individual value.
604 void
605 SparcModuleAsmPrinter::printConstantValueOnly(const Constant* CV)
606 {
607   ConstantArray *CPA = dyn_cast<ConstantArray>(CV);
608   
609   if (CPA && isStringCompatible(CPA))
610     { // print the string alone and return
611       toAsm << "\t" << ".ascii" << "\t" << getAsCString(CPA) << "\n";
612     }
613   else if (CPA)
614     { // Not a string.  Print the values in successive locations
615       const std::vector<Use> &constValues = CPA->getValues();
616       for (unsigned i=1; i < constValues.size(); i++)
617         this->printConstantValueOnly(cast<Constant>(constValues[i].get()));
618     }
619   else if (ConstantStruct *CPS = dyn_cast<ConstantStruct>(CV))
620     { // Print the fields in successive locations
621       const std::vector<Use>& constValues = CPS->getValues();
622       for (unsigned i=1; i < constValues.size(); i++)
623         this->printConstantValueOnly(cast<Constant>(constValues[i].get()));
624     }
625   else
626     this->printSingleConstant(CV);
627 }
628
629 // Print a constant (which may be an aggregate) prefixed by all the
630 // appropriate directives.  Uses printConstantValueOnly() to print the
631 // value or values.
632 void
633 SparcModuleAsmPrinter::printConstant(const Constant* CV, string valID)
634 {
635   if (valID.length() == 0)
636     valID = getID(CV);
637   
638   toAsm << "\t.align\t" << ConstantToAlignment(CV, Target) << "\n";
639   
640   // Print .size and .type only if it is not a string.
641   ConstantArray *CPA = dyn_cast<ConstantArray>(CV);
642   if (CPA && isStringCompatible(CPA))
643     { // print it as a string and return
644       toAsm << valID << ":\n";
645       toAsm << "\t" << ".ascii" << "\t" << getAsCString(CPA) << "\n";
646       return;
647     }
648   
649   toAsm << "\t.type" << "\t" << valID << ",#object\n";
650
651   unsigned int constSize = ConstantToSize(CV, Target);
652   if (constSize)
653     toAsm << "\t.size" << "\t" << valID << "," << constSize << "\n";
654   
655   toAsm << valID << ":\n";
656   
657   printConstantValueOnly(CV);
658 }
659
660
661 void SparcModuleAsmPrinter::FoldConstants(const Module *M,
662                                           std::hash_set<const Constant*> &MC) {
663   for (Module::const_iterator I = M->begin(), E = M->end(); I != E; ++I)
664     if (!(*I)->isExternal()) {
665       const std::hash_set<const Constant*> &pool =
666         MachineCodeForMethod::get(*I).getConstantPoolValues();
667       MC.insert(pool.begin(), pool.end());
668     }
669 }
670
671 void SparcModuleAsmPrinter::printGlobalVariable(const GlobalVariable* GV)
672 {
673   toAsm << "\t.global\t" << getID(GV) << "\n";
674   
675   if (GV->hasInitializer())
676     printConstant(GV->getInitializer(), getID(GV));
677   else {
678     toAsm << "\t.align\t" << TypeToAlignment(GV->getType()->getElementType(),
679                                                 Target) << "\n";
680     toAsm << "\t.type\t" << getID(GV) << ",#object\n";
681     toAsm << "\t.reserve\t" << getID(GV) << ","
682           << Target.findOptimalStorageSize(GV->getType()->getElementType())
683           << "\n";
684   }
685 }
686
687
688 void SparcModuleAsmPrinter::emitGlobalsAndConstants(const Module *M) {
689   // First, get the constants there were marked by the code generator for
690   // inclusion in the assembly code data area and fold them all into a
691   // single constant pool since there may be lots of duplicates.  Also,
692   // lets force these constants into the slot table so that we can get
693   // unique names for unnamed constants also.
694   // 
695   std::hash_set<const Constant*> moduleConstants;
696   FoldConstants(M, moduleConstants);
697     
698   // Now, emit the three data sections separately; the cost of I/O should
699   // make up for the cost of extra passes over the globals list!
700   // 
701   // Read-only data section (implies initialized)
702   for (Module::const_giterator GI=M->gbegin(), GE=M->gend(); GI != GE; ++GI)
703     {
704       const GlobalVariable* GV = *GI;
705       if (GV->hasInitializer() && GV->isConstant())
706         {
707           if (GI == M->gbegin())
708             enterSection(AsmPrinter::ReadOnlyData);
709           printGlobalVariable(GV);
710         }
711     }
712   
713   for (std::hash_set<const Constant*>::const_iterator
714          I = moduleConstants.begin(),
715          E = moduleConstants.end();  I != E; ++I)
716     printConstant(*I);
717   
718   // Initialized read-write data section
719   for (Module::const_giterator GI=M->gbegin(), GE=M->gend(); GI != GE; ++GI)
720     {
721       const GlobalVariable* GV = *GI;
722       if (GV->hasInitializer() && ! GV->isConstant())
723         {
724           if (GI == M->gbegin())
725             enterSection(AsmPrinter::InitRWData);
726           printGlobalVariable(GV);
727         }
728     }
729   
730   // Uninitialized read-write data section
731   for (Module::const_giterator GI=M->gbegin(), GE=M->gend(); GI != GE; ++GI)
732     {
733       const GlobalVariable* GV = *GI;
734       if (! GV->hasInitializer())
735         {
736           if (GI == M->gbegin())
737             enterSection(AsmPrinter::UninitRWData);
738           printGlobalVariable(GV);
739         }
740     }
741   
742   toAsm << "\n";
743 }
744
745 }  // End anonymous namespace
746
747 Pass *UltraSparc::getModuleAsmPrinterPass(PassManager &PM, std::ostream &Out) {
748   return new SparcModuleAsmPrinter(Out, *this);
749 }