Use CommentString where possible, fix a bug where aix mode wouldn't assemble
[oota-llvm.git] / lib / Target / PowerPC / PPCAsmPrinter.cpp
1 //===-- PPCAsmPrinter.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 "PPC.h"
21 #include "PPCTargetMachine.h"
22 #include "PPCSubtarget.h"
23 #include "llvm/Constants.h"
24 #include "llvm/DerivedTypes.h"
25 #include "llvm/Module.h"
26 #include "llvm/Assembly/Writer.h"
27 #include "llvm/CodeGen/AsmPrinter.h"
28 #include "llvm/CodeGen/MachineConstantPool.h"
29 #include "llvm/CodeGen/MachineFunctionPass.h"
30 #include "llvm/CodeGen/MachineInstr.h"
31 #include "llvm/CodeGen/ValueTypes.h"
32 #include "llvm/Support/Mangler.h"
33 #include "llvm/Support/MathExtras.h"
34 #include "llvm/Support/CommandLine.h"
35 #include "llvm/Support/Debug.h"
36 #include "llvm/Target/MRegisterInfo.h"
37 #include "llvm/Target/TargetInstrInfo.h"
38 #include "llvm/ADT/Statistic.h"
39 #include "llvm/ADT/StringExtras.h"
40 #include <set>
41 using namespace llvm;
42
43 namespace {
44   Statistic<> EmittedInsts("asm-printer", "Number of machine instrs printed");
45
46   class PPCAsmPrinter : public AsmPrinter {
47   public:
48     std::set<std::string> FnStubs, GVStubs, LinkOnceStubs;
49     
50     PPCAsmPrinter(std::ostream &O, TargetMachine &TM)
51       : AsmPrinter(O, TM), FunctionNumber(0) {}
52
53     /// Unique incrementer for label values for referencing Global values.
54     ///
55     unsigned FunctionNumber;
56
57     virtual const char *getPassName() const {
58       return "PowerPC Assembly Printer";
59     }
60
61     PPCTargetMachine &getTM() {
62       return static_cast<PPCTargetMachine&>(TM);
63     }
64
65     void printConstantPool(MachineConstantPool *MCP);
66
67     unsigned enumRegToMachineReg(unsigned enumReg) {
68       switch (enumReg) {
69       default: assert(0 && "Unhandled register!"); break;
70       case PPC::CR0:  return  0;
71       case PPC::CR1:  return  1;
72       case PPC::CR2:  return  2;
73       case PPC::CR3:  return  3;
74       case PPC::CR4:  return  4;
75       case PPC::CR5:  return  5;
76       case PPC::CR6:  return  6;
77       case PPC::CR7:  return  7;
78       }
79       abort();
80     }
81
82     /// printInstruction - This method is automatically generated by tablegen
83     /// from the instruction set description.  This method returns true if the
84     /// machine instruction was sufficiently described to print it, otherwise it
85     /// returns false.
86     bool printInstruction(const MachineInstr *MI);
87
88     void printMachineInstruction(const MachineInstr *MI);
89     void printOp(const MachineOperand &MO);
90
91     void printOperand(const MachineInstr *MI, unsigned OpNo, MVT::ValueType VT){
92       const MachineOperand &MO = MI->getOperand(OpNo);
93       if (MO.getType() == MachineOperand::MO_MachineRegister) {
94         assert(MRegisterInfo::isPhysicalRegister(MO.getReg())&&"Not physreg??");
95         O << TM.getRegisterInfo()->get(MO.getReg()).Name;
96       } else if (MO.isImmediate()) {
97         O << MO.getImmedValue();
98       } else {
99         printOp(MO);
100       }
101     }
102
103     void printU5ImmOperand(const MachineInstr *MI, unsigned OpNo,
104                             MVT::ValueType VT) {
105       unsigned char value = MI->getOperand(OpNo).getImmedValue();
106       assert(value <= 31 && "Invalid u5imm argument!");
107       O << (unsigned int)value;
108     }
109     void printU6ImmOperand(const MachineInstr *MI, unsigned OpNo,
110                             MVT::ValueType VT) {
111       unsigned char value = MI->getOperand(OpNo).getImmedValue();
112       assert(value <= 63 && "Invalid u6imm argument!");
113       O << (unsigned int)value;
114     }
115     void printS16ImmOperand(const MachineInstr *MI, unsigned OpNo,
116                             MVT::ValueType VT) {
117       O << (short)MI->getOperand(OpNo).getImmedValue();
118     }
119     void printU16ImmOperand(const MachineInstr *MI, unsigned OpNo,
120                             MVT::ValueType VT) {
121       O << (unsigned short)MI->getOperand(OpNo).getImmedValue();
122     }
123     void printS16X4ImmOperand(const MachineInstr *MI, unsigned OpNo,
124                               MVT::ValueType VT) {
125       O << (short)MI->getOperand(OpNo).getImmedValue()*4;
126     }
127     void printBranchOperand(const MachineInstr *MI, unsigned OpNo,
128                             MVT::ValueType VT) {
129       // Branches can take an immediate operand.  This is used by the branch
130       // selection pass to print $+8, an eight byte displacement from the PC.
131       if (MI->getOperand(OpNo).isImmediate()) {
132         O << "$+" << MI->getOperand(OpNo).getImmedValue();
133       } else {
134         printOp(MI->getOperand(OpNo));
135       }
136     }
137     void printCallOperand(const MachineInstr *MI, unsigned OpNo,
138                           MVT::ValueType VT) {
139       const MachineOperand &MO = MI->getOperand(OpNo);
140       if (!PPCGenerateStaticCode) {
141         if (MO.getType() == MachineOperand::MO_ExternalSymbol) {
142           std::string Name(GlobalPrefix); Name += MO.getSymbolName();
143           FnStubs.insert(Name);
144           O << "L" << Name << "$stub";
145           return;
146         } else if (MO.getType() == MachineOperand::MO_GlobalAddress &&
147                    isa<Function>(MO.getGlobal()) && 
148                    cast<Function>(MO.getGlobal())->isExternal()) {
149           // Dynamically-resolved functions need a stub for the function.
150           std::string Name = Mang->getValueName(MO.getGlobal());
151           FnStubs.insert(Name);
152           O << "L" << Name << "$stub";
153           return;
154         }
155       }
156       
157       printOp(MI->getOperand(OpNo));
158     }
159     void printAbsAddrOperand(const MachineInstr *MI, unsigned OpNo,
160                              MVT::ValueType VT) {
161      O << (int)MI->getOperand(OpNo).getImmedValue()*4;
162     }
163     void printPICLabel(const MachineInstr *MI, unsigned OpNo,
164                        MVT::ValueType VT) {
165       // FIXME: should probably be converted to cout.width and cout.fill
166       O << "\"L0000" << FunctionNumber << "$pb\"\n";
167       O << "\"L0000" << FunctionNumber << "$pb\":";
168     }
169     void printSymbolHi(const MachineInstr *MI, unsigned OpNo,
170                        MVT::ValueType VT) {
171       if (MI->getOperand(OpNo).isImmediate()) {
172         printS16ImmOperand(MI, OpNo, VT);
173       } else {
174         O << "ha16(";
175         printOp(MI->getOperand(OpNo));
176         if (PICEnabled)
177           O << "-\"L0000" << FunctionNumber << "$pb\")";
178         else
179           O << ')';
180       }
181     }
182     void printSymbolLo(const MachineInstr *MI, unsigned OpNo,
183                        MVT::ValueType VT) {
184       if (MI->getOperand(OpNo).isImmediate()) {
185         printS16ImmOperand(MI, OpNo, VT);
186       } else {
187         O << "lo16(";
188         printOp(MI->getOperand(OpNo));
189         if (PICEnabled)
190           O << "-\"L0000" << FunctionNumber << "$pb\")";
191         else
192           O << ')';
193       }
194     }
195     void printcrbitm(const MachineInstr *MI, unsigned OpNo,
196                        MVT::ValueType VT) {
197       unsigned CCReg = MI->getOperand(OpNo).getReg();
198       unsigned RegNo = enumRegToMachineReg(CCReg);
199       O << (0x80 >> RegNo);
200     }
201
202     virtual bool runOnMachineFunction(MachineFunction &F) = 0;
203     virtual bool doFinalization(Module &M) = 0;
204   };
205
206   /// DarwinAsmPrinter - PowerPC assembly printer, customized for Darwin/Mac OS
207   /// X
208   ///
209   struct DarwinAsmPrinter : public PPCAsmPrinter {
210
211     DarwinAsmPrinter(std::ostream &O, TargetMachine &TM)
212       : PPCAsmPrinter(O, TM) {
213       CommentString = ";";
214       GlobalPrefix = "_";
215       PrivateGlobalPrefix = "L";     // Marker for constant pool idxs
216       ZeroDirective = "\t.space\t";  // ".space N" emits N zeros.
217       Data64bitsDirective = 0;       // we can't emit a 64-bit unit
218       AlignmentIsInBytes = false;    // Alignment is by power of 2.
219     }
220
221     virtual const char *getPassName() const {
222       return "Darwin PPC Assembly Printer";
223     }
224
225     bool runOnMachineFunction(MachineFunction &F);
226     bool doInitialization(Module &M);
227     bool doFinalization(Module &M);
228   };
229
230   /// AIXAsmPrinter - PowerPC assembly printer, customized for AIX
231   ///
232   struct AIXAsmPrinter : public PPCAsmPrinter {
233     /// Map for labels corresponding to global variables
234     ///
235     std::map<const GlobalVariable*,std::string> GVToLabelMap;
236
237     AIXAsmPrinter(std::ostream &O, TargetMachine &TM)
238       : PPCAsmPrinter(O, TM) {
239       CommentString = "#";
240       GlobalPrefix = ".";
241       ZeroDirective = "\t.space\t";  // ".space N" emits N zeros.
242       Data64bitsDirective = 0;       // we can't emit a 64-bit unit
243       AlignmentIsInBytes = false;    // Alignment is by power of 2.
244     }
245
246     virtual const char *getPassName() const {
247       return "AIX PPC Assembly Printer";
248     }
249
250     bool runOnMachineFunction(MachineFunction &F);
251     bool doInitialization(Module &M);
252     bool doFinalization(Module &M);
253   };
254 } // end of anonymous namespace
255
256 /// createDarwinAsmPrinterPass - Returns a pass that prints the PPC assembly
257 /// code for a MachineFunction to the given output stream, in a format that the
258 /// Darwin assembler can deal with.
259 ///
260 FunctionPass *llvm::createDarwinAsmPrinter(std::ostream &o, TargetMachine &tm) {
261   return new DarwinAsmPrinter(o, tm);
262 }
263
264 /// createAIXAsmPrinterPass - Returns a pass that prints the PPC assembly code
265 /// for a MachineFunction to the given output stream, in a format that the
266 /// AIX 5L assembler can deal with.
267 ///
268 FunctionPass *llvm::createAIXAsmPrinter(std::ostream &o, TargetMachine &tm) {
269   return new AIXAsmPrinter(o, tm);
270 }
271
272 // Include the auto-generated portion of the assembly writer
273 #include "PPCGenAsmWriter.inc"
274
275 void PPCAsmPrinter::printOp(const MachineOperand &MO) {
276   const MRegisterInfo &RI = *TM.getRegisterInfo();
277   int new_symbol;
278
279   switch (MO.getType()) {
280   case MachineOperand::MO_VirtualRegister:
281     if (Value *V = MO.getVRegValueOrNull()) {
282       O << "<" << V->getName() << ">";
283       return;
284     }
285     // FALLTHROUGH
286   case MachineOperand::MO_MachineRegister:
287   case MachineOperand::MO_CCRegister:
288     O << RI.get(MO.getReg()).Name;
289     return;
290
291   case MachineOperand::MO_SignExtendedImmed:
292   case MachineOperand::MO_UnextendedImmed:
293     std::cerr << "printOp() does not handle immediate values\n";
294     abort();
295     return;
296
297   case MachineOperand::MO_PCRelativeDisp:
298     std::cerr << "Shouldn't use addPCDisp() when building PPC MachineInstrs";
299     abort();
300     return;
301
302   case MachineOperand::MO_MachineBasicBlock: {
303     MachineBasicBlock *MBBOp = MO.getMachineBasicBlock();
304     O << PrivateGlobalPrefix << "BB" << FunctionNumber << "_"
305       << MBBOp->getNumber() << "\t; " << MBBOp->getBasicBlock()->getName();
306     return;
307   }
308
309   case MachineOperand::MO_ConstantPoolIndex:
310     O << PrivateGlobalPrefix << "CPI" << FunctionNumber
311       << '_' << MO.getConstantPoolIndex();
312     return;
313
314   case MachineOperand::MO_ExternalSymbol:
315     O << GlobalPrefix << MO.getSymbolName();
316     return;
317
318   case MachineOperand::MO_GlobalAddress: {
319     GlobalValue *GV = MO.getGlobal();
320     std::string Name = Mang->getValueName(GV);
321
322     // External or weakly linked global variables need non-lazily-resolved stubs
323     if (!PPCGenerateStaticCode &&
324         ((GV->isExternal() || GV->hasWeakLinkage() ||
325           GV->hasLinkOnceLinkage()))) {
326       if (GV->hasLinkOnceLinkage())
327         LinkOnceStubs.insert(Name);
328       else
329         GVStubs.insert(Name);
330       O << "L" << Name << "$non_lazy_ptr";
331       return;
332     }
333
334     O << Name;
335     return;
336   }
337
338   default:
339     O << "<unknown operand type: " << MO.getType() << ">";
340     return;
341   }
342 }
343
344 /// printMachineInstruction -- Print out a single PowerPC MI in Darwin syntax to
345 /// the current output stream.
346 ///
347 void PPCAsmPrinter::printMachineInstruction(const MachineInstr *MI) {
348   ++EmittedInsts;
349
350   // Check for slwi/srwi mnemonics.
351   if (MI->getOpcode() == PPC::RLWINM) {
352     bool FoundMnemonic = false;
353     unsigned char SH = MI->getOperand(2).getImmedValue();
354     unsigned char MB = MI->getOperand(3).getImmedValue();
355     unsigned char ME = MI->getOperand(4).getImmedValue();
356     if (SH <= 31 && MB == 0 && ME == (31-SH)) {
357       O << "slwi "; FoundMnemonic = true;
358     }
359     if (SH <= 31 && MB == (32-SH) && ME == 31) {
360       O << "srwi "; FoundMnemonic = true;
361       SH = 32-SH;
362     }
363     if (FoundMnemonic) {
364       printOperand(MI, 0, MVT::i64);
365       O << ", ";
366       printOperand(MI, 1, MVT::i64);
367       O << ", " << (unsigned int)SH << "\n";
368       return;
369     }
370   }
371
372   if (printInstruction(MI))
373     return; // Printer was automatically generated
374
375   assert(0 && "Unhandled instruction in asm writer!");
376   abort();
377   return;
378 }
379
380 /// printConstantPool - Print to the current output stream assembly
381 /// representations of the constants in the constant pool MCP. This is
382 /// used to print out constants which have been "spilled to memory" by
383 /// the code generator.
384 ///
385 void PPCAsmPrinter::printConstantPool(MachineConstantPool *MCP) {
386   const std::vector<Constant*> &CP = MCP->getConstants();
387   const TargetData &TD = TM.getTargetData();
388   
389   if (CP.empty()) return;
390   
391   SwitchSection(".const", 0);
392   for (unsigned i = 0, e = CP.size(); i != e; ++i) {
393     // FIXME: force doubles to be naturally aligned.  We should handle this
394     // more correctly in the future.
395     unsigned Alignment = TD.getTypeAlignmentShift(CP[i]->getType());
396     if (CP[i]->getType() == Type::DoubleTy && Alignment < 3) Alignment = 3;
397     
398     EmitAlignment(Alignment);
399     O << PrivateGlobalPrefix << "CPI" << FunctionNumber << '_' << i
400       << ":\t\t\t\t\t" << CommentString << *CP[i] << '\n';
401     EmitGlobalConstant(CP[i]);
402   }
403 }
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   const Function *F = MF.getFunction();
418   SwitchSection(".text", F);
419   EmitAlignment(4, F);
420   if (!F->hasInternalLinkage())
421     O << "\t.globl\t" << CurrentFnName << "\n";
422   O << CurrentFnName << ":\n";
423
424   // Print out code for the function.
425   for (MachineFunction::const_iterator I = MF.begin(), E = MF.end();
426        I != E; ++I) {
427     // Print a label for the basic block.
428     if (I != MF.begin()) {
429       O << PrivateGlobalPrefix << "BB" << FunctionNumber << '_'
430         << I->getNumber() << ":\t";
431       if (!I->getBasicBlock()->getName().empty())
432         O << CommentString << " " << I->getBasicBlock()->getName();
433       O << "\n";
434     }
435     for (MachineBasicBlock::const_iterator II = I->begin(), E = I->end();
436          II != E; ++II) {
437       // Print the assembly for the instruction.
438       O << "\t";
439       printMachineInstruction(II);
440     }
441   }
442   ++FunctionNumber;
443
444   // We didn't modify anything.
445   return false;
446 }
447
448
449 bool DarwinAsmPrinter::doInitialization(Module &M) {
450   if (TM.getSubtarget<PPCSubtarget>().isGigaProcessor())
451     O << "\t.machine ppc970\n";
452   AsmPrinter::doInitialization(M);
453   
454   // Darwin wants symbols to be quoted if they have complex names.
455   Mang->setUseQuotes(true);
456   return false;
457 }
458
459 bool DarwinAsmPrinter::doFinalization(Module &M) {
460   const TargetData &TD = TM.getTargetData();
461
462   // Print out module-level global variables here.
463   for (Module::const_global_iterator I = M.global_begin(), E = M.global_end();
464        I != E; ++I)
465     if (I->hasInitializer()) {   // External global require no code
466       O << '\n';
467       std::string name = Mang->getValueName(I);
468       Constant *C = I->getInitializer();
469       unsigned Size = TD.getTypeSize(C->getType());
470       unsigned Align = TD.getTypeAlignmentShift(C->getType());
471
472       if (C->isNullValue() && /* FIXME: Verify correct */
473           (I->hasInternalLinkage() || I->hasWeakLinkage() ||
474            I->hasLinkOnceLinkage())) {
475         SwitchSection(".data", I);
476         if (Size == 0) Size = 1;   // .comm Foo, 0 is undefined, avoid it.
477         if (I->hasInternalLinkage())
478           O << ".lcomm " << name << "," << Size << "," << Align;
479         else
480           O << ".comm " << name << "," << Size;
481         O << "\t\t; '" << I->getName() << "'\n";
482       } else {
483         switch (I->getLinkage()) {
484         case GlobalValue::LinkOnceLinkage:
485           SwitchSection("", 0);
486           O << ".section __TEXT,__textcoal_nt,coalesced,no_toc\n"
487             << ".weak_definition " << name << '\n'
488             << ".private_extern " << name << '\n'
489             << ".section __DATA,__datacoal_nt,coalesced,no_toc\n";
490           LinkOnceStubs.insert(name);
491           break;
492         case GlobalValue::WeakLinkage:
493           O << ".weak_definition " << name << '\n'
494             << ".private_extern " << name << '\n';
495           break;
496         case GlobalValue::AppendingLinkage:
497           // FIXME: appending linkage variables should go into a section of
498           // their name or something.  For now, just emit them as external.
499         case GlobalValue::ExternalLinkage:
500           // If external or appending, declare as a global symbol
501           O << "\t.globl " << name << "\n";
502           // FALL THROUGH
503         case GlobalValue::InternalLinkage:
504           SwitchSection(".data", I);
505           break;
506         default:
507           std::cerr << "Unknown linkage type!";
508           abort();
509         }
510
511         EmitAlignment(Align, I);
512         O << name << ":\t\t\t\t; '" << I->getName() << "'\n";
513         EmitGlobalConstant(C);
514       }
515     }
516
517   // Output stubs for dynamically-linked functions
518   for (std::set<std::string>::iterator i = FnStubs.begin(), e = FnStubs.end();
519        i != e; ++i)
520   {
521     if (PICEnabled) {
522     O << ".data\n";
523     O << ".section __TEXT,__picsymbolstub1,symbol_stubs,pure_instructions,32\n";
524     EmitAlignment(2);
525     O << "L" << *i << "$stub:\n";
526     O << "\t.indirect_symbol " << *i << "\n";
527     O << "\tmflr r0\n";
528     O << "\tbcl 20,31,L0$" << *i << "\n";
529     O << "L0$" << *i << ":\n";
530     O << "\tmflr r11\n";
531     O << "\taddis r11,r11,ha16(L" << *i << "$lazy_ptr-L0$" << *i << ")\n";
532     O << "\tmtlr r0\n";
533     O << "\tlwzu r12,lo16(L" << *i << "$lazy_ptr-L0$" << *i << ")(r11)\n";
534     O << "\tmtctr r12\n";
535     O << "\tbctr\n";
536     O << ".data\n";
537     O << ".lazy_symbol_pointer\n";
538     O << "L" << *i << "$lazy_ptr:\n";
539     O << "\t.indirect_symbol " << *i << "\n";
540     O << "\t.long dyld_stub_binding_helper\n";
541     } else {
542     O << "\t.section __TEXT,__symbol_stub1,symbol_stubs,pure_instructions,16\n";
543     EmitAlignment(4);
544     O << "L" << *i << "$stub:\n";
545     O << "\t.indirect_symbol " << *i << "\n";
546     O << "\tlis r11,ha16(L" << *i << "$lazy_ptr)\n";
547     O << "\tlwzu r12,lo16(L" << *i << "$lazy_ptr)(r11)\n";
548     O << "\tmtctr r12\n";
549     O << "\tbctr\n";
550     O << "\t.lazy_symbol_pointer\n";
551     O << "L" << *i << "$lazy_ptr:\n";
552     O << "\t.indirect_symbol " << *i << "\n";
553     O << "\t.long dyld_stub_binding_helper\n";
554     }
555   }
556
557   O << "\n";
558
559   // Output stubs for external global variables
560   if (GVStubs.begin() != GVStubs.end())
561     O << ".data\n.non_lazy_symbol_pointer\n";
562   for (std::set<std::string>::iterator i = GVStubs.begin(), e = GVStubs.end();
563        i != e; ++i) {
564     O << "L" << *i << "$non_lazy_ptr:\n";
565     O << "\t.indirect_symbol " << *i << "\n";
566     O << "\t.long\t0\n";
567   }
568
569   // Output stubs for link-once variables
570   if (LinkOnceStubs.begin() != LinkOnceStubs.end())
571     O << ".data\n.align 2\n";
572   for (std::set<std::string>::iterator i = LinkOnceStubs.begin(),
573          e = LinkOnceStubs.end(); i != e; ++i) {
574     O << "L" << *i << "$non_lazy_ptr:\n"
575       << "\t.long\t" << *i << '\n';
576   }
577
578   // Funny Darwin hack: This flag tells the linker that no global symbols
579   // contain code that falls through to other global symbols (e.g. the obvious
580   // implementation of multiple entry points).  If this doesn't occur, the
581   // linker can safely perform dead code stripping.  Since LLVM never generates
582   // code that does this, it is always safe to set.
583   O << "\t.subsections_via_symbols\n";
584
585   AsmPrinter::doFinalization(M);
586   return false; // success
587 }
588
589 /// runOnMachineFunction - This uses the printMachineInstruction()
590 /// method to print assembly for each instruction.
591 ///
592 bool AIXAsmPrinter::runOnMachineFunction(MachineFunction &MF) {
593   SetupMachineFunction(MF);
594
595   // Print out constants referenced by the function
596   printConstantPool(MF.getConstantPool());
597
598   // Print out header for the function.
599   O << "\t.csect .text[PR]\n"
600     << "\t.align 2\n"
601     << "\t.globl "  << CurrentFnName << '\n'
602     << "\t.globl ." << CurrentFnName << '\n'
603     << "\t.csect "  << CurrentFnName << "[DS],3\n"
604     << CurrentFnName << ":\n"
605     << "\t.llong ." << CurrentFnName << ", TOC[tc0], 0\n"
606     << "\t.csect .text[PR]\n"
607     << '.' << CurrentFnName << ":\n";
608
609   // Print out code for the function.
610   for (MachineFunction::const_iterator I = MF.begin(), E = MF.end();
611        I != E; ++I) {
612     // Print a label for the basic block.
613     O << PrivateGlobalPrefix << "BB" << FunctionNumber << '_' << I->getNumber()
614       << ":\t" << CommentString << I->getBasicBlock()->getName() << '\n';
615     for (MachineBasicBlock::const_iterator II = I->begin(), E = I->end();
616       II != E; ++II) {
617       // Print the assembly for the instruction.
618       O << "\t";
619       printMachineInstruction(II);
620     }
621   }
622   ++FunctionNumber;
623
624   O << "LT.." << CurrentFnName << ":\n"
625     << "\t.long 0\n"
626     << "\t.byte 0,0,32,65,128,0,0,0\n"
627     << "\t.long LT.." << CurrentFnName << "-." << CurrentFnName << '\n'
628     << "\t.short 3\n"
629     << "\t.byte \"" << CurrentFnName << "\"\n"
630     << "\t.align 2\n";
631
632   // We didn't modify anything.
633   return false;
634 }
635
636 bool AIXAsmPrinter::doInitialization(Module &M) {
637   SwitchSection("", 0);
638   const TargetData &TD = TM.getTargetData();
639
640   O << "\t.machine \"ppc64\"\n"
641     << "\t.toc\n"
642     << "\t.csect .text[PR]\n";
643
644   // Print out module-level global variables
645   for (Module::const_global_iterator I = M.global_begin(), E = M.global_end();
646        I != E; ++I) {
647     if (!I->hasInitializer())
648       continue;
649
650     std::string Name = I->getName();
651     Constant *C = I->getInitializer();
652     // N.B.: We are defaulting to writable strings
653     if (I->hasExternalLinkage()) {
654       O << "\t.globl " << Name << '\n'
655         << "\t.csect .data[RW],3\n";
656     } else {
657       O << "\t.csect _global.rw_c[RW],3\n";
658     }
659     O << Name << ":\n";
660     EmitGlobalConstant(C);
661   }
662
663   // Output labels for globals
664   if (M.global_begin() != M.global_end()) O << "\t.toc\n";
665   for (Module::const_global_iterator I = M.global_begin(), E = M.global_end();
666        I != E; ++I) {
667     const GlobalVariable *GV = I;
668     // Do not output labels for unused variables
669     if (GV->isExternal() && GV->use_begin() == GV->use_end())
670       continue;
671
672     std::string Name = GV->getName();
673     std::string Label = "LC.." + utostr(FunctionNumber++);
674     GVToLabelMap[GV] = Label;
675     O << Label << ":\n"
676       << "\t.tc " << Name << "[TC]," << Name;
677     if (GV->isExternal()) O << "[RW]";
678     O << '\n';
679   }
680
681   AsmPrinter::doInitialization(M);
682   return false; // success
683 }
684
685 bool AIXAsmPrinter::doFinalization(Module &M) {
686   const TargetData &TD = TM.getTargetData();
687   // Print out module-level global variables
688   for (Module::const_global_iterator I = M.global_begin(), E = M.global_end();
689        I != E; ++I) {
690     if (I->hasInitializer() || I->hasExternalLinkage())
691       continue;
692
693     std::string Name = I->getName();
694     if (I->hasInternalLinkage()) {
695       O << "\t.lcomm " << Name << ",16,_global.bss_c";
696     } else {
697       O << "\t.comm " << Name << "," << TD.getTypeSize(I->getType())
698         << "," << Log2_32((unsigned)TD.getTypeAlignment(I->getType()));
699     }
700     O << "\t\t" << CommentString << " ";
701     WriteAsOperand(O, I, false, true, &M);
702     O << "\n";
703   }
704
705   O << "_section_.text:\n"
706     << "\t.csect .data[RW],3\n"
707     << "\t.llong _section_.text\n";
708   AsmPrinter::doFinalization(M);
709   return false; // success
710 }