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