PPCAsmPrinter.cpp revision 58fc1f52ce070003acbdfedc85d52ba999a2bd11
1b5f6f51ebcac183818061bf53427a3e7808ef10dsewardj//===-- PPCAsmPrinter.cpp - Print machine instrs to PowerPC assembly ------===//
2e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn//
3e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn//                     The LLVM Compiler Infrastructure
4e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn//
57fd15d674f18757167305947732057099e175914njn// This file is distributed under the University of Illinois Open Source
67fd15d674f18757167305947732057099e175914njn// License. See LICENSE.TXT for details.
77fd15d674f18757167305947732057099e175914njn//
87fd15d674f18757167305947732057099e175914njn//===----------------------------------------------------------------------===//
9e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn//
10e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn// This file contains a printer that converts from our internal representation
11e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn// of machine-dependent LLVM code to PowerPC assembly language. This printer is
12b9c427c63a278cc612ae0ec573be7bb1abaa447fnjn// the output mechanism used by `llc'.
13b9c427c63a278cc612ae0ec573be7bb1abaa447fnjn//
14de4a1d01951937632098a6cda45859afa587a06fsewardj// Documentation at http://developer.apple.com/documentation/DeveloperTools/
15ec062e8d96a361af9905b5447027819dfbfee01asewardj// Reference/Assembler/ASMIntroduction/chapter_1_section_1.html
16e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn//
17e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn//===----------------------------------------------------------------------===//
18e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn
19e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn#define DEBUG_TYPE "asmprinter"
20e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn#include "PPC.h"
21e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn#include "InstPrinter/PPCInstPrinter.h"
22e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn#include "MCTargetDesc/PPCPredicates.h"
23e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn#include "MCTargetDesc/PPCMCExpr.h"
24e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn#include "PPCSubtarget.h"
25e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn#include "PPCTargetMachine.h"
26e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn#include "llvm/ADT/MapVector.h"
27e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn#include "llvm/ADT/SmallString.h"
28de4a1d01951937632098a6cda45859afa587a06fsewardj#include "llvm/ADT/StringExtras.h"
29e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn#include "llvm/Assembly/Writer.h"
30e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn#include "llvm/CodeGen/AsmPrinter.h"
31de4a1d01951937632098a6cda45859afa587a06fsewardj#include "llvm/CodeGen/MachineFunctionPass.h"
32e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn#include "llvm/CodeGen/MachineInstr.h"
33e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn#include "llvm/CodeGen/MachineInstrBuilder.h"
34e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn#include "llvm/CodeGen/MachineModuleInfoImpls.h"
35de4a1d01951937632098a6cda45859afa587a06fsewardj#include "llvm/CodeGen/TargetLoweringObjectFileImpl.h"
36e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn#include "llvm/DebugInfo.h"
37e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn#include "llvm/IR/Constants.h"
38e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn#include "llvm/IR/DerivedTypes.h"
39e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn#include "llvm/IR/Module.h"
40e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn#include "llvm/MC/MCAsmInfo.h"
41e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn#include "llvm/MC/MCContext.h"
42e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn#include "llvm/MC/MCExpr.h"
43e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn#include "llvm/MC/MCInst.h"
44e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn#include "llvm/MC/MCInstBuilder.h"
45e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn#include "llvm/MC/MCSectionELF.h"
46e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn#include "llvm/MC/MCSectionMachO.h"
47de4a1d01951937632098a6cda45859afa587a06fsewardj#include "llvm/MC/MCStreamer.h"
48e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn#include "llvm/MC/MCSymbol.h"
49e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn#include "llvm/Support/CommandLine.h"
50e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn#include "llvm/Support/Debug.h"
51e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn#include "llvm/Support/ELF.h"
52e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn#include "llvm/Support/ErrorHandling.h"
53e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn#include "llvm/Support/MathExtras.h"
54e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn#include "llvm/Support/TargetRegistry.h"
55e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn#include "llvm/Support/raw_ostream.h"
56de4a1d01951937632098a6cda45859afa587a06fsewardj#include "llvm/Target/Mangler.h"
57de4a1d01951937632098a6cda45859afa587a06fsewardj#include "llvm/Target/TargetInstrInfo.h"
58de4a1d01951937632098a6cda45859afa587a06fsewardj#include "llvm/Target/TargetOptions.h"
5930d76c6abc3e7d338b1ca81256fa3ce93eccc09fnjn#include "llvm/Target/TargetRegisterInfo.h"
6030d76c6abc3e7d338b1ca81256fa3ce93eccc09fnjnusing namespace llvm;
6130d76c6abc3e7d338b1ca81256fa3ce93eccc09fnjn
6230d76c6abc3e7d338b1ca81256fa3ce93eccc09fnjnnamespace {
6330d76c6abc3e7d338b1ca81256fa3ce93eccc09fnjn  class PPCAsmPrinter : public AsmPrinter {
6430d76c6abc3e7d338b1ca81256fa3ce93eccc09fnjn  protected:
6530d76c6abc3e7d338b1ca81256fa3ce93eccc09fnjn    MapVector<MCSymbol*, MCSymbol*> TOC;
6630d76c6abc3e7d338b1ca81256fa3ce93eccc09fnjn    const PPCSubtarget &Subtarget;
670ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    uint64_t TOCLabelID;
6830d76c6abc3e7d338b1ca81256fa3ce93eccc09fnjn  public:
6930d76c6abc3e7d338b1ca81256fa3ce93eccc09fnjn    explicit PPCAsmPrinter(TargetMachine &TM, MCStreamer &Streamer)
7030d76c6abc3e7d338b1ca81256fa3ce93eccc09fnjn      : AsmPrinter(TM, Streamer),
7130d76c6abc3e7d338b1ca81256fa3ce93eccc09fnjn        Subtarget(TM.getSubtarget<PPCSubtarget>()), TOCLabelID(0) {}
7230d76c6abc3e7d338b1ca81256fa3ce93eccc09fnjn
73de4a1d01951937632098a6cda45859afa587a06fsewardj    virtual const char *getPassName() const {
74de4a1d01951937632098a6cda45859afa587a06fsewardj      return "PowerPC Assembly Printer";
75de4a1d01951937632098a6cda45859afa587a06fsewardj    }
767104416748e90239b97560f5d727da107e3e08a9sewardj
777104416748e90239b97560f5d727da107e3e08a9sewardj    MCSymbol *lookUpOrCreateTOCEntry(MCSymbol *Sym);
787104416748e90239b97560f5d727da107e3e08a9sewardj
797104416748e90239b97560f5d727da107e3e08a9sewardj    virtual void EmitInstruction(const MachineInstr *MI);
807104416748e90239b97560f5d727da107e3e08a9sewardj
817104416748e90239b97560f5d727da107e3e08a9sewardj    void printOperand(const MachineInstr *MI, unsigned OpNo, raw_ostream &O);
820fe1d4c134ba889ff5e0a3b1b4dc8f36e610ca97sewardj
830fe1d4c134ba889ff5e0a3b1b4dc8f36e610ca97sewardj    bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,
840fe1d4c134ba889ff5e0a3b1b4dc8f36e610ca97sewardj                         unsigned AsmVariant, const char *ExtraCode,
850fe1d4c134ba889ff5e0a3b1b4dc8f36e610ca97sewardj                         raw_ostream &O);
860fe1d4c134ba889ff5e0a3b1b4dc8f36e610ca97sewardj    bool PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNo,
870fe1d4c134ba889ff5e0a3b1b4dc8f36e610ca97sewardj                               unsigned AsmVariant, const char *ExtraCode,
880fe1d4c134ba889ff5e0a3b1b4dc8f36e610ca97sewardj                               raw_ostream &O);
890fe1d4c134ba889ff5e0a3b1b4dc8f36e610ca97sewardj  };
900fe1d4c134ba889ff5e0a3b1b4dc8f36e610ca97sewardj
910fe1d4c134ba889ff5e0a3b1b4dc8f36e610ca97sewardj  /// PPCLinuxAsmPrinter - PowerPC assembly printer, customized for Linux
927104416748e90239b97560f5d727da107e3e08a9sewardj  class PPCLinuxAsmPrinter : public PPCAsmPrinter {
937104416748e90239b97560f5d727da107e3e08a9sewardj  public:
947104416748e90239b97560f5d727da107e3e08a9sewardj    explicit PPCLinuxAsmPrinter(TargetMachine &TM, MCStreamer &Streamer)
9539de4b473801ab10a48e356cddc863212dd28cd1fitzhardinge      : PPCAsmPrinter(TM, Streamer) {}
9639de4b473801ab10a48e356cddc863212dd28cd1fitzhardinge
973dd0a912e48a4884ee51ab3afe41856c165185canjn    virtual const char *getPassName() const {
983dd0a912e48a4884ee51ab3afe41856c165185canjn      return "Linux PPC Assembly Printer";
993dd0a912e48a4884ee51ab3afe41856c165185canjn    }
1003dd0a912e48a4884ee51ab3afe41856c165185canjn
101f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj    bool doFinalization(Module &M);
1020ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
1030ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    virtual void EmitFunctionEntryLabel();
1040ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
1050ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    void EmitFunctionBodyEnd();
10659570ffbe31930ab4d678754daaeec0715117a3dsewardj  };
10759570ffbe31930ab4d678754daaeec0715117a3dsewardj
10859570ffbe31930ab4d678754daaeec0715117a3dsewardj  /// PPCDarwinAsmPrinter - PowerPC assembly printer, customized for Darwin/Mac
10959570ffbe31930ab4d678754daaeec0715117a3dsewardj  /// OS X
11059570ffbe31930ab4d678754daaeec0715117a3dsewardj  class PPCDarwinAsmPrinter : public PPCAsmPrinter {
1117af3230a91de23a737946c1b4649b2f826672bf6sewardj  public:
1127af3230a91de23a737946c1b4649b2f826672bf6sewardj    explicit PPCDarwinAsmPrinter(TargetMachine &TM, MCStreamer &Streamer)
1137f489813d200fb614a0856fca05e2f9ebf66dd48bart      : PPCAsmPrinter(TM, Streamer) {}
114f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj
115f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj    virtual const char *getPassName() const {
116f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      return "Darwin PPC Assembly Printer";
117f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj    }
11859570ffbe31930ab4d678754daaeec0715117a3dsewardj
119b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj    bool doFinalization(Module &M);
120b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj    void EmitStartOfAsmFile(Module &M);
121f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj
1226e9de463ef677f093e9f24f126e1b11c28cf59fdsewardj    void EmitFunctionStubs(const MachineModuleInfoMachO::SymbolListTy &Stubs);
123f76d27a697a7b0bf3b84490baf60623fc96a23afnjn  };
124f76d27a697a7b0bf3b84490baf60623fc96a23afnjn} // end of anonymous namespace
125f76d27a697a7b0bf3b84490baf60623fc96a23afnjn
1266e9de463ef677f093e9f24f126e1b11c28cf59fdsewardj/// stripRegisterPrefix - This method strips the character prefix from a
1276e9de463ef677f093e9f24f126e1b11c28cf59fdsewardj/// register name so that only the number is left.  Used by for linux asm.
1287f489813d200fb614a0856fca05e2f9ebf66dd48bartstatic const char *stripRegisterPrefix(const char *RegName) {
12959570ffbe31930ab4d678754daaeec0715117a3dsewardj  switch (RegName[0]) {
130f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj    case 'r':
13159570ffbe31930ab4d678754daaeec0715117a3dsewardj    case 'f':
132f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj    case 'v': return RegName + 1;
13359570ffbe31930ab4d678754daaeec0715117a3dsewardj    case 'c': if (RegName[1] == 'r') return RegName + 2;
134f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj  }
13559570ffbe31930ab4d678754daaeec0715117a3dsewardj
136f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj  return RegName;
13759570ffbe31930ab4d678754daaeec0715117a3dsewardj}
13859570ffbe31930ab4d678754daaeec0715117a3dsewardj
139b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardjvoid PPCAsmPrinter::printOperand(const MachineInstr *MI, unsigned OpNo,
140b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj                                 raw_ostream &O) {
141f76d27a697a7b0bf3b84490baf60623fc96a23afnjn  const MachineOperand &MO = MI->getOperand(OpNo);
142f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj
1430ec07f32bbbb209d749b9974408e6f025ad40b31sewardj  switch (MO.getType()) {
1440ec07f32bbbb209d749b9974408e6f025ad40b31sewardj  case MachineOperand::MO_Register: {
1450ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    const char *RegName = PPCInstPrinter::getRegisterName(MO.getReg());
1460ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    // Linux assembler (Others?) does not take register mnemonics.
147b5f6f51ebcac183818061bf53427a3e7808ef10dsewardj    // FIXME - What about special registers used in mfspr/mtspr?
148b5f6f51ebcac183818061bf53427a3e7808ef10dsewardj    if (!Subtarget.isDarwin()) RegName = stripRegisterPrefix(RegName);
1490ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    O << RegName;
15030d76c6abc3e7d338b1ca81256fa3ce93eccc09fnjn    return;
1510ec07f32bbbb209d749b9974408e6f025ad40b31sewardj  }
1520ec07f32bbbb209d749b9974408e6f025ad40b31sewardj  case MachineOperand::MO_Immediate:
15330d76c6abc3e7d338b1ca81256fa3ce93eccc09fnjn    O << MO.getImm();
154de4a1d01951937632098a6cda45859afa587a06fsewardj    return;
155575ce8ef8fa86a502dabe152293320676922dcfebart
156575ce8ef8fa86a502dabe152293320676922dcfebart  case MachineOperand::MO_MachineBasicBlock:
157575ce8ef8fa86a502dabe152293320676922dcfebart    O << *MO.getMBB()->getSymbol();
158575ce8ef8fa86a502dabe152293320676922dcfebart    return;
1594b3a74204894e943c43cb8e8aae39d813040702csewardj  case MachineOperand::MO_JumpTableIndex:
1604b3a74204894e943c43cb8e8aae39d813040702csewardj    O << MAI->getPrivateGlobalPrefix() << "JTI" << getFunctionNumber()
1614b3a74204894e943c43cb8e8aae39d813040702csewardj      << '_' << MO.getIndex();
162575ce8ef8fa86a502dabe152293320676922dcfebart    // FIXME: PIC relocation model
1634b3a74204894e943c43cb8e8aae39d813040702csewardj    return;
1644b3a74204894e943c43cb8e8aae39d813040702csewardj  case MachineOperand::MO_ConstantPoolIndex:
1654b3a74204894e943c43cb8e8aae39d813040702csewardj    O << MAI->getPrivateGlobalPrefix() << "CPI" << getFunctionNumber()
166575ce8ef8fa86a502dabe152293320676922dcfebart      << '_' << MO.getIndex();
167575ce8ef8fa86a502dabe152293320676922dcfebart    return;
168575ce8ef8fa86a502dabe152293320676922dcfebart  case MachineOperand::MO_BlockAddress:
169575ce8ef8fa86a502dabe152293320676922dcfebart    O << *GetBlockAddressSymbol(MO.getBlockAddress());
170575ce8ef8fa86a502dabe152293320676922dcfebart    return;
17117dfe1addc98de357b9e24ddbe4ad7df4454873aflorian  case MachineOperand::MO_ExternalSymbol: {
172575ce8ef8fa86a502dabe152293320676922dcfebart    // Computing the address of an external symbol, not calling it.
17317dfe1addc98de357b9e24ddbe4ad7df4454873aflorian    if (TM.getRelocationModel() == Reloc::Static) {
174575ce8ef8fa86a502dabe152293320676922dcfebart      O << *GetExternalSymbolSymbol(MO.getSymbolName());
1754b3a74204894e943c43cb8e8aae39d813040702csewardj      return;
1764b3a74204894e943c43cb8e8aae39d813040702csewardj    }
1774b3a74204894e943c43cb8e8aae39d813040702csewardj
1784b3a74204894e943c43cb8e8aae39d813040702csewardj    MCSymbol *NLPSym =
1794b3a74204894e943c43cb8e8aae39d813040702csewardj      OutContext.GetOrCreateSymbol(StringRef(MAI->getGlobalPrefix())+
1804b3a74204894e943c43cb8e8aae39d813040702csewardj                                   MO.getSymbolName()+"$non_lazy_ptr");
1810ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    MachineModuleInfoImpl::StubValueTy &StubSym =
18226aba4d3ef6cebc34879e82d88bcbe3c3b3b9f9enjn      MMI->getObjFileInfo<MachineModuleInfoMachO>().getGVStubEntry(NLPSym);
18326aba4d3ef6cebc34879e82d88bcbe3c3b3b9f9enjn    if (StubSym.getPointer() == 0)
1840ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      StubSym = MachineModuleInfoImpl::
1850ec07f32bbbb209d749b9974408e6f025ad40b31sewardj        StubValueTy(GetExternalSymbolSymbol(MO.getSymbolName()), true);
186575ce8ef8fa86a502dabe152293320676922dcfebart
187575ce8ef8fa86a502dabe152293320676922dcfebart    O << *NLPSym;
1889af10a1c0d1b8897195ccfbc6dc46d8113d77153sewardj    return;
189575ce8ef8fa86a502dabe152293320676922dcfebart  }
19026aba4d3ef6cebc34879e82d88bcbe3c3b3b9f9enjn  case MachineOperand::MO_GlobalAddress: {
1910ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    // Computing the address of a global symbol, not calling it.
1920ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    const GlobalValue *GV = MO.getGlobal();
1930ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    MCSymbol *SymToPrint;
1940ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
1950ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    // External or weakly linked global variables need non-lazily-resolved stubs
196de4a1d01951937632098a6cda45859afa587a06fsewardj    if (TM.getRelocationModel() != Reloc::Static &&
1970ec07f32bbbb209d749b9974408e6f025ad40b31sewardj        (GV->isDeclaration() || GV->isWeakForLinker())) {
1980ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      if (!GV->hasHiddenVisibility()) {
1990ec07f32bbbb209d749b9974408e6f025ad40b31sewardj        SymToPrint = GetSymbolWithGlobalValueBase(GV, "$non_lazy_ptr");
2000ec07f32bbbb209d749b9974408e6f025ad40b31sewardj        MachineModuleInfoImpl::StubValueTy &StubSym =
2010ec07f32bbbb209d749b9974408e6f025ad40b31sewardj          MMI->getObjFileInfo<MachineModuleInfoMachO>()
2020ec07f32bbbb209d749b9974408e6f025ad40b31sewardj            .getGVStubEntry(SymToPrint);
2030ec07f32bbbb209d749b9974408e6f025ad40b31sewardj        if (StubSym.getPointer() == 0)
2040ec07f32bbbb209d749b9974408e6f025ad40b31sewardj          StubSym = MachineModuleInfoImpl::
2059af10a1c0d1b8897195ccfbc6dc46d8113d77153sewardj            StubValueTy(Mang->getSymbol(GV), !GV->hasInternalLinkage());
206e90c6836fd430124799e52896c99ea27b1c88541nethercote      } else if (GV->isDeclaration() || GV->hasCommonLinkage() ||
2075426544c9c3fc835ead99fae9e2054625110ef3enethercote                 GV->hasAvailableExternallyLinkage()) {
2085426544c9c3fc835ead99fae9e2054625110ef3enethercote        SymToPrint = GetSymbolWithGlobalValueBase(GV, "$non_lazy_ptr");
2095426544c9c3fc835ead99fae9e2054625110ef3enethercote
2105426544c9c3fc835ead99fae9e2054625110ef3enethercote        MachineModuleInfoImpl::StubValueTy &StubSym =
2119af10a1c0d1b8897195ccfbc6dc46d8113d77153sewardj          MMI->getObjFileInfo<MachineModuleInfoMachO>().
2125426544c9c3fc835ead99fae9e2054625110ef3enethercote                    getHiddenGVStubEntry(SymToPrint);
2130ec07f32bbbb209d749b9974408e6f025ad40b31sewardj        if (StubSym.getPointer() == 0)
214d68ac3e974d25f88492774f6baa491999afde9f9sewardj          StubSym = MachineModuleInfoImpl::
215d68ac3e974d25f88492774f6baa491999afde9f9sewardj            StubValueTy(Mang->getSymbol(GV), !GV->hasInternalLinkage());
216d68ac3e974d25f88492774f6baa491999afde9f9sewardj      } else {
217d68ac3e974d25f88492774f6baa491999afde9f9sewardj        SymToPrint = Mang->getSymbol(GV);
218d68ac3e974d25f88492774f6baa491999afde9f9sewardj      }
219d68ac3e974d25f88492774f6baa491999afde9f9sewardj    } else {
220d68ac3e974d25f88492774f6baa491999afde9f9sewardj      SymToPrint = Mang->getSymbol(GV);
221d68ac3e974d25f88492774f6baa491999afde9f9sewardj    }
222d68ac3e974d25f88492774f6baa491999afde9f9sewardj
223d68ac3e974d25f88492774f6baa491999afde9f9sewardj    O << *SymToPrint;
224d68ac3e974d25f88492774f6baa491999afde9f9sewardj
225d68ac3e974d25f88492774f6baa491999afde9f9sewardj    printOffset(MO.getOffset(), O);
226e90c6836fd430124799e52896c99ea27b1c88541nethercote    return;
227de4a1d01951937632098a6cda45859afa587a06fsewardj  }
228f76d27a697a7b0bf3b84490baf60623fc96a23afnjn
2290ec07f32bbbb209d749b9974408e6f025ad40b31sewardj  default:
230520a03a4c59703908bae4cc437814abf0a24cdcdsewardj    O << "<unknown operand type: " << MO.getType() << ">";
231602278444fa6b4135a44d19ae833ed42a9898e48sewardj    return;
232c885844f7484a13bcf1c7f9b14cf5bc527462963sewardj  }
233c885844f7484a13bcf1c7f9b14cf5bc527462963sewardj}
234c885844f7484a13bcf1c7f9b14cf5bc527462963sewardj
235c885844f7484a13bcf1c7f9b14cf5bc527462963sewardj/// PrintAsmOperand - Print out an operand for an inline asm expression.
236c885844f7484a13bcf1c7f9b14cf5bc527462963sewardj///
237c885844f7484a13bcf1c7f9b14cf5bc527462963sewardjbool PPCAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,
238c885844f7484a13bcf1c7f9b14cf5bc527462963sewardj                                    unsigned AsmVariant,
2390ec07f32bbbb209d749b9974408e6f025ad40b31sewardj                                    const char *ExtraCode, raw_ostream &O) {
2400ec07f32bbbb209d749b9974408e6f025ad40b31sewardj  // Does this asm operand have a single letter operand modifier?
2411a85f4f4e5e1ec2518137ffa9a6a9bf7d9c50df9sewardj  if (ExtraCode && ExtraCode[0]) {
2420ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    if (ExtraCode[1] != 0) return true; // Unknown modifier.
243575ce8ef8fa86a502dabe152293320676922dcfebart
244575ce8ef8fa86a502dabe152293320676922dcfebart    switch (ExtraCode[0]) {
2459af10a1c0d1b8897195ccfbc6dc46d8113d77153sewardj    default:
246575ce8ef8fa86a502dabe152293320676922dcfebart      // See if this is a generic print operand
247575ce8ef8fa86a502dabe152293320676922dcfebart      return AsmPrinter::PrintAsmOperand(MI, OpNo, AsmVariant, ExtraCode, O);
2480ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    case 'c': // Don't print "$" before a global var name or constant.
2490ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      break; // PPC never has a prefix.
2500ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    case 'L': // Write second word of DImode reference.
2510ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      // Verify that this operand has two consecutive registers.
2520ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      if (!MI->getOperand(OpNo).isReg() ||
2530ec07f32bbbb209d749b9974408e6f025ad40b31sewardj          OpNo+1 == MI->getNumOperands() ||
2549af10a1c0d1b8897195ccfbc6dc46d8113d77153sewardj          !MI->getOperand(OpNo+1).isReg())
2550ec07f32bbbb209d749b9974408e6f025ad40b31sewardj        return true;
2560ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      ++OpNo;   // Return the high-part.
2570ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      break;
2580ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    case 'I':
2590ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      // Write 'i' if an integer constant, otherwise nothing.  Used to print
2600ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      // addi vs add, etc.
2610ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      if (MI->getOperand(OpNo).isImm())
262575ce8ef8fa86a502dabe152293320676922dcfebart        O << "i";
263575ce8ef8fa86a502dabe152293320676922dcfebart      return false;
2640ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    }
265c885844f7484a13bcf1c7f9b14cf5bc527462963sewardj  }
266c885844f7484a13bcf1c7f9b14cf5bc527462963sewardj
267c885844f7484a13bcf1c7f9b14cf5bc527462963sewardj  printOperand(MI, OpNo, O);
2680ec07f32bbbb209d749b9974408e6f025ad40b31sewardj  return false;
2690ec07f32bbbb209d749b9974408e6f025ad40b31sewardj}
2700ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
2710ec07f32bbbb209d749b9974408e6f025ad40b31sewardj// At the moment, all inline asm memory operands are a single register.
2720ec07f32bbbb209d749b9974408e6f025ad40b31sewardj// In any case, the output of this routine should always be just one
2730ec07f32bbbb209d749b9974408e6f025ad40b31sewardj// assembler operand.
2740ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
275c885844f7484a13bcf1c7f9b14cf5bc527462963sewardjbool PPCAsmPrinter::PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNo,
276ca0518df66f8c3375a860f1a55a51f18e2a16c44njn                                          unsigned AsmVariant,
2770ec07f32bbbb209d749b9974408e6f025ad40b31sewardj                                          const char *ExtraCode,
2780ec07f32bbbb209d749b9974408e6f025ad40b31sewardj                                          raw_ostream &O) {
2790ec07f32bbbb209d749b9974408e6f025ad40b31sewardj  if (ExtraCode && ExtraCode[0]) {
2800ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    if (ExtraCode[1] != 0) return true; // Unknown modifier.
2810ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
282602278444fa6b4135a44d19ae833ed42a9898e48sewardj    switch (ExtraCode[0]) {
2837f489813d200fb614a0856fca05e2f9ebf66dd48bart    default: return true;  // Unknown modifier.
2847f489813d200fb614a0856fca05e2f9ebf66dd48bart    case 'y': // A memory reference for an X-form instruction
2857f489813d200fb614a0856fca05e2f9ebf66dd48bart      {
2867f489813d200fb614a0856fca05e2f9ebf66dd48bart        const char *RegName = "r0";
2877f489813d200fb614a0856fca05e2f9ebf66dd48bart        if (!Subtarget.isDarwin()) RegName = stripRegisterPrefix(RegName);
2887f489813d200fb614a0856fca05e2f9ebf66dd48bart        O << RegName << ", ";
2897f489813d200fb614a0856fca05e2f9ebf66dd48bart        printOperand(MI, OpNo, O);
2907f489813d200fb614a0856fca05e2f9ebf66dd48bart        return false;
2917f489813d200fb614a0856fca05e2f9ebf66dd48bart      }
2927f489813d200fb614a0856fca05e2f9ebf66dd48bart    }
2937f489813d200fb614a0856fca05e2f9ebf66dd48bart  }
2947f489813d200fb614a0856fca05e2f9ebf66dd48bart
2957f489813d200fb614a0856fca05e2f9ebf66dd48bart  assert(MI->getOperand(OpNo).isReg());
2967f489813d200fb614a0856fca05e2f9ebf66dd48bart  O << "0(";
2977f489813d200fb614a0856fca05e2f9ebf66dd48bart  printOperand(MI, OpNo, O);
2987f489813d200fb614a0856fca05e2f9ebf66dd48bart  O << ")";
2997f489813d200fb614a0856fca05e2f9ebf66dd48bart  return false;
300575ce8ef8fa86a502dabe152293320676922dcfebart}
301575ce8ef8fa86a502dabe152293320676922dcfebart
3027f489813d200fb614a0856fca05e2f9ebf66dd48bart
303575ce8ef8fa86a502dabe152293320676922dcfebart/// lookUpOrCreateTOCEntry -- Given a symbol, look up whether a TOC entry
304575ce8ef8fa86a502dabe152293320676922dcfebart/// exists for it.  If not, create one.  Then return a symbol that references
305575ce8ef8fa86a502dabe152293320676922dcfebart/// the TOC entry.
306575ce8ef8fa86a502dabe152293320676922dcfebartMCSymbol *PPCAsmPrinter::lookUpOrCreateTOCEntry(MCSymbol *Sym) {
307575ce8ef8fa86a502dabe152293320676922dcfebart
308575ce8ef8fa86a502dabe152293320676922dcfebart  MCSymbol *&TOCEntry = TOC[Sym];
309575ce8ef8fa86a502dabe152293320676922dcfebart
310575ce8ef8fa86a502dabe152293320676922dcfebart  // To avoid name clash check if the name already exists.
311575ce8ef8fa86a502dabe152293320676922dcfebart  while (TOCEntry == 0) {
312575ce8ef8fa86a502dabe152293320676922dcfebart    if (OutContext.LookupSymbol(Twine(MAI->getPrivateGlobalPrefix()) +
313575ce8ef8fa86a502dabe152293320676922dcfebart                                "C" + Twine(TOCLabelID++)) == 0) {
314575ce8ef8fa86a502dabe152293320676922dcfebart      TOCEntry = GetTempSymbol("C", TOCLabelID);
315575ce8ef8fa86a502dabe152293320676922dcfebart    }
316575ce8ef8fa86a502dabe152293320676922dcfebart  }
317575ce8ef8fa86a502dabe152293320676922dcfebart
318575ce8ef8fa86a502dabe152293320676922dcfebart  return TOCEntry;
319575ce8ef8fa86a502dabe152293320676922dcfebart}
320575ce8ef8fa86a502dabe152293320676922dcfebart
321575ce8ef8fa86a502dabe152293320676922dcfebart
322575ce8ef8fa86a502dabe152293320676922dcfebart/// EmitInstruction -- Print out a single PowerPC MI in Darwin syntax to
323575ce8ef8fa86a502dabe152293320676922dcfebart/// the current output stream.
324575ce8ef8fa86a502dabe152293320676922dcfebart///
325575ce8ef8fa86a502dabe152293320676922dcfebartvoid PPCAsmPrinter::EmitInstruction(const MachineInstr *MI) {
326575ce8ef8fa86a502dabe152293320676922dcfebart  MCInst TmpInst;
327575ce8ef8fa86a502dabe152293320676922dcfebart
328575ce8ef8fa86a502dabe152293320676922dcfebart  // Lower multi-instruction pseudo operations.
329575ce8ef8fa86a502dabe152293320676922dcfebart  switch (MI->getOpcode()) {
3307f489813d200fb614a0856fca05e2f9ebf66dd48bart  default: break;
3317f489813d200fb614a0856fca05e2f9ebf66dd48bart  case TargetOpcode::DBG_VALUE:
3327f489813d200fb614a0856fca05e2f9ebf66dd48bart    llvm_unreachable("Should be handled target independently");
3337f489813d200fb614a0856fca05e2f9ebf66dd48bart  case PPC::MovePCtoLR:
3347f489813d200fb614a0856fca05e2f9ebf66dd48bart  case PPC::MovePCtoLR8: {
3357f489813d200fb614a0856fca05e2f9ebf66dd48bart    // Transform %LR = MovePCtoLR
3367f489813d200fb614a0856fca05e2f9ebf66dd48bart    // Into this, where the label is the PIC base:
3377f489813d200fb614a0856fca05e2f9ebf66dd48bart    //     bl L1$pb
3387f489813d200fb614a0856fca05e2f9ebf66dd48bart    // L1$pb:
3397f489813d200fb614a0856fca05e2f9ebf66dd48bart    MCSymbol *PICBase = MF->getPICBaseSymbol();
3407f489813d200fb614a0856fca05e2f9ebf66dd48bart
3417f489813d200fb614a0856fca05e2f9ebf66dd48bart    // Emit the 'bl'.
3427f489813d200fb614a0856fca05e2f9ebf66dd48bart    OutStreamer.EmitInstruction(MCInstBuilder(PPC::BL)
3437f489813d200fb614a0856fca05e2f9ebf66dd48bart      // FIXME: We would like an efficient form for this, so we don't have to do
3447f489813d200fb614a0856fca05e2f9ebf66dd48bart      // a lot of extra uniquing.
3457f489813d200fb614a0856fca05e2f9ebf66dd48bart      .addExpr(MCSymbolRefExpr::Create(PICBase, OutContext)));
3467f489813d200fb614a0856fca05e2f9ebf66dd48bart
3477f489813d200fb614a0856fca05e2f9ebf66dd48bart    // Emit the label.
3487f489813d200fb614a0856fca05e2f9ebf66dd48bart    OutStreamer.EmitLabel(PICBase);
3490ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    return;
350f76d27a697a7b0bf3b84490baf60623fc96a23afnjn  }
3510ec07f32bbbb209d749b9974408e6f025ad40b31sewardj  case PPC::LDtocJTI:
352f76d27a697a7b0bf3b84490baf60623fc96a23afnjn  case PPC::LDtocCPT:
353c885844f7484a13bcf1c7f9b14cf5bc527462963sewardj  case PPC::LDtoc: {
354c885844f7484a13bcf1c7f9b14cf5bc527462963sewardj    // Transform %X3 = LDtoc <ga:@min1>, %X2
355c885844f7484a13bcf1c7f9b14cf5bc527462963sewardj    LowerPPCMachineInstrToMCInst(MI, TmpInst, *this);
356c885844f7484a13bcf1c7f9b14cf5bc527462963sewardj
357c885844f7484a13bcf1c7f9b14cf5bc527462963sewardj    // Change the opcode to LD, and the global address operand to be a
358c885844f7484a13bcf1c7f9b14cf5bc527462963sewardj    // reference to the TOC entry we will synthesize later.
359c885844f7484a13bcf1c7f9b14cf5bc527462963sewardj    TmpInst.setOpcode(PPC::LD);
3600ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    const MachineOperand &MO = MI->getOperand(1);
3610ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
3621a85f4f4e5e1ec2518137ffa9a6a9bf7d9c50df9sewardj    // Map symbol -> label of TOC entry
3630ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    assert(MO.isGlobal() || MO.isCPI() || MO.isJTI());
364575ce8ef8fa86a502dabe152293320676922dcfebart    MCSymbol *MOSymbol = 0;
365575ce8ef8fa86a502dabe152293320676922dcfebart    if (MO.isGlobal())
3669af10a1c0d1b8897195ccfbc6dc46d8113d77153sewardj      MOSymbol = Mang->getSymbol(MO.getGlobal());
367575ce8ef8fa86a502dabe152293320676922dcfebart    else if (MO.isCPI())
368575ce8ef8fa86a502dabe152293320676922dcfebart      MOSymbol = GetCPISymbol(MO.getIndex());
3690ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    else if (MO.isJTI())
3700ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      MOSymbol = GetJTISymbol(MO.getIndex());
3710ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
3720ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    MCSymbol *TOCEntry = lookUpOrCreateTOCEntry(MOSymbol);
3730ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
3740ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    const MCExpr *Exp =
3759af10a1c0d1b8897195ccfbc6dc46d8113d77153sewardj      MCSymbolRefExpr::Create(TOCEntry, MCSymbolRefExpr::VK_PPC_TOC,
3760ec07f32bbbb209d749b9974408e6f025ad40b31sewardj                              OutContext);
3770ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    TmpInst.getOperand(1) = MCOperand::CreateExpr(Exp);
3780ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    OutStreamer.EmitInstruction(TmpInst);
3790ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    return;
3800ec07f32bbbb209d749b9974408e6f025ad40b31sewardj  }
3810ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
3820ec07f32bbbb209d749b9974408e6f025ad40b31sewardj  case PPC::ADDIStocHA: {
383575ce8ef8fa86a502dabe152293320676922dcfebart    // Transform %Xd = ADDIStocHA %X2, <ga:@sym>
384575ce8ef8fa86a502dabe152293320676922dcfebart    LowerPPCMachineInstrToMCInst(MI, TmpInst, *this);
3850ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
386c885844f7484a13bcf1c7f9b14cf5bc527462963sewardj    // Change the opcode to ADDIS8.  If the global address is external,
387c885844f7484a13bcf1c7f9b14cf5bc527462963sewardj    // has common linkage, is a function address, or is a jump table
388c885844f7484a13bcf1c7f9b14cf5bc527462963sewardj    // address, then generate a TOC entry and reference that.  Otherwise
3890ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    // reference the symbol directly.
3900ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    TmpInst.setOpcode(PPC::ADDIS8);
3910ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    const MachineOperand &MO = MI->getOperand(2);
3920ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    assert((MO.isGlobal() || MO.isCPI() || MO.isJTI()) &&
3930ec07f32bbbb209d749b9974408e6f025ad40b31sewardj           "Invalid operand for ADDIStocHA!");
3940ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    MCSymbol *MOSymbol = 0;
3950ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    bool IsExternal = false;
396c885844f7484a13bcf1c7f9b14cf5bc527462963sewardj    bool IsFunction = false;
3972c48c7b0a453d32375a4df17e153011b797ef28csewardj    bool IsCommon = false;
3980ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    bool IsAvailExt = false;
3990ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
4000ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    if (MO.isGlobal()) {
4010ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      const GlobalValue *GValue = MO.getGlobal();
4020ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      const GlobalAlias *GAlias = dyn_cast<GlobalAlias>(GValue);
403f76d27a697a7b0bf3b84490baf60623fc96a23afnjn      const GlobalValue *RealGValue = GAlias ?
4040ec07f32bbbb209d749b9974408e6f025ad40b31sewardj        GAlias->resolveAliasedGlobal(false) : GValue;
405f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      MOSymbol = Mang->getSymbol(RealGValue);
4060ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      const GlobalVariable *GVar = dyn_cast<GlobalVariable>(RealGValue);
407f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      IsExternal = GVar && !GVar->hasInitializer();
408d68ac3e974d25f88492774f6baa491999afde9f9sewardj      IsCommon = GVar && RealGValue->hasCommonLinkage();
409d68ac3e974d25f88492774f6baa491999afde9f9sewardj      IsFunction = !GVar;
410d68ac3e974d25f88492774f6baa491999afde9f9sewardj      IsAvailExt = GVar && RealGValue->hasAvailableExternallyLinkage();
411c885844f7484a13bcf1c7f9b14cf5bc527462963sewardj    } else if (MO.isCPI())
412d68ac3e974d25f88492774f6baa491999afde9f9sewardj      MOSymbol = GetCPISymbol(MO.getIndex());
413d68ac3e974d25f88492774f6baa491999afde9f9sewardj    else if (MO.isJTI())
414d68ac3e974d25f88492774f6baa491999afde9f9sewardj      MOSymbol = GetJTISymbol(MO.getIndex());
4150ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
4160ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    if (IsExternal || IsFunction || IsCommon || IsAvailExt || MO.isJTI())
4171a85f4f4e5e1ec2518137ffa9a6a9bf7d9c50df9sewardj      MOSymbol = lookUpOrCreateTOCEntry(MOSymbol);
4180ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
419575ce8ef8fa86a502dabe152293320676922dcfebart    const MCExpr *Exp =
420575ce8ef8fa86a502dabe152293320676922dcfebart      MCSymbolRefExpr::Create(MOSymbol, MCSymbolRefExpr::VK_PPC_TOC_HA,
4219af10a1c0d1b8897195ccfbc6dc46d8113d77153sewardj                              OutContext);
4220ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    TmpInst.getOperand(2) = MCOperand::CreateExpr(Exp);
423575ce8ef8fa86a502dabe152293320676922dcfebart    OutStreamer.EmitInstruction(TmpInst);
424575ce8ef8fa86a502dabe152293320676922dcfebart    return;
4251c5bcb1e17532ec1630056fb2e58ef8e15267f15sewardj  }
4261c5bcb1e17532ec1630056fb2e58ef8e15267f15sewardj  case PPC::LDtocL: {
4270ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    // Transform %Xd = LDtocL <ga:@sym>, %Xs
4280ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    LowerPPCMachineInstrToMCInst(MI, TmpInst, *this);
4290ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
4300ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    // Change the opcode to LD.  If the global address is external, has
4310ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    // common linkage, or is a jump table address, then reference the
4329af10a1c0d1b8897195ccfbc6dc46d8113d77153sewardj    // associated TOC entry.  Otherwise reference the symbol directly.
4330ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    TmpInst.setOpcode(PPC::LD);
4341c5bcb1e17532ec1630056fb2e58ef8e15267f15sewardj    const MachineOperand &MO = MI->getOperand(1);
4351c5bcb1e17532ec1630056fb2e58ef8e15267f15sewardj    assert((MO.isGlobal() || MO.isJTI() || MO.isCPI()) &&
4361c5bcb1e17532ec1630056fb2e58ef8e15267f15sewardj           "Invalid operand for LDtocL!");
4370ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    MCSymbol *MOSymbol = 0;
4381c5bcb1e17532ec1630056fb2e58ef8e15267f15sewardj
4391c5bcb1e17532ec1630056fb2e58ef8e15267f15sewardj    if (MO.isJTI())
4401c5bcb1e17532ec1630056fb2e58ef8e15267f15sewardj      MOSymbol = lookUpOrCreateTOCEntry(GetJTISymbol(MO.getIndex()));
4411c5bcb1e17532ec1630056fb2e58ef8e15267f15sewardj    else if (MO.isCPI())
4421c5bcb1e17532ec1630056fb2e58ef8e15267f15sewardj      MOSymbol = GetCPISymbol(MO.getIndex());
443575ce8ef8fa86a502dabe152293320676922dcfebart    else if (MO.isGlobal()) {
444575ce8ef8fa86a502dabe152293320676922dcfebart      const GlobalValue *GValue = MO.getGlobal();
4450ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      const GlobalAlias *GAlias = dyn_cast<GlobalAlias>(GValue);
446d68ac3e974d25f88492774f6baa491999afde9f9sewardj      const GlobalValue *RealGValue = GAlias ?
447d68ac3e974d25f88492774f6baa491999afde9f9sewardj        GAlias->resolveAliasedGlobal(false) : GValue;
4481c5bcb1e17532ec1630056fb2e58ef8e15267f15sewardj      MOSymbol = Mang->getSymbol(RealGValue);
4490ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      const GlobalVariable *GVar = dyn_cast<GlobalVariable>(RealGValue);
4500ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
4511c5bcb1e17532ec1630056fb2e58ef8e15267f15sewardj      if (!GVar || !GVar->hasInitializer() || RealGValue->hasCommonLinkage() ||
4521c5bcb1e17532ec1630056fb2e58ef8e15267f15sewardj          RealGValue->hasAvailableExternallyLinkage())
4531c5bcb1e17532ec1630056fb2e58ef8e15267f15sewardj        MOSymbol = lookUpOrCreateTOCEntry(MOSymbol);
4540ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    }
4551c5bcb1e17532ec1630056fb2e58ef8e15267f15sewardj
4560ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    const MCExpr *Exp =
457d68ac3e974d25f88492774f6baa491999afde9f9sewardj      MCSymbolRefExpr::Create(MOSymbol, MCSymbolRefExpr::VK_PPC_TOC_LO,
4580ec07f32bbbb209d749b9974408e6f025ad40b31sewardj                              OutContext);
4590ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    TmpInst.getOperand(1) = MCOperand::CreateExpr(Exp);
4600ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    OutStreamer.EmitInstruction(TmpInst);
4610ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    return;
4620ec07f32bbbb209d749b9974408e6f025ad40b31sewardj  }
4630ec07f32bbbb209d749b9974408e6f025ad40b31sewardj  case PPC::ADDItocL: {
464f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj    // Transform %Xd = ADDItocL %Xs, <ga:@sym>
4650ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    LowerPPCMachineInstrToMCInst(MI, TmpInst, *this);
466f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj
4670ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    // Change the opcode to ADDI8.  If the global address is external, then
468f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj    // generate a TOC entry and reference that.  Otherwise reference the
469d68ac3e974d25f88492774f6baa491999afde9f9sewardj    // symbol directly.
470d68ac3e974d25f88492774f6baa491999afde9f9sewardj    TmpInst.setOpcode(PPC::ADDI8);
471d68ac3e974d25f88492774f6baa491999afde9f9sewardj    const MachineOperand &MO = MI->getOperand(2);
472d68ac3e974d25f88492774f6baa491999afde9f9sewardj    assert((MO.isGlobal() || MO.isCPI()) && "Invalid operand for ADDItocL");
473d68ac3e974d25f88492774f6baa491999afde9f9sewardj    MCSymbol *MOSymbol = 0;
474d68ac3e974d25f88492774f6baa491999afde9f9sewardj    bool IsExternal = false;
475d68ac3e974d25f88492774f6baa491999afde9f9sewardj    bool IsFunction = false;
476d68ac3e974d25f88492774f6baa491999afde9f9sewardj
4771a85f4f4e5e1ec2518137ffa9a6a9bf7d9c50df9sewardj    if (MO.isGlobal()) {
4781a85f4f4e5e1ec2518137ffa9a6a9bf7d9c50df9sewardj      const GlobalValue *GValue = MO.getGlobal();
4791a85f4f4e5e1ec2518137ffa9a6a9bf7d9c50df9sewardj      const GlobalAlias *GAlias = dyn_cast<GlobalAlias>(GValue);
4801a85f4f4e5e1ec2518137ffa9a6a9bf7d9c50df9sewardj      const GlobalValue *RealGValue = GAlias ?
481575ce8ef8fa86a502dabe152293320676922dcfebart        GAlias->resolveAliasedGlobal(false) : GValue;
482575ce8ef8fa86a502dabe152293320676922dcfebart      MOSymbol = Mang->getSymbol(RealGValue);
4839af10a1c0d1b8897195ccfbc6dc46d8113d77153sewardj      const GlobalVariable *GVar = dyn_cast<GlobalVariable>(RealGValue);
4840ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      IsExternal = GVar && !GVar->hasInitializer();
485575ce8ef8fa86a502dabe152293320676922dcfebart      IsFunction = !GVar;
486575ce8ef8fa86a502dabe152293320676922dcfebart    } else if (MO.isCPI())
4878258a3a849f8bf47146ff1740d2dac429bb453a5sewardj      MOSymbol = GetCPISymbol(MO.getIndex());
4888258a3a849f8bf47146ff1740d2dac429bb453a5sewardj
4891a85f4f4e5e1ec2518137ffa9a6a9bf7d9c50df9sewardj    if (IsFunction || IsExternal)
4901a85f4f4e5e1ec2518137ffa9a6a9bf7d9c50df9sewardj      MOSymbol = lookUpOrCreateTOCEntry(MOSymbol);
4911a85f4f4e5e1ec2518137ffa9a6a9bf7d9c50df9sewardj
4921a85f4f4e5e1ec2518137ffa9a6a9bf7d9c50df9sewardj    const MCExpr *Exp =
4931a85f4f4e5e1ec2518137ffa9a6a9bf7d9c50df9sewardj      MCSymbolRefExpr::Create(MOSymbol, MCSymbolRefExpr::VK_PPC_TOC_LO,
4949af10a1c0d1b8897195ccfbc6dc46d8113d77153sewardj                              OutContext);
4950ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    TmpInst.getOperand(2) = MCOperand::CreateExpr(Exp);
4968258a3a849f8bf47146ff1740d2dac429bb453a5sewardj    OutStreamer.EmitInstruction(TmpInst);
4978258a3a849f8bf47146ff1740d2dac429bb453a5sewardj    return;
4988258a3a849f8bf47146ff1740d2dac429bb453a5sewardj  }
4991a85f4f4e5e1ec2518137ffa9a6a9bf7d9c50df9sewardj  case PPC::ADDISgotTprelHA: {
5008258a3a849f8bf47146ff1740d2dac429bb453a5sewardj    // Transform: %Xd = ADDISgotTprelHA %X2, <ga:@sym>
5018258a3a849f8bf47146ff1740d2dac429bb453a5sewardj    // Into:      %Xd = ADDIS8 %X2, sym@got@tlsgd@ha
5028258a3a849f8bf47146ff1740d2dac429bb453a5sewardj    assert(Subtarget.isPPC64() && "Not supported for 32-bit PowerPC");
5038258a3a849f8bf47146ff1740d2dac429bb453a5sewardj    const MachineOperand &MO = MI->getOperand(2);
5048258a3a849f8bf47146ff1740d2dac429bb453a5sewardj    const GlobalValue *GValue = MO.getGlobal();
505575ce8ef8fa86a502dabe152293320676922dcfebart    MCSymbol *MOSymbol = Mang->getSymbol(GValue);
506575ce8ef8fa86a502dabe152293320676922dcfebart    const MCExpr *SymGotTprel =
5071a85f4f4e5e1ec2518137ffa9a6a9bf7d9c50df9sewardj      MCSymbolRefExpr::Create(MOSymbol, MCSymbolRefExpr::VK_PPC_GOT_TPREL_HA,
508d68ac3e974d25f88492774f6baa491999afde9f9sewardj                              OutContext);
509d68ac3e974d25f88492774f6baa491999afde9f9sewardj    OutStreamer.EmitInstruction(MCInstBuilder(PPC::ADDIS8)
5108258a3a849f8bf47146ff1740d2dac429bb453a5sewardj                                .addReg(MI->getOperand(0).getReg())
5111a85f4f4e5e1ec2518137ffa9a6a9bf7d9c50df9sewardj                                .addReg(PPC::X2)
5121a85f4f4e5e1ec2518137ffa9a6a9bf7d9c50df9sewardj                                .addExpr(SymGotTprel));
5138258a3a849f8bf47146ff1740d2dac429bb453a5sewardj    return;
5148258a3a849f8bf47146ff1740d2dac429bb453a5sewardj  }
5158258a3a849f8bf47146ff1740d2dac429bb453a5sewardj  case PPC::LDgotTprelL: {
5161a85f4f4e5e1ec2518137ffa9a6a9bf7d9c50df9sewardj    // Transform %Xd = LDgotTprelL <ga:@sym>, %Xs
5178258a3a849f8bf47146ff1740d2dac429bb453a5sewardj    LowerPPCMachineInstrToMCInst(MI, TmpInst, *this);
5181a85f4f4e5e1ec2518137ffa9a6a9bf7d9c50df9sewardj
519d68ac3e974d25f88492774f6baa491999afde9f9sewardj    // Change the opcode to LD.
520d68ac3e974d25f88492774f6baa491999afde9f9sewardj    TmpInst.setOpcode(PPC::LD);
521d68ac3e974d25f88492774f6baa491999afde9f9sewardj    const MachineOperand &MO = MI->getOperand(1);
5228258a3a849f8bf47146ff1740d2dac429bb453a5sewardj    const GlobalValue *GValue = MO.getGlobal();
5238258a3a849f8bf47146ff1740d2dac429bb453a5sewardj    MCSymbol *MOSymbol = Mang->getSymbol(GValue);
5248258a3a849f8bf47146ff1740d2dac429bb453a5sewardj    const MCExpr *Exp =
525d68ac3e974d25f88492774f6baa491999afde9f9sewardj      MCSymbolRefExpr::Create(MOSymbol, MCSymbolRefExpr::VK_PPC_GOT_TPREL_LO,
5268258a3a849f8bf47146ff1740d2dac429bb453a5sewardj                              OutContext);
527d68ac3e974d25f88492774f6baa491999afde9f9sewardj    TmpInst.getOperand(1) = MCOperand::CreateExpr(Exp);
528d68ac3e974d25f88492774f6baa491999afde9f9sewardj    OutStreamer.EmitInstruction(TmpInst);
5290ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    return;
5301a85f4f4e5e1ec2518137ffa9a6a9bf7d9c50df9sewardj  }
5311a85f4f4e5e1ec2518137ffa9a6a9bf7d9c50df9sewardj  case PPC::ADDIStlsgdHA: {
5321a85f4f4e5e1ec2518137ffa9a6a9bf7d9c50df9sewardj    // Transform: %Xd = ADDIStlsgdHA %X2, <ga:@sym>
5331a85f4f4e5e1ec2518137ffa9a6a9bf7d9c50df9sewardj    // Into:      %Xd = ADDIS8 %X2, sym@got@tlsgd@ha
5341a85f4f4e5e1ec2518137ffa9a6a9bf7d9c50df9sewardj    assert(Subtarget.isPPC64() && "Not supported for 32-bit PowerPC");
5351a85f4f4e5e1ec2518137ffa9a6a9bf7d9c50df9sewardj    const MachineOperand &MO = MI->getOperand(2);
536f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj    const GlobalValue *GValue = MO.getGlobal();
537f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj    MCSymbol *MOSymbol = Mang->getSymbol(GValue);
53859570ffbe31930ab4d678754daaeec0715117a3dsewardj    const MCExpr *SymGotTlsGD =
53959570ffbe31930ab4d678754daaeec0715117a3dsewardj      MCSymbolRefExpr::Create(MOSymbol, MCSymbolRefExpr::VK_PPC_GOT_TLSGD_HA,
54059570ffbe31930ab4d678754daaeec0715117a3dsewardj                              OutContext);
54159570ffbe31930ab4d678754daaeec0715117a3dsewardj    OutStreamer.EmitInstruction(MCInstBuilder(PPC::ADDIS8)
54259570ffbe31930ab4d678754daaeec0715117a3dsewardj                                .addReg(MI->getOperand(0).getReg())
54359570ffbe31930ab4d678754daaeec0715117a3dsewardj                                .addReg(PPC::X2)
54459570ffbe31930ab4d678754daaeec0715117a3dsewardj                                .addExpr(SymGotTlsGD));
54559570ffbe31930ab4d678754daaeec0715117a3dsewardj    return;
54659570ffbe31930ab4d678754daaeec0715117a3dsewardj  }
54759570ffbe31930ab4d678754daaeec0715117a3dsewardj  case PPC::ADDItlsgdL: {
54859570ffbe31930ab4d678754daaeec0715117a3dsewardj    // Transform: %Xd = ADDItlsgdL %Xs, <ga:@sym>
54959570ffbe31930ab4d678754daaeec0715117a3dsewardj    // Into:      %Xd = ADDI8 %Xs, sym@got@tlsgd@l
55059570ffbe31930ab4d678754daaeec0715117a3dsewardj    assert(Subtarget.isPPC64() && "Not supported for 32-bit PowerPC");
55159570ffbe31930ab4d678754daaeec0715117a3dsewardj    const MachineOperand &MO = MI->getOperand(2);
552575ce8ef8fa86a502dabe152293320676922dcfebart    const GlobalValue *GValue = MO.getGlobal();
553575ce8ef8fa86a502dabe152293320676922dcfebart    MCSymbol *MOSymbol = Mang->getSymbol(GValue);
55459570ffbe31930ab4d678754daaeec0715117a3dsewardj    const MCExpr *SymGotTlsGD =
55559570ffbe31930ab4d678754daaeec0715117a3dsewardj      MCSymbolRefExpr::Create(MOSymbol, MCSymbolRefExpr::VK_PPC_GOT_TLSGD_LO,
556575ce8ef8fa86a502dabe152293320676922dcfebart                              OutContext);
557575ce8ef8fa86a502dabe152293320676922dcfebart    OutStreamer.EmitInstruction(MCInstBuilder(PPC::ADDI8)
55859570ffbe31930ab4d678754daaeec0715117a3dsewardj                                .addReg(MI->getOperand(0).getReg())
55959570ffbe31930ab4d678754daaeec0715117a3dsewardj                                .addReg(MI->getOperand(1).getReg())
56059570ffbe31930ab4d678754daaeec0715117a3dsewardj                                .addExpr(SymGotTlsGD));
56159570ffbe31930ab4d678754daaeec0715117a3dsewardj    return;
56259570ffbe31930ab4d678754daaeec0715117a3dsewardj  }
56359570ffbe31930ab4d678754daaeec0715117a3dsewardj  case PPC::GETtlsADDR: {
56459570ffbe31930ab4d678754daaeec0715117a3dsewardj    // Transform: %X3 = GETtlsADDR %X3, <ga:@sym>
56559570ffbe31930ab4d678754daaeec0715117a3dsewardj    // Into:      BL8_NOP_TLSGD __tls_get_addr(sym@tlsgd)
56659570ffbe31930ab4d678754daaeec0715117a3dsewardj    assert(Subtarget.isPPC64() && "Not supported for 32-bit PowerPC");
56759570ffbe31930ab4d678754daaeec0715117a3dsewardj
56859570ffbe31930ab4d678754daaeec0715117a3dsewardj    StringRef Name = "__tls_get_addr";
56959570ffbe31930ab4d678754daaeec0715117a3dsewardj    MCSymbol *TlsGetAddr = OutContext.GetOrCreateSymbol(Name);
57059570ffbe31930ab4d678754daaeec0715117a3dsewardj    const MCSymbolRefExpr *TlsRef =
57159570ffbe31930ab4d678754daaeec0715117a3dsewardj      MCSymbolRefExpr::Create(TlsGetAddr, MCSymbolRefExpr::VK_None, OutContext);
57259570ffbe31930ab4d678754daaeec0715117a3dsewardj    const MachineOperand &MO = MI->getOperand(2);
57359570ffbe31930ab4d678754daaeec0715117a3dsewardj    const GlobalValue *GValue = MO.getGlobal();
574575ce8ef8fa86a502dabe152293320676922dcfebart    MCSymbol *MOSymbol = Mang->getSymbol(GValue);
575575ce8ef8fa86a502dabe152293320676922dcfebart    const MCExpr *SymVar =
57659570ffbe31930ab4d678754daaeec0715117a3dsewardj      MCSymbolRefExpr::Create(MOSymbol, MCSymbolRefExpr::VK_TLSGD, OutContext);
57759570ffbe31930ab4d678754daaeec0715117a3dsewardj    OutStreamer.EmitInstruction(MCInstBuilder(PPC::BL8_NOP_TLSGD)
57859570ffbe31930ab4d678754daaeec0715117a3dsewardj                                .addExpr(TlsRef)
57959570ffbe31930ab4d678754daaeec0715117a3dsewardj                                .addExpr(SymVar));
58059570ffbe31930ab4d678754daaeec0715117a3dsewardj    return;
58159570ffbe31930ab4d678754daaeec0715117a3dsewardj  }
58259570ffbe31930ab4d678754daaeec0715117a3dsewardj  case PPC::ADDIStlsldHA: {
58359570ffbe31930ab4d678754daaeec0715117a3dsewardj    // Transform: %Xd = ADDIStlsldHA %X2, <ga:@sym>
58459570ffbe31930ab4d678754daaeec0715117a3dsewardj    // Into:      %Xd = ADDIS8 %X2, sym@got@tlsld@ha
58559570ffbe31930ab4d678754daaeec0715117a3dsewardj    assert(Subtarget.isPPC64() && "Not supported for 32-bit PowerPC");
58659570ffbe31930ab4d678754daaeec0715117a3dsewardj    const MachineOperand &MO = MI->getOperand(2);
58759570ffbe31930ab4d678754daaeec0715117a3dsewardj    const GlobalValue *GValue = MO.getGlobal();
58859570ffbe31930ab4d678754daaeec0715117a3dsewardj    MCSymbol *MOSymbol = Mang->getSymbol(GValue);
58959570ffbe31930ab4d678754daaeec0715117a3dsewardj    const MCExpr *SymGotTlsLD =
59059570ffbe31930ab4d678754daaeec0715117a3dsewardj      MCSymbolRefExpr::Create(MOSymbol, MCSymbolRefExpr::VK_PPC_GOT_TLSLD_HA,
59159570ffbe31930ab4d678754daaeec0715117a3dsewardj                              OutContext);
59259570ffbe31930ab4d678754daaeec0715117a3dsewardj    OutStreamer.EmitInstruction(MCInstBuilder(PPC::ADDIS8)
59359570ffbe31930ab4d678754daaeec0715117a3dsewardj                                .addReg(MI->getOperand(0).getReg())
59459570ffbe31930ab4d678754daaeec0715117a3dsewardj                                .addReg(PPC::X2)
59559570ffbe31930ab4d678754daaeec0715117a3dsewardj                                .addExpr(SymGotTlsLD));
59659570ffbe31930ab4d678754daaeec0715117a3dsewardj    return;
59759570ffbe31930ab4d678754daaeec0715117a3dsewardj  }
598b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj  case PPC::ADDItlsldL: {
599b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj    // Transform: %Xd = ADDItlsldL %Xs, <ga:@sym>
600b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj    // Into:      %Xd = ADDI8 %Xs, sym@got@tlsld@l
601b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj    assert(Subtarget.isPPC64() && "Not supported for 32-bit PowerPC");
602b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj    const MachineOperand &MO = MI->getOperand(2);
603b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj    const GlobalValue *GValue = MO.getGlobal();
604b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj    MCSymbol *MOSymbol = Mang->getSymbol(GValue);
605b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj    const MCExpr *SymGotTlsLD =
606b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      MCSymbolRefExpr::Create(MOSymbol, MCSymbolRefExpr::VK_PPC_GOT_TLSLD_LO,
607b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj                              OutContext);
608b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj    OutStreamer.EmitInstruction(MCInstBuilder(PPC::ADDI8)
609b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj                                .addReg(MI->getOperand(0).getReg())
610b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj                                .addReg(MI->getOperand(1).getReg())
611b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj                                .addExpr(SymGotTlsLD));
612b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj    return;
613b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj  }
614b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj  case PPC::GETtlsldADDR: {
615b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj    // Transform: %X3 = GETtlsldADDR %X3, <ga:@sym>
616b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj    // Into:      BL8_NOP_TLSLD __tls_get_addr(sym@tlsld)
617b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj    assert(Subtarget.isPPC64() && "Not supported for 32-bit PowerPC");
618b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj
619b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj    StringRef Name = "__tls_get_addr";
620b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj    MCSymbol *TlsGetAddr = OutContext.GetOrCreateSymbol(Name);
621b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj    const MCSymbolRefExpr *TlsRef =
622575ce8ef8fa86a502dabe152293320676922dcfebart      MCSymbolRefExpr::Create(TlsGetAddr, MCSymbolRefExpr::VK_None, OutContext);
623575ce8ef8fa86a502dabe152293320676922dcfebart    const MachineOperand &MO = MI->getOperand(2);
624b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj    const GlobalValue *GValue = MO.getGlobal();
625575ce8ef8fa86a502dabe152293320676922dcfebart    MCSymbol *MOSymbol = Mang->getSymbol(GValue);
626575ce8ef8fa86a502dabe152293320676922dcfebart    const MCExpr *SymVar =
627b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      MCSymbolRefExpr::Create(MOSymbol, MCSymbolRefExpr::VK_TLSLD, OutContext);
628b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj    OutStreamer.EmitInstruction(MCInstBuilder(PPC::BL8_NOP_TLSLD)
629b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj                                .addExpr(TlsRef)
630b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj                                .addExpr(SymVar));
631b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj    return;
632b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj  }
633b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj  case PPC::ADDISdtprelHA: {
634b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj    // Transform: %Xd = ADDISdtprelHA %X3, <ga:@sym>
635b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj    // Into:      %Xd = ADDIS8 %X3, sym@dtprel@ha
636b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj    assert(Subtarget.isPPC64() && "Not supported for 32-bit PowerPC");
637b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj    const MachineOperand &MO = MI->getOperand(2);
638b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj    const GlobalValue *GValue = MO.getGlobal();
639b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj    MCSymbol *MOSymbol = Mang->getSymbol(GValue);
640b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj    const MCExpr *SymDtprel =
641b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      MCSymbolRefExpr::Create(MOSymbol, MCSymbolRefExpr::VK_PPC_DTPREL_HA,
642b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj                              OutContext);
643b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj    OutStreamer.EmitInstruction(MCInstBuilder(PPC::ADDIS8)
644b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj                                .addReg(MI->getOperand(0).getReg())
645b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj                                .addReg(PPC::X3)
646575ce8ef8fa86a502dabe152293320676922dcfebart                                .addExpr(SymDtprel));
647575ce8ef8fa86a502dabe152293320676922dcfebart    return;
648b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj  }
649b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj  case PPC::ADDIdtprelL: {
650b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj    // Transform: %Xd = ADDIdtprelL %Xs, <ga:@sym>
651b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj    // Into:      %Xd = ADDI8 %Xs, sym@dtprel@l
652b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj    assert(Subtarget.isPPC64() && "Not supported for 32-bit PowerPC");
653b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj    const MachineOperand &MO = MI->getOperand(2);
654b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj    const GlobalValue *GValue = MO.getGlobal();
655b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj    MCSymbol *MOSymbol = Mang->getSymbol(GValue);
656b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj    const MCExpr *SymDtprel =
657b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      MCSymbolRefExpr::Create(MOSymbol, MCSymbolRefExpr::VK_PPC_DTPREL_LO,
658b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj                              OutContext);
659b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj    OutStreamer.EmitInstruction(MCInstBuilder(PPC::ADDI8)
660b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj                                .addReg(MI->getOperand(0).getReg())
661b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj                                .addReg(MI->getOperand(1).getReg())
662b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj                                .addExpr(SymDtprel));
663b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj    return;
664b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj  }
665b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj  case PPC::MFCRpseud:
666b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj  case PPC::MFCR8pseud:
667b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj    // Transform: %R3 = MFCRpseud %CR7
668f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj    // Into:      %R3 = MFCR      ;; cr7
66926aba4d3ef6cebc34879e82d88bcbe3c3b3b9f9enjn    OutStreamer.AddComment(PPCInstPrinter::
67037091fb739760631f436043c47de612cf9fd2dd1sewardj                           getRegisterName(MI->getOperand(1).getReg()));
6712e93c50dc50235189661b70e3f27a4098d5cccccsewardj    OutStreamer.EmitInstruction(MCInstBuilder(Subtarget.isPPC64() ? PPC::MFCR8 : PPC::MFCR)
67269d9c4625034b60c08e04cc246fcf8093d23fde5nethercote      .addReg(MI->getOperand(0).getReg()));
67330d76c6abc3e7d338b1ca81256fa3ce93eccc09fnjn    return;
674f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj  case PPC::SYNC:
6750ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    // In Book E sync is called msync, handle this special case here...
6760ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    if (Subtarget.isBookE()) {
6770ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      OutStreamer.EmitRawText(StringRef("\tmsync"));
6780ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      return;
6790ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    }
6800ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    break;
6810ec07f32bbbb209d749b9974408e6f025ad40b31sewardj  case PPC::LD:
6820ec07f32bbbb209d749b9974408e6f025ad40b31sewardj  case PPC::STD:
6830ec07f32bbbb209d749b9974408e6f025ad40b31sewardj  case PPC::LWA: {
6840ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    // Verify alignment is legal, so we don't create relocations
6850ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    // that can't be supported.
6860ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    // FIXME:  This test is currently disabled for Darwin.  The test
6870ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    // suite shows a handful of test cases that fail this check for
6880ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    // Darwin.  Those need to be investigated before this sanity test
6890ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    // can be enabled for those subtargets.
6900ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    if (!Subtarget.isDarwin()) {
6910ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      unsigned OpNum = (MI->getOpcode() == PPC::STD) ? 2 : 1;
6920ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      const MachineOperand &MO = MI->getOperand(OpNum);
6930ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      if (MO.isGlobal() && MO.getGlobal()->getAlignment() < 4)
6940ec07f32bbbb209d749b9974408e6f025ad40b31sewardj        llvm_unreachable("Global must be word-aligned for LD, STD, LWA!");
6950ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    }
6960ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    // Now process the instruction normally.
69785cf90056b7a8d98d88335b47c599a35b35ff7casewardj    break;
69885cf90056b7a8d98d88335b47c599a35b35ff7casewardj  }
69985cf90056b7a8d98d88335b47c599a35b35ff7casewardj  }
70085cf90056b7a8d98d88335b47c599a35b35ff7casewardj
7010ec07f32bbbb209d749b9974408e6f025ad40b31sewardj  LowerPPCMachineInstrToMCInst(MI, TmpInst, *this);
7025f5ef2ae9e7c2ce5ebc36c1e2fc98e5f81650be3njn  OutStreamer.EmitInstruction(TmpInst);
7035f5ef2ae9e7c2ce5ebc36c1e2fc98e5f81650be3njn}
7045f5ef2ae9e7c2ce5ebc36c1e2fc98e5f81650be3njn
7055f5ef2ae9e7c2ce5ebc36c1e2fc98e5f81650be3njnvoid PPCLinuxAsmPrinter::EmitFunctionEntryLabel() {
7060ec07f32bbbb209d749b9974408e6f025ad40b31sewardj  if (!Subtarget.isPPC64())  // linux/ppc32 - Normal entry label.
70796044842731e581702c9ed4104d2949fcde20fd8sewardj    return AsmPrinter::EmitFunctionEntryLabel();
7080ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
7090ec07f32bbbb209d749b9974408e6f025ad40b31sewardj  // Emit an official procedure descriptor.
71096044842731e581702c9ed4104d2949fcde20fd8sewardj  MCSectionSubPair Current = OutStreamer.getCurrentSection();
7110ec07f32bbbb209d749b9974408e6f025ad40b31sewardj  const MCSectionELF *Section = OutStreamer.getContext().getELFSection(".opd",
712d68ac3e974d25f88492774f6baa491999afde9f9sewardj      ELF::SHT_PROGBITS, ELF::SHF_WRITE | ELF::SHF_ALLOC,
713d68ac3e974d25f88492774f6baa491999afde9f9sewardj      SectionKind::getReadOnly());
714d68ac3e974d25f88492774f6baa491999afde9f9sewardj  OutStreamer.SwitchSection(Section);
715d68ac3e974d25f88492774f6baa491999afde9f9sewardj  OutStreamer.EmitLabel(CurrentFnSym);
716d68ac3e974d25f88492774f6baa491999afde9f9sewardj  OutStreamer.EmitValueToAlignment(8);
7170ec07f32bbbb209d749b9974408e6f025ad40b31sewardj  MCSymbol *Symbol1 =
7180ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    OutContext.GetOrCreateSymbol(".L." + Twine(CurrentFnSym->getName()));
7190ec07f32bbbb209d749b9974408e6f025ad40b31sewardj  // Generates a R_PPC64_ADDR64 (from FK_DATA_8) relocation for the function
7200ec07f32bbbb209d749b9974408e6f025ad40b31sewardj  // entry point.
7210ec07f32bbbb209d749b9974408e6f025ad40b31sewardj  OutStreamer.EmitValue(MCSymbolRefExpr::Create(Symbol1, OutContext),
7220ec07f32bbbb209d749b9974408e6f025ad40b31sewardj			8 /*size*/);
7230ec07f32bbbb209d749b9974408e6f025ad40b31sewardj  MCSymbol *Symbol2 = OutContext.GetOrCreateSymbol(StringRef(".TOC."));
7240ec07f32bbbb209d749b9974408e6f025ad40b31sewardj  // Generates a R_PPC64_TOC relocation for TOC base insertion.
7250ec07f32bbbb209d749b9974408e6f025ad40b31sewardj  OutStreamer.EmitValue(MCSymbolRefExpr::Create(Symbol2,
7260ec07f32bbbb209d749b9974408e6f025ad40b31sewardj                        MCSymbolRefExpr::VK_PPC_TOCBASE, OutContext),
7270ec07f32bbbb209d749b9974408e6f025ad40b31sewardj                        8/*size*/);
7280ec07f32bbbb209d749b9974408e6f025ad40b31sewardj  // Emit a null environment pointer.
7290ec07f32bbbb209d749b9974408e6f025ad40b31sewardj  OutStreamer.EmitIntValue(0, 8 /* size */);
7300ec07f32bbbb209d749b9974408e6f025ad40b31sewardj  OutStreamer.SwitchSection(Current.first, Current.second);
7310ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
7320ec07f32bbbb209d749b9974408e6f025ad40b31sewardj  MCSymbol *RealFnSym = OutContext.GetOrCreateSymbol(
7335ce4b150ce5d32c9af07a24717081ea34568388asewardj                          ".L." + Twine(CurrentFnSym->getName()));
7345ce4b150ce5d32c9af07a24717081ea34568388asewardj  OutStreamer.EmitLabel(RealFnSym);
7355ce4b150ce5d32c9af07a24717081ea34568388asewardj  CurrentFnSymForSize = RealFnSym;
7365ce4b150ce5d32c9af07a24717081ea34568388asewardj}
7372b5f0a90334a2271791c110548a842fadb5ffc65njn
7382b5f0a90334a2271791c110548a842fadb5ffc65njn
7392b5f0a90334a2271791c110548a842fadb5ffc65njnbool PPCLinuxAsmPrinter::doFinalization(Module &M) {
7402b5f0a90334a2271791c110548a842fadb5ffc65njn  const DataLayout *TD = TM.getDataLayout();
7412b5f0a90334a2271791c110548a842fadb5ffc65njn
7422b5f0a90334a2271791c110548a842fadb5ffc65njn  bool isPPC64 = TD->getPointerSizeInBits() == 64;
7432b5f0a90334a2271791c110548a842fadb5ffc65njn
7442b5f0a90334a2271791c110548a842fadb5ffc65njn  if (isPPC64 && !TOC.empty()) {
7452b5f0a90334a2271791c110548a842fadb5ffc65njn    const MCSectionELF *Section = OutStreamer.getContext().getELFSection(".toc",
7462b5f0a90334a2271791c110548a842fadb5ffc65njn        ELF::SHT_PROGBITS, ELF::SHF_WRITE | ELF::SHF_ALLOC,
7472b5f0a90334a2271791c110548a842fadb5ffc65njn        SectionKind::getReadOnly());
7482b5f0a90334a2271791c110548a842fadb5ffc65njn    OutStreamer.SwitchSection(Section);
7492b5f0a90334a2271791c110548a842fadb5ffc65njn
7502b5f0a90334a2271791c110548a842fadb5ffc65njn    for (MapVector<MCSymbol*, MCSymbol*>::iterator I = TOC.begin(),
7512b5f0a90334a2271791c110548a842fadb5ffc65njn         E = TOC.end(); I != E; ++I) {
7522b5f0a90334a2271791c110548a842fadb5ffc65njn      OutStreamer.EmitLabel(I->second);
753f76d27a697a7b0bf3b84490baf60623fc96a23afnjn      MCSymbol *S = OutContext.GetOrCreateSymbol(I->first->getName());
7540ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      OutStreamer.EmitTCEntry(*S);
755f76d27a697a7b0bf3b84490baf60623fc96a23afnjn    }
7560ec07f32bbbb209d749b9974408e6f025ad40b31sewardj  }
7570ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
7580ec07f32bbbb209d749b9974408e6f025ad40b31sewardj  MachineModuleInfoELF &MMIELF =
7590ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    MMI->getObjFileInfo<MachineModuleInfoELF>();
7600ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
7610ec07f32bbbb209d749b9974408e6f025ad40b31sewardj  MachineModuleInfoELF::SymbolListTy Stubs = MMIELF.GetGVStubList();
7620ec07f32bbbb209d749b9974408e6f025ad40b31sewardj  if (!Stubs.empty()) {
7630ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    OutStreamer.SwitchSection(getObjFileLowering().getDataSection());
76466226cc1e5e852de3584c76984dace8679730b42sewardj    for (unsigned i = 0, e = Stubs.size(); i != e; ++i) {
7650ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      // L_foo$stub:
76666226cc1e5e852de3584c76984dace8679730b42sewardj      OutStreamer.EmitLabel(Stubs[i].first);
7670ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      //   .long _foo
7680ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      OutStreamer.EmitValue(MCSymbolRefExpr::Create(Stubs[i].second.getPointer(),
76966226cc1e5e852de3584c76984dace8679730b42sewardj                                                    OutContext),
7700ec07f32bbbb209d749b9974408e6f025ad40b31sewardj                            isPPC64 ? 8 : 4/*size*/);
7710ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    }
7720ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
7730ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    Stubs.clear();
7740ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    OutStreamer.AddBlankLine();
7750ec07f32bbbb209d749b9974408e6f025ad40b31sewardj  }
7760ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
7770ec07f32bbbb209d749b9974408e6f025ad40b31sewardj  return AsmPrinter::doFinalization(M);
7780ec07f32bbbb209d749b9974408e6f025ad40b31sewardj}
7790ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
78066226cc1e5e852de3584c76984dace8679730b42sewardj/// EmitFunctionBodyEnd - Print the traceback table before the .size
7810ec07f32bbbb209d749b9974408e6f025ad40b31sewardj/// directive.
78266226cc1e5e852de3584c76984dace8679730b42sewardj///
7830ec07f32bbbb209d749b9974408e6f025ad40b31sewardjvoid PPCLinuxAsmPrinter::EmitFunctionBodyEnd() {
7840ec07f32bbbb209d749b9974408e6f025ad40b31sewardj  // Only the 64-bit target requires a traceback table.  For now,
78566226cc1e5e852de3584c76984dace8679730b42sewardj  // we only emit the word of zeroes that GDB requires to find
7860ec07f32bbbb209d749b9974408e6f025ad40b31sewardj  // the end of the function, and zeroes for the eight-byte
7870ec07f32bbbb209d749b9974408e6f025ad40b31sewardj  // mandatory fields.
78887a287b47f496063f5869dc5039a81baeb6a29aesewardj  // FIXME: We should fill in the eight-byte mandatory fields as described in
7890ec07f32bbbb209d749b9974408e6f025ad40b31sewardj  // the PPC64 ELF ABI (this is a low-priority item because GDB does not
7900ec07f32bbbb209d749b9974408e6f025ad40b31sewardj  // currently make use of these fields).
7910ec07f32bbbb209d749b9974408e6f025ad40b31sewardj  if (Subtarget.isPPC64()) {
79287a287b47f496063f5869dc5039a81baeb6a29aesewardj    OutStreamer.EmitIntValue(0, 4/*size*/);
7930ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    OutStreamer.EmitIntValue(0, 8/*size*/);
7940ec07f32bbbb209d749b9974408e6f025ad40b31sewardj  }
7950ec07f32bbbb209d749b9974408e6f025ad40b31sewardj}
7960ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
7970ec07f32bbbb209d749b9974408e6f025ad40b31sewardjvoid PPCDarwinAsmPrinter::EmitStartOfAsmFile(Module &M) {
7980ec07f32bbbb209d749b9974408e6f025ad40b31sewardj  static const char *const CPUDirectives[] = {
7990ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    "",
80066226cc1e5e852de3584c76984dace8679730b42sewardj    "ppc",
8010ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    "ppc440",
80266226cc1e5e852de3584c76984dace8679730b42sewardj    "ppc601",
8030ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    "ppc602",
8040ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    "ppc603",
80566226cc1e5e852de3584c76984dace8679730b42sewardj    "ppc7400",
8060ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    "ppc750",
8070ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    "ppc970",
8080ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    "ppcA2",
80987a287b47f496063f5869dc5039a81baeb6a29aesewardj    "ppce500mc",
8100ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    "ppce5500",
8110ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    "power3",
8120ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    "power4",
8130ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    "power5",
81487a287b47f496063f5869dc5039a81baeb6a29aesewardj    "power5x",
8150ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    "power6",
8169e8b07ab0fb74fb15098c406a5dc71e273d50b1csewardj    "power6x",
8179e8b07ab0fb74fb15098c406a5dc71e273d50b1csewardj    "power7",
8189e8b07ab0fb74fb15098c406a5dc71e273d50b1csewardj    "ppc64"
8199e8b07ab0fb74fb15098c406a5dc71e273d50b1csewardj  };
8209e8b07ab0fb74fb15098c406a5dc71e273d50b1csewardj
8219e8b07ab0fb74fb15098c406a5dc71e273d50b1csewardj  unsigned Directive = Subtarget.getDarwinDirective();
8229e8b07ab0fb74fb15098c406a5dc71e273d50b1csewardj  if (Subtarget.hasMFOCRF() && Directive < PPC::DIR_970)
8239e8b07ab0fb74fb15098c406a5dc71e273d50b1csewardj    Directive = PPC::DIR_970;
8249e8b07ab0fb74fb15098c406a5dc71e273d50b1csewardj  if (Subtarget.hasAltivec() && Directive < PPC::DIR_7400)
8259e8b07ab0fb74fb15098c406a5dc71e273d50b1csewardj    Directive = PPC::DIR_7400;
8269e8b07ab0fb74fb15098c406a5dc71e273d50b1csewardj  if (Subtarget.isPPC64() && Directive < PPC::DIR_64)
8279e8b07ab0fb74fb15098c406a5dc71e273d50b1csewardj    Directive = PPC::DIR_64;
8289e8b07ab0fb74fb15098c406a5dc71e273d50b1csewardj  assert(Directive <= PPC::DIR_64 && "Directive out of range.");
8299e8b07ab0fb74fb15098c406a5dc71e273d50b1csewardj
8309e8b07ab0fb74fb15098c406a5dc71e273d50b1csewardj  // FIXME: This is a total hack, finish mc'izing the PPC backend.
8319e8b07ab0fb74fb15098c406a5dc71e273d50b1csewardj  if (OutStreamer.hasRawTextSupport()) {
83287a287b47f496063f5869dc5039a81baeb6a29aesewardj    assert(Directive < sizeof(CPUDirectives) / sizeof(*CPUDirectives) &&
8339e8b07ab0fb74fb15098c406a5dc71e273d50b1csewardj           "CPUDirectives[] might not be up-to-date!");
8349e8b07ab0fb74fb15098c406a5dc71e273d50b1csewardj    OutStreamer.EmitRawText("\t.machine " + Twine(CPUDirectives[Directive]));
8359e8b07ab0fb74fb15098c406a5dc71e273d50b1csewardj  }
8369e8b07ab0fb74fb15098c406a5dc71e273d50b1csewardj
8379e8b07ab0fb74fb15098c406a5dc71e273d50b1csewardj  // Prime text sections so they are adjacent.  This reduces the likelihood a
83887a287b47f496063f5869dc5039a81baeb6a29aesewardj  // large data or debug section causes a branch to exceed 16M limit.
8399e8b07ab0fb74fb15098c406a5dc71e273d50b1csewardj  const TargetLoweringObjectFileMachO &TLOFMacho =
8400ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    static_cast<const TargetLoweringObjectFileMachO &>(getObjFileLowering());
8410ec07f32bbbb209d749b9974408e6f025ad40b31sewardj  OutStreamer.SwitchSection(TLOFMacho.getTextCoalSection());
8420ec07f32bbbb209d749b9974408e6f025ad40b31sewardj  if (TM.getRelocationModel() == Reloc::PIC_) {
8430ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    OutStreamer.SwitchSection(
8440ec07f32bbbb209d749b9974408e6f025ad40b31sewardj           OutContext.getMachOSection("__TEXT", "__picsymbolstub1",
8450ec07f32bbbb209d749b9974408e6f025ad40b31sewardj                                      MCSectionMachO::S_SYMBOL_STUBS |
84666226cc1e5e852de3584c76984dace8679730b42sewardj                                      MCSectionMachO::S_ATTR_PURE_INSTRUCTIONS,
8470ec07f32bbbb209d749b9974408e6f025ad40b31sewardj                                      32, SectionKind::getText()));
84866226cc1e5e852de3584c76984dace8679730b42sewardj  } else if (TM.getRelocationModel() == Reloc::DynamicNoPIC) {
8490ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    OutStreamer.SwitchSection(
8500ec07f32bbbb209d749b9974408e6f025ad40b31sewardj           OutContext.getMachOSection("__TEXT","__symbol_stub1",
85166226cc1e5e852de3584c76984dace8679730b42sewardj                                      MCSectionMachO::S_SYMBOL_STUBS |
8520ec07f32bbbb209d749b9974408e6f025ad40b31sewardj                                      MCSectionMachO::S_ATTR_PURE_INSTRUCTIONS,
8530ec07f32bbbb209d749b9974408e6f025ad40b31sewardj                                      16, SectionKind::getText()));
8540ec07f32bbbb209d749b9974408e6f025ad40b31sewardj  }
8550ec07f32bbbb209d749b9974408e6f025ad40b31sewardj  OutStreamer.SwitchSection(getObjFileLowering().getTextSection());
8560ec07f32bbbb209d749b9974408e6f025ad40b31sewardj}
8570ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
8580ec07f32bbbb209d749b9974408e6f025ad40b31sewardjstatic MCSymbol *GetLazyPtr(MCSymbol *Sym, MCContext &Ctx) {
8590ec07f32bbbb209d749b9974408e6f025ad40b31sewardj  // Remove $stub suffix, add $lazy_ptr.
8600ec07f32bbbb209d749b9974408e6f025ad40b31sewardj  StringRef NoStub = Sym->getName().substr(0, Sym->getName().size()-5);
8610ec07f32bbbb209d749b9974408e6f025ad40b31sewardj  return Ctx.GetOrCreateSymbol(NoStub + "$lazy_ptr");
8620ec07f32bbbb209d749b9974408e6f025ad40b31sewardj}
8630ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
8640ec07f32bbbb209d749b9974408e6f025ad40b31sewardjstatic MCSymbol *GetAnonSym(MCSymbol *Sym, MCContext &Ctx) {
8650ec07f32bbbb209d749b9974408e6f025ad40b31sewardj  // Add $tmp suffix to $stub, yielding $stub$tmp.
8660ec07f32bbbb209d749b9974408e6f025ad40b31sewardj  return Ctx.GetOrCreateSymbol(Sym->getName() + "$tmp");
8670ec07f32bbbb209d749b9974408e6f025ad40b31sewardj}
8680ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
8690ec07f32bbbb209d749b9974408e6f025ad40b31sewardjvoid PPCDarwinAsmPrinter::
8700ec07f32bbbb209d749b9974408e6f025ad40b31sewardjEmitFunctionStubs(const MachineModuleInfoMachO::SymbolListTy &Stubs) {
87166226cc1e5e852de3584c76984dace8679730b42sewardj  bool isPPC64 = TM.getDataLayout()->getPointerSizeInBits() == 64;
8720ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
87366226cc1e5e852de3584c76984dace8679730b42sewardj  const TargetLoweringObjectFileMachO &TLOFMacho =
8740ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    static_cast<const TargetLoweringObjectFileMachO &>(getObjFileLowering());
8750ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
87666226cc1e5e852de3584c76984dace8679730b42sewardj  // .lazy_symbol_pointer
8770ec07f32bbbb209d749b9974408e6f025ad40b31sewardj  const MCSection *LSPSection = TLOFMacho.getLazySymbolPointerSection();
8780ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
8790ec07f32bbbb209d749b9974408e6f025ad40b31sewardj  // Output stubs for dynamically-linked functions
8800ec07f32bbbb209d749b9974408e6f025ad40b31sewardj  if (TM.getRelocationModel() == Reloc::PIC_) {
8810ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    const MCSection *StubSection =
8820ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    OutContext.getMachOSection("__TEXT", "__picsymbolstub1",
88387a287b47f496063f5869dc5039a81baeb6a29aesewardj                               MCSectionMachO::S_SYMBOL_STUBS |
8840ec07f32bbbb209d749b9974408e6f025ad40b31sewardj                               MCSectionMachO::S_ATTR_PURE_INSTRUCTIONS,
8850ec07f32bbbb209d749b9974408e6f025ad40b31sewardj                               32, SectionKind::getText());
8860ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    for (unsigned i = 0, e = Stubs.size(); i != e; ++i) {
8870ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      OutStreamer.SwitchSection(StubSection);
8880ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      EmitAlignment(4);
8890ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
8900ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      MCSymbol *Stub = Stubs[i].first;
89187a287b47f496063f5869dc5039a81baeb6a29aesewardj      MCSymbol *RawSym = Stubs[i].second.getPointer();
8920ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      MCSymbol *LazyPtr = GetLazyPtr(Stub, OutContext);
8930ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      MCSymbol *AnonSymbol = GetAnonSym(Stub, OutContext);
8940ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
8950ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      OutStreamer.EmitLabel(Stub);
8960ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      OutStreamer.EmitSymbolAttribute(RawSym, MCSA_IndirectSymbol);
8970ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
8980ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      const MCExpr *Anon = MCSymbolRefExpr::Create(AnonSymbol, OutContext);
89966226cc1e5e852de3584c76984dace8679730b42sewardj      const MCExpr *LazyPtrExpr = MCSymbolRefExpr::Create(LazyPtr, OutContext);
9000ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      const MCExpr *Sub =
90166226cc1e5e852de3584c76984dace8679730b42sewardj        MCBinaryExpr::CreateSub(LazyPtrExpr, Anon, OutContext);
9020ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
9030ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      // mflr r0
90466226cc1e5e852de3584c76984dace8679730b42sewardj      OutStreamer.EmitInstruction(MCInstBuilder(PPC::MFLR).addReg(PPC::R0));
9050ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      // bcl 20, 31, AnonSymbol
9060ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      OutStreamer.EmitInstruction(MCInstBuilder(PPC::BCLalways).addExpr(Anon));
9070ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      OutStreamer.EmitLabel(AnonSymbol);
9080ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      // mflr r11
9090ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      OutStreamer.EmitInstruction(MCInstBuilder(PPC::MFLR).addReg(PPC::R11));
9100ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      // addis r11, r11, ha16(LazyPtr - AnonSymbol)
9110ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      const MCExpr *SubHa16 = PPCMCExpr::CreateHa(Sub, OutContext);
91287a287b47f496063f5869dc5039a81baeb6a29aesewardj      OutStreamer.EmitInstruction(MCInstBuilder(PPC::ADDIS)
9130ec07f32bbbb209d749b9974408e6f025ad40b31sewardj        .addReg(PPC::R11)
9140ec07f32bbbb209d749b9974408e6f025ad40b31sewardj        .addReg(PPC::R11)
9150ec07f32bbbb209d749b9974408e6f025ad40b31sewardj        .addExpr(SubHa16));
9160ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      // mtlr r0
9170ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      OutStreamer.EmitInstruction(MCInstBuilder(PPC::MTLR).addReg(PPC::R0));
9180ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
9190ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      // ldu r12, lo16(LazyPtr - AnonSymbol)(r11)
9200ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      // lwzu r12, lo16(LazyPtr - AnonSymbol)(r11)
92187a287b47f496063f5869dc5039a81baeb6a29aesewardj      const MCExpr *SubLo16 = PPCMCExpr::CreateLo(Sub, OutContext);
9220ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      OutStreamer.EmitInstruction(MCInstBuilder(isPPC64 ? PPC::LDU : PPC::LWZU)
9230ec07f32bbbb209d749b9974408e6f025ad40b31sewardj        .addReg(PPC::R12)
9240ec07f32bbbb209d749b9974408e6f025ad40b31sewardj        .addExpr(SubLo16).addExpr(SubLo16)
9250ec07f32bbbb209d749b9974408e6f025ad40b31sewardj        .addReg(PPC::R11));
9260ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      // mtctr r12
9270ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      OutStreamer.EmitInstruction(MCInstBuilder(PPC::MTCTR).addReg(PPC::R12));
9280ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      // bctr
92966226cc1e5e852de3584c76984dace8679730b42sewardj      OutStreamer.EmitInstruction(MCInstBuilder(PPC::BCTR));
93066226cc1e5e852de3584c76984dace8679730b42sewardj
9310ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      OutStreamer.SwitchSection(LSPSection);
93266226cc1e5e852de3584c76984dace8679730b42sewardj      OutStreamer.EmitLabel(LazyPtr);
9330ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      OutStreamer.EmitSymbolAttribute(RawSym, MCSA_IndirectSymbol);
9340ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
93566226cc1e5e852de3584c76984dace8679730b42sewardj      MCSymbol *DyldStubBindingHelper =
9360ec07f32bbbb209d749b9974408e6f025ad40b31sewardj        OutContext.GetOrCreateSymbol(StringRef("dyld_stub_binding_helper"));
9370ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      if (isPPC64) {
9380ec07f32bbbb209d749b9974408e6f025ad40b31sewardj        // .quad dyld_stub_binding_helper
9390ec07f32bbbb209d749b9974408e6f025ad40b31sewardj        OutStreamer.EmitSymbolValue(DyldStubBindingHelper, 8);
9400ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      } else {
9410ec07f32bbbb209d749b9974408e6f025ad40b31sewardj        // .long dyld_stub_binding_helper
9420ec07f32bbbb209d749b9974408e6f025ad40b31sewardj        OutStreamer.EmitSymbolValue(DyldStubBindingHelper, 4);
9430ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      }
94487a287b47f496063f5869dc5039a81baeb6a29aesewardj    }
9450ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    OutStreamer.AddBlankLine();
9460ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    return;
9470ec07f32bbbb209d749b9974408e6f025ad40b31sewardj  }
9480ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
9490ec07f32bbbb209d749b9974408e6f025ad40b31sewardj  const MCSection *StubSection =
9500ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    OutContext.getMachOSection("__TEXT","__symbol_stub1",
9510ec07f32bbbb209d749b9974408e6f025ad40b31sewardj                               MCSectionMachO::S_SYMBOL_STUBS |
9520ec07f32bbbb209d749b9974408e6f025ad40b31sewardj                               MCSectionMachO::S_ATTR_PURE_INSTRUCTIONS,
9530ec07f32bbbb209d749b9974408e6f025ad40b31sewardj                               16, SectionKind::getText());
95487a287b47f496063f5869dc5039a81baeb6a29aesewardj  for (unsigned i = 0, e = Stubs.size(); i != e; ++i) {
9550ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    MCSymbol *Stub = Stubs[i].first;
9560ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    MCSymbol *RawSym = Stubs[i].second.getPointer();
9570ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    MCSymbol *LazyPtr = GetLazyPtr(Stub, OutContext);
9580ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    const MCExpr *LazyPtrExpr = MCSymbolRefExpr::Create(LazyPtr, OutContext);
9590ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
9600ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    OutStreamer.SwitchSection(StubSection);
9610ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    EmitAlignment(4);
96266226cc1e5e852de3584c76984dace8679730b42sewardj    OutStreamer.EmitLabel(Stub);
96366226cc1e5e852de3584c76984dace8679730b42sewardj    OutStreamer.EmitSymbolAttribute(RawSym, MCSA_IndirectSymbol);
9640ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
96566226cc1e5e852de3584c76984dace8679730b42sewardj    // lis r11, ha16(LazyPtr)
9660ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    const MCExpr *LazyPtrHa16 = PPCMCExpr::CreateHa(LazyPtrExpr, OutContext);
9670ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    OutStreamer.EmitInstruction(MCInstBuilder(PPC::LIS)
96866226cc1e5e852de3584c76984dace8679730b42sewardj      .addReg(PPC::R11)
9690ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      .addExpr(LazyPtrHa16));
9700ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
9710ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    // ldu r12, lo16(LazyPtr)(r11)
9720ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    // lwzu r12, lo16(LazyPtr)(r11)
9730ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    const MCExpr *LazyPtrLo16 = PPCMCExpr::CreateLo(LazyPtrExpr, OutContext);
9740ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    OutStreamer.EmitInstruction(MCInstBuilder(isPPC64 ? PPC::LDU : PPC::LWZU)
9750ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      .addReg(PPC::R12)
9760ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      .addExpr(LazyPtrLo16).addExpr(LazyPtrLo16)
9770ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      .addReg(PPC::R11));
9780ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
9790ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    // mtctr r12
9800ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    OutStreamer.EmitInstruction(MCInstBuilder(PPC::MTCTR).addReg(PPC::R12));
9810ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    // bctr
9820ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    OutStreamer.EmitInstruction(MCInstBuilder(PPC::BCTR));
9830ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
9840ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    OutStreamer.SwitchSection(LSPSection);
9850ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    OutStreamer.EmitLabel(LazyPtr);
9860ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    OutStreamer.EmitSymbolAttribute(RawSym, MCSA_IndirectSymbol);
9870ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
9880ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    MCSymbol *DyldStubBindingHelper =
9890ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      OutContext.GetOrCreateSymbol(StringRef("dyld_stub_binding_helper"));
9900ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    if (isPPC64) {
9910ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      // .quad dyld_stub_binding_helper
9920ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      OutStreamer.EmitSymbolValue(DyldStubBindingHelper, 8);
9930ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    } else {
9940ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      // .long dyld_stub_binding_helper
9950ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      OutStreamer.EmitSymbolValue(DyldStubBindingHelper, 4);
99645fa5b0cef1884f5025e64401a1443d3e129ed5esewardj    }
99745fa5b0cef1884f5025e64401a1443d3e129ed5esewardj  }
99845fa5b0cef1884f5025e64401a1443d3e129ed5esewardj
99945fa5b0cef1884f5025e64401a1443d3e129ed5esewardj  OutStreamer.AddBlankLine();
100045fa5b0cef1884f5025e64401a1443d3e129ed5esewardj}
100145fa5b0cef1884f5025e64401a1443d3e129ed5esewardj
100245fa5b0cef1884f5025e64401a1443d3e129ed5esewardj
100345fa5b0cef1884f5025e64401a1443d3e129ed5esewardjbool PPCDarwinAsmPrinter::doFinalization(Module &M) {
100445fa5b0cef1884f5025e64401a1443d3e129ed5esewardj  bool isPPC64 = TM.getDataLayout()->getPointerSizeInBits() == 64;
100545fa5b0cef1884f5025e64401a1443d3e129ed5esewardj
100645fa5b0cef1884f5025e64401a1443d3e129ed5esewardj  // Darwin/PPC always uses mach-o.
100745fa5b0cef1884f5025e64401a1443d3e129ed5esewardj  const TargetLoweringObjectFileMachO &TLOFMacho =
100845fa5b0cef1884f5025e64401a1443d3e129ed5esewardj    static_cast<const TargetLoweringObjectFileMachO &>(getObjFileLowering());
100945fa5b0cef1884f5025e64401a1443d3e129ed5esewardj  MachineModuleInfoMachO &MMIMacho =
101045fa5b0cef1884f5025e64401a1443d3e129ed5esewardj    MMI->getObjFileInfo<MachineModuleInfoMachO>();
101145fa5b0cef1884f5025e64401a1443d3e129ed5esewardj
101245fa5b0cef1884f5025e64401a1443d3e129ed5esewardj  MachineModuleInfoMachO::SymbolListTy Stubs = MMIMacho.GetFnStubList();
101387a287b47f496063f5869dc5039a81baeb6a29aesewardj  if (!Stubs.empty())
101445fa5b0cef1884f5025e64401a1443d3e129ed5esewardj    EmitFunctionStubs(Stubs);
101545fa5b0cef1884f5025e64401a1443d3e129ed5esewardj
101645fa5b0cef1884f5025e64401a1443d3e129ed5esewardj  if (MAI->doesSupportExceptionHandling() && MMI) {
101745fa5b0cef1884f5025e64401a1443d3e129ed5esewardj    // Add the (possibly multiple) personalities to the set of global values.
101845fa5b0cef1884f5025e64401a1443d3e129ed5esewardj    // Only referenced functions get into the Personalities list.
101945fa5b0cef1884f5025e64401a1443d3e129ed5esewardj    const std::vector<const Function*> &Personalities = MMI->getPersonalities();
102045fa5b0cef1884f5025e64401a1443d3e129ed5esewardj    for (std::vector<const Function*>::const_iterator I = Personalities.begin(),
102145fa5b0cef1884f5025e64401a1443d3e129ed5esewardj         E = Personalities.end(); I != E; ++I) {
102245fa5b0cef1884f5025e64401a1443d3e129ed5esewardj      if (*I) {
102345fa5b0cef1884f5025e64401a1443d3e129ed5esewardj        MCSymbol *NLPSym = GetSymbolWithGlobalValueBase(*I, "$non_lazy_ptr");
102445fa5b0cef1884f5025e64401a1443d3e129ed5esewardj        MachineModuleInfoImpl::StubValueTy &StubSym =
102587a287b47f496063f5869dc5039a81baeb6a29aesewardj          MMIMacho.getGVStubEntry(NLPSym);
102645fa5b0cef1884f5025e64401a1443d3e129ed5esewardj        StubSym = MachineModuleInfoImpl::StubValueTy(Mang->getSymbol(*I), true);
102745fa5b0cef1884f5025e64401a1443d3e129ed5esewardj      }
102845fa5b0cef1884f5025e64401a1443d3e129ed5esewardj    }
102945fa5b0cef1884f5025e64401a1443d3e129ed5esewardj  }
103045fa5b0cef1884f5025e64401a1443d3e129ed5esewardj
103145fa5b0cef1884f5025e64401a1443d3e129ed5esewardj  // Output stubs for dynamically-linked functions.
103245fa5b0cef1884f5025e64401a1443d3e129ed5esewardj  Stubs = MMIMacho.GetGVStubList();
103345fa5b0cef1884f5025e64401a1443d3e129ed5esewardj
103445fa5b0cef1884f5025e64401a1443d3e129ed5esewardj  // Output macho stubs for external and common global variables.
103545fa5b0cef1884f5025e64401a1443d3e129ed5esewardj  if (!Stubs.empty()) {
103645fa5b0cef1884f5025e64401a1443d3e129ed5esewardj    // Switch with ".non_lazy_symbol_pointer" directive.
103745fa5b0cef1884f5025e64401a1443d3e129ed5esewardj    OutStreamer.SwitchSection(TLOFMacho.getNonLazySymbolPointerSection());
103845fa5b0cef1884f5025e64401a1443d3e129ed5esewardj    EmitAlignment(isPPC64 ? 3 : 2);
103945fa5b0cef1884f5025e64401a1443d3e129ed5esewardj
104045fa5b0cef1884f5025e64401a1443d3e129ed5esewardj    for (unsigned i = 0, e = Stubs.size(); i != e; ++i) {
104145fa5b0cef1884f5025e64401a1443d3e129ed5esewardj      // L_foo$stub:
104245fa5b0cef1884f5025e64401a1443d3e129ed5esewardj      OutStreamer.EmitLabel(Stubs[i].first);
104345fa5b0cef1884f5025e64401a1443d3e129ed5esewardj      //   .indirect_symbol _foo
104445fa5b0cef1884f5025e64401a1443d3e129ed5esewardj      MachineModuleInfoImpl::StubValueTy &MCSym = Stubs[i].second;
104545fa5b0cef1884f5025e64401a1443d3e129ed5esewardj      OutStreamer.EmitSymbolAttribute(MCSym.getPointer(), MCSA_IndirectSymbol);
104645fa5b0cef1884f5025e64401a1443d3e129ed5esewardj
104745fa5b0cef1884f5025e64401a1443d3e129ed5esewardj      if (MCSym.getInt())
104845fa5b0cef1884f5025e64401a1443d3e129ed5esewardj        // External to current translation unit.
104945fa5b0cef1884f5025e64401a1443d3e129ed5esewardj        OutStreamer.EmitIntValue(0, isPPC64 ? 8 : 4/*size*/);
105045fa5b0cef1884f5025e64401a1443d3e129ed5esewardj      else
105187a287b47f496063f5869dc5039a81baeb6a29aesewardj        // Internal to current translation unit.
105245fa5b0cef1884f5025e64401a1443d3e129ed5esewardj        //
105345fa5b0cef1884f5025e64401a1443d3e129ed5esewardj        // When we place the LSDA into the TEXT section, the type info pointers
105445fa5b0cef1884f5025e64401a1443d3e129ed5esewardj        // need to be indirect and pc-rel. We accomplish this by using NLPs.
105545fa5b0cef1884f5025e64401a1443d3e129ed5esewardj        // However, sometimes the types are local to the file. So we need to
105645fa5b0cef1884f5025e64401a1443d3e129ed5esewardj        // fill in the value for the NLP in those cases.
105745fa5b0cef1884f5025e64401a1443d3e129ed5esewardj        OutStreamer.EmitValue(MCSymbolRefExpr::Create(MCSym.getPointer(),
105845fa5b0cef1884f5025e64401a1443d3e129ed5esewardj                                                      OutContext),
105945fa5b0cef1884f5025e64401a1443d3e129ed5esewardj                              isPPC64 ? 8 : 4/*size*/);
106045fa5b0cef1884f5025e64401a1443d3e129ed5esewardj    }
106145fa5b0cef1884f5025e64401a1443d3e129ed5esewardj
106245fa5b0cef1884f5025e64401a1443d3e129ed5esewardj    Stubs.clear();
106345fa5b0cef1884f5025e64401a1443d3e129ed5esewardj    OutStreamer.AddBlankLine();
106487a287b47f496063f5869dc5039a81baeb6a29aesewardj  }
106545fa5b0cef1884f5025e64401a1443d3e129ed5esewardj
106645fa5b0cef1884f5025e64401a1443d3e129ed5esewardj  Stubs = MMIMacho.GetHiddenGVStubList();
106745fa5b0cef1884f5025e64401a1443d3e129ed5esewardj  if (!Stubs.empty()) {
106845fa5b0cef1884f5025e64401a1443d3e129ed5esewardj    OutStreamer.SwitchSection(getObjFileLowering().getDataSection());
106945fa5b0cef1884f5025e64401a1443d3e129ed5esewardj    EmitAlignment(isPPC64 ? 3 : 2);
107045fa5b0cef1884f5025e64401a1443d3e129ed5esewardj
107145fa5b0cef1884f5025e64401a1443d3e129ed5esewardj    for (unsigned i = 0, e = Stubs.size(); i != e; ++i) {
10725ce4b150ce5d32c9af07a24717081ea34568388asewardj      // L_foo$stub:
10735ce4b150ce5d32c9af07a24717081ea34568388asewardj      OutStreamer.EmitLabel(Stubs[i].first);
10745ce4b150ce5d32c9af07a24717081ea34568388asewardj      //   .long _foo
10755ce4b150ce5d32c9af07a24717081ea34568388asewardj      OutStreamer.EmitValue(MCSymbolRefExpr::
10765ce4b150ce5d32c9af07a24717081ea34568388asewardj                            Create(Stubs[i].second.getPointer(),
10775ce4b150ce5d32c9af07a24717081ea34568388asewardj                                   OutContext),
10785ce4b150ce5d32c9af07a24717081ea34568388asewardj                            isPPC64 ? 8 : 4/*size*/);
10795ce4b150ce5d32c9af07a24717081ea34568388asewardj    }
10805ce4b150ce5d32c9af07a24717081ea34568388asewardj
10815ce4b150ce5d32c9af07a24717081ea34568388asewardj    Stubs.clear();
10825ce4b150ce5d32c9af07a24717081ea34568388asewardj    OutStreamer.AddBlankLine();
10835ce4b150ce5d32c9af07a24717081ea34568388asewardj  }
10845ce4b150ce5d32c9af07a24717081ea34568388asewardj
10855ce4b150ce5d32c9af07a24717081ea34568388asewardj  // Funny Darwin hack: This flag tells the linker that no global symbols
10865ce4b150ce5d32c9af07a24717081ea34568388asewardj  // contain code that falls through to other global symbols (e.g. the obvious
10875ce4b150ce5d32c9af07a24717081ea34568388asewardj  // implementation of multiple entry points).  If this doesn't occur, the
10885ce4b150ce5d32c9af07a24717081ea34568388asewardj  // linker can safely perform dead code stripping.  Since LLVM never generates
10895ce4b150ce5d32c9af07a24717081ea34568388asewardj  // code that does this, it is always safe to set.
10905ce4b150ce5d32c9af07a24717081ea34568388asewardj  OutStreamer.EmitAssemblerFlag(MCAF_SubsectionsViaSymbols);
10915ce4b150ce5d32c9af07a24717081ea34568388asewardj
109287a287b47f496063f5869dc5039a81baeb6a29aesewardj  return AsmPrinter::doFinalization(M);
10935ce4b150ce5d32c9af07a24717081ea34568388asewardj}
10945ce4b150ce5d32c9af07a24717081ea34568388asewardj
10955ce4b150ce5d32c9af07a24717081ea34568388asewardj/// createPPCAsmPrinterPass - Returns a pass that prints the PPC assembly code
10965ce4b150ce5d32c9af07a24717081ea34568388asewardj/// for a MachineFunction to the given output stream, in a format that the
10975ce4b150ce5d32c9af07a24717081ea34568388asewardj/// Darwin assembler can deal with.
10985ce4b150ce5d32c9af07a24717081ea34568388asewardj///
10995ce4b150ce5d32c9af07a24717081ea34568388asewardjstatic AsmPrinter *createPPCAsmPrinterPass(TargetMachine &tm,
11005ce4b150ce5d32c9af07a24717081ea34568388asewardj                                           MCStreamer &Streamer) {
11015ce4b150ce5d32c9af07a24717081ea34568388asewardj  const PPCSubtarget *Subtarget = &tm.getSubtarget<PPCSubtarget>();
11025ce4b150ce5d32c9af07a24717081ea34568388asewardj
11035ce4b150ce5d32c9af07a24717081ea34568388asewardj  if (Subtarget->isDarwin())
11045ce4b150ce5d32c9af07a24717081ea34568388asewardj    return new PPCDarwinAsmPrinter(tm, Streamer);
11055ce4b150ce5d32c9af07a24717081ea34568388asewardj  return new PPCLinuxAsmPrinter(tm, Streamer);
110687a287b47f496063f5869dc5039a81baeb6a29aesewardj}
11075ce4b150ce5d32c9af07a24717081ea34568388asewardj
11085ce4b150ce5d32c9af07a24717081ea34568388asewardj// Force static initialization.
11095ce4b150ce5d32c9af07a24717081ea34568388asewardjextern "C" void LLVMInitializePowerPCAsmPrinter() {
11105ce4b150ce5d32c9af07a24717081ea34568388asewardj  TargetRegistry::RegisterAsmPrinter(ThePPC32Target, createPPCAsmPrinterPass);
11115ce4b150ce5d32c9af07a24717081ea34568388asewardj  TargetRegistry::RegisterAsmPrinter(ThePPC64Target, createPPCAsmPrinterPass);
11125ce4b150ce5d32c9af07a24717081ea34568388asewardj}
11135ce4b150ce5d32c9af07a24717081ea34568388asewardj