PPCAsmPrinter.cpp revision 15404d060ba8b604c03b9223a0f2e2abcd0fdded
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 "PPCPredicates.h"
22#include "PPCTargetMachine.h"
23#include "PPCSubtarget.h"
24#include "llvm/Constants.h"
25#include "llvm/DerivedTypes.h"
26#include "llvm/Module.h"
27#include "llvm/Assembly/Writer.h"
28#include "llvm/CodeGen/AsmPrinter.h"
29#include "llvm/CodeGen/DwarfWriter.h"
30#include "llvm/CodeGen/MachineDebugInfo.h"
31#include "llvm/CodeGen/MachineFunctionPass.h"
32#include "llvm/CodeGen/MachineInstr.h"
33#include "llvm/Support/Mangler.h"
34#include "llvm/Support/MathExtras.h"
35#include "llvm/Support/CommandLine.h"
36#include "llvm/Support/Debug.h"
37#include "llvm/Support/Compiler.h"
38#include "llvm/Target/TargetAsmInfo.h"
39#include "llvm/Target/MRegisterInfo.h"
40#include "llvm/Target/TargetInstrInfo.h"
41#include "llvm/Target/TargetOptions.h"
42#include "llvm/ADT/Statistic.h"
43#include "llvm/ADT/StringExtras.h"
44#include <set>
45using namespace llvm;
46
47namespace {
48  Statistic EmittedInsts("asm-printer", "Number of machine instrs printed");
49
50  struct VISIBILITY_HIDDEN PPCAsmPrinter : public AsmPrinter {
51    std::set<std::string> FnStubs, GVStubs;
52    const PPCSubtarget &Subtarget;
53
54    PPCAsmPrinter(std::ostream &O, TargetMachine &TM, const TargetAsmInfo *T)
55      : AsmPrinter(O, TM, T), Subtarget(TM.getSubtarget<PPCSubtarget>()) {
56    }
57
58    virtual const char *getPassName() const {
59      return "PowerPC Assembly Printer";
60    }
61
62    PPCTargetMachine &getTM() {
63      return static_cast<PPCTargetMachine&>(TM);
64    }
65
66    unsigned enumRegToMachineReg(unsigned enumReg) {
67      switch (enumReg) {
68      default: assert(0 && "Unhandled register!"); break;
69      case PPC::CR0:  return  0;
70      case PPC::CR1:  return  1;
71      case PPC::CR2:  return  2;
72      case PPC::CR3:  return  3;
73      case PPC::CR4:  return  4;
74      case PPC::CR5:  return  5;
75      case PPC::CR6:  return  6;
76      case PPC::CR7:  return  7;
77      }
78      abort();
79    }
80
81    /// printInstruction - This method is automatically generated by tablegen
82    /// from the instruction set description.  This method returns true if the
83    /// machine instruction was sufficiently described to print it, otherwise it
84    /// returns false.
85    bool printInstruction(const MachineInstr *MI);
86
87    void printMachineInstruction(const MachineInstr *MI);
88    void printOp(const MachineOperand &MO);
89
90    void printOperand(const MachineInstr *MI, unsigned OpNo) {
91      const MachineOperand &MO = MI->getOperand(OpNo);
92      if (MO.isRegister()) {
93        assert(MRegisterInfo::isPhysicalRegister(MO.getReg())&&"Not physreg??");
94        O << TM.getRegisterInfo()->get(MO.getReg()).Name;
95      } else if (MO.isImmediate()) {
96        O << MO.getImmedValue();
97      } else {
98        printOp(MO);
99      }
100    }
101
102    bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,
103                         unsigned AsmVariant, const char *ExtraCode);
104    bool PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNo,
105                               unsigned AsmVariant, const char *ExtraCode);
106
107
108    void printS5ImmOperand(const MachineInstr *MI, unsigned OpNo) {
109      char value = MI->getOperand(OpNo).getImmedValue();
110      value = (value << (32-5)) >> (32-5);
111      O << (int)value;
112    }
113    void printU5ImmOperand(const MachineInstr *MI, unsigned OpNo) {
114      unsigned char value = MI->getOperand(OpNo).getImmedValue();
115      assert(value <= 31 && "Invalid u5imm argument!");
116      O << (unsigned int)value;
117    }
118    void printU6ImmOperand(const MachineInstr *MI, unsigned OpNo) {
119      unsigned char value = MI->getOperand(OpNo).getImmedValue();
120      assert(value <= 63 && "Invalid u6imm argument!");
121      O << (unsigned int)value;
122    }
123    void printS16ImmOperand(const MachineInstr *MI, unsigned OpNo) {
124      O << (short)MI->getOperand(OpNo).getImmedValue();
125    }
126    void printU16ImmOperand(const MachineInstr *MI, unsigned OpNo) {
127      O << (unsigned short)MI->getOperand(OpNo).getImmedValue();
128    }
129    void printS16X4ImmOperand(const MachineInstr *MI, unsigned OpNo) {
130      if (MI->getOperand(OpNo).isImmediate()) {
131        O << (short)(MI->getOperand(OpNo).getImmedValue()*4);
132      } else {
133        O << "lo16(";
134        printOp(MI->getOperand(OpNo));
135        if (TM.getRelocationModel() == Reloc::PIC_)
136          O << "-\"L" << getFunctionNumber() << "$pb\")";
137        else
138          O << ')';
139      }
140    }
141    void printBranchOperand(const MachineInstr *MI, unsigned OpNo) {
142      // Branches can take an immediate operand.  This is used by the branch
143      // selection pass to print $+8, an eight byte displacement from the PC.
144      if (MI->getOperand(OpNo).isImmediate()) {
145        O << "$+" << MI->getOperand(OpNo).getImmedValue()*4;
146      } else {
147        printOp(MI->getOperand(OpNo));
148      }
149    }
150    void printCallOperand(const MachineInstr *MI, unsigned OpNo) {
151      const MachineOperand &MO = MI->getOperand(OpNo);
152      if (TM.getRelocationModel() != Reloc::Static) {
153        if (MO.getType() == MachineOperand::MO_GlobalAddress) {
154          GlobalValue *GV = MO.getGlobal();
155          if (((GV->isExternal() || GV->hasWeakLinkage() ||
156                GV->hasLinkOnceLinkage()))) {
157            // Dynamically-resolved functions need a stub for the function.
158            std::string Name = Mang->getValueName(GV);
159            FnStubs.insert(Name);
160            O << "L" << Name << "$stub";
161            if (GV->hasExternalWeakLinkage())
162              ExtWeakSymbols.insert(GV);
163            return;
164          }
165        }
166        if (MO.getType() == MachineOperand::MO_ExternalSymbol) {
167          std::string Name(TAI->getGlobalPrefix()); Name += MO.getSymbolName();
168          FnStubs.insert(Name);
169          O << "L" << Name << "$stub";
170          return;
171        }
172      }
173
174      printOp(MI->getOperand(OpNo));
175    }
176    void printAbsAddrOperand(const MachineInstr *MI, unsigned OpNo) {
177     O << (int)MI->getOperand(OpNo).getImmedValue()*4;
178    }
179    void printPICLabel(const MachineInstr *MI, unsigned OpNo) {
180      O << "\"L" << getFunctionNumber() << "$pb\"\n";
181      O << "\"L" << getFunctionNumber() << "$pb\":";
182    }
183    void printSymbolHi(const MachineInstr *MI, unsigned OpNo) {
184      if (MI->getOperand(OpNo).isImmediate()) {
185        printS16ImmOperand(MI, OpNo);
186      } else {
187        O << "ha16(";
188        printOp(MI->getOperand(OpNo));
189        if (TM.getRelocationModel() == Reloc::PIC_)
190          O << "-\"L" << getFunctionNumber() << "$pb\")";
191        else
192          O << ')';
193      }
194    }
195    void printSymbolLo(const MachineInstr *MI, unsigned OpNo) {
196      if (MI->getOperand(OpNo).isImmediate()) {
197        printS16ImmOperand(MI, OpNo);
198      } else {
199        O << "lo16(";
200        printOp(MI->getOperand(OpNo));
201        if (TM.getRelocationModel() == Reloc::PIC_)
202          O << "-\"L" << getFunctionNumber() << "$pb\")";
203        else
204          O << ')';
205      }
206    }
207    void printcrbitm(const MachineInstr *MI, unsigned OpNo) {
208      unsigned CCReg = MI->getOperand(OpNo).getReg();
209      unsigned RegNo = enumRegToMachineReg(CCReg);
210      O << (0x80 >> RegNo);
211    }
212    // The new addressing mode printers.
213    void printMemRegImm(const MachineInstr *MI, unsigned OpNo) {
214      printSymbolLo(MI, OpNo);
215      O << '(';
216      if (MI->getOperand(OpNo+1).isRegister() &&
217          MI->getOperand(OpNo+1).getReg() == PPC::R0)
218        O << "0";
219      else
220        printOperand(MI, OpNo+1);
221      O << ')';
222    }
223    void printMemRegImmShifted(const MachineInstr *MI, unsigned OpNo) {
224      if (MI->getOperand(OpNo).isImmediate())
225        printS16X4ImmOperand(MI, OpNo);
226      else
227        printSymbolLo(MI, OpNo);
228      O << '(';
229      if (MI->getOperand(OpNo+1).isRegister() &&
230          MI->getOperand(OpNo+1).getReg() == PPC::R0)
231        O << "0";
232      else
233        printOperand(MI, OpNo+1);
234      O << ')';
235    }
236
237    void printMemRegReg(const MachineInstr *MI, unsigned OpNo) {
238      // When used as the base register, r0 reads constant zero rather than
239      // the value contained in the register.  For this reason, the darwin
240      // assembler requires that we print r0 as 0 (no r) when used as the base.
241      const MachineOperand &MO = MI->getOperand(OpNo);
242      if (MO.getReg() == PPC::R0)
243        O << '0';
244      else
245        O << TM.getRegisterInfo()->get(MO.getReg()).Name;
246      O << ", ";
247      printOperand(MI, OpNo+1);
248    }
249
250    void printPredicateOperand(const MachineInstr *MI, unsigned OpNo,
251                               const char *Modifier);
252
253    virtual bool runOnMachineFunction(MachineFunction &F) = 0;
254    virtual bool doFinalization(Module &M) = 0;
255  };
256
257  /// DarwinAsmPrinter - PowerPC assembly printer, customized for Darwin/Mac OS
258  /// X
259  struct VISIBILITY_HIDDEN DarwinAsmPrinter : public PPCAsmPrinter {
260
261    DwarfWriter DW;
262
263    DarwinAsmPrinter(std::ostream &O, PPCTargetMachine &TM,
264                     const TargetAsmInfo *T)
265      : PPCAsmPrinter(O, TM, T), DW(O, this, T) {
266    }
267
268    virtual const char *getPassName() const {
269      return "Darwin PPC Assembly Printer";
270    }
271
272    bool runOnMachineFunction(MachineFunction &F);
273    bool doInitialization(Module &M);
274    bool doFinalization(Module &M);
275
276    void getAnalysisUsage(AnalysisUsage &AU) const {
277      AU.setPreservesAll();
278      AU.addRequired<MachineDebugInfo>();
279      PPCAsmPrinter::getAnalysisUsage(AU);
280    }
281
282    /// getSectionForFunction - Return the section that we should emit the
283    /// specified function body into.
284    virtual std::string getSectionForFunction(const Function &F) const;
285  };
286} // end of anonymous namespace
287
288// Include the auto-generated portion of the assembly writer
289#include "PPCGenAsmWriter.inc"
290
291void PPCAsmPrinter::printOp(const MachineOperand &MO) {
292  switch (MO.getType()) {
293  case MachineOperand::MO_Immediate:
294    cerr << "printOp() does not handle immediate values\n";
295    abort();
296    return;
297
298  case MachineOperand::MO_MachineBasicBlock:
299    printBasicBlockLabel(MO.getMachineBasicBlock());
300    return;
301  case MachineOperand::MO_JumpTableIndex:
302    O << TAI->getPrivateGlobalPrefix() << "JTI" << getFunctionNumber()
303      << '_' << MO.getJumpTableIndex();
304    // FIXME: PIC relocation model
305    return;
306  case MachineOperand::MO_ConstantPoolIndex:
307    O << TAI->getPrivateGlobalPrefix() << "CPI" << getFunctionNumber()
308      << '_' << MO.getConstantPoolIndex();
309    return;
310  case MachineOperand::MO_ExternalSymbol:
311    // Computing the address of an external symbol, not calling it.
312    if (TM.getRelocationModel() != Reloc::Static) {
313      std::string Name(TAI->getGlobalPrefix()); Name += MO.getSymbolName();
314      GVStubs.insert(Name);
315      O << "L" << Name << "$non_lazy_ptr";
316      return;
317    }
318    O << TAI->getGlobalPrefix() << MO.getSymbolName();
319    return;
320  case MachineOperand::MO_GlobalAddress: {
321    // Computing the address of a global symbol, not calling it.
322    GlobalValue *GV = MO.getGlobal();
323    std::string Name = Mang->getValueName(GV);
324
325    // External or weakly linked global variables need non-lazily-resolved stubs
326    if (TM.getRelocationModel() != Reloc::Static) {
327      if (((GV->isExternal() || GV->hasWeakLinkage() ||
328            GV->hasLinkOnceLinkage()))) {
329        GVStubs.insert(Name);
330        O << "L" << Name << "$non_lazy_ptr";
331        return;
332      }
333    }
334    O << Name;
335
336    if (GV->hasExternalWeakLinkage())
337      ExtWeakSymbols.insert(GV);
338    return;
339  }
340
341  default:
342    O << "<unknown operand type: " << MO.getType() << ">";
343    return;
344  }
345}
346
347/// PrintAsmOperand - Print out an operand for an inline asm expression.
348///
349bool PPCAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,
350                                    unsigned AsmVariant,
351                                    const char *ExtraCode) {
352  // Does this asm operand have a single letter operand modifier?
353  if (ExtraCode && ExtraCode[0]) {
354    if (ExtraCode[1] != 0) return true; // Unknown modifier.
355
356    switch (ExtraCode[0]) {
357    default: return true;  // Unknown modifier.
358    case 'L': // Write second word of DImode reference.
359      // Verify that this operand has two consecutive registers.
360      if (!MI->getOperand(OpNo).isRegister() ||
361          OpNo+1 == MI->getNumOperands() ||
362          !MI->getOperand(OpNo+1).isRegister())
363        return true;
364      ++OpNo;   // Return the high-part.
365      break;
366    }
367  }
368
369  printOperand(MI, OpNo);
370  return false;
371}
372
373bool PPCAsmPrinter::PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNo,
374                                          unsigned AsmVariant,
375                                          const char *ExtraCode) {
376  if (ExtraCode && ExtraCode[0])
377    return true; // Unknown modifier.
378  printMemRegReg(MI, OpNo);
379  return false;
380}
381
382void PPCAsmPrinter::printPredicateOperand(const MachineInstr *MI, unsigned OpNo,
383                                          const char *Modifier) {
384  assert(Modifier && "Must specify 'cc' or 'reg' as predicate op modifier!");
385  unsigned Code = MI->getOperand(OpNo).getImm();
386  if (!strcmp(Modifier, "cc")) {
387    switch ((PPC::Predicate)Code) {
388    case PPC::PRED_ALWAYS: return; // Don't print anything for always.
389    case PPC::PRED_LT: O << "lt"; return;
390    case PPC::PRED_LE: O << "le"; return;
391    case PPC::PRED_EQ: O << "eq"; return;
392    case PPC::PRED_GE: O << "ge"; return;
393    case PPC::PRED_GT: O << "gt"; return;
394    case PPC::PRED_NE: O << "ne"; return;
395    case PPC::PRED_UN: O << "un"; return;
396    case PPC::PRED_NU: O << "nu"; return;
397    }
398
399  } else {
400    assert(!strcmp(Modifier, "reg") &&
401           "Need to specify 'cc' or 'reg' as predicate op modifier!");
402    // Don't print the register for 'always'.
403    if (Code == PPC::PRED_ALWAYS) return;
404    printOperand(MI, OpNo+1);
405  }
406}
407
408
409/// printMachineInstruction -- Print out a single PowerPC MI in Darwin syntax to
410/// the current output stream.
411///
412void PPCAsmPrinter::printMachineInstruction(const MachineInstr *MI) {
413  ++EmittedInsts;
414
415  // Check for slwi/srwi mnemonics.
416  if (MI->getOpcode() == PPC::RLWINM) {
417    bool FoundMnemonic = false;
418    unsigned char SH = MI->getOperand(2).getImmedValue();
419    unsigned char MB = MI->getOperand(3).getImmedValue();
420    unsigned char ME = MI->getOperand(4).getImmedValue();
421    if (SH <= 31 && MB == 0 && ME == (31-SH)) {
422      O << "slwi "; FoundMnemonic = true;
423    }
424    if (SH <= 31 && MB == (32-SH) && ME == 31) {
425      O << "srwi "; FoundMnemonic = true;
426      SH = 32-SH;
427    }
428    if (FoundMnemonic) {
429      printOperand(MI, 0);
430      O << ", ";
431      printOperand(MI, 1);
432      O << ", " << (unsigned int)SH << "\n";
433      return;
434    }
435  } else if (MI->getOpcode() == PPC::OR || MI->getOpcode() == PPC::OR8) {
436    if (MI->getOperand(1).getReg() == MI->getOperand(2).getReg()) {
437      O << "mr ";
438      printOperand(MI, 0);
439      O << ", ";
440      printOperand(MI, 1);
441      O << "\n";
442      return;
443    }
444  } else if (MI->getOpcode() == PPC::RLDICR) {
445    unsigned char SH = MI->getOperand(2).getImmedValue();
446    unsigned char ME = MI->getOperand(3).getImmedValue();
447    // rldicr RA, RS, SH, 63-SH == sldi RA, RS, SH
448    if (63-SH == ME) {
449      O << "sldi ";
450      printOperand(MI, 0);
451      O << ", ";
452      printOperand(MI, 1);
453      O << ", " << (unsigned int)SH << "\n";
454      return;
455    }
456  }
457
458  if (printInstruction(MI))
459    return; // Printer was automatically generated
460
461  assert(0 && "Unhandled instruction in asm writer!");
462  abort();
463  return;
464}
465
466
467
468std::string DarwinAsmPrinter::getSectionForFunction(const Function &F) const {
469  switch (F.getLinkage()) {
470  default: assert(0 && "Unknown linkage type!");
471  case Function::ExternalLinkage:
472  case Function::InternalLinkage: return TAI->getTextSection();
473  case Function::WeakLinkage:
474  case Function::LinkOnceLinkage:
475    return ".section __TEXT,__textcoal_nt,coalesced,pure_instructions";
476  }
477}
478
479/// runOnMachineFunction - This uses the printMachineInstruction()
480/// method to print assembly for each instruction.
481///
482bool DarwinAsmPrinter::runOnMachineFunction(MachineFunction &MF) {
483  DW.SetDebugInfo(&getAnalysis<MachineDebugInfo>());
484
485  SetupMachineFunction(MF);
486  O << "\n\n";
487
488  // Print out constants referenced by the function
489  EmitConstantPool(MF.getConstantPool());
490
491  // Print out labels for the function.
492  const Function *F = MF.getFunction();
493  SwitchToTextSection(getSectionForFunction(*F).c_str(), F);
494
495  switch (F->getLinkage()) {
496  default: assert(0 && "Unknown linkage type!");
497  case Function::InternalLinkage:  // Symbols default to internal.
498    break;
499  case Function::ExternalLinkage:
500    O << "\t.globl\t" << CurrentFnName << "\n";
501    break;
502  case Function::WeakLinkage:
503  case Function::LinkOnceLinkage:
504    O << "\t.globl\t" << CurrentFnName << "\n";
505    O << "\t.weak_definition\t" << CurrentFnName << "\n";
506    break;
507  }
508  EmitAlignment(4, F);
509  O << CurrentFnName << ":\n";
510
511  // Emit pre-function debug information.
512  DW.BeginFunction(&MF);
513
514  // Print out code for the function.
515  for (MachineFunction::const_iterator I = MF.begin(), E = MF.end();
516       I != E; ++I) {
517    // Print a label for the basic block.
518    if (I != MF.begin()) {
519      printBasicBlockLabel(I, true);
520      O << '\n';
521    }
522    for (MachineBasicBlock::const_iterator II = I->begin(), E = I->end();
523         II != E; ++II) {
524      // Print the assembly for the instruction.
525      O << "\t";
526      printMachineInstruction(II);
527    }
528  }
529
530  // Print out jump tables referenced by the function.
531  EmitJumpTableInfo(MF.getJumpTableInfo(), MF);
532
533  // Emit post-function debug information.
534  DW.EndFunction();
535
536  // We didn't modify anything.
537  return false;
538}
539
540
541bool DarwinAsmPrinter::doInitialization(Module &M) {
542  static const char *CPUDirectives[] = {
543    "ppc",
544    "ppc601",
545    "ppc602",
546    "ppc603",
547    "ppc7400",
548    "ppc750",
549    "ppc970",
550    "ppc64"
551  };
552
553  unsigned Directive = Subtarget.getDarwinDirective();
554  if (Subtarget.isGigaProcessor() && Directive < PPC::DIR_970)
555    Directive = PPC::DIR_970;
556  if (Subtarget.hasAltivec() && Directive < PPC::DIR_7400)
557    Directive = PPC::DIR_7400;
558  if (Subtarget.isPPC64() && Directive < PPC::DIR_970)
559    Directive = PPC::DIR_64;
560  assert(Directive <= PPC::DIR_64 && "Directive out of range.");
561  O << "\t.machine " << CPUDirectives[Directive] << "\n";
562
563  AsmPrinter::doInitialization(M);
564
565  // Darwin wants symbols to be quoted if they have complex names.
566  Mang->setUseQuotes(true);
567
568  // Prime text sections so they are adjacent.  This reduces the likelihood a
569  // large data or debug section causes a branch to exceed 16M limit.
570  SwitchToTextSection(".section __TEXT,__textcoal_nt,coalesced,"
571                      "pure_instructions");
572  if (TM.getRelocationModel() == Reloc::PIC_) {
573    SwitchToTextSection(".section __TEXT,__picsymbolstub1,symbol_stubs,"
574                          "pure_instructions,32");
575  } else if (TM.getRelocationModel() == Reloc::DynamicNoPIC) {
576    SwitchToTextSection(".section __TEXT,__symbol_stub1,symbol_stubs,"
577                        "pure_instructions,16");
578  }
579  SwitchToTextSection(TAI->getTextSection());
580
581  // Emit initial debug information.
582  DW.BeginModule(&M);
583  return false;
584}
585
586bool DarwinAsmPrinter::doFinalization(Module &M) {
587  const TargetData *TD = TM.getTargetData();
588
589  // Print out module-level global variables here.
590  for (Module::const_global_iterator I = M.global_begin(), E = M.global_end();
591       I != E; ++I) {
592    if (!I->hasInitializer()) continue;   // External global require no code
593
594    // Check to see if this is a special global used by LLVM, if so, emit it.
595    if (EmitSpecialLLVMGlobal(I))
596      continue;
597
598    std::string name = Mang->getValueName(I);
599    Constant *C = I->getInitializer();
600    unsigned Size = TD->getTypeSize(C->getType());
601    unsigned Align = TD->getPreferredAlignmentLog(I);
602
603    if (C->isNullValue() && /* FIXME: Verify correct */
604        (I->hasInternalLinkage() || I->hasWeakLinkage() ||
605         I->hasLinkOnceLinkage() ||
606         (I->hasExternalLinkage() && !I->hasSection()))) {
607      if (Size == 0) Size = 1;   // .comm Foo, 0 is undefined, avoid it.
608      if (I->hasExternalLinkage()) {
609        O << "\t.globl " << name << '\n';
610        O << "\t.zerofill __DATA, __common, " << name << ", "
611          << Size << ", " << Align;
612      } else if (I->hasInternalLinkage()) {
613        SwitchToDataSection("\t.data", I);
614        O << TAI->getLCOMMDirective() << name << "," << Size << "," << Align;
615      } else {
616        SwitchToDataSection("\t.data", I);
617        O << ".comm " << name << "," << Size;
618      }
619      O << "\t\t; '" << I->getName() << "'\n";
620    } else {
621      switch (I->getLinkage()) {
622      case GlobalValue::LinkOnceLinkage:
623      case GlobalValue::WeakLinkage:
624        O << "\t.globl " << name << '\n'
625          << "\t.weak_definition " << name << '\n';
626        SwitchToDataSection(".section __DATA,__datacoal_nt,coalesced", I);
627        break;
628      case GlobalValue::AppendingLinkage:
629        // FIXME: appending linkage variables should go into a section of
630        // their name or something.  For now, just emit them as external.
631      case GlobalValue::ExternalLinkage:
632        // If external or appending, declare as a global symbol
633        O << "\t.globl " << name << "\n";
634        // FALL THROUGH
635      case GlobalValue::InternalLinkage:
636        if (I->isConstant()) {
637          const ConstantArray *CVA = dyn_cast<ConstantArray>(C);
638          if (TAI->getCStringSection() && CVA && CVA->isCString()) {
639            SwitchToDataSection(TAI->getCStringSection(), I);
640            break;
641          }
642        }
643
644        SwitchToDataSection("\t.data", I);
645        break;
646      default:
647        cerr << "Unknown linkage type!";
648        abort();
649      }
650
651      EmitAlignment(Align, I);
652      O << name << ":\t\t\t\t; '" << I->getName() << "'\n";
653
654      // If the initializer is a extern weak symbol, remember to emit the weak
655      // reference!
656      if (const GlobalValue *GV = dyn_cast<GlobalValue>(C))
657        if (GV->hasExternalWeakLinkage())
658          ExtWeakSymbols.insert(GV);
659
660      EmitGlobalConstant(C);
661      O << '\n';
662    }
663  }
664
665  bool isPPC64 = TD->getPointerSizeInBits() == 64;
666
667  // Output stubs for dynamically-linked functions
668  if (TM.getRelocationModel() == Reloc::PIC_) {
669    for (std::set<std::string>::iterator i = FnStubs.begin(), e = FnStubs.end();
670         i != e; ++i) {
671      SwitchToTextSection(".section __TEXT,__picsymbolstub1,symbol_stubs,"
672                          "pure_instructions,32");
673      EmitAlignment(4);
674      O << "L" << *i << "$stub:\n";
675      O << "\t.indirect_symbol " << *i << "\n";
676      O << "\tmflr r0\n";
677      O << "\tbcl 20,31,L0$" << *i << "\n";
678      O << "L0$" << *i << ":\n";
679      O << "\tmflr r11\n";
680      O << "\taddis r11,r11,ha16(L" << *i << "$lazy_ptr-L0$" << *i << ")\n";
681      O << "\tmtlr r0\n";
682      if (isPPC64)
683        O << "\tldu r12,lo16(L" << *i << "$lazy_ptr-L0$" << *i << ")(r11)\n";
684      else
685        O << "\tlwzu r12,lo16(L" << *i << "$lazy_ptr-L0$" << *i << ")(r11)\n";
686      O << "\tmtctr r12\n";
687      O << "\tbctr\n";
688      SwitchToDataSection(".lazy_symbol_pointer");
689      O << "L" << *i << "$lazy_ptr:\n";
690      O << "\t.indirect_symbol " << *i << "\n";
691      if (isPPC64)
692        O << "\t.quad dyld_stub_binding_helper\n";
693      else
694        O << "\t.long dyld_stub_binding_helper\n";
695    }
696  } else {
697    for (std::set<std::string>::iterator i = FnStubs.begin(), e = FnStubs.end();
698         i != e; ++i) {
699      SwitchToTextSection(".section __TEXT,__symbol_stub1,symbol_stubs,"
700                          "pure_instructions,16");
701      EmitAlignment(4);
702      O << "L" << *i << "$stub:\n";
703      O << "\t.indirect_symbol " << *i << "\n";
704      O << "\tlis r11,ha16(L" << *i << "$lazy_ptr)\n";
705      if (isPPC64)
706        O << "\tldu r12,lo16(L" << *i << "$lazy_ptr)(r11)\n";
707      else
708        O << "\tlwzu r12,lo16(L" << *i << "$lazy_ptr)(r11)\n";
709      O << "\tmtctr r12\n";
710      O << "\tbctr\n";
711      SwitchToDataSection(".lazy_symbol_pointer");
712      O << "L" << *i << "$lazy_ptr:\n";
713      O << "\t.indirect_symbol " << *i << "\n";
714      if (isPPC64)
715        O << "\t.quad dyld_stub_binding_helper\n";
716      else
717        O << "\t.long dyld_stub_binding_helper\n";
718    }
719  }
720
721  O << "\n";
722
723  // Output stubs for external and common global variables.
724  if (GVStubs.begin() != GVStubs.end()) {
725    SwitchToDataSection(".non_lazy_symbol_pointer");
726    for (std::set<std::string>::iterator I = GVStubs.begin(),
727         E = GVStubs.end(); I != E; ++I) {
728      O << "L" << *I << "$non_lazy_ptr:\n";
729      O << "\t.indirect_symbol " << *I << "\n";
730      if (isPPC64)
731        O << "\t.quad\t0\n";
732      else
733        O << "\t.long\t0\n";
734
735    }
736  }
737
738  // Emit initial debug information.
739  DW.EndModule();
740
741  // Funny Darwin hack: This flag tells the linker that no global symbols
742  // contain code that falls through to other global symbols (e.g. the obvious
743  // implementation of multiple entry points).  If this doesn't occur, the
744  // linker can safely perform dead code stripping.  Since LLVM never generates
745  // code that does this, it is always safe to set.
746  O << "\t.subsections_via_symbols\n";
747
748  AsmPrinter::doFinalization(M);
749  return false; // success
750}
751
752
753
754/// createDarwinCodePrinterPass - Returns a pass that prints the PPC assembly
755/// code for a MachineFunction to the given output stream, in a format that the
756/// Darwin assembler can deal with.
757///
758FunctionPass *llvm::createPPCAsmPrinterPass(std::ostream &o,
759                                            PPCTargetMachine &tm) {
760  return new DarwinAsmPrinter(o, tm, tm.getTargetAsmInfo());
761}
762
763