Add # of printed instructions statistic to both the SPARC and X86 LLC backends.
[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 necessary 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 FunctionPass and a Pass.
8 // The FunctionPass is pipelined together with all of the rest of the code
9 // generation stages, and the Pass runs at the end to emit code for global
10 // variables and such.
11 //
12 //===----------------------------------------------------------------------===//
13
14 #include "llvm/CodeGen/MachineInstr.h"
15 #include "llvm/CodeGen/MachineFunction.h"
16 #include "llvm/CodeGen/MachineFunctionInfo.h"
17 #include "llvm/Constants.h"
18 #include "llvm/DerivedTypes.h"
19 #include "llvm/Module.h"
20 #include "llvm/SlotCalculator.h"
21 #include "llvm/Pass.h"
22 #include "llvm/Assembly/Writer.h"
23 #include "Support/StringExtras.h"
24 #include "Support/Statistic.h"
25 #include "SparcInternals.h"
26 #include <string>
27
28 namespace {
29
30 Statistic<> EmittedInsts("asm-printer", "Number of machine instrs printed");
31
32 class GlobalIdTable: public Annotation {
33   static AnnotationID AnnotId;
34   friend class AsmPrinter;              // give access to AnnotId
35   
36   typedef hash_map<const Value*, int> ValIdMap;
37   typedef ValIdMap::const_iterator ValIdMapConstIterator;
38   typedef ValIdMap::      iterator ValIdMapIterator;
39 public:
40   SlotCalculator Table;    // map anonymous values to unique integer IDs
41   ValIdMap valToIdMap;     // used for values not handled by SlotCalculator 
42   
43   GlobalIdTable(Module* M) : Annotation(AnnotId), Table(M, true) {}
44 };
45
46 AnnotationID GlobalIdTable::AnnotId =
47   AnnotationManager::getID("ASM PRINTER GLOBAL TABLE ANNOT");
48   
49 //===---------------------------------------------------------------------===//
50 //   Code Shared By the two printer passes, as a mixin
51 //===---------------------------------------------------------------------===//
52
53 class AsmPrinter {
54   GlobalIdTable* idTable;
55 public:
56   std::ostream &toAsm;
57   const TargetMachine &Target;
58   
59   enum Sections {
60     Unknown,
61     Text,
62     ReadOnlyData,
63     InitRWData,
64     ZeroInitRWData,
65   } CurSection;
66
67   AsmPrinter(std::ostream &os, const TargetMachine &T)
68     : idTable(0), toAsm(os), Target(T), CurSection(Unknown) {}
69   
70   // (start|end)(Module|Function) - Callback methods to be invoked by subclasses
71   void startModule(Module &M) {
72     // Create the global id table if it does not already exist
73     idTable = (GlobalIdTable*)M.getAnnotation(GlobalIdTable::AnnotId);
74     if (idTable == NULL) {
75       idTable = new GlobalIdTable(&M);
76       M.addAnnotation(idTable);
77     }
78   }
79   void startFunction(Function &F) {
80     // Make sure the slot table has information about this function...
81     idTable->Table.incorporateFunction(&F);
82   }
83   void endFunction(Function &) {
84     idTable->Table.purgeFunction();  // Forget all about F
85   }
86   void endModule() {
87   }
88
89   // Check if a value is external or accessible from external code.
90   bool isExternal(const Value* V) {
91     const GlobalValue *GV = dyn_cast<GlobalValue>(V);
92     return GV && GV->hasExternalLinkage();
93   }
94   
95   // enterSection - Use this method to enter a different section of the output
96   // executable.  This is used to only output necessary section transitions.
97   //
98   void enterSection(enum Sections S) {
99     if (S == CurSection) return;        // Only switch section if necessary
100     CurSection = S;
101
102     toAsm << "\n\t.section ";
103     switch (S)
104       {
105       default: assert(0 && "Bad section name!");
106       case Text:         toAsm << "\".text\""; break;
107       case ReadOnlyData: toAsm << "\".rodata\",#alloc"; break;
108       case InitRWData:   toAsm << "\".data\",#alloc,#write"; break;
109       case ZeroInitRWData: toAsm << "\".bss\",#alloc,#write"; break;
110       }
111     toAsm << "\n";
112   }
113
114   static std::string getValidSymbolName(const std::string &S) {
115     std::string Result;
116     
117     // Symbol names in Sparc assembly language have these rules:
118     // (a) Must match { letter | _ | . | $ } { letter | _ | . | $ | digit }*
119     // (b) A name beginning in "." is treated as a local name.
120     // 
121     if (isdigit(S[0]))
122       Result = "ll";
123     
124     for (unsigned i = 0; i < S.size(); ++i)
125       {
126         char C = S[i];
127         if (C == '_' || C == '.' || C == '$' || isalpha(C) || isdigit(C))
128           Result += C;
129         else
130           {
131             Result += '_';
132             Result += char('0' + ((unsigned char)C >> 4));
133             Result += char('0' + (C & 0xF));
134           }
135       }
136     return Result;
137   }
138
139   // getID - Return a valid identifier for the specified value.  Base it on
140   // the name of the identifier if possible (qualified by the type), and
141   // use a numbered value based on prefix otherwise.
142   // FPrefix is always prepended to the output identifier.
143   //
144   std::string getID(const Value *V, const char *Prefix, const char *FPrefix = 0) {
145     std::string Result = FPrefix ? FPrefix : "";  // "Forced prefix"
146
147     Result += V->hasName() ? V->getName() : std::string(Prefix);
148
149     // Qualify all internal names with a unique id.
150     if (!isExternal(V)) {
151       int valId = idTable->Table.getValSlot(V);
152       if (valId == -1) {
153         GlobalIdTable::ValIdMapConstIterator I = idTable->valToIdMap.find(V);
154         if (I == idTable->valToIdMap.end())
155           valId = idTable->valToIdMap[V] = idTable->valToIdMap.size();
156         else
157           valId = I->second;
158       }
159       Result = Result + "_" + itostr(valId);
160
161       // Replace or prefix problem characters in the name
162       Result = getValidSymbolName(Result);
163     }
164
165     return Result;
166   }
167   
168   // getID Wrappers - Ensure consistent usage...
169   std::string getID(const Function *F) {
170     return getID(F, "LLVMFunction_");
171   }
172   std::string getID(const BasicBlock *BB) {
173     return getID(BB, "LL", (".L_"+getID(BB->getParent())+"_").c_str());
174   }
175   std::string getID(const GlobalVariable *GV) {
176     return getID(GV, "LLVMGlobal_");
177   }
178   std::string getID(const Constant *CV) {
179     return getID(CV, "LLVMConst_", ".C_");
180   }
181   std::string getID(const GlobalValue *GV) {
182     if (const GlobalVariable *V = dyn_cast<GlobalVariable>(GV))
183       return getID(V);
184     else if (const Function *F = dyn_cast<Function>(GV))
185       return getID(F);
186     assert(0 && "Unexpected type of GlobalValue!");
187     return "";
188   }
189
190   // Combines expressions 
191   inline std::string ConstantArithExprToString(const ConstantExpr* CE,
192                                                const TargetMachine &TM,
193                                                const std::string &op) {
194     return "(" + valToExprString(CE->getOperand(0), TM) + op
195                + valToExprString(CE->getOperand(1), TM) + ")";
196   }
197
198   // ConstantExprToString() - Convert a ConstantExpr to an asm expression
199   // and return this as a string.
200   std::string ConstantExprToString(const ConstantExpr* CE,
201                                    const TargetMachine& target) {
202     std::string S;
203     switch(CE->getOpcode()) {
204     case Instruction::GetElementPtr:
205       { // generate a symbolic expression for the byte address
206         const Value* ptrVal = CE->getOperand(0);
207         std::vector<Value*> idxVec(CE->op_begin()+1, CE->op_end());
208         const TargetData &TD = target.getTargetData();
209         S += "(" + valToExprString(ptrVal, target) + ") + ("
210           + utostr(TD.getIndexedOffset(ptrVal->getType(),idxVec)) + ")";
211         break;
212       }
213
214     case Instruction::Cast:
215       // Support only non-converting casts for now, i.e., a no-op.
216       // This assertion is not a complete check.
217       assert(target.getTargetData().getTypeSize(CE->getType()) ==
218              target.getTargetData().getTypeSize(CE->getOperand(0)->getType()));
219       S += "(" + valToExprString(CE->getOperand(0), target) + ")";
220       break;
221
222     case Instruction::Add:
223       S += ConstantArithExprToString(CE, target, ") + (");
224       break;
225
226     case Instruction::Sub:
227       S += ConstantArithExprToString(CE, target, ") - (");
228       break;
229
230     case Instruction::Mul:
231       S += ConstantArithExprToString(CE, target, ") * (");
232       break;
233
234     case Instruction::Div:
235       S += ConstantArithExprToString(CE, target, ") / (");
236       break;
237
238     case Instruction::Rem:
239       S += ConstantArithExprToString(CE, target, ") % (");
240       break;
241
242     case Instruction::And:
243       // Logical && for booleans; bitwise & otherwise
244       S += ConstantArithExprToString(CE, target,
245                ((CE->getType() == Type::BoolTy)? ") && (" : ") & ("));
246       break;
247
248     case Instruction::Or:
249       // Logical || for booleans; bitwise | otherwise
250       S += ConstantArithExprToString(CE, target,
251                ((CE->getType() == Type::BoolTy)? ") || (" : ") | ("));
252       break;
253
254     case Instruction::Xor:
255       // Bitwise ^ for all types
256       S += ConstantArithExprToString(CE, target, ") ^ (");
257       break;
258
259     default:
260       assert(0 && "Unsupported operator in ConstantExprToString()");
261       break;
262     }
263
264     return S;
265   }
266
267   // valToExprString - Helper function for ConstantExprToString().
268   // Appends result to argument string S.
269   // 
270   std::string valToExprString(const Value* V, const TargetMachine& target) {
271     std::string S;
272     bool failed = false;
273     if (const Constant* CV = dyn_cast<Constant>(V)) { // symbolic or known
274
275       if (const ConstantBool *CB = dyn_cast<ConstantBool>(CV))
276         S += std::string(CB == ConstantBool::True ? "1" : "0");
277       else if (const ConstantSInt *CI = dyn_cast<ConstantSInt>(CV))
278         S += itostr(CI->getValue());
279       else if (const ConstantUInt *CI = dyn_cast<ConstantUInt>(CV))
280         S += utostr(CI->getValue());
281       else if (const ConstantFP *CFP = dyn_cast<ConstantFP>(CV))
282         S += ftostr(CFP->getValue());
283       else if (isa<ConstantPointerNull>(CV))
284         S += "0";
285       else if (const ConstantPointerRef *CPR = dyn_cast<ConstantPointerRef>(CV))
286         S += valToExprString(CPR->getValue(), target);
287       else if (const ConstantExpr *CE = dyn_cast<ConstantExpr>(CV))
288         S += ConstantExprToString(CE, target);
289       else
290         failed = true;
291
292     } else if (const GlobalValue* GV = dyn_cast<GlobalValue>(V)) {
293       S += getID(GV);
294     }
295     else
296       failed = true;
297
298     if (failed) {
299       assert(0 && "Cannot convert value to string");
300       S += "<illegal-value>";
301     }
302     return S;
303   }
304
305 };
306
307
308
309 //===----------------------------------------------------------------------===//
310 //   SparcFunctionAsmPrinter Code
311 //===----------------------------------------------------------------------===//
312
313 struct SparcFunctionAsmPrinter : public FunctionPass, public AsmPrinter {
314   inline SparcFunctionAsmPrinter(std::ostream &os, const TargetMachine &t)
315     : AsmPrinter(os, t) {}
316
317   const char *getPassName() const {
318     return "Output Sparc Assembly for Functions";
319   }
320
321   virtual bool doInitialization(Module &M) {
322     startModule(M);
323     return false;
324   }
325
326   virtual bool runOnFunction(Function &F) {
327     startFunction(F);
328     emitFunction(F);
329     endFunction(F);
330     return false;
331   }
332
333   virtual bool doFinalization(Module &M) {
334     endModule();
335     return false;
336   }
337
338   virtual void getAnalysisUsage(AnalysisUsage &AU) const {
339     AU.setPreservesAll();
340   }
341
342   void emitFunction(const Function &F);
343 private :
344   void emitBasicBlock(const MachineBasicBlock &MBB);
345   void emitMachineInst(const MachineInstr *MI);
346   
347   unsigned int printOperands(const MachineInstr *MI, unsigned int opNum);
348   void printOneOperand(const MachineOperand &Op, MachineOpCode opCode);
349
350   bool OpIsBranchTargetLabel(const MachineInstr *MI, unsigned int opNum);
351   bool OpIsMemoryAddressBase(const MachineInstr *MI, unsigned int opNum);
352   
353   unsigned getOperandMask(unsigned Opcode) {
354     switch (Opcode) {
355     case V9::SUBccr:
356     case V9::SUBcci:   return 1 << 3;  // Remove CC argument
357   //case BA:      return 1 << 0;  // Remove Arg #0, which is always null or xcc
358     default:      return 0;       // By default, don't hack operands...
359     }
360   }
361 };
362
363 inline bool
364 SparcFunctionAsmPrinter::OpIsBranchTargetLabel(const MachineInstr *MI,
365                                                unsigned int opNum) {
366   switch (MI->getOpCode()) {
367   case V9::JMPLCALLr:
368   case V9::JMPLCALLi:
369   case V9::JMPLRETr:
370   case V9::JMPLRETi:
371     return (opNum == 0);
372   default:
373     return false;
374   }
375 }
376
377
378 inline bool
379 SparcFunctionAsmPrinter::OpIsMemoryAddressBase(const MachineInstr *MI,
380                                                unsigned int opNum) {
381   if (Target.getInstrInfo().isLoad(MI->getOpCode()))
382     return (opNum == 0);
383   else if (Target.getInstrInfo().isStore(MI->getOpCode()))
384     return (opNum == 1);
385   else
386     return false;
387 }
388
389
390 #define PrintOp1PlusOp2(mop1, mop2, opCode) \
391   printOneOperand(mop1, opCode); \
392   toAsm << "+"; \
393   printOneOperand(mop2, opCode);
394
395 unsigned int
396 SparcFunctionAsmPrinter::printOperands(const MachineInstr *MI,
397                                unsigned int opNum)
398 {
399   const MachineOperand& mop = MI->getOperand(opNum);
400   
401   if (OpIsBranchTargetLabel(MI, opNum))
402     {
403       PrintOp1PlusOp2(mop, MI->getOperand(opNum+1), MI->getOpCode());
404       return 2;
405     }
406   else if (OpIsMemoryAddressBase(MI, opNum))
407     {
408       toAsm << "[";
409       PrintOp1PlusOp2(mop, MI->getOperand(opNum+1), MI->getOpCode());
410       toAsm << "]";
411       return 2;
412     }
413   else
414     {
415       printOneOperand(mop, MI->getOpCode());
416       return 1;
417     }
418 }
419
420 void
421 SparcFunctionAsmPrinter::printOneOperand(const MachineOperand &mop,
422                                          MachineOpCode opCode)
423 {
424   bool needBitsFlag = true;
425   
426   if (mop.opHiBits32())
427     toAsm << "%lm(";
428   else if (mop.opLoBits32())
429     toAsm << "%lo(";
430   else if (mop.opHiBits64())
431     toAsm << "%hh(";
432   else if (mop.opLoBits64())
433     toAsm << "%hm(";
434   else
435     needBitsFlag = false;
436   
437   switch (mop.getType())
438     {
439     case MachineOperand::MO_VirtualRegister:
440     case MachineOperand::MO_CCRegister:
441     case MachineOperand::MO_MachineRegister:
442       {
443         int regNum = (int)mop.getAllocatedRegNum();
444         
445         if (regNum == Target.getRegInfo().getInvalidRegNum()) {
446           // better to print code with NULL registers than to die
447           toAsm << "<NULL VALUE>";
448         } else {
449           toAsm << "%" << Target.getRegInfo().getUnifiedRegName(regNum);
450         }
451         break;
452       }
453     
454     case MachineOperand::MO_PCRelativeDisp:
455       {
456         const Value *Val = mop.getVRegValue();
457         assert(Val && "\tNULL Value in SparcFunctionAsmPrinter");
458         
459         if (const BasicBlock *BB = dyn_cast<BasicBlock>(Val))
460           toAsm << getID(BB);
461         else if (const Function *M = dyn_cast<Function>(Val))
462           toAsm << getID(M);
463         else if (const GlobalVariable *GV = dyn_cast<GlobalVariable>(Val))
464           toAsm << getID(GV);
465         else if (const Constant *CV = dyn_cast<Constant>(Val))
466           toAsm << getID(CV);
467         else
468           assert(0 && "Unrecognized value in SparcFunctionAsmPrinter");
469         break;
470       }
471     
472     case MachineOperand::MO_SignExtendedImmed:
473       toAsm << mop.getImmedValue();
474       break;
475
476     case MachineOperand::MO_UnextendedImmed:
477       toAsm << (uint64_t) mop.getImmedValue();
478       break;
479     
480     default:
481       toAsm << mop;      // use dump field
482       break;
483     }
484   
485   if (needBitsFlag)
486     toAsm << ")";
487 }
488
489 void
490 SparcFunctionAsmPrinter::emitMachineInst(const MachineInstr *MI)
491 {
492   unsigned Opcode = MI->getOpCode();
493
494   if (Target.getInstrInfo().isDummyPhiInstr(Opcode))
495     return;  // IGNORE PHI NODES
496
497   toAsm << "\t" << Target.getInstrInfo().getName(Opcode) << "\t";
498
499   unsigned Mask = getOperandMask(Opcode);
500   
501   bool NeedComma = false;
502   unsigned N = 1;
503   for (unsigned OpNum = 0; OpNum < MI->getNumOperands(); OpNum += N)
504     if (! ((1 << OpNum) & Mask)) {        // Ignore this operand?
505       if (NeedComma) toAsm << ", ";         // Handle comma outputting
506       NeedComma = true;
507       N = printOperands(MI, OpNum);
508     } else
509       N = 1;
510   
511   toAsm << "\n";
512   ++EmittedInsts;
513 }
514
515 void
516 SparcFunctionAsmPrinter::emitBasicBlock(const MachineBasicBlock &MBB)
517 {
518   // Emit a label for the basic block
519   toAsm << getID(MBB.getBasicBlock()) << ":\n";
520
521   // Loop over all of the instructions in the basic block...
522   for (MachineBasicBlock::const_iterator MII = MBB.begin(), MIE = MBB.end();
523        MII != MIE; ++MII)
524     emitMachineInst(*MII);
525   toAsm << "\n";  // Separate BB's with newlines
526 }
527
528 void
529 SparcFunctionAsmPrinter::emitFunction(const Function &F)
530 {
531   std::string methName = getID(&F);
532   toAsm << "!****** Outputing Function: " << methName << " ******\n";
533   enterSection(AsmPrinter::Text);
534   toAsm << "\t.align\t4\n\t.global\t" << methName << "\n";
535   //toAsm << "\t.type\t" << methName << ",#function\n";
536   toAsm << "\t.type\t" << methName << ", 2\n";
537   toAsm << methName << ":\n";
538
539   // Output code for all of the basic blocks in the function...
540   MachineFunction &MF = MachineFunction::get(&F);
541   for (MachineFunction::const_iterator I = MF.begin(), E = MF.end(); I != E;++I)
542     emitBasicBlock(*I);
543
544   // Output a .size directive so the debugger knows the extents of the function
545   toAsm << ".EndOf_" << methName << ":\n\t.size "
546            << methName << ", .EndOf_"
547            << methName << "-" << methName << "\n";
548
549   // Put some spaces between the functions
550   toAsm << "\n\n";
551 }
552
553 }  // End anonymous namespace
554
555 Pass *UltraSparc::getFunctionAsmPrinterPass(std::ostream &Out) {
556   return new SparcFunctionAsmPrinter(Out, *this);
557 }
558
559
560
561
562
563 //===----------------------------------------------------------------------===//
564 //   SparcFunctionAsmPrinter Code
565 //===----------------------------------------------------------------------===//
566
567 namespace {
568
569 class SparcModuleAsmPrinter : public Pass, public AsmPrinter {
570 public:
571   SparcModuleAsmPrinter(std::ostream &os, TargetMachine &t)
572     : AsmPrinter(os, t) {}
573
574   const char *getPassName() const { return "Output Sparc Assembly for Module"; }
575
576   virtual bool run(Module &M) {
577     startModule(M);
578     emitGlobalsAndConstants(M);
579     endModule();
580     return false;
581   }
582
583   virtual void getAnalysisUsage(AnalysisUsage &AU) const {
584     AU.setPreservesAll();
585   }
586
587 private:
588   void emitGlobalsAndConstants  (const Module &M);
589
590   void printGlobalVariable      (const GlobalVariable *GV);
591   void PrintZeroBytesToPad      (int numBytes);
592   void printSingleConstantValue (const Constant* CV);
593   void printConstantValueOnly   (const Constant* CV, int numPadBytesAfter = 0);
594   void printConstant            (const Constant* CV, std::string valID = "");
595
596   static void FoldConstants     (const Module &M,
597                                  hash_set<const Constant*> &moduleConstants);
598 };
599
600
601 // Can we treat the specified array as a string?  Only if it is an array of
602 // ubytes or non-negative sbytes.
603 //
604 static bool isStringCompatible(const ConstantArray *CVA) {
605   const Type *ETy = cast<ArrayType>(CVA->getType())->getElementType();
606   if (ETy == Type::UByteTy) return true;
607   if (ETy != Type::SByteTy) return false;
608
609   for (unsigned i = 0; i < CVA->getNumOperands(); ++i)
610     if (cast<ConstantSInt>(CVA->getOperand(i))->getValue() < 0)
611       return false;
612
613   return true;
614 }
615
616 // toOctal - Convert the low order bits of X into an octal letter
617 static inline char toOctal(int X) {
618   return (X&7)+'0';
619 }
620
621 // getAsCString - Return the specified array as a C compatible string, only if
622 // the predicate isStringCompatible is true.
623 //
624 static std::string getAsCString(const ConstantArray *CVA) {
625   assert(isStringCompatible(CVA) && "Array is not string compatible!");
626
627   std::string Result;
628   const Type *ETy = cast<ArrayType>(CVA->getType())->getElementType();
629   Result = "\"";
630   for (unsigned i = 0; i < CVA->getNumOperands(); ++i) {
631     unsigned char C = cast<ConstantInt>(CVA->getOperand(i))->getRawValue();
632
633     if (C == '"') {
634       Result += "\\\"";
635     } else if (C == '\\') {
636       Result += "\\\\";
637     } else if (isprint(C)) {
638       Result += C;
639     } else {
640       Result += '\\';                   // print all other chars as octal value
641       Result += toOctal(C >> 6);
642       Result += toOctal(C >> 3);
643       Result += toOctal(C >> 0);
644     }
645   }
646   Result += "\"";
647
648   return Result;
649 }
650
651 inline bool
652 ArrayTypeIsString(const ArrayType* arrayType)
653 {
654   return (arrayType->getElementType() == Type::UByteTy ||
655           arrayType->getElementType() == Type::SByteTy);
656 }
657
658
659 inline const std::string
660 TypeToDataDirective(const Type* type)
661 {
662   switch(type->getPrimitiveID())
663     {
664     case Type::BoolTyID: case Type::UByteTyID: case Type::SByteTyID:
665       return ".byte";
666     case Type::UShortTyID: case Type::ShortTyID:
667       return ".half";
668     case Type::UIntTyID: case Type::IntTyID:
669       return ".word";
670     case Type::ULongTyID: case Type::LongTyID: case Type::PointerTyID:
671       return ".xword";
672     case Type::FloatTyID:
673       return ".word";
674     case Type::DoubleTyID:
675       return ".xword";
676     case Type::ArrayTyID:
677       if (ArrayTypeIsString((ArrayType*) type))
678         return ".ascii";
679       else
680         return "<InvaliDataTypeForPrinting>";
681     default:
682       return "<InvaliDataTypeForPrinting>";
683     }
684 }
685
686 // Get the size of the type
687 // 
688 inline unsigned int
689 TypeToSize(const Type* type, const TargetMachine& target)
690 {
691   return target.findOptimalStorageSize(type);
692 }
693
694 // Get the size of the constant for the given target.
695 // If this is an unsized array, return 0.
696 // 
697 inline unsigned int
698 ConstantToSize(const Constant* CV, const TargetMachine& target)
699 {
700   if (const ConstantArray* CVA = dyn_cast<ConstantArray>(CV))
701     {
702       const ArrayType *aty = cast<ArrayType>(CVA->getType());
703       if (ArrayTypeIsString(aty))
704         return 1 + CVA->getNumOperands();
705     }
706   
707   return TypeToSize(CV->getType(), target);
708 }
709
710 // Align data larger than one L1 cache line on L1 cache line boundaries.
711 // Align all smaller data on the next higher 2^x boundary (4, 8, ...).
712 // 
713 inline unsigned int
714 SizeToAlignment(unsigned int size, const TargetMachine& target)
715 {
716   unsigned short cacheLineSize = target.getCacheInfo().getCacheLineSize(1); 
717   if (size > (unsigned) cacheLineSize / 2)
718     return cacheLineSize;
719   else
720     for (unsigned sz=1; /*no condition*/; sz *= 2)
721       if (sz >= size)
722         return sz;
723 }
724
725 // Get the size of the type and then use SizeToAlignment.
726 // 
727 inline unsigned int
728 TypeToAlignment(const Type* type, const TargetMachine& target)
729 {
730   return SizeToAlignment(TypeToSize(type, target), target);
731 }
732
733 // Get the size of the constant and then use SizeToAlignment.
734 // Handles strings as a special case;
735 inline unsigned int
736 ConstantToAlignment(const Constant* CV, const TargetMachine& target)
737 {
738   if (const ConstantArray* CVA = dyn_cast<ConstantArray>(CV))
739     if (ArrayTypeIsString(cast<ArrayType>(CVA->getType())))
740       return SizeToAlignment(1 + CVA->getNumOperands(), target);
741   
742   return TypeToAlignment(CV->getType(), target);
743 }
744
745
746 // Print a single constant value.
747 void
748 SparcModuleAsmPrinter::printSingleConstantValue(const Constant* CV)
749 {
750   assert(CV->getType() != Type::VoidTy &&
751          CV->getType() != Type::TypeTy &&
752          CV->getType() != Type::LabelTy &&
753          "Unexpected type for Constant");
754   
755   assert((!isa<ConstantArray>(CV) && ! isa<ConstantStruct>(CV))
756          && "Aggregate types should be handled outside this function");
757   
758   toAsm << "\t" << TypeToDataDirective(CV->getType()) << "\t";
759   
760   if (const ConstantPointerRef* CPR = dyn_cast<ConstantPointerRef>(CV))
761     { // This is a constant address for a global variable or method.
762       // Use the name of the variable or method as the address value.
763       assert(isa<GlobalValue>(CPR->getValue()) && "Unexpected non-global");
764       toAsm << getID(CPR->getValue()) << "\n";
765     }
766   else if (isa<ConstantPointerNull>(CV))
767     { // Null pointer value
768       toAsm << "0\n";
769     }
770   else if (const ConstantExpr* CE = dyn_cast<ConstantExpr>(CV))
771     { // Constant expression built from operators, constants, and symbolic addrs
772       toAsm << ConstantExprToString(CE, Target) << "\n";
773     }
774   else if (CV->getType()->isPrimitiveType())     // Check primitive types last
775     {
776       if (CV->getType()->isFloatingPoint()) {
777         // FP Constants are printed as integer constants to avoid losing
778         // precision...
779         double Val = cast<ConstantFP>(CV)->getValue();
780         if (CV->getType() == Type::FloatTy) {
781           float FVal = (float)Val;
782           char *ProxyPtr = (char*)&FVal;        // Abide by C TBAA rules
783           toAsm << *(unsigned int*)ProxyPtr;            
784         } else if (CV->getType() == Type::DoubleTy) {
785           char *ProxyPtr = (char*)&Val;         // Abide by C TBAA rules
786           toAsm << *(uint64_t*)ProxyPtr;            
787         } else {
788           assert(0 && "Unknown floating point type!");
789         }
790         
791         toAsm << "\t! " << CV->getType()->getDescription()
792               << " value: " << Val << "\n";
793       } else {
794         WriteAsOperand(toAsm, CV, false, false) << "\n";
795       }
796     }
797   else
798     {
799       assert(0 && "Unknown elementary type for constant");
800     }
801 }
802
803 void
804 SparcModuleAsmPrinter::PrintZeroBytesToPad(int numBytes)
805 {
806   for ( ; numBytes >= 8; numBytes -= 8)
807     printSingleConstantValue(Constant::getNullValue(Type::ULongTy));
808
809   if (numBytes >= 4)
810     {
811       printSingleConstantValue(Constant::getNullValue(Type::UIntTy));
812       numBytes -= 4;
813     }
814
815   while (numBytes--)
816     printSingleConstantValue(Constant::getNullValue(Type::UByteTy));
817 }
818
819 // Print a constant value or values (it may be an aggregate).
820 // Uses printSingleConstantValue() to print each individual value.
821 void
822 SparcModuleAsmPrinter::printConstantValueOnly(const Constant* CV,
823                                               int numPadBytesAfter /* = 0*/)
824 {
825   const ConstantArray *CVA = dyn_cast<ConstantArray>(CV);
826
827   if (CVA && isStringCompatible(CVA))
828     { // print the string alone and return
829       toAsm << "\t" << ".ascii" << "\t" << getAsCString(CVA) << "\n";
830     }
831   else if (CVA)
832     { // Not a string.  Print the values in successive locations
833       const std::vector<Use> &constValues = CVA->getValues();
834       for (unsigned i=0; i < constValues.size(); i++)
835         printConstantValueOnly(cast<Constant>(constValues[i].get()));
836     }
837   else if (const ConstantStruct *CVS = dyn_cast<ConstantStruct>(CV))
838     { // Print the fields in successive locations. Pad to align if needed!
839       const StructLayout *cvsLayout =
840         Target.getTargetData().getStructLayout(CVS->getType());
841       const std::vector<Use>& constValues = CVS->getValues();
842       unsigned sizeSoFar = 0;
843       for (unsigned i=0, N = constValues.size(); i < N; i++)
844         {
845           const Constant* field = cast<Constant>(constValues[i].get());
846
847           // Check if padding is needed and insert one or more 0s.
848           unsigned fieldSize =
849             Target.getTargetData().getTypeSize(field->getType());
850           int padSize = ((i == N-1? cvsLayout->StructSize
851                                   : cvsLayout->MemberOffsets[i+1])
852                          - cvsLayout->MemberOffsets[i]) - fieldSize;
853           sizeSoFar += (fieldSize + padSize);
854
855           // Now print the actual field value
856           printConstantValueOnly(field, padSize);
857         }
858       assert(sizeSoFar == cvsLayout->StructSize &&
859              "Layout of constant struct may be incorrect!");
860     }
861   else
862     printSingleConstantValue(CV);
863
864   if (numPadBytesAfter)
865     PrintZeroBytesToPad(numPadBytesAfter);
866 }
867
868 // Print a constant (which may be an aggregate) prefixed by all the
869 // appropriate directives.  Uses printConstantValueOnly() to print the
870 // value or values.
871 void
872 SparcModuleAsmPrinter::printConstant(const Constant* CV, std::string valID)
873 {
874   if (valID.length() == 0)
875     valID = getID(CV);
876   
877   toAsm << "\t.align\t" << ConstantToAlignment(CV, Target) << "\n";
878   
879   // Print .size and .type only if it is not a string.
880   const ConstantArray *CVA = dyn_cast<ConstantArray>(CV);
881   if (CVA && isStringCompatible(CVA))
882     { // print it as a string and return
883       toAsm << valID << ":\n";
884       toAsm << "\t" << ".ascii" << "\t" << getAsCString(CVA) << "\n";
885       return;
886     }
887   
888   toAsm << "\t.type" << "\t" << valID << ",#object\n";
889
890   unsigned int constSize = ConstantToSize(CV, Target);
891   if (constSize)
892     toAsm << "\t.size" << "\t" << valID << "," << constSize << "\n";
893   
894   toAsm << valID << ":\n";
895   
896   printConstantValueOnly(CV);
897 }
898
899
900 void SparcModuleAsmPrinter::FoldConstants(const Module &M,
901                                           hash_set<const Constant*> &MC) {
902   for (Module::const_iterator I = M.begin(), E = M.end(); I != E; ++I)
903     if (!I->isExternal()) {
904       const hash_set<const Constant*> &pool =
905         MachineFunction::get(I).getInfo()->getConstantPoolValues();
906       MC.insert(pool.begin(), pool.end());
907     }
908 }
909
910 void SparcModuleAsmPrinter::printGlobalVariable(const GlobalVariable* GV)
911 {
912   if (GV->hasExternalLinkage())
913     toAsm << "\t.global\t" << getID(GV) << "\n";
914   
915   if (GV->hasInitializer() && ! GV->getInitializer()->isNullValue())
916     printConstant(GV->getInitializer(), getID(GV));
917   else {
918     toAsm << "\t.align\t" << TypeToAlignment(GV->getType()->getElementType(),
919                                                 Target) << "\n";
920     toAsm << "\t.type\t" << getID(GV) << ",#object\n";
921     toAsm << "\t.reserve\t" << getID(GV) << ","
922           << TypeToSize(GV->getType()->getElementType(), Target)
923           << "\n";
924   }
925 }
926
927
928 void SparcModuleAsmPrinter::emitGlobalsAndConstants(const Module &M) {
929   // First, get the constants there were marked by the code generator for
930   // inclusion in the assembly code data area and fold them all into a
931   // single constant pool since there may be lots of duplicates.  Also,
932   // lets force these constants into the slot table so that we can get
933   // unique names for unnamed constants also.
934   // 
935   hash_set<const Constant*> moduleConstants;
936   FoldConstants(M, moduleConstants);
937     
938   // Output constants spilled to memory
939   enterSection(AsmPrinter::ReadOnlyData);
940   for (hash_set<const Constant*>::const_iterator I = moduleConstants.begin(),
941          E = moduleConstants.end();  I != E; ++I)
942     printConstant(*I);
943
944   // Output global variables...
945   for (Module::const_giterator GI = M.gbegin(), GE = M.gend(); GI != GE; ++GI)
946     if (! GI->isExternal()) {
947       assert(GI->hasInitializer());
948       if (GI->isConstant())
949         enterSection(AsmPrinter::ReadOnlyData);   // read-only, initialized data
950       else if (GI->getInitializer()->isNullValue())
951         enterSection(AsmPrinter::ZeroInitRWData); // read-write zero data
952       else
953         enterSection(AsmPrinter::InitRWData);     // read-write non-zero data
954
955       printGlobalVariable(GI);
956     }
957
958   toAsm << "\n";
959 }
960
961 }  // End anonymous namespace
962
963 Pass *UltraSparc::getModuleAsmPrinterPass(std::ostream &Out) {
964   return new SparcModuleAsmPrinter(Out, *this);
965 }