remove the TargetLoweringObjectFileMachO::getMachoSection
[oota-llvm.git] / lib / Target / PowerPC / AsmPrinter / PPCAsmPrinter.cpp
1 //===-- PPCAsmPrinter.cpp - Print machine instrs to PowerPC assembly --------=//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // 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/MachineFunctionPass.h"
30 #include "llvm/CodeGen/MachineInstr.h"
31 #include "llvm/CodeGen/MachineInstrBuilder.h"
32 #include "llvm/CodeGen/MachineModuleInfoImpls.h"
33 #include "llvm/CodeGen/TargetLoweringObjectFileImpl.h"
34 #include "llvm/MC/MCAsmInfo.h"
35 #include "llvm/MC/MCContext.h"
36 #include "llvm/MC/MCExpr.h"
37 #include "llvm/MC/MCSectionMachO.h"
38 #include "llvm/MC/MCStreamer.h"
39 #include "llvm/MC/MCSymbol.h"
40 #include "llvm/Target/Mangler.h"
41 #include "llvm/Target/TargetRegisterInfo.h"
42 #include "llvm/Target/TargetInstrInfo.h"
43 #include "llvm/Target/TargetOptions.h"
44 #include "llvm/Target/TargetRegistry.h"
45 #include "llvm/Support/MathExtras.h"
46 #include "llvm/Support/ErrorHandling.h"
47 #include "llvm/Support/raw_ostream.h"
48 #include "llvm/ADT/StringExtras.h"
49 #include "llvm/ADT/StringSet.h"
50 #include "llvm/ADT/SmallString.h"
51 using namespace llvm;
52
53 namespace {
54   class PPCAsmPrinter : public AsmPrinter {
55   protected:
56     DenseMap<MCSymbol*, MCSymbol*> TOC;
57     const PPCSubtarget &Subtarget;
58     uint64_t LabelID;
59   public:
60     explicit PPCAsmPrinter(TargetMachine &TM, MCStreamer &Streamer)
61       : AsmPrinter(TM, Streamer),
62         Subtarget(TM.getSubtarget<PPCSubtarget>()), LabelID(0) {}
63
64     virtual const char *getPassName() const {
65       return "PowerPC Assembly Printer";
66     }
67
68     PPCTargetMachine &getTM() {
69       return static_cast<PPCTargetMachine&>(TM);
70     }
71
72     unsigned enumRegToMachineReg(unsigned enumReg) {
73       switch (enumReg) {
74       default: llvm_unreachable("Unhandled register!");
75       case PPC::CR0:  return  0;
76       case PPC::CR1:  return  1;
77       case PPC::CR2:  return  2;
78       case PPC::CR3:  return  3;
79       case PPC::CR4:  return  4;
80       case PPC::CR5:  return  5;
81       case PPC::CR6:  return  6;
82       case PPC::CR7:  return  7;
83       }
84       llvm_unreachable(0);
85     }
86
87     /// printInstruction - This method is automatically generated by tablegen
88     /// from the instruction set description.  This method returns true if the
89     /// machine instruction was sufficiently described to print it, otherwise it
90     /// returns false.
91     void printInstruction(const MachineInstr *MI, raw_ostream &O);
92     static const char *getRegisterName(unsigned RegNo);
93
94
95     virtual void EmitInstruction(const MachineInstr *MI);
96     void printOp(const MachineOperand &MO, raw_ostream &O);
97
98     /// stripRegisterPrefix - This method strips the character prefix from a
99     /// register name so that only the number is left.  Used by for linux asm.
100     const char *stripRegisterPrefix(const char *RegName) {
101       switch (RegName[0]) {
102       case 'r':
103       case 'f':
104       case 'v': return RegName + 1;
105       case 'c': if (RegName[1] == 'r') return RegName + 2;
106       }
107
108       return RegName;
109     }
110
111     /// printRegister - Print register according to target requirements.
112     ///
113     void printRegister(const MachineOperand &MO, bool R0AsZero, raw_ostream &O){
114       unsigned RegNo = MO.getReg();
115       assert(TargetRegisterInfo::isPhysicalRegister(RegNo) && "Not physreg??");
116
117       // If we should use 0 for R0.
118       if (R0AsZero && RegNo == PPC::R0) {
119         O << "0";
120         return;
121       }
122
123       const char *RegName = getRegisterName(RegNo);
124       // Linux assembler (Others?) does not take register mnemonics.
125       // FIXME - What about special registers used in mfspr/mtspr?
126       if (!Subtarget.isDarwin()) RegName = stripRegisterPrefix(RegName);
127       O << RegName;
128     }
129
130     void printOperand(const MachineInstr *MI, unsigned OpNo, raw_ostream &O) {
131       const MachineOperand &MO = MI->getOperand(OpNo);
132       if (MO.isReg()) {
133         printRegister(MO, false, O);
134       } else if (MO.isImm()) {
135         O << MO.getImm();
136       } else {
137         printOp(MO, O);
138       }
139     }
140
141     bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,
142                          unsigned AsmVariant, const char *ExtraCode,
143                          raw_ostream &O);
144     bool PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNo,
145                                unsigned AsmVariant, const char *ExtraCode,
146                                raw_ostream &O);
147
148
149     void printS5ImmOperand(const MachineInstr *MI, unsigned OpNo,
150                            raw_ostream &O) {
151       char value = MI->getOperand(OpNo).getImm();
152       value = (value << (32-5)) >> (32-5);
153       O << (int)value;
154     }
155     void printU5ImmOperand(const MachineInstr *MI, unsigned OpNo,
156                            raw_ostream &O) {
157       unsigned char value = MI->getOperand(OpNo).getImm();
158       assert(value <= 31 && "Invalid u5imm argument!");
159       O << (unsigned int)value;
160     }
161     void printU6ImmOperand(const MachineInstr *MI, unsigned OpNo,
162                            raw_ostream &O) {
163       unsigned char value = MI->getOperand(OpNo).getImm();
164       assert(value <= 63 && "Invalid u6imm argument!");
165       O << (unsigned int)value;
166     }
167     void printS16ImmOperand(const MachineInstr *MI, unsigned OpNo, 
168                             raw_ostream &O) {
169       O << (short)MI->getOperand(OpNo).getImm();
170     }
171     void printU16ImmOperand(const MachineInstr *MI, unsigned OpNo,
172                             raw_ostream &O) {
173       O << (unsigned short)MI->getOperand(OpNo).getImm();
174     }
175     void printS16X4ImmOperand(const MachineInstr *MI, unsigned OpNo,
176                               raw_ostream &O) {
177       if (MI->getOperand(OpNo).isImm()) {
178         O << (short)(MI->getOperand(OpNo).getImm()*4);
179       } else {
180         O << "lo16(";
181         printOp(MI->getOperand(OpNo), O);
182         if (TM.getRelocationModel() == Reloc::PIC_)
183           O << "-\"L" << getFunctionNumber() << "$pb\")";
184         else
185           O << ')';
186       }
187     }
188     void printBranchOperand(const MachineInstr *MI, unsigned OpNo,
189                             raw_ostream &O) {
190       // Branches can take an immediate operand.  This is used by the branch
191       // selection pass to print $+8, an eight byte displacement from the PC.
192       if (MI->getOperand(OpNo).isImm()) {
193         O << "$+" << MI->getOperand(OpNo).getImm()*4;
194       } else {
195         printOp(MI->getOperand(OpNo), O);
196       }
197     }
198     void printCallOperand(const MachineInstr *MI, unsigned OpNo,
199                           raw_ostream &O) {
200       const MachineOperand &MO = MI->getOperand(OpNo);
201       if (TM.getRelocationModel() != Reloc::Static) {
202         if (MO.getType() == MachineOperand::MO_GlobalAddress) {
203           GlobalValue *GV = MO.getGlobal();
204           if (GV->isDeclaration() || GV->isWeakForLinker()) {
205             // Dynamically-resolved functions need a stub for the function.
206             MCSymbol *Sym = GetSymbolWithGlobalValueBase(GV, "$stub");
207             MachineModuleInfoImpl::StubValueTy &StubSym =
208               MMI->getObjFileInfo<MachineModuleInfoMachO>().getFnStubEntry(Sym);
209             if (StubSym.getPointer() == 0)
210               StubSym = MachineModuleInfoImpl::
211                 StubValueTy(Mang->getSymbol(GV), !GV->hasInternalLinkage());
212             O << *Sym;
213             return;
214           }
215         }
216         if (MO.getType() == MachineOperand::MO_ExternalSymbol) {
217           SmallString<128> TempNameStr;
218           TempNameStr += StringRef(MO.getSymbolName());
219           TempNameStr += StringRef("$stub");
220           
221           MCSymbol *Sym = GetExternalSymbolSymbol(TempNameStr.str());
222           MachineModuleInfoImpl::StubValueTy &StubSym =
223             MMI->getObjFileInfo<MachineModuleInfoMachO>().getFnStubEntry(Sym);
224           if (StubSym.getPointer() == 0)
225             StubSym = MachineModuleInfoImpl::
226               StubValueTy(GetExternalSymbolSymbol(MO.getSymbolName()), true);
227           O << *Sym;
228           return;
229         }
230       }
231
232       printOp(MI->getOperand(OpNo), O);
233     }
234     void printAbsAddrOperand(const MachineInstr *MI, unsigned OpNo,
235                              raw_ostream &O) {
236      O << (int)MI->getOperand(OpNo).getImm()*4;
237     }
238     void printPICLabel(const MachineInstr *MI, unsigned OpNo, raw_ostream &O) {
239       O << "\"L" << getFunctionNumber() << "$pb\"\n";
240       O << "\"L" << getFunctionNumber() << "$pb\":";
241     }
242     void printSymbolHi(const MachineInstr *MI, unsigned OpNo, raw_ostream &O) {
243       if (MI->getOperand(OpNo).isImm()) {
244         printS16ImmOperand(MI, OpNo, O);
245       } else {
246         if (Subtarget.isDarwin()) O << "ha16(";
247         printOp(MI->getOperand(OpNo), O);
248         if (TM.getRelocationModel() == Reloc::PIC_)
249           O << "-\"L" << getFunctionNumber() << "$pb\"";
250         if (Subtarget.isDarwin())
251           O << ')';
252         else
253           O << "@ha";
254       }
255     }
256     void printSymbolLo(const MachineInstr *MI, unsigned OpNo, raw_ostream &O) {
257       if (MI->getOperand(OpNo).isImm()) {
258         printS16ImmOperand(MI, OpNo, O);
259       } else {
260         if (Subtarget.isDarwin()) O << "lo16(";
261         printOp(MI->getOperand(OpNo), O);
262         if (TM.getRelocationModel() == Reloc::PIC_)
263           O << "-\"L" << getFunctionNumber() << "$pb\"";
264         if (Subtarget.isDarwin())
265           O << ')';
266         else
267           O << "@l";
268       }
269     }
270     void printcrbitm(const MachineInstr *MI, unsigned OpNo, raw_ostream &O) {
271       unsigned CCReg = MI->getOperand(OpNo).getReg();
272       unsigned RegNo = enumRegToMachineReg(CCReg);
273       O << (0x80 >> RegNo);
274     }
275     // The new addressing mode printers.
276     void printMemRegImm(const MachineInstr *MI, unsigned OpNo, raw_ostream &O) {
277       printSymbolLo(MI, OpNo, O);
278       O << '(';
279       if (MI->getOperand(OpNo+1).isReg() &&
280           MI->getOperand(OpNo+1).getReg() == PPC::R0)
281         O << "0";
282       else
283         printOperand(MI, OpNo+1, O);
284       O << ')';
285     }
286     void printMemRegImmShifted(const MachineInstr *MI, unsigned OpNo,
287                                raw_ostream &O) {
288       if (MI->getOperand(OpNo).isImm())
289         printS16X4ImmOperand(MI, OpNo, O);
290       else
291         printSymbolLo(MI, OpNo, O);
292       O << '(';
293       if (MI->getOperand(OpNo+1).isReg() &&
294           MI->getOperand(OpNo+1).getReg() == PPC::R0)
295         O << "0";
296       else
297         printOperand(MI, OpNo+1, O);
298       O << ')';
299     }
300
301     void printMemRegReg(const MachineInstr *MI, unsigned OpNo, raw_ostream &O) {
302       // When used as the base register, r0 reads constant zero rather than
303       // the value contained in the register.  For this reason, the darwin
304       // assembler requires that we print r0 as 0 (no r) when used as the base.
305       const MachineOperand &MO = MI->getOperand(OpNo);
306       printRegister(MO, true, O);
307       O << ", ";
308       printOperand(MI, OpNo+1, O);
309     }
310
311     void printTOCEntryLabel(const MachineInstr *MI, unsigned OpNo,
312                             raw_ostream &O) {
313       const MachineOperand &MO = MI->getOperand(OpNo);
314       assert(MO.getType() == MachineOperand::MO_GlobalAddress);
315       MCSymbol *Sym = Mang->getSymbol(MO.getGlobal());
316
317       // Map symbol -> label of TOC entry.
318       MCSymbol *&TOCEntry = TOC[Sym];
319       if (TOCEntry == 0)
320         TOCEntry = OutContext.
321           GetOrCreateSymbol(StringRef(MAI->getPrivateGlobalPrefix()) +
322                             "C" + Twine(LabelID++));
323
324       O << *TOCEntry << "@toc";
325     }
326
327     void printPredicateOperand(const MachineInstr *MI, unsigned OpNo,
328                                raw_ostream &O, const char *Modifier);
329   };
330
331   /// PPCLinuxAsmPrinter - PowerPC assembly printer, customized for Linux
332   class PPCLinuxAsmPrinter : public PPCAsmPrinter {
333   public:
334     explicit PPCLinuxAsmPrinter(TargetMachine &TM, MCStreamer &Streamer)
335       : PPCAsmPrinter(TM, Streamer) {}
336
337     virtual const char *getPassName() const {
338       return "Linux PPC Assembly Printer";
339     }
340
341     bool doFinalization(Module &M);
342
343     virtual void EmitFunctionEntryLabel();
344   };
345
346   /// PPCDarwinAsmPrinter - PowerPC assembly printer, customized for Darwin/Mac
347   /// OS X
348   class PPCDarwinAsmPrinter : public PPCAsmPrinter {
349   public:
350     explicit PPCDarwinAsmPrinter(TargetMachine &TM, MCStreamer &Streamer)
351       : PPCAsmPrinter(TM, Streamer) {}
352
353     virtual const char *getPassName() const {
354       return "Darwin PPC Assembly Printer";
355     }
356
357     bool doFinalization(Module &M);
358     void EmitStartOfAsmFile(Module &M);
359
360     void EmitFunctionStubs(const MachineModuleInfoMachO::SymbolListTy &Stubs);
361   };
362 } // end of anonymous namespace
363
364 // Include the auto-generated portion of the assembly writer
365 #include "PPCGenAsmWriter.inc"
366
367 void PPCAsmPrinter::printOp(const MachineOperand &MO, raw_ostream &O) {
368   switch (MO.getType()) {
369   case MachineOperand::MO_Immediate:
370     llvm_unreachable("printOp() does not handle immediate values");
371
372   case MachineOperand::MO_MachineBasicBlock:
373     O << *MO.getMBB()->getSymbol();
374     return;
375   case MachineOperand::MO_JumpTableIndex:
376     O << MAI->getPrivateGlobalPrefix() << "JTI" << getFunctionNumber()
377       << '_' << MO.getIndex();
378     // FIXME: PIC relocation model
379     return;
380   case MachineOperand::MO_ConstantPoolIndex:
381     O << MAI->getPrivateGlobalPrefix() << "CPI" << getFunctionNumber()
382       << '_' << MO.getIndex();
383     return;
384   case MachineOperand::MO_BlockAddress:
385     O << *GetBlockAddressSymbol(MO.getBlockAddress());
386     return;
387   case MachineOperand::MO_ExternalSymbol: {
388     // Computing the address of an external symbol, not calling it.
389     if (TM.getRelocationModel() == Reloc::Static) {
390       O << *GetExternalSymbolSymbol(MO.getSymbolName());
391       return;
392     }
393
394     MCSymbol *NLPSym = 
395       OutContext.GetOrCreateSymbol(StringRef(MAI->getGlobalPrefix())+
396                                    MO.getSymbolName()+"$non_lazy_ptr");
397     MachineModuleInfoImpl::StubValueTy &StubSym = 
398       MMI->getObjFileInfo<MachineModuleInfoMachO>().getGVStubEntry(NLPSym);
399     if (StubSym.getPointer() == 0)
400       StubSym = MachineModuleInfoImpl::
401         StubValueTy(GetExternalSymbolSymbol(MO.getSymbolName()), true);
402     
403     O << *NLPSym;
404     return;
405   }
406   case MachineOperand::MO_GlobalAddress: {
407     // Computing the address of a global symbol, not calling it.
408     GlobalValue *GV = MO.getGlobal();
409     MCSymbol *SymToPrint;
410
411     // External or weakly linked global variables need non-lazily-resolved stubs
412     if (TM.getRelocationModel() != Reloc::Static &&
413         (GV->isDeclaration() || GV->isWeakForLinker())) {
414       if (!GV->hasHiddenVisibility()) {
415         SymToPrint = GetSymbolWithGlobalValueBase(GV, "$non_lazy_ptr");
416         MachineModuleInfoImpl::StubValueTy &StubSym = 
417           MMI->getObjFileInfo<MachineModuleInfoMachO>()
418             .getGVStubEntry(SymToPrint);
419         if (StubSym.getPointer() == 0)
420           StubSym = MachineModuleInfoImpl::
421             StubValueTy(Mang->getSymbol(GV), !GV->hasInternalLinkage());
422       } else if (GV->isDeclaration() || GV->hasCommonLinkage() ||
423                  GV->hasAvailableExternallyLinkage()) {
424         SymToPrint = GetSymbolWithGlobalValueBase(GV, "$non_lazy_ptr");
425         
426         MachineModuleInfoImpl::StubValueTy &StubSym = 
427           MMI->getObjFileInfo<MachineModuleInfoMachO>().
428                     getHiddenGVStubEntry(SymToPrint);
429         if (StubSym.getPointer() == 0)
430           StubSym = MachineModuleInfoImpl::
431             StubValueTy(Mang->getSymbol(GV), !GV->hasInternalLinkage());
432       } else {
433         SymToPrint = Mang->getSymbol(GV);
434       }
435     } else {
436       SymToPrint = Mang->getSymbol(GV);
437     }
438     
439     O << *SymToPrint;
440
441     printOffset(MO.getOffset(), O);
442     return;
443   }
444
445   default:
446     O << "<unknown operand type: " << MO.getType() << ">";
447     return;
448   }
449 }
450
451 /// PrintAsmOperand - Print out an operand for an inline asm expression.
452 ///
453 bool PPCAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,
454                                     unsigned AsmVariant,
455                                     const char *ExtraCode, raw_ostream &O) {
456   // Does this asm operand have a single letter operand modifier?
457   if (ExtraCode && ExtraCode[0]) {
458     if (ExtraCode[1] != 0) return true; // Unknown modifier.
459
460     switch (ExtraCode[0]) {
461     default: return true;  // Unknown modifier.
462     case 'c': // Don't print "$" before a global var name or constant.
463       // PPC never has a prefix.
464       printOperand(MI, OpNo, O);
465       return false;
466     case 'L': // Write second word of DImode reference.
467       // Verify that this operand has two consecutive registers.
468       if (!MI->getOperand(OpNo).isReg() ||
469           OpNo+1 == MI->getNumOperands() ||
470           !MI->getOperand(OpNo+1).isReg())
471         return true;
472       ++OpNo;   // Return the high-part.
473       break;
474     case 'I':
475       // Write 'i' if an integer constant, otherwise nothing.  Used to print
476       // addi vs add, etc.
477       if (MI->getOperand(OpNo).isImm())
478         O << "i";
479       return false;
480     }
481   }
482
483   printOperand(MI, OpNo, O);
484   return false;
485 }
486
487 // At the moment, all inline asm memory operands are a single register.
488 // In any case, the output of this routine should always be just one
489 // assembler operand.
490
491 bool PPCAsmPrinter::PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNo,
492                                           unsigned AsmVariant,
493                                           const char *ExtraCode,
494                                           raw_ostream &O) {
495   if (ExtraCode && ExtraCode[0])
496     return true; // Unknown modifier.
497   assert (MI->getOperand(OpNo).isReg());
498   O << "0(";
499   printOperand(MI, OpNo, O);
500   O << ")";
501   return false;
502 }
503
504 void PPCAsmPrinter::printPredicateOperand(const MachineInstr *MI, unsigned OpNo,
505                                           raw_ostream &O, const char *Modifier){
506   assert(Modifier && "Must specify 'cc' or 'reg' as predicate op modifier!");
507   unsigned Code = MI->getOperand(OpNo).getImm();
508   if (!strcmp(Modifier, "cc")) {
509     switch ((PPC::Predicate)Code) {
510     case PPC::PRED_ALWAYS: return; // Don't print anything for always.
511     case PPC::PRED_LT: O << "lt"; return;
512     case PPC::PRED_LE: O << "le"; return;
513     case PPC::PRED_EQ: O << "eq"; return;
514     case PPC::PRED_GE: O << "ge"; return;
515     case PPC::PRED_GT: O << "gt"; return;
516     case PPC::PRED_NE: O << "ne"; return;
517     case PPC::PRED_UN: O << "un"; return;
518     case PPC::PRED_NU: O << "nu"; return;
519     }
520
521   } else {
522     assert(!strcmp(Modifier, "reg") &&
523            "Need to specify 'cc' or 'reg' as predicate op modifier!");
524     // Don't print the register for 'always'.
525     if (Code == PPC::PRED_ALWAYS) return;
526     printOperand(MI, OpNo+1, O);
527   }
528 }
529
530
531 /// EmitInstruction -- Print out a single PowerPC MI in Darwin syntax to
532 /// the current output stream.
533 ///
534 void PPCAsmPrinter::EmitInstruction(const MachineInstr *MI) {
535   SmallString<128> Str;
536   raw_svector_ostream O(Str);
537
538   // Check for slwi/srwi mnemonics.
539   if (MI->getOpcode() == PPC::RLWINM) {
540     unsigned char SH = MI->getOperand(2).getImm();
541     unsigned char MB = MI->getOperand(3).getImm();
542     unsigned char ME = MI->getOperand(4).getImm();
543     bool useSubstituteMnemonic = false;
544     if (SH <= 31 && MB == 0 && ME == (31-SH)) {
545       O << "\tslwi "; useSubstituteMnemonic = true;
546     }
547     if (SH <= 31 && MB == (32-SH) && ME == 31) {
548       O << "\tsrwi "; useSubstituteMnemonic = true;
549       SH = 32-SH;
550     }
551     if (useSubstituteMnemonic) {
552       printOperand(MI, 0, O);
553       O << ", ";
554       printOperand(MI, 1, O);
555       O << ", " << (unsigned int)SH;
556       OutStreamer.EmitRawText(O.str());
557       return;
558     }
559   }
560   
561   if ((MI->getOpcode() == PPC::OR || MI->getOpcode() == PPC::OR8) &&
562       MI->getOperand(1).getReg() == MI->getOperand(2).getReg()) {
563     O << "\tmr ";
564     printOperand(MI, 0, O);
565     O << ", ";
566     printOperand(MI, 1, O);
567     OutStreamer.EmitRawText(O.str());
568     return;
569   }
570   
571   if (MI->getOpcode() == PPC::RLDICR) {
572     unsigned char SH = MI->getOperand(2).getImm();
573     unsigned char ME = MI->getOperand(3).getImm();
574     // rldicr RA, RS, SH, 63-SH == sldi RA, RS, SH
575     if (63-SH == ME) {
576       O << "\tsldi ";
577       printOperand(MI, 0, O);
578       O << ", ";
579       printOperand(MI, 1, O);
580       O << ", " << (unsigned int)SH;
581       OutStreamer.EmitRawText(O.str());
582       return;
583     }
584   }
585
586   printInstruction(MI, O);
587   OutStreamer.EmitRawText(O.str());
588 }
589
590 void PPCLinuxAsmPrinter::EmitFunctionEntryLabel() {
591   if (!Subtarget.isPPC64())  // linux/ppc32 - Normal entry label.
592     return AsmPrinter::EmitFunctionEntryLabel();
593     
594   // Emit an official procedure descriptor.
595   // FIXME 64-bit SVR4: Use MCSection here!
596   OutStreamer.EmitRawText(StringRef("\t.section\t\".opd\",\"aw\""));
597   OutStreamer.EmitRawText(StringRef("\t.align 3"));
598   OutStreamer.EmitLabel(CurrentFnSym);
599   OutStreamer.EmitRawText("\t.quad .L." + Twine(CurrentFnSym->getName()) +
600                           ",.TOC.@tocbase");
601   OutStreamer.EmitRawText(StringRef("\t.previous"));
602   OutStreamer.EmitRawText(".L." + Twine(CurrentFnSym->getName()) + ":");
603 }
604
605
606 bool PPCLinuxAsmPrinter::doFinalization(Module &M) {
607   const TargetData *TD = TM.getTargetData();
608
609   bool isPPC64 = TD->getPointerSizeInBits() == 64;
610
611   if (isPPC64 && !TOC.empty()) {
612     // FIXME 64-bit SVR4: Use MCSection here?
613     OutStreamer.EmitRawText(StringRef("\t.section\t\".toc\",\"aw\""));
614
615     // FIXME: This is nondeterminstic!
616     for (DenseMap<MCSymbol*, MCSymbol*>::iterator I = TOC.begin(),
617          E = TOC.end(); I != E; ++I) {
618       OutStreamer.EmitLabel(I->second);
619       OutStreamer.EmitRawText("\t.tc " + Twine(I->first->getName()) +
620                               "[TC]," + I->first->getName());
621     }
622   }
623
624   return AsmPrinter::doFinalization(M);
625 }
626
627 void PPCDarwinAsmPrinter::EmitStartOfAsmFile(Module &M) {
628   static const char *const CPUDirectives[] = {
629     "",
630     "ppc",
631     "ppc601",
632     "ppc602",
633     "ppc603",
634     "ppc7400",
635     "ppc750",
636     "ppc970",
637     "ppc64"
638   };
639
640   unsigned Directive = Subtarget.getDarwinDirective();
641   if (Subtarget.isGigaProcessor() && Directive < PPC::DIR_970)
642     Directive = PPC::DIR_970;
643   if (Subtarget.hasAltivec() && Directive < PPC::DIR_7400)
644     Directive = PPC::DIR_7400;
645   if (Subtarget.isPPC64() && Directive < PPC::DIR_970)
646     Directive = PPC::DIR_64;
647   assert(Directive <= PPC::DIR_64 && "Directive out of range.");
648   OutStreamer.EmitRawText("\t.machine " + Twine(CPUDirectives[Directive]));
649
650   // Prime text sections so they are adjacent.  This reduces the likelihood a
651   // large data or debug section causes a branch to exceed 16M limit.
652   TargetLoweringObjectFileMachO &TLOFMacho = 
653     static_cast<TargetLoweringObjectFileMachO &>(getObjFileLowering());
654   OutStreamer.SwitchSection(TLOFMacho.getTextCoalSection());
655   if (TM.getRelocationModel() == Reloc::PIC_) {
656     OutStreamer.SwitchSection(
657            OutContext.getMachOSection("__TEXT", "__picsymbolstub1",
658                                       MCSectionMachO::S_SYMBOL_STUBS |
659                                       MCSectionMachO::S_ATTR_PURE_INSTRUCTIONS,
660                                       32, SectionKind::getText()));
661   } else if (TM.getRelocationModel() == Reloc::DynamicNoPIC) {
662     OutStreamer.SwitchSection(
663            OutContext.getMachOSection("__TEXT","__symbol_stub1",
664                                       MCSectionMachO::S_SYMBOL_STUBS |
665                                       MCSectionMachO::S_ATTR_PURE_INSTRUCTIONS,
666                                       16, SectionKind::getText()));
667   }
668   OutStreamer.SwitchSection(getObjFileLowering().getTextSection());
669 }
670
671 static MCSymbol *GetLazyPtr(MCSymbol *Sym, MCContext &Ctx) {
672   // Remove $stub suffix, add $lazy_ptr.
673   SmallString<128> TmpStr(Sym->getName().begin(), Sym->getName().end()-5);
674   TmpStr += "$lazy_ptr";
675   return Ctx.GetOrCreateSymbol(TmpStr.str());
676 }
677
678 static MCSymbol *GetAnonSym(MCSymbol *Sym, MCContext &Ctx) {
679   // Add $tmp suffix to $stub, yielding $stub$tmp.
680   SmallString<128> TmpStr(Sym->getName().begin(), Sym->getName().end());
681   TmpStr += "$tmp";
682   return Ctx.GetOrCreateSymbol(TmpStr.str());
683 }
684
685 void PPCDarwinAsmPrinter::
686 EmitFunctionStubs(const MachineModuleInfoMachO::SymbolListTy &Stubs) {
687   bool isPPC64 = TM.getTargetData()->getPointerSizeInBits() == 64;
688   
689   TargetLoweringObjectFileMachO &TLOFMacho = 
690     static_cast<TargetLoweringObjectFileMachO &>(getObjFileLowering());
691
692   // .lazy_symbol_pointer
693   const MCSection *LSPSection = TLOFMacho.getLazySymbolPointerSection();
694   
695   // Output stubs for dynamically-linked functions
696   if (TM.getRelocationModel() == Reloc::PIC_) {
697     const MCSection *StubSection = 
698     OutContext.getMachOSection("__TEXT", "__picsymbolstub1",
699                                MCSectionMachO::S_SYMBOL_STUBS |
700                                MCSectionMachO::S_ATTR_PURE_INSTRUCTIONS,
701                                32, SectionKind::getText());
702     for (unsigned i = 0, e = Stubs.size(); i != e; ++i) {
703       OutStreamer.SwitchSection(StubSection);
704       EmitAlignment(4);
705       
706       MCSymbol *Stub = Stubs[i].first;
707       MCSymbol *RawSym = Stubs[i].second.getPointer();
708       MCSymbol *LazyPtr = GetLazyPtr(Stub, OutContext);
709       MCSymbol *AnonSymbol = GetAnonSym(Stub, OutContext);
710                                            
711       OutStreamer.EmitLabel(Stub);
712       OutStreamer.EmitSymbolAttribute(RawSym, MCSA_IndirectSymbol);
713       // FIXME: MCize this.
714       OutStreamer.EmitRawText(StringRef("\tmflr r0"));
715       OutStreamer.EmitRawText("\tbcl 20,31," + Twine(AnonSymbol->getName()));
716       OutStreamer.EmitLabel(AnonSymbol);
717       OutStreamer.EmitRawText(StringRef("\tmflr r11"));
718       OutStreamer.EmitRawText("\taddis r11,r11,ha16("+Twine(LazyPtr->getName())+
719                               "-" + AnonSymbol->getName() + ")");
720       OutStreamer.EmitRawText(StringRef("\tmtlr r0"));
721       
722       if (isPPC64)
723         OutStreamer.EmitRawText("\tldu r12,lo16(" + Twine(LazyPtr->getName()) +
724                                 "-" + AnonSymbol->getName() + ")(r11)");
725       else
726         OutStreamer.EmitRawText("\tlwzu r12,lo16(" + Twine(LazyPtr->getName()) +
727                                 "-" + AnonSymbol->getName() + ")(r11)");
728       OutStreamer.EmitRawText(StringRef("\tmtctr r12"));
729       OutStreamer.EmitRawText(StringRef("\tbctr"));
730       
731       OutStreamer.SwitchSection(LSPSection);
732       OutStreamer.EmitLabel(LazyPtr);
733       OutStreamer.EmitSymbolAttribute(RawSym, MCSA_IndirectSymbol);
734       
735       if (isPPC64)
736         OutStreamer.EmitRawText(StringRef("\t.quad dyld_stub_binding_helper"));
737       else
738         OutStreamer.EmitRawText(StringRef("\t.long dyld_stub_binding_helper"));
739     }
740     OutStreamer.AddBlankLine();
741     return;
742   }
743   
744   const MCSection *StubSection =
745     OutContext.getMachOSection("__TEXT","__symbol_stub1",
746                                MCSectionMachO::S_SYMBOL_STUBS |
747                                MCSectionMachO::S_ATTR_PURE_INSTRUCTIONS,
748                                16, SectionKind::getText());
749   for (unsigned i = 0, e = Stubs.size(); i != e; ++i) {
750     MCSymbol *Stub = Stubs[i].first;
751     MCSymbol *RawSym = Stubs[i].second.getPointer();
752     MCSymbol *LazyPtr = GetLazyPtr(Stub, OutContext);
753
754     OutStreamer.SwitchSection(StubSection);
755     EmitAlignment(4);
756     OutStreamer.EmitLabel(Stub);
757     OutStreamer.EmitSymbolAttribute(RawSym, MCSA_IndirectSymbol);
758     OutStreamer.EmitRawText("\tlis r11,ha16(" + Twine(LazyPtr->getName()) +")");
759     if (isPPC64)
760       OutStreamer.EmitRawText("\tldu r12,lo16(" + Twine(LazyPtr->getName()) +
761                               ")(r11)");
762     else
763       OutStreamer.EmitRawText("\tlwzu r12,lo16(" + Twine(LazyPtr->getName()) +
764                               ")(r11)");
765     OutStreamer.EmitRawText(StringRef("\tmtctr r12"));
766     OutStreamer.EmitRawText(StringRef("\tbctr"));
767     OutStreamer.SwitchSection(LSPSection);
768     OutStreamer.EmitLabel(LazyPtr);
769     OutStreamer.EmitSymbolAttribute(RawSym, MCSA_IndirectSymbol);
770     
771     if (isPPC64)
772       OutStreamer.EmitRawText(StringRef("\t.quad dyld_stub_binding_helper"));
773     else
774       OutStreamer.EmitRawText(StringRef("\t.long dyld_stub_binding_helper"));
775   }
776   
777   OutStreamer.AddBlankLine();
778 }
779
780
781 bool PPCDarwinAsmPrinter::doFinalization(Module &M) {
782   bool isPPC64 = TM.getTargetData()->getPointerSizeInBits() == 64;
783
784   // Darwin/PPC always uses mach-o.
785   TargetLoweringObjectFileMachO &TLOFMacho = 
786     static_cast<TargetLoweringObjectFileMachO &>(getObjFileLowering());
787   MachineModuleInfoMachO &MMIMacho =
788     MMI->getObjFileInfo<MachineModuleInfoMachO>();
789   
790   MachineModuleInfoMachO::SymbolListTy Stubs = MMIMacho.GetFnStubList();
791   if (!Stubs.empty())
792     EmitFunctionStubs(Stubs);
793
794   if (MAI->doesSupportExceptionHandling() && MMI) {
795     // Add the (possibly multiple) personalities to the set of global values.
796     // Only referenced functions get into the Personalities list.
797     const std::vector<Function *> &Personalities = MMI->getPersonalities();
798     for (std::vector<Function *>::const_iterator I = Personalities.begin(),
799          E = Personalities.end(); I != E; ++I) {
800       if (*I) {
801         MCSymbol *NLPSym = GetSymbolWithGlobalValueBase(*I, "$non_lazy_ptr");
802         MachineModuleInfoImpl::StubValueTy &StubSym =
803           MMIMacho.getGVStubEntry(NLPSym);
804         StubSym = MachineModuleInfoImpl::StubValueTy(Mang->getSymbol(*I), true);
805       }
806     }
807   }
808
809   // Output stubs for dynamically-linked functions.
810   Stubs = MMIMacho.GetGVStubList();
811   
812   // Output macho stubs for external and common global variables.
813   if (!Stubs.empty()) {
814     // Switch with ".non_lazy_symbol_pointer" directive.
815     OutStreamer.SwitchSection(TLOFMacho.getNonLazySymbolPointerSection());
816     EmitAlignment(isPPC64 ? 3 : 2);
817     
818     for (unsigned i = 0, e = Stubs.size(); i != e; ++i) {
819       // L_foo$stub:
820       OutStreamer.EmitLabel(Stubs[i].first);
821       //   .indirect_symbol _foo
822       MachineModuleInfoImpl::StubValueTy &MCSym = Stubs[i].second;
823       OutStreamer.EmitSymbolAttribute(MCSym.getPointer(), MCSA_IndirectSymbol);
824
825       if (MCSym.getInt())
826         // External to current translation unit.
827         OutStreamer.EmitIntValue(0, isPPC64 ? 8 : 4/*size*/, 0/*addrspace*/);
828       else
829         // Internal to current translation unit.
830         //
831         // When we place the LSDA into the TEXT section, the type info pointers
832         // need to be indirect and pc-rel. We accomplish this by using NLPs.
833         // However, sometimes the types are local to the file. So we need to
834         // fill in the value for the NLP in those cases.
835         OutStreamer.EmitValue(MCSymbolRefExpr::Create(MCSym.getPointer(),
836                                                       OutContext),
837                               isPPC64 ? 8 : 4/*size*/, 0/*addrspace*/);
838     }
839
840     Stubs.clear();
841     OutStreamer.AddBlankLine();
842   }
843
844   Stubs = MMIMacho.GetHiddenGVStubList();
845   if (!Stubs.empty()) {
846     OutStreamer.SwitchSection(getObjFileLowering().getDataSection());
847     EmitAlignment(isPPC64 ? 3 : 2);
848     
849     for (unsigned i = 0, e = Stubs.size(); i != e; ++i) {
850       // L_foo$stub:
851       OutStreamer.EmitLabel(Stubs[i].first);
852       //   .long _foo
853       OutStreamer.EmitValue(MCSymbolRefExpr::
854                             Create(Stubs[i].second.getPointer(),
855                                    OutContext),
856                             isPPC64 ? 8 : 4/*size*/, 0/*addrspace*/);
857     }
858
859     Stubs.clear();
860     OutStreamer.AddBlankLine();
861   }
862
863   // Funny Darwin hack: This flag tells the linker that no global symbols
864   // contain code that falls through to other global symbols (e.g. the obvious
865   // implementation of multiple entry points).  If this doesn't occur, the
866   // linker can safely perform dead code stripping.  Since LLVM never generates
867   // code that does this, it is always safe to set.
868   OutStreamer.EmitAssemblerFlag(MCAF_SubsectionsViaSymbols);
869
870   return AsmPrinter::doFinalization(M);
871 }
872
873 /// createPPCAsmPrinterPass - Returns a pass that prints the PPC assembly code
874 /// for a MachineFunction to the given output stream, in a format that the
875 /// Darwin assembler can deal with.
876 ///
877 static AsmPrinter *createPPCAsmPrinterPass(TargetMachine &tm,
878                                            MCStreamer &Streamer) {
879   const PPCSubtarget *Subtarget = &tm.getSubtarget<PPCSubtarget>();
880
881   if (Subtarget->isDarwin())
882     return new PPCDarwinAsmPrinter(tm, Streamer);
883   return new PPCLinuxAsmPrinter(tm, Streamer);
884 }
885
886 // Force static initialization.
887 extern "C" void LLVMInitializePowerPCAsmPrinter() { 
888   TargetRegistry::RegisterAsmPrinter(ThePPC32Target, createPPCAsmPrinterPass);
889   TargetRegistry::RegisterAsmPrinter(ThePPC64Target, createPPCAsmPrinterPass);
890 }