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