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