Handle GhostLinkage (should not ever reach the assembly printing stage!)
[oota-llvm.git] / lib / Target / PowerPC / PPCAsmPrinter.cpp
1 //===-- PowerPCAsmPrinter.cpp - Print machine instrs to PowerPC assembly --===//
2 // 
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file was developed by the LLVM research group and is distributed under
6 // the University of Illinois Open Source License. See LICENSE.TXT for details.
7 // 
8 //===----------------------------------------------------------------------===//
9 //
10 // This file contains a printer that converts from our internal representation
11 // of machine-dependent LLVM code to PowerPC assembly language. This printer is
12 // the output mechanism used by `llc'.
13 //
14 // Documentation at http://developer.apple.com/documentation/DeveloperTools/
15 // Reference/Assembler/ASMIntroduction/chapter_1_section_1.html
16 //
17 //===----------------------------------------------------------------------===//
18
19 #define DEBUG_TYPE "asmprinter"
20 #include "PowerPC.h"
21 #include "PowerPCTargetMachine.h"
22 #include "llvm/Constants.h"
23 #include "llvm/DerivedTypes.h"
24 #include "llvm/Module.h"
25 #include "llvm/Assembly/Writer.h"
26 #include "llvm/CodeGen/AsmPrinter.h"
27 #include "llvm/CodeGen/MachineConstantPool.h"
28 #include "llvm/CodeGen/MachineFunctionPass.h"
29 #include "llvm/CodeGen/MachineInstr.h"
30 #include "llvm/CodeGen/ValueTypes.h"
31 #include "llvm/Support/Mangler.h"
32 #include "llvm/Support/MathExtras.h"
33 #include "llvm/Support/CommandLine.h"
34 #include "llvm/Support/Debug.h"
35 #include "llvm/Target/MRegisterInfo.h"
36 #include "llvm/ADT/Statistic.h"
37 #include "llvm/ADT/StringExtras.h"
38 #include <set>
39 using namespace llvm;
40
41 namespace {
42   Statistic<> EmittedInsts("asm-printer", "Number of machine instrs printed");
43
44   struct PowerPCAsmPrinter : public AsmPrinter {
45     std::set<std::string> FnStubs, GVStubs, LinkOnceStubs;
46     std::set<std::string> Strings;
47     
48     PowerPCAsmPrinter(std::ostream &O, TargetMachine &TM)
49       : AsmPrinter(O, TM), LabelNumber(0) {}
50
51     /// Unique incrementer for label values for referencing Global values.
52     ///
53     unsigned LabelNumber;
54   
55     virtual const char *getPassName() const {
56       return "PowerPC Assembly Printer";
57     }
58
59     PowerPCTargetMachine &getTM() {
60       return static_cast<PowerPCTargetMachine&>(TM);
61     }
62
63     /// printInstruction - This method is automatically generated by tablegen
64     /// from the instruction set description.  This method returns true if the
65     /// machine instruction was sufficiently described to print it, otherwise it
66     /// returns false.
67     bool printInstruction(const MachineInstr *MI);
68
69     void printMachineInstruction(const MachineInstr *MI);
70     void printOp(const MachineOperand &MO, bool LoadAddrOp = false);
71
72     void printOperand(const MachineInstr *MI, unsigned OpNo, MVT::ValueType VT){
73       const MachineOperand &MO = MI->getOperand(OpNo);
74       if (MO.getType() == MachineOperand::MO_MachineRegister) {
75         assert(MRegisterInfo::isPhysicalRegister(MO.getReg())&&"Not physreg??");
76         O << LowercaseString(TM.getRegisterInfo()->get(MO.getReg()).Name);
77       } else if (MO.isImmediate()) {
78         O << MO.getImmedValue();
79       } else {
80         printOp(MO);
81       }
82     }
83
84     void printU5ImmOperand(const MachineInstr *MI, unsigned OpNo,
85                             MVT::ValueType VT) {
86       unsigned char value = MI->getOperand(OpNo).getImmedValue();
87       assert(value <= 31 && "Invalid u5imm argument!");
88       O << (unsigned int)value;
89     }
90     void printU6ImmOperand(const MachineInstr *MI, unsigned OpNo,
91                             MVT::ValueType VT) {
92       unsigned char value = MI->getOperand(OpNo).getImmedValue();
93       assert(value <= 63 && "Invalid u6imm argument!");
94       O << (unsigned int)value;
95     }
96     void printS16ImmOperand(const MachineInstr *MI, unsigned OpNo,
97                             MVT::ValueType VT) {
98       O << (short)MI->getOperand(OpNo).getImmedValue();
99     }
100     void printU16ImmOperand(const MachineInstr *MI, unsigned OpNo,
101                             MVT::ValueType VT) {
102       O << (unsigned short)MI->getOperand(OpNo).getImmedValue();
103     }
104     void printBranchOperand(const MachineInstr *MI, unsigned OpNo,
105                             MVT::ValueType VT) {
106       // Branches can take an immediate operand.  This is used by the branch
107       // selection pass to print $+8, an eight byte displacement from the PC.
108       if (MI->getOperand(OpNo).isImmediate()) {
109         O << "$+" << MI->getOperand(OpNo).getImmedValue() << '\n';
110       } else {
111         printOp(MI->getOperand(OpNo));
112       }
113     }
114     void printPICLabel(const MachineInstr *MI, unsigned OpNo,
115                        MVT::ValueType VT) {
116       // FIXME: should probably be converted to cout.width and cout.fill
117       O << "\"L0000" << LabelNumber << "$pb\"\n";
118       O << "\"L0000" << LabelNumber << "$pb\":";
119     }
120     void printSymbolHi(const MachineInstr *MI, unsigned OpNo,
121                        MVT::ValueType VT) {
122       O << "ha16(";
123       printOp(MI->getOperand(OpNo), true /* LoadAddrOp */);
124       O << "-\"L0000" << LabelNumber << "$pb\")";
125     }
126     void printSymbolLo(const MachineInstr *MI, unsigned OpNo,
127                        MVT::ValueType VT) {
128       // FIXME: Because LFS, LFD, and LWZ can be used either with a s16imm or
129       // a lo16 of a global or constant pool operand, we must handle both here.
130       // this isn't a great design, but it works for now.
131       if (MI->getOperand(OpNo).isImmediate()) {
132         O << (short)MI->getOperand(OpNo).getImmedValue();
133       } else {
134         O << "lo16(";
135         printOp(MI->getOperand(OpNo), true /* LoadAddrOp */);
136         O << "-\"L0000" << LabelNumber << "$pb\")";
137       }
138     }
139   
140     virtual void printConstantPool(MachineConstantPool *MCP) = 0;
141     virtual bool runOnMachineFunction(MachineFunction &F) = 0;    
142     virtual bool doFinalization(Module &M) = 0;
143   };
144   
145   /// DarwinAsmPrinter - PowerPC assembly printer, customized for Darwin/Mac OS
146   /// X
147   ///
148   struct DarwinAsmPrinter : public PowerPCAsmPrinter {
149
150     DarwinAsmPrinter(std::ostream &O, TargetMachine &TM)
151       : PowerPCAsmPrinter(O, TM) {
152       CommentString = ";";
153       GlobalPrefix = "_";
154       ZeroDirective = "\t.space\t";  // ".space N" emits N zeros.
155       Data64bitsDirective = 0;       // we can't emit a 64-bit unit
156       AlignmentIsInBytes = false;    // Alignment is by power of 2.
157     }
158
159     virtual const char *getPassName() const {
160       return "Darwin PPC Assembly Printer";
161     }
162
163     void printConstantPool(MachineConstantPool *MCP);
164     bool runOnMachineFunction(MachineFunction &F);    
165     bool doFinalization(Module &M);
166   };
167   
168   /// AIXAsmPrinter - PowerPC assembly printer, customized for AIX
169   ///
170   struct AIXAsmPrinter : public PowerPCAsmPrinter {
171     /// Map for labels corresponding to global variables
172     ///
173     std::map<const GlobalVariable*,std::string> GVToLabelMap;
174
175     AIXAsmPrinter(std::ostream &O, TargetMachine &TM)
176       : PowerPCAsmPrinter(O, TM) {
177       CommentString = "#";
178       GlobalPrefix = "_";
179       ZeroDirective = "\t.space\t";  // ".space N" emits N zeros.
180       Data64bitsDirective = 0;       // we can't emit a 64-bit unit
181       AlignmentIsInBytes = false;    // Alignment is by power of 2.
182     }
183     
184     virtual const char *getPassName() const {
185       return "AIX PPC Assembly Printer";
186     }
187
188     void printConstantPool(MachineConstantPool *MCP);
189     bool runOnMachineFunction(MachineFunction &F);    
190     bool doInitialization(Module &M);
191     bool doFinalization(Module &M);
192   };
193 } // end of anonymous namespace
194
195 // SwitchSection - Switch to the specified section of the executable if we are
196 // not already in it!
197 //
198 static void SwitchSection(std::ostream &OS, std::string &CurSection,
199                           const char *NewSection) {
200   if (CurSection != NewSection) {
201     CurSection = NewSection;
202     if (!CurSection.empty())
203       OS << "\t" << NewSection << "\n";
204   }
205 }
206
207 /// isStringCompatible - Can we treat the specified array as a string?
208 /// Only if it is an array of ubytes or non-negative sbytes.
209 ///
210 static bool isStringCompatible(const ConstantArray *CVA) {
211   const Type *ETy = cast<ArrayType>(CVA->getType())->getElementType();
212   if (ETy == Type::UByteTy) return true;
213   if (ETy != Type::SByteTy) return false;
214
215   for (unsigned i = 0; i < CVA->getNumOperands(); ++i)
216     if (cast<ConstantSInt>(CVA->getOperand(i))->getValue() < 0)
217       return false;
218
219   return true;
220 }
221
222 /// toOctal - Convert the low order bits of X into an octal digit.
223 ///
224 static inline char toOctal(int X) {
225   return (X&7)+'0';
226 }
227
228 // Possible states while outputting ASCII strings
229 namespace {
230   enum StringSection {
231     None,
232     Alpha,
233     Numeric
234   };
235 }
236
237 /// SwitchStringSection - manage the changes required to output bytes as
238 /// characters in a string vs. numeric decimal values
239 /// 
240 static inline void SwitchStringSection(std::ostream &O, StringSection NewSect,
241                                        StringSection &Current) {
242   if (Current == None) {
243     if (NewSect == Alpha)
244       O << "\t.byte \"";
245     else if (NewSect == Numeric)
246       O << "\t.byte ";
247   } else if (Current == Alpha) {
248     if (NewSect == None)
249       O << "\"";
250     else if (NewSect == Numeric) 
251       O << "\"\n"
252         << "\t.byte ";
253   } else if (Current == Numeric) {
254     if (NewSect == Alpha)
255       O << '\n'
256         << "\t.byte \"";
257     else if (NewSect == Numeric)
258       O << ", ";
259   }
260
261   Current = NewSect;
262 }
263
264 /// getAsCString - Return the specified array as a C compatible
265 /// string, only if the predicate isStringCompatible is true.
266 ///
267 static void printAsCString(std::ostream &O, const ConstantArray *CVA) {
268   assert(isStringCompatible(CVA) && "Array is not string compatible!");
269
270   if (CVA->getNumOperands() == 0)
271     return;
272
273   StringSection Current = None;
274   for (unsigned i = 0, e = CVA->getNumOperands(); i != e; ++i) {
275     unsigned char C = cast<ConstantInt>(CVA->getOperand(i))->getRawValue();
276     if (C == '"') {
277       SwitchStringSection(O, Alpha, Current);
278       O << "\"\"";
279     } else if (isprint(C)) {
280       SwitchStringSection(O, Alpha, Current);
281       O << C;
282     } else {
283       SwitchStringSection(O, Numeric, Current);
284       O << utostr((unsigned)C);
285     }
286   }
287   SwitchStringSection(O, None, Current);
288   O << '\n';
289 }
290
291 /// createDarwinAsmPrinterPass - Returns a pass that prints the PPC assembly 
292 /// code for a MachineFunction to the given output stream, in a format that the 
293 /// Darwin assembler can deal with.
294 ///
295 FunctionPass *llvm::createDarwinAsmPrinter(std::ostream &o, TargetMachine &tm) {
296   return new DarwinAsmPrinter(o, tm);
297 }
298
299 /// createAIXAsmPrinterPass - Returns a pass that prints the PPC assembly code
300 /// for a MachineFunction to the given output stream, in a format that the 
301 /// AIX 5L assembler can deal with.
302 ///
303 FunctionPass *llvm::createAIXAsmPrinter(std::ostream &o, TargetMachine &tm) {
304   return new AIXAsmPrinter(o, tm);
305 }
306
307 // Include the auto-generated portion of the assembly writer
308 #include "PowerPCGenAsmWriter.inc"
309
310 void PowerPCAsmPrinter::printOp(const MachineOperand &MO,
311                               bool LoadAddrOp /* = false */) {
312   const MRegisterInfo &RI = *TM.getRegisterInfo();
313   int new_symbol;
314   
315   switch (MO.getType()) {
316   case MachineOperand::MO_VirtualRegister:
317     if (Value *V = MO.getVRegValueOrNull()) {
318       O << "<" << V->getName() << ">";
319       return;
320     }
321     // FALLTHROUGH
322   case MachineOperand::MO_MachineRegister:
323   case MachineOperand::MO_CCRegister:
324     O << LowercaseString(RI.get(MO.getReg()).Name);
325     return;
326
327   case MachineOperand::MO_SignExtendedImmed:
328   case MachineOperand::MO_UnextendedImmed:
329     std::cerr << "printOp() does not handle immediate values\n";
330     abort();
331     return;
332
333   case MachineOperand::MO_PCRelativeDisp:
334     std::cerr << "Shouldn't use addPCDisp() when building PPC MachineInstrs";
335     abort();
336     return;
337     
338   case MachineOperand::MO_MachineBasicBlock: {
339     MachineBasicBlock *MBBOp = MO.getMachineBasicBlock();
340     O << ".LBB" << Mang->getValueName(MBBOp->getParent()->getFunction())
341       << "_" << MBBOp->getNumber() << "\t; "
342       << MBBOp->getBasicBlock()->getName();
343     return;
344   }
345
346   case MachineOperand::MO_ConstantPoolIndex:
347     O << ".CPI" << CurrentFnName << "_" << MO.getConstantPoolIndex();
348     return;
349
350   case MachineOperand::MO_ExternalSymbol:
351     O << MO.getSymbolName();
352     return;
353
354   case MachineOperand::MO_GlobalAddress: {
355     GlobalValue *GV = MO.getGlobal();
356     std::string Name = Mang->getValueName(GV);
357
358     // Dynamically-resolved functions need a stub for the function.  Be
359     // wary however not to output $stub for external functions whose addresses
360     // are taken.  Those should be emitted as $non_lazy_ptr below.
361     Function *F = dyn_cast<Function>(GV);
362     if (F && F->isExternal() && !LoadAddrOp &&
363         getTM().CalledFunctions.count(F)) {
364       FnStubs.insert(Name);
365       O << "L" << Name << "$stub";
366       return;
367     }
368     
369     // External or weakly linked global variables need non-lazily-resolved stubs
370     if ((GV->isExternal() || GV->hasWeakLinkage() || GV->hasLinkOnceLinkage()) 
371          && getTM().AddressTaken.count(GV)) {
372       GVStubs.insert(Name);
373       O << "L" << Name << "$non_lazy_ptr";
374       return;
375     }
376     
377     if (F && LoadAddrOp && getTM().AddressTaken.count(GV)) {
378       LinkOnceStubs.insert(Name);
379       O << "L" << Name << "$non_lazy_ptr";
380       return;
381     }
382             
383     O << Mang->getValueName(GV);
384     return;
385   }
386     
387   default:
388     O << "<unknown operand type: " << MO.getType() << ">";
389     return;
390   }
391 }
392
393 /// printMachineInstruction -- Print out a single PowerPC MI in Darwin syntax to
394 /// the current output stream.
395 ///
396 void PowerPCAsmPrinter::printMachineInstruction(const MachineInstr *MI) {
397   ++EmittedInsts;
398   if (printInstruction(MI))
399     return; // Printer was automatically generated
400   
401   assert(0 && "Unhandled instruction in asm writer!");
402   abort();
403   return;
404 }
405
406 /// runOnMachineFunction - This uses the printMachineInstruction()
407 /// method to print assembly for each instruction.
408 ///
409 bool DarwinAsmPrinter::runOnMachineFunction(MachineFunction &MF) {
410   setupMachineFunction(MF);
411   O << "\n\n";
412
413   // Print out constants referenced by the function
414   printConstantPool(MF.getConstantPool());
415
416   // Print out labels for the function.
417   O << "\t.text\n";
418   emitAlignment(2);
419   O << "\t.globl\t" << CurrentFnName << "\n";
420   O << CurrentFnName << ":\n";
421
422   // Print out code for the function.
423   for (MachineFunction::const_iterator I = MF.begin(), E = MF.end();
424        I != E; ++I) {
425     // Print a label for the basic block.
426     O << ".LBB" << CurrentFnName << "_" << I->getNumber() << ":\t"
427       << CommentString << " " << I->getBasicBlock()->getName() << "\n";
428     for (MachineBasicBlock::const_iterator II = I->begin(), E = I->end();
429          II != E; ++II) {
430       // Print the assembly for the instruction.
431       O << "\t";
432       printMachineInstruction(II);
433     }
434   }
435   ++LabelNumber;
436
437   // We didn't modify anything.
438   return false;
439 }
440
441 /// printConstantPool - Print to the current output stream assembly
442 /// representations of the constants in the constant pool MCP. This is
443 /// used to print out constants which have been "spilled to memory" by
444 /// the code generator.
445 ///
446 void DarwinAsmPrinter::printConstantPool(MachineConstantPool *MCP) {
447   const std::vector<Constant*> &CP = MCP->getConstants();
448   const TargetData &TD = TM.getTargetData();
449  
450   if (CP.empty()) return;
451
452   for (unsigned i = 0, e = CP.size(); i != e; ++i) {
453     O << "\t.const\n";
454     emitAlignment(TD.getTypeAlignmentShift(CP[i]->getType()));
455     O << ".CPI" << CurrentFnName << "_" << i << ":\t\t\t\t\t" << CommentString
456       << *CP[i] << "\n";
457     emitGlobalConstant(CP[i]);
458   }
459 }
460
461 bool DarwinAsmPrinter::doFinalization(Module &M) {
462   const TargetData &TD = TM.getTargetData();
463   std::string CurSection;
464
465   // Print out module-level global variables here.
466   for (Module::const_giterator I = M.gbegin(), E = M.gend(); I != E; ++I)
467     if (I->hasInitializer()) {   // External global require no code
468       O << '\n';
469       std::string name = Mang->getValueName(I);
470       Constant *C = I->getInitializer();
471       unsigned Size = TD.getTypeSize(C->getType());
472       unsigned Align = TD.getTypeAlignmentShift(C->getType());
473
474       if (C->isNullValue() && /* FIXME: Verify correct */
475           (I->hasInternalLinkage() || I->hasWeakLinkage() || 
476            I->hasLinkOnceLinkage())) {
477         SwitchSection(O, CurSection, ".data");
478         if (I->hasInternalLinkage())
479           O << ".lcomm " << name << "," << TD.getTypeSize(C->getType())
480             << "," << Align;
481         else 
482           O << ".comm " << name << "," << TD.getTypeSize(C->getType());
483         O << "\t\t; ";
484         WriteAsOperand(O, I, true, true, &M);
485         O << '\n';
486       } else {
487         switch (I->getLinkage()) {
488         case GlobalValue::LinkOnceLinkage:
489           O << ".section __TEXT,__textcoal_nt,coalesced,no_toc\n"
490             << ".weak_definition " << name << '\n'
491             << ".private_extern " << name << '\n'
492             << ".section __DATA,__datacoal_nt,coalesced,no_toc\n";
493           LinkOnceStubs.insert(name);
494           break;  
495         case GlobalValue::WeakLinkage:   // FIXME: Verify correct for weak.
496           // Nonnull linkonce -> weak
497           O << "\t.weak " << name << "\n";
498           SwitchSection(O, CurSection, "");
499           O << "\t.section\t.llvm.linkonce.d." << name << ",\"aw\",@progbits\n";
500           break;
501         case GlobalValue::AppendingLinkage:
502           // FIXME: appending linkage variables should go into a section of
503           // their name or something.  For now, just emit them as external.
504         case GlobalValue::ExternalLinkage:
505           // If external or appending, declare as a global symbol
506           O << "\t.globl " << name << "\n";
507           // FALL THROUGH
508         case GlobalValue::InternalLinkage:
509           SwitchSection(O, CurSection, ".data");
510           break;
511         case GlobalValue::GhostLinkage:
512           std::cerr << "Error: unmaterialized (GhostLinkage) function in asm!";
513           abort();
514         }
515
516         emitAlignment(Align);
517         O << name << ":\t\t\t\t; ";
518         WriteAsOperand(O, I, true, true, &M);
519         O << " = ";
520         WriteAsOperand(O, C, false, false, &M);
521         O << "\n";
522         emitGlobalConstant(C);
523       }
524     }
525
526   // Output stubs for dynamically-linked functions
527   for (std::set<std::string>::iterator i = FnStubs.begin(), e = FnStubs.end(); 
528        i != e; ++i)
529   {
530     O << ".data\n";
531     O << ".section __TEXT,__picsymbolstub1,symbol_stubs,pure_instructions,32\n";
532     emitAlignment(2);
533     O << "L" << *i << "$stub:\n";
534     O << "\t.indirect_symbol " << *i << "\n";
535     O << "\tmflr r0\n";
536     O << "\tbcl 20,31,L0$" << *i << "\n";
537     O << "L0$" << *i << ":\n";
538     O << "\tmflr r11\n";
539     O << "\taddis r11,r11,ha16(L" << *i << "$lazy_ptr-L0$" << *i << ")\n";
540     O << "\tmtlr r0\n";
541     O << "\tlwzu r12,lo16(L" << *i << "$lazy_ptr-L0$" << *i << ")(r11)\n";
542     O << "\tmtctr r12\n";
543     O << "\tbctr\n";
544     O << ".data\n";
545     O << ".lazy_symbol_pointer\n";
546     O << "L" << *i << "$lazy_ptr:\n";
547     O << "\t.indirect_symbol " << *i << "\n";
548     O << "\t.long dyld_stub_binding_helper\n";
549   }
550
551   O << "\n";
552
553   // Output stubs for external global variables
554   if (GVStubs.begin() != GVStubs.end())
555     O << ".data\n.non_lazy_symbol_pointer\n";
556   for (std::set<std::string>::iterator i = GVStubs.begin(), e = GVStubs.end(); 
557        i != e; ++i) {
558     O << "L" << *i << "$non_lazy_ptr:\n";
559     O << "\t.indirect_symbol " << *i << "\n";
560     O << "\t.long\t0\n";
561   }
562   
563   // Output stubs for link-once variables
564   if (LinkOnceStubs.begin() != LinkOnceStubs.end())
565     O << ".data\n.align 2\n";
566   for (std::set<std::string>::iterator i = LinkOnceStubs.begin(), 
567          e = LinkOnceStubs.end(); i != e; ++i) {
568     O << "L" << *i << "$non_lazy_ptr:\n"
569       << "\t.long\t" << *i << '\n';
570   }
571   
572   AsmPrinter::doFinalization(M);
573   return false; // success
574 }
575
576 /// runOnMachineFunction - This uses the printMachineInstruction()
577 /// method to print assembly for each instruction.
578 ///
579 bool AIXAsmPrinter::runOnMachineFunction(MachineFunction &MF) {
580   CurrentFnName = MF.getFunction()->getName();
581
582   // Print out constants referenced by the function
583   printConstantPool(MF.getConstantPool());
584
585   // Print out header for the function.
586   O << "\t.csect .text[PR]\n"
587     << "\t.align 2\n"
588     << "\t.globl "  << CurrentFnName << '\n'
589     << "\t.globl ." << CurrentFnName << '\n'
590     << "\t.csect "  << CurrentFnName << "[DS],3\n"
591     << CurrentFnName << ":\n"
592     << "\t.llong ." << CurrentFnName << ", TOC[tc0], 0\n"
593     << "\t.csect .text[PR]\n"
594     << '.' << CurrentFnName << ":\n";
595
596   // Print out code for the function.
597   for (MachineFunction::const_iterator I = MF.begin(), E = MF.end();
598        I != E; ++I) {
599     // Print a label for the basic block.
600     O << "LBB" << CurrentFnName << "_" << I->getNumber() << ":\t# "
601       << I->getBasicBlock()->getName() << "\n";
602     for (MachineBasicBlock::const_iterator II = I->begin(), E = I->end();
603       II != E; ++II) {
604       // Print the assembly for the instruction.
605       O << "\t";
606       printMachineInstruction(II);
607     }
608   }
609   ++LabelNumber;
610
611   O << "LT.." << CurrentFnName << ":\n"
612     << "\t.long 0\n"
613     << "\t.byte 0,0,32,65,128,0,0,0\n"
614     << "\t.long LT.." << CurrentFnName << "-." << CurrentFnName << '\n'
615     << "\t.short 3\n"
616     << "\t.byte \"" << CurrentFnName << "\"\n"
617     << "\t.align 2\n";
618
619   // We didn't modify anything.
620   return false;
621 }
622
623 /// printConstantPool - Print to the current output stream assembly
624 /// representations of the constants in the constant pool MCP. This is
625 /// used to print out constants which have been "spilled to memory" by
626 /// the code generator.
627 ///
628 void AIXAsmPrinter::printConstantPool(MachineConstantPool *MCP) {
629   const std::vector<Constant*> &CP = MCP->getConstants();
630   const TargetData &TD = TM.getTargetData();
631  
632   if (CP.empty()) return;
633
634   for (unsigned i = 0, e = CP.size(); i != e; ++i) {
635     O << "\t.const\n";
636     O << "\t.align " << (unsigned)TD.getTypeAlignment(CP[i]->getType())
637       << "\n";
638     O << ".CPI" << CurrentFnName << "_" << i << ":\t\t\t\t\t;"
639       << *CP[i] << "\n";
640     emitGlobalConstant(CP[i]);
641   }
642 }
643
644 bool AIXAsmPrinter::doInitialization(Module &M) {
645   const TargetData &TD = TM.getTargetData();
646   std::string CurSection;
647
648   O << "\t.machine \"ppc64\"\n" 
649     << "\t.toc\n"
650     << "\t.csect .text[PR]\n";
651
652   // Print out module-level global variables
653   for (Module::const_giterator I = M.gbegin(), E = M.gend(); I != E; ++I) {
654     if (!I->hasInitializer())
655       continue;
656  
657     std::string Name = I->getName();
658     Constant *C = I->getInitializer();
659     // N.B.: We are defaulting to writable strings
660     if (I->hasExternalLinkage()) { 
661       O << "\t.globl " << Name << '\n'
662         << "\t.csect .data[RW],3\n";
663     } else {
664       O << "\t.csect _global.rw_c[RW],3\n";
665     }
666     O << Name << ":\n";
667     emitGlobalConstant(C);
668   }
669
670   // Output labels for globals
671   if (M.gbegin() != M.gend()) O << "\t.toc\n";
672   for (Module::const_giterator I = M.gbegin(), E = M.gend(); I != E; ++I) {
673     const GlobalVariable *GV = I;
674     // Do not output labels for unused variables
675     if (GV->isExternal() && GV->use_begin() == GV->use_end())
676       continue;
677
678     std::string Name = GV->getName();
679     std::string Label = "LC.." + utostr(LabelNumber++);
680     GVToLabelMap[GV] = Label;
681     O << Label << ":\n"
682       << "\t.tc " << Name << "[TC]," << Name;
683     if (GV->isExternal()) O << "[RW]";
684     O << '\n';
685   }
686
687   Mang = new Mangler(M, ".");
688   return false; // success
689 }
690
691 bool AIXAsmPrinter::doFinalization(Module &M) {
692   const TargetData &TD = TM.getTargetData();
693   // Print out module-level global variables
694   for (Module::const_giterator I = M.gbegin(), E = M.gend(); I != E; ++I) {
695     if (I->hasInitializer() || I->hasExternalLinkage())
696       continue;
697
698     std::string Name = I->getName();
699     if (I->hasInternalLinkage()) {
700       O << "\t.lcomm " << Name << ",16,_global.bss_c";
701     } else {
702       O << "\t.comm " << Name << "," << TD.getTypeSize(I->getType())
703         << "," << log2((unsigned)TD.getTypeAlignment(I->getType()));
704     }
705     O << "\t\t# ";
706     WriteAsOperand(O, I, true, true, &M);
707     O << "\n";
708   }
709
710   O << "_section_.text:\n"
711     << "\t.csect .data[RW],3\n"
712     << "\t.llong _section_.text\n";
713
714   delete Mang;
715   return false; // success
716 }