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