131d157ae1ac2cd9c787dc3c1d28e64c682803844Jia Liu//===-- PPCAsmPrinter.cpp - Print machine instrs to PowerPC assembly ------===//
2b5f662fa0314f7e7e690aae8ebff7136cc3a5ab0Misha Brukman//
35dfe3a9c3bd9091f9adecc909665d52bdd4edd8cMisha Brukman//                     The LLVM Compiler Infrastructure
45dfe3a9c3bd9091f9adecc909665d52bdd4edd8cMisha Brukman//
54ee451de366474b9c228b4e5fa573795a715216dChris Lattner// This file is distributed under the University of Illinois Open Source
64ee451de366474b9c228b4e5fa573795a715216dChris Lattner// License. See LICENSE.TXT for details.
7b5f662fa0314f7e7e690aae8ebff7136cc3a5ab0Misha Brukman//
85dfe3a9c3bd9091f9adecc909665d52bdd4edd8cMisha Brukman//===----------------------------------------------------------------------===//
95dfe3a9c3bd9091f9adecc909665d52bdd4edd8cMisha Brukman//
1005fcd0c891c1cab4b90368094081a96ebf655e96Misha Brukman// This file contains a printer that converts from our internal representation
1105fcd0c891c1cab4b90368094081a96ebf655e96Misha Brukman// of machine-dependent LLVM code to PowerPC assembly language. This printer is
1283660c5aed4902dd218ba0f730dc7801b99b30cbChris Lattner// the output mechanism used by `llc'.
135dfe3a9c3bd9091f9adecc909665d52bdd4edd8cMisha Brukman//
1405fcd0c891c1cab4b90368094081a96ebf655e96Misha Brukman// Documentation at http://developer.apple.com/documentation/DeveloperTools/
1505fcd0c891c1cab4b90368094081a96ebf655e96Misha Brukman// Reference/Assembler/ASMIntroduction/chapter_1_section_1.html
16218bec7bd3a2deb94768e298025f07d7682c4377Misha Brukman//
175dfe3a9c3bd9091f9adecc909665d52bdd4edd8cMisha Brukman//===----------------------------------------------------------------------===//
185dfe3a9c3bd9091f9adecc909665d52bdd4edd8cMisha Brukman
1905794498d95903d22e4402d005d1f03fab3bc78aMisha Brukman#define DEBUG_TYPE "asmprinter"
202668959b8879097db368aec7d76c455260abc75bChris Lattner#include "PPC.h"
2179aa3417eb6f58d668aadfedf075240a41d35a26Craig Topper#include "InstPrinter/PPCInstPrinter.h"
2294b9550a32d189704a8eae55505edf62662c0534Evan Cheng#include "MCTargetDesc/PPCPredicates.h"
23edaa58ee66699b99841ee5dfdd485aedbae3bf90Ulrich Weigand#include "MCTargetDesc/PPCMCExpr.h"
24d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "PPCSubtarget.h"
25d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "PPCTargetMachine.h"
26d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/ADT/MapVector.h"
27d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/ADT/SmallString.h"
28d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/ADT/StringExtras.h"
295dfe3a9c3bd9091f9adecc909665d52bdd4edd8cMisha Brukman#include "llvm/Assembly/Writer.h"
30a3840795a58b3fe3c7d986bfa20951e8d5e1d6e2Chris Lattner#include "llvm/CodeGen/AsmPrinter.h"
3105794498d95903d22e4402d005d1f03fab3bc78aMisha Brukman#include "llvm/CodeGen/MachineFunctionPass.h"
325dfe3a9c3bd9091f9adecc909665d52bdd4edd8cMisha Brukman#include "llvm/CodeGen/MachineInstr.h"
33381802f8e06668d0ec5fc760804c83e511dafc7cBill Wendling#include "llvm/CodeGen/MachineInstrBuilder.h"
34d3ec0b5446441f39988db4107cd37f6e7349f399Chris Lattner#include "llvm/CodeGen/MachineModuleInfoImpls.h"
35362dd0bef5437f85586c046bc53287b6fbe9c099Anton Korobeynikov#include "llvm/CodeGen/TargetLoweringObjectFileImpl.h"
36d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/DebugInfo.h"
370b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/Constants.h"
380b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/DerivedTypes.h"
390b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/Module.h"
40325d3dcfe4d5efc91db0f59b20a72a11dea024edChris Lattner#include "llvm/MC/MCAsmInfo.h"
410b4bad54f64944880eca9331fbb34545adbe7833Chris Lattner#include "llvm/MC/MCContext.h"
4208d726c912f74d6ea61bea97e7719fc635927dbfBill Wendling#include "llvm/MC/MCExpr.h"
43293ef9ae0fd533429dc54d94c895c39a564466f7Chris Lattner#include "llvm/MC/MCInst.h"
44391271f3bbcec02e0da26d7c246bfabff5cb4ddfBenjamin Kramer#include "llvm/MC/MCInstBuilder.h"
45d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/MC/MCSectionELF.h"
46f9bdeddb96043559c61f176f8077e3b91a0c544fChris Lattner#include "llvm/MC/MCSectionMachO.h"
476c2f9e14fdf14d8c1c687c6bd9918183fa7f8a7fChris Lattner#include "llvm/MC/MCStreamer.h"
48325d3dcfe4d5efc91db0f59b20a72a11dea024edChris Lattner#include "llvm/MC/MCSymbol.h"
49293ef9ae0fd533429dc54d94c895c39a564466f7Chris Lattner#include "llvm/Support/CommandLine.h"
5040e0bad33193112eab0cc40a556ed347e6568cfeDevang Patel#include "llvm/Support/Debug.h"
51d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/Support/ELF.h"
52dac237e18209b697a8ba122d0ddd9cad4dfba1f8Torok Edwin#include "llvm/Support/ErrorHandling.h"
53d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/Support/MathExtras.h"
543e74d6fdd248e20a280f1dff3da9a6c689c2c4c3Evan Cheng#include "llvm/Support/TargetRegistry.h"
55b23569aff0a6d2b231cb93cc4acd0ac060ba560fChris Lattner#include "llvm/Support/raw_ostream.h"
56d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/Target/Mangler.h"
57d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/Target/TargetInstrInfo.h"
58d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/Target/TargetOptions.h"
59d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/Target/TargetRegisterInfo.h"
60a3840795a58b3fe3c7d986bfa20951e8d5e1d6e2Chris Lattnerusing namespace llvm;
615dfe3a9c3bd9091f9adecc909665d52bdd4edd8cMisha Brukman
6295b2c7da5e83670881270c1cd231a240be0556d9Chris Lattnernamespace {
636726b6d75a8b679068a58cb954ba97cf9d1690baNick Lewycky  class PPCAsmPrinter : public AsmPrinter {
6457f0db833dc30404f1f5d28b23df326e520698ecBill Wendling  protected:
6595d8afc5f2898b59240b0c0cd78d6f54140a91b8Ulrich Weigand    MapVector<MCSymbol*, MCSymbol*> TOC;
66dadceedbdb9ef642c49283b632dcfefe48ee4cf4Chris Lattner    const PPCSubtarget &Subtarget;
67374c608fcac7fd550ce0cb1826355849a5e015beChris Lattner    uint64_t TOCLabelID;
6857f0db833dc30404f1f5d28b23df326e520698ecBill Wendling  public:
69b23569aff0a6d2b231cb93cc4acd0ac060ba560fChris Lattner    explicit PPCAsmPrinter(TargetMachine &TM, MCStreamer &Streamer)
70b23569aff0a6d2b231cb93cc4acd0ac060ba560fChris Lattner      : AsmPrinter(TM, Streamer),
71374c608fcac7fd550ce0cb1826355849a5e015beChris Lattner        Subtarget(TM.getSubtarget<PPCSubtarget>()), TOCLabelID(0) {}
72b5f662fa0314f7e7e690aae8ebff7136cc3a5ab0Misha Brukman
735dfe3a9c3bd9091f9adecc909665d52bdd4edd8cMisha Brukman    virtual const char *getPassName() const {
74ed42853be1ef530890043da7c8966dc6678cf9bfNate Begeman      return "PowerPC Assembly Printer";
755dfe3a9c3bd9091f9adecc909665d52bdd4edd8cMisha Brukman    }
765dfe3a9c3bd9091f9adecc909665d52bdd4edd8cMisha Brukman
7734a9d4b3b9b7858b729a1af67afa721c048fe5e7Bill Schmidt    MCSymbol *lookUpOrCreateTOCEntry(MCSymbol *Sym);
78e59bf59ba55c6bdba82a7126e91f5bb53118e84cNate Begeman
79d49fe1b6bc4615684c2ec71140a21e9c4cd69ce3Chris Lattner    virtual void EmitInstruction(const MachineInstr *MI);
807bb424fafcfc3452c209556cd764e60b45ae6a5dChris Lattner
81cb22fa6536bd17e54a89dc82cafc9fdf48321c36Chris Lattner    void printOperand(const MachineInstr *MI, unsigned OpNo, raw_ostream &O);
8234da127be57c4d153f3ceae7a04b31aec373641fAnton Korobeynikov
83588732748ba804e1e258df8856e20b3b73348ac3Chris Lattner    bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,
84c75c028a15a13786eee585aa634b4faf694dd00aChris Lattner                         unsigned AsmVariant, const char *ExtraCode,
85c75c028a15a13786eee585aa634b4faf694dd00aChris Lattner                         raw_ostream &O);
862c003e26e583e6acafca142ef93efa95a84866a1Chris Lattner    bool PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNo,
87c75c028a15a13786eee585aa634b4faf694dd00aChris Lattner                               unsigned AsmVariant, const char *ExtraCode,
88c75c028a15a13786eee585aa634b4faf694dd00aChris Lattner                               raw_ostream &O);
89ed42853be1ef530890043da7c8966dc6678cf9bfNate Begeman  };
90b5f662fa0314f7e7e690aae8ebff7136cc3a5ab0Misha Brukman
9134da127be57c4d153f3ceae7a04b31aec373641fAnton Korobeynikov  /// PPCLinuxAsmPrinter - PowerPC assembly printer, customized for Linux
926726b6d75a8b679068a58cb954ba97cf9d1690baNick Lewycky  class PPCLinuxAsmPrinter : public PPCAsmPrinter {
9357f0db833dc30404f1f5d28b23df326e520698ecBill Wendling  public:
94b23569aff0a6d2b231cb93cc4acd0ac060ba560fChris Lattner    explicit PPCLinuxAsmPrinter(TargetMachine &TM, MCStreamer &Streamer)
95b23569aff0a6d2b231cb93cc4acd0ac060ba560fChris Lattner      : PPCAsmPrinter(TM, Streamer) {}
96bf1118285c0f784b120a69b4a4207e15ef065eadJim Laskey
97bf1118285c0f784b120a69b4a4207e15ef065eadJim Laskey    virtual const char *getPassName() const {
98bf1118285c0f784b120a69b4a4207e15ef065eadJim Laskey      return "Linux PPC Assembly Printer";
99bf1118285c0f784b120a69b4a4207e15ef065eadJim Laskey    }
100bf1118285c0f784b120a69b4a4207e15ef065eadJim Laskey
1016b16eff207f99bbde3c0f7340452a5287218772cTilmann Scheller    bool doFinalization(Module &M);
10234da127be57c4d153f3ceae7a04b31aec373641fAnton Korobeynikov
1032cf7251d39f28888af06b6f941eabd1d10995382Chris Lattner    virtual void EmitFunctionEntryLabel();
104c6c2ced38411215e5bf46ded787c23810160dfa7Roman Divacky
105c6c2ced38411215e5bf46ded787c23810160dfa7Roman Divacky    void EmitFunctionBodyEnd();
106bf1118285c0f784b120a69b4a4207e15ef065eadJim Laskey  };
107bf1118285c0f784b120a69b4a4207e15ef065eadJim Laskey
10834da127be57c4d153f3ceae7a04b31aec373641fAnton Korobeynikov  /// PPCDarwinAsmPrinter - PowerPC assembly printer, customized for Darwin/Mac
10934da127be57c4d153f3ceae7a04b31aec373641fAnton Korobeynikov  /// OS X
1106726b6d75a8b679068a58cb954ba97cf9d1690baNick Lewycky  class PPCDarwinAsmPrinter : public PPCAsmPrinter {
11157f0db833dc30404f1f5d28b23df326e520698ecBill Wendling  public:
112b23569aff0a6d2b231cb93cc4acd0ac060ba560fChris Lattner    explicit PPCDarwinAsmPrinter(TargetMachine &TM, MCStreamer &Streamer)
113b23569aff0a6d2b231cb93cc4acd0ac060ba560fChris Lattner      : PPCAsmPrinter(TM, Streamer) {}
114ed42853be1ef530890043da7c8966dc6678cf9bfNate Begeman
115ed42853be1ef530890043da7c8966dc6678cf9bfNate Begeman    virtual const char *getPassName() const {
116ed42853be1ef530890043da7c8966dc6678cf9bfNate Begeman      return "Darwin PPC Assembly Printer";
117ed42853be1ef530890043da7c8966dc6678cf9bfNate Begeman    }
11834da127be57c4d153f3ceae7a04b31aec373641fAnton Korobeynikov
1195dfe3a9c3bd9091f9adecc909665d52bdd4edd8cMisha Brukman    bool doFinalization(Module &M);
120812209a58c5520c604bc9279aa069e5ae066e860Bob Wilson    void EmitStartOfAsmFile(Module &M);
12134da127be57c4d153f3ceae7a04b31aec373641fAnton Korobeynikov
12273a1aa0966af7605b5a15585b1b88ffc7dbd3e3eChris Lattner    void EmitFunctionStubs(const MachineModuleInfoMachO::SymbolListTy &Stubs);
1235dfe3a9c3bd9091f9adecc909665d52bdd4edd8cMisha Brukman  };
1245dfe3a9c3bd9091f9adecc909665d52bdd4edd8cMisha Brukman} // end of anonymous namespace
1255dfe3a9c3bd9091f9adecc909665d52bdd4edd8cMisha Brukman
126cb22fa6536bd17e54a89dc82cafc9fdf48321c36Chris Lattner/// stripRegisterPrefix - This method strips the character prefix from a
127cb22fa6536bd17e54a89dc82cafc9fdf48321c36Chris Lattner/// register name so that only the number is left.  Used by for linux asm.
128cb22fa6536bd17e54a89dc82cafc9fdf48321c36Chris Lattnerstatic const char *stripRegisterPrefix(const char *RegName) {
129cb22fa6536bd17e54a89dc82cafc9fdf48321c36Chris Lattner  switch (RegName[0]) {
130cb22fa6536bd17e54a89dc82cafc9fdf48321c36Chris Lattner    case 'r':
131cb22fa6536bd17e54a89dc82cafc9fdf48321c36Chris Lattner    case 'f':
132cb22fa6536bd17e54a89dc82cafc9fdf48321c36Chris Lattner    case 'v': return RegName + 1;
133cb22fa6536bd17e54a89dc82cafc9fdf48321c36Chris Lattner    case 'c': if (RegName[1] == 'r') return RegName + 2;
134cb22fa6536bd17e54a89dc82cafc9fdf48321c36Chris Lattner  }
135cb22fa6536bd17e54a89dc82cafc9fdf48321c36Chris Lattner
136cb22fa6536bd17e54a89dc82cafc9fdf48321c36Chris Lattner  return RegName;
137cb22fa6536bd17e54a89dc82cafc9fdf48321c36Chris Lattner}
138ed42853be1ef530890043da7c8966dc6678cf9bfNate Begeman
139cb22fa6536bd17e54a89dc82cafc9fdf48321c36Chris Lattnervoid PPCAsmPrinter::printOperand(const MachineInstr *MI, unsigned OpNo,
140cb22fa6536bd17e54a89dc82cafc9fdf48321c36Chris Lattner                                 raw_ostream &O) {
141cb22fa6536bd17e54a89dc82cafc9fdf48321c36Chris Lattner  const MachineOperand &MO = MI->getOperand(OpNo);
142cb22fa6536bd17e54a89dc82cafc9fdf48321c36Chris Lattner
1435dfe3a9c3bd9091f9adecc909665d52bdd4edd8cMisha Brukman  switch (MO.getType()) {
144cb22fa6536bd17e54a89dc82cafc9fdf48321c36Chris Lattner  case MachineOperand::MO_Register: {
145cb22fa6536bd17e54a89dc82cafc9fdf48321c36Chris Lattner    const char *RegName = PPCInstPrinter::getRegisterName(MO.getReg());
146cb22fa6536bd17e54a89dc82cafc9fdf48321c36Chris Lattner    // Linux assembler (Others?) does not take register mnemonics.
147cb22fa6536bd17e54a89dc82cafc9fdf48321c36Chris Lattner    // FIXME - What about special registers used in mfspr/mtspr?
148cb22fa6536bd17e54a89dc82cafc9fdf48321c36Chris Lattner    if (!Subtarget.isDarwin()) RegName = stripRegisterPrefix(RegName);
149cb22fa6536bd17e54a89dc82cafc9fdf48321c36Chris Lattner    O << RegName;
150cb22fa6536bd17e54a89dc82cafc9fdf48321c36Chris Lattner    return;
151cb22fa6536bd17e54a89dc82cafc9fdf48321c36Chris Lattner  }
15263b3d7113d93fda622c4954c6b1d046ce029044eChris Lattner  case MachineOperand::MO_Immediate:
153cb22fa6536bd17e54a89dc82cafc9fdf48321c36Chris Lattner    O << MO.getImm();
154cb22fa6536bd17e54a89dc82cafc9fdf48321c36Chris Lattner    return;
155af313fb188a8d03ad863de81fa9f87b0a76579fcMisha Brukman
15637efe6764568a3829fee26aba532283131d1a104Nate Begeman  case MachineOperand::MO_MachineBasicBlock:
1571b2eb0e8a6aaf034675b17be6d853cb1c666200fChris Lattner    O << *MO.getMBB()->getSymbol();
15837efe6764568a3829fee26aba532283131d1a104Nate Begeman    return;
15937efe6764568a3829fee26aba532283131d1a104Nate Begeman  case MachineOperand::MO_JumpTableIndex:
16033adcfb4d217f5f23d9bde8ba02b8e48f9605fc5Chris Lattner    O << MAI->getPrivateGlobalPrefix() << "JTI" << getFunctionNumber()
1618aa797aa51cd4ea1ec6f46f4891a6897944b75b2Chris Lattner      << '_' << MO.getIndex();
16237efe6764568a3829fee26aba532283131d1a104Nate Begeman    // FIXME: PIC relocation model
1635dfe3a9c3bd9091f9adecc909665d52bdd4edd8cMisha Brukman    return;
16405fcd0c891c1cab4b90368094081a96ebf655e96Misha Brukman  case MachineOperand::MO_ConstantPoolIndex:
16533adcfb4d217f5f23d9bde8ba02b8e48f9605fc5Chris Lattner    O << MAI->getPrivateGlobalPrefix() << "CPI" << getFunctionNumber()
1668aa797aa51cd4ea1ec6f46f4891a6897944b75b2Chris Lattner      << '_' << MO.getIndex();
1675dfe3a9c3bd9091f9adecc909665d52bdd4edd8cMisha Brukman    return;
1683d90dbee695e723f422dafca3fc75f193268ab9eBob Wilson  case MachineOperand::MO_BlockAddress:
16910b318bcb39218d2ed525e4862c854bc8d1baf63Chris Lattner    O << *GetBlockAddressSymbol(MO.getBlockAddress());
1703d90dbee695e723f422dafca3fc75f193268ab9eBob Wilson    return;
1718f831cbf0d9d1eb7de08d50b5d55ef84fdacba2eChris Lattner  case MachineOperand::MO_ExternalSymbol: {
172a637c32e381316da47285961111e1793c542cc15Chris Lattner    // Computing the address of an external symbol, not calling it.
17375abc68d324158b72c58b5caf2224b1e35ac0c92Chris Lattner    if (TM.getRelocationModel() == Reloc::Static) {
174d3ec0b5446441f39988db4107cd37f6e7349f399Chris Lattner      O << *GetExternalSymbolSymbol(MO.getSymbolName());
17575abc68d324158b72c58b5caf2224b1e35ac0c92Chris Lattner      return;
176a637c32e381316da47285961111e1793c542cc15Chris Lattner    }
177d3ec0b5446441f39988db4107cd37f6e7349f399Chris Lattner
178d269a6e460a71a6c5c361a26c56c91fdb9486f45Chris Lattner    MCSymbol *NLPSym =
17975abc68d324158b72c58b5caf2224b1e35ac0c92Chris Lattner      OutContext.GetOrCreateSymbol(StringRef(MAI->getGlobalPrefix())+
18075abc68d324158b72c58b5caf2224b1e35ac0c92Chris Lattner                                   MO.getSymbolName()+"$non_lazy_ptr");
181cebae36f57456fe6b0e13726acd1e0250654f02dBill Wendling    MachineModuleInfoImpl::StubValueTy &StubSym =
182d3ec0b5446441f39988db4107cd37f6e7349f399Chris Lattner      MMI->getObjFileInfo<MachineModuleInfoMachO>().getGVStubEntry(NLPSym);
183cebae36f57456fe6b0e13726acd1e0250654f02dBill Wendling    if (StubSym.getPointer() == 0)
184cebae36f57456fe6b0e13726acd1e0250654f02dBill Wendling      StubSym = MachineModuleInfoImpl::
185cebae36f57456fe6b0e13726acd1e0250654f02dBill Wendling        StubValueTy(GetExternalSymbolSymbol(MO.getSymbolName()), true);
186d3ec0b5446441f39988db4107cd37f6e7349f399Chris Lattner
18710b318bcb39218d2ed525e4862c854bc8d1baf63Chris Lattner    O << *NLPSym;
18805fcd0c891c1cab4b90368094081a96ebf655e96Misha Brukman    return;
1898f831cbf0d9d1eb7de08d50b5d55ef84fdacba2eChris Lattner  }
190b73a711ed7c1da332ae8d22b0defcbdf0411d1a4Nate Begeman  case MachineOperand::MO_GlobalAddress: {
191a637c32e381316da47285961111e1793c542cc15Chris Lattner    // Computing the address of a global symbol, not calling it.
19246510a73e977273ec67747eb34cbdb43f815e451Dan Gohman    const GlobalValue *GV = MO.getGlobal();
193a40128c3504b1b650fc57882b7b5d8efd3f7de28Chris Lattner    MCSymbol *SymToPrint;
194b73a711ed7c1da332ae8d22b0defcbdf0411d1a4Nate Begeman
195fcf4a42cdf5d34b7761f34e3cb978b4cef93e2cbNate Begeman    // External or weakly linked global variables need non-lazily-resolved stubs
1968f831cbf0d9d1eb7de08d50b5d55ef84fdacba2eChris Lattner    if (TM.getRelocationModel() != Reloc::Static &&
1978f831cbf0d9d1eb7de08d50b5d55ef84fdacba2eChris Lattner        (GV->isDeclaration() || GV->isWeakForLinker())) {
1988f831cbf0d9d1eb7de08d50b5d55ef84fdacba2eChris Lattner      if (!GV->hasHiddenVisibility()) {
1997a2ba94d03b43f41b54872dacd7b2250dde4c7bdChris Lattner        SymToPrint = GetSymbolWithGlobalValueBase(GV, "$non_lazy_ptr");
200cebae36f57456fe6b0e13726acd1e0250654f02dBill Wendling        MachineModuleInfoImpl::StubValueTy &StubSym =
201cebae36f57456fe6b0e13726acd1e0250654f02dBill Wendling          MMI->getObjFileInfo<MachineModuleInfoMachO>()
202cebae36f57456fe6b0e13726acd1e0250654f02dBill Wendling            .getGVStubEntry(SymToPrint);
203cebae36f57456fe6b0e13726acd1e0250654f02dBill Wendling        if (StubSym.getPointer() == 0)
204cebae36f57456fe6b0e13726acd1e0250654f02dBill Wendling          StubSym = MachineModuleInfoImpl::
205d62f1b4168d4327c119642d28c26c836ae6717abChris Lattner            StubValueTy(Mang->getSymbol(GV), !GV->hasInternalLinkage());
2068f831cbf0d9d1eb7de08d50b5d55ef84fdacba2eChris Lattner      } else if (GV->isDeclaration() || GV->hasCommonLinkage() ||
2078f831cbf0d9d1eb7de08d50b5d55ef84fdacba2eChris Lattner                 GV->hasAvailableExternallyLinkage()) {
2087a2ba94d03b43f41b54872dacd7b2250dde4c7bdChris Lattner        SymToPrint = GetSymbolWithGlobalValueBase(GV, "$non_lazy_ptr");
209d3ec0b5446441f39988db4107cd37f6e7349f399Chris Lattner
210cebae36f57456fe6b0e13726acd1e0250654f02dBill Wendling        MachineModuleInfoImpl::StubValueTy &StubSym =
211d3ec0b5446441f39988db4107cd37f6e7349f399Chris Lattner          MMI->getObjFileInfo<MachineModuleInfoMachO>().
212d3ec0b5446441f39988db4107cd37f6e7349f399Chris Lattner                    getHiddenGVStubEntry(SymToPrint);
213cebae36f57456fe6b0e13726acd1e0250654f02dBill Wendling        if (StubSym.getPointer() == 0)
214cebae36f57456fe6b0e13726acd1e0250654f02dBill Wendling          StubSym = MachineModuleInfoImpl::
215d62f1b4168d4327c119642d28c26c836ae6717abChris Lattner            StubValueTy(Mang->getSymbol(GV), !GV->hasInternalLinkage());
2168f831cbf0d9d1eb7de08d50b5d55ef84fdacba2eChris Lattner      } else {
217d62f1b4168d4327c119642d28c26c836ae6717abChris Lattner        SymToPrint = Mang->getSymbol(GV);
218a637c32e381316da47285961111e1793c542cc15Chris Lattner      }
2198f831cbf0d9d1eb7de08d50b5d55ef84fdacba2eChris Lattner    } else {
220d62f1b4168d4327c119642d28c26c836ae6717abChris Lattner      SymToPrint = Mang->getSymbol(GV);
2215dfe3a9c3bd9091f9adecc909665d52bdd4edd8cMisha Brukman    }
222a40128c3504b1b650fc57882b7b5d8efd3f7de28Chris Lattner
22310b318bcb39218d2ed525e4862c854bc8d1baf63Chris Lattner    O << *SymToPrint;
22434da127be57c4d153f3ceae7a04b31aec373641fAnton Korobeynikov
2250c08d092049c025c9ccf7143e39f39dc4e30d6b4Chris Lattner    printOffset(MO.getOffset(), O);
2265dfe3a9c3bd9091f9adecc909665d52bdd4edd8cMisha Brukman    return;
227b73a711ed7c1da332ae8d22b0defcbdf0411d1a4Nate Begeman  }
228b5f662fa0314f7e7e690aae8ebff7136cc3a5ab0Misha Brukman
2295dfe3a9c3bd9091f9adecc909665d52bdd4edd8cMisha Brukman  default:
23005fcd0c891c1cab4b90368094081a96ebf655e96Misha Brukman    O << "<unknown operand type: " << MO.getType() << ">";
23122e12076e9bd62401d28b0c6bae380955a76abffMisha Brukman    return;
2325dfe3a9c3bd9091f9adecc909665d52bdd4edd8cMisha Brukman  }
2335dfe3a9c3bd9091f9adecc909665d52bdd4edd8cMisha Brukman}
2345dfe3a9c3bd9091f9adecc909665d52bdd4edd8cMisha Brukman
235e3f01570c172570fb2c0bacc6b8860ee6809362dChris Lattner/// PrintAsmOperand - Print out an operand for an inline asm expression.
236e3f01570c172570fb2c0bacc6b8860ee6809362dChris Lattner///
237e3f01570c172570fb2c0bacc6b8860ee6809362dChris Lattnerbool PPCAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,
23834da127be57c4d153f3ceae7a04b31aec373641fAnton Korobeynikov                                    unsigned AsmVariant,
239c75c028a15a13786eee585aa634b4faf694dd00aChris Lattner                                    const char *ExtraCode, raw_ostream &O) {
240e3f01570c172570fb2c0bacc6b8860ee6809362dChris Lattner  // Does this asm operand have a single letter operand modifier?
241e3f01570c172570fb2c0bacc6b8860ee6809362dChris Lattner  if (ExtraCode && ExtraCode[0]) {
242e3f01570c172570fb2c0bacc6b8860ee6809362dChris Lattner    if (ExtraCode[1] != 0) return true; // Unknown modifier.
24334da127be57c4d153f3ceae7a04b31aec373641fAnton Korobeynikov
244e3f01570c172570fb2c0bacc6b8860ee6809362dChris Lattner    switch (ExtraCode[0]) {
2450518fca843ff87d069ecb07fc00d306c1f587d58Jack Carter    default:
2460518fca843ff87d069ecb07fc00d306c1f587d58Jack Carter      // See if this is a generic print operand
2470518fca843ff87d069ecb07fc00d306c1f587d58Jack Carter      return AsmPrinter::PrintAsmOperand(MI, OpNo, AsmVariant, ExtraCode, O);
24878192b620450ce7897b68c48cd5d3f1a6defbb7bChris Lattner    case 'c': // Don't print "$" before a global var name or constant.
249cb22fa6536bd17e54a89dc82cafc9fdf48321c36Chris Lattner      break; // PPC never has a prefix.
25034da127be57c4d153f3ceae7a04b31aec373641fAnton Korobeynikov    case 'L': // Write second word of DImode reference.
251e3f01570c172570fb2c0bacc6b8860ee6809362dChris Lattner      // Verify that this operand has two consecutive registers.
252d735b8019b0f297d7c14b55adcd887af24d8e602Dan Gohman      if (!MI->getOperand(OpNo).isReg() ||
253e3f01570c172570fb2c0bacc6b8860ee6809362dChris Lattner          OpNo+1 == MI->getNumOperands() ||
254d735b8019b0f297d7c14b55adcd887af24d8e602Dan Gohman          !MI->getOperand(OpNo+1).isReg())
255e3f01570c172570fb2c0bacc6b8860ee6809362dChris Lattner        return true;
256e3f01570c172570fb2c0bacc6b8860ee6809362dChris Lattner      ++OpNo;   // Return the high-part.
257e3f01570c172570fb2c0bacc6b8860ee6809362dChris Lattner      break;
2586c2d2601614ba769c0371f01e22ebebd92643be5Chris Lattner    case 'I':
2596c2d2601614ba769c0371f01e22ebebd92643be5Chris Lattner      // Write 'i' if an integer constant, otherwise nothing.  Used to print
2606c2d2601614ba769c0371f01e22ebebd92643be5Chris Lattner      // addi vs add, etc.
261d735b8019b0f297d7c14b55adcd887af24d8e602Dan Gohman      if (MI->getOperand(OpNo).isImm())
2626c2d2601614ba769c0371f01e22ebebd92643be5Chris Lattner        O << "i";
2636c2d2601614ba769c0371f01e22ebebd92643be5Chris Lattner      return false;
264e3f01570c172570fb2c0bacc6b8860ee6809362dChris Lattner    }
265e3f01570c172570fb2c0bacc6b8860ee6809362dChris Lattner  }
26634da127be57c4d153f3ceae7a04b31aec373641fAnton Korobeynikov
26735c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner  printOperand(MI, OpNo, O);
268e3f01570c172570fb2c0bacc6b8860ee6809362dChris Lattner  return false;
269e3f01570c172570fb2c0bacc6b8860ee6809362dChris Lattner}
270e3f01570c172570fb2c0bacc6b8860ee6809362dChris Lattner
2715cfd4ddece1b73a719830ae84eb74d491f87b9d5Dale Johannesen// At the moment, all inline asm memory operands are a single register.
2725cfd4ddece1b73a719830ae84eb74d491f87b9d5Dale Johannesen// In any case, the output of this routine should always be just one
2735cfd4ddece1b73a719830ae84eb74d491f87b9d5Dale Johannesen// assembler operand.
2745cfd4ddece1b73a719830ae84eb74d491f87b9d5Dale Johannesen
2752c003e26e583e6acafca142ef93efa95a84866a1Chris Lattnerbool PPCAsmPrinter::PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNo,
27634da127be57c4d153f3ceae7a04b31aec373641fAnton Korobeynikov                                          unsigned AsmVariant,
277c75c028a15a13786eee585aa634b4faf694dd00aChris Lattner                                          const char *ExtraCode,
278c75c028a15a13786eee585aa634b4faf694dd00aChris Lattner                                          raw_ostream &O) {
279827b7a070d349737f1d6ff63115e0cbb0c031f9cHal Finkel  if (ExtraCode && ExtraCode[0]) {
280827b7a070d349737f1d6ff63115e0cbb0c031f9cHal Finkel    if (ExtraCode[1] != 0) return true; // Unknown modifier.
281827b7a070d349737f1d6ff63115e0cbb0c031f9cHal Finkel
282827b7a070d349737f1d6ff63115e0cbb0c031f9cHal Finkel    switch (ExtraCode[0]) {
283827b7a070d349737f1d6ff63115e0cbb0c031f9cHal Finkel    default: return true;  // Unknown modifier.
284827b7a070d349737f1d6ff63115e0cbb0c031f9cHal Finkel    case 'y': // A memory reference for an X-form instruction
285827b7a070d349737f1d6ff63115e0cbb0c031f9cHal Finkel      {
286827b7a070d349737f1d6ff63115e0cbb0c031f9cHal Finkel        const char *RegName = "r0";
287827b7a070d349737f1d6ff63115e0cbb0c031f9cHal Finkel        if (!Subtarget.isDarwin()) RegName = stripRegisterPrefix(RegName);
288827b7a070d349737f1d6ff63115e0cbb0c031f9cHal Finkel        O << RegName << ", ";
289827b7a070d349737f1d6ff63115e0cbb0c031f9cHal Finkel        printOperand(MI, OpNo, O);
290827b7a070d349737f1d6ff63115e0cbb0c031f9cHal Finkel        return false;
291827b7a070d349737f1d6ff63115e0cbb0c031f9cHal Finkel      }
292827b7a070d349737f1d6ff63115e0cbb0c031f9cHal Finkel    }
293827b7a070d349737f1d6ff63115e0cbb0c031f9cHal Finkel  }
294827b7a070d349737f1d6ff63115e0cbb0c031f9cHal Finkel
295cb22fa6536bd17e54a89dc82cafc9fdf48321c36Chris Lattner  assert(MI->getOperand(OpNo).isReg());
2964e68f8803d8e28d52cc2f16a4eef5c175878b0f3Dale Johannesen  O << "0(";
29735c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner  printOperand(MI, OpNo, O);
2984e68f8803d8e28d52cc2f16a4eef5c175878b0f3Dale Johannesen  O << ")";
2992c003e26e583e6acafca142ef93efa95a84866a1Chris Lattner  return false;
3002c003e26e583e6acafca142ef93efa95a84866a1Chris Lattner}
301e3f01570c172570fb2c0bacc6b8860ee6809362dChris Lattner
302af53a87052f41664ff5962731d0b64e3b51a5501Chris Lattner
30334a9d4b3b9b7858b729a1af67afa721c048fe5e7Bill Schmidt/// lookUpOrCreateTOCEntry -- Given a symbol, look up whether a TOC entry
30434a9d4b3b9b7858b729a1af67afa721c048fe5e7Bill Schmidt/// exists for it.  If not, create one.  Then return a symbol that references
30534a9d4b3b9b7858b729a1af67afa721c048fe5e7Bill Schmidt/// the TOC entry.
30634a9d4b3b9b7858b729a1af67afa721c048fe5e7Bill SchmidtMCSymbol *PPCAsmPrinter::lookUpOrCreateTOCEntry(MCSymbol *Sym) {
30734a9d4b3b9b7858b729a1af67afa721c048fe5e7Bill Schmidt
30834a9d4b3b9b7858b729a1af67afa721c048fe5e7Bill Schmidt  MCSymbol *&TOCEntry = TOC[Sym];
30934a9d4b3b9b7858b729a1af67afa721c048fe5e7Bill Schmidt
31034a9d4b3b9b7858b729a1af67afa721c048fe5e7Bill Schmidt  // To avoid name clash check if the name already exists.
31134a9d4b3b9b7858b729a1af67afa721c048fe5e7Bill Schmidt  while (TOCEntry == 0) {
31234a9d4b3b9b7858b729a1af67afa721c048fe5e7Bill Schmidt    if (OutContext.LookupSymbol(Twine(MAI->getPrivateGlobalPrefix()) +
31334a9d4b3b9b7858b729a1af67afa721c048fe5e7Bill Schmidt                                "C" + Twine(TOCLabelID++)) == 0) {
31434a9d4b3b9b7858b729a1af67afa721c048fe5e7Bill Schmidt      TOCEntry = GetTempSymbol("C", TOCLabelID);
31534a9d4b3b9b7858b729a1af67afa721c048fe5e7Bill Schmidt    }
31634a9d4b3b9b7858b729a1af67afa721c048fe5e7Bill Schmidt  }
31734a9d4b3b9b7858b729a1af67afa721c048fe5e7Bill Schmidt
31834a9d4b3b9b7858b729a1af67afa721c048fe5e7Bill Schmidt  return TOCEntry;
31934a9d4b3b9b7858b729a1af67afa721c048fe5e7Bill Schmidt}
32034a9d4b3b9b7858b729a1af67afa721c048fe5e7Bill Schmidt
32134a9d4b3b9b7858b729a1af67afa721c048fe5e7Bill Schmidt
322d49fe1b6bc4615684c2ec71140a21e9c4cd69ce3Chris Lattner/// EmitInstruction -- Print out a single PowerPC MI in Darwin syntax to
323e59bf59ba55c6bdba82a7126e91f5bb53118e84cNate Begeman/// the current output stream.
3245dfe3a9c3bd9091f9adecc909665d52bdd4edd8cMisha Brukman///
325d49fe1b6bc4615684c2ec71140a21e9c4cd69ce3Chris Lattnervoid PPCAsmPrinter::EmitInstruction(const MachineInstr *MI) {
326cb22fa6536bd17e54a89dc82cafc9fdf48321c36Chris Lattner  MCInst TmpInst;
327cb22fa6536bd17e54a89dc82cafc9fdf48321c36Chris Lattner
328cb22fa6536bd17e54a89dc82cafc9fdf48321c36Chris Lattner  // Lower multi-instruction pseudo operations.
329cb22fa6536bd17e54a89dc82cafc9fdf48321c36Chris Lattner  switch (MI->getOpcode()) {
330cb22fa6536bd17e54a89dc82cafc9fdf48321c36Chris Lattner  default: break;
3310187e7a9ba5c50b4559e0c2e0afceb6d5cd32190David Blaikie  case TargetOpcode::DBG_VALUE:
3320187e7a9ba5c50b4559e0c2e0afceb6d5cd32190David Blaikie    llvm_unreachable("Should be handled target independently");
333cb22fa6536bd17e54a89dc82cafc9fdf48321c36Chris Lattner  case PPC::MovePCtoLR:
334cb22fa6536bd17e54a89dc82cafc9fdf48321c36Chris Lattner  case PPC::MovePCtoLR8: {
335cb22fa6536bd17e54a89dc82cafc9fdf48321c36Chris Lattner    // Transform %LR = MovePCtoLR
336cb22fa6536bd17e54a89dc82cafc9fdf48321c36Chris Lattner    // Into this, where the label is the PIC base:
337cb22fa6536bd17e54a89dc82cafc9fdf48321c36Chris Lattner    //     bl L1$pb
338cb22fa6536bd17e54a89dc82cafc9fdf48321c36Chris Lattner    // L1$pb:
339cb22fa6536bd17e54a89dc82cafc9fdf48321c36Chris Lattner    MCSymbol *PICBase = MF->getPICBaseSymbol();
3402ead458ae8423d6ecaec7cbd45e1e2c71ce9e618Chris Lattner
341cb22fa6536bd17e54a89dc82cafc9fdf48321c36Chris Lattner    // Emit the 'bl'.
34286765fbe170198e7bb40fd8499d1354f4c786f60Ulrich Weigand    OutStreamer.EmitInstruction(MCInstBuilder(PPC::BL)
343391271f3bbcec02e0da26d7c246bfabff5cb4ddfBenjamin Kramer      // FIXME: We would like an efficient form for this, so we don't have to do
344391271f3bbcec02e0da26d7c246bfabff5cb4ddfBenjamin Kramer      // a lot of extra uniquing.
345ed9e442cf098663ce213cb16778b44be466b441fBenjamin Kramer      .addExpr(MCSymbolRefExpr::Create(PICBase, OutContext)));
346cb22fa6536bd17e54a89dc82cafc9fdf48321c36Chris Lattner
347cb22fa6536bd17e54a89dc82cafc9fdf48321c36Chris Lattner    // Emit the label.
348cb22fa6536bd17e54a89dc82cafc9fdf48321c36Chris Lattner    OutStreamer.EmitLabel(PICBase);
349cb22fa6536bd17e54a89dc82cafc9fdf48321c36Chris Lattner    return;
350cb22fa6536bd17e54a89dc82cafc9fdf48321c36Chris Lattner  }
3519fb8b49380e7cf6ce88400ad65051e830563bc81Roman Divacky  case PPC::LDtocJTI:
3529fb8b49380e7cf6ce88400ad65051e830563bc81Roman Divacky  case PPC::LDtocCPT:
353cb22fa6536bd17e54a89dc82cafc9fdf48321c36Chris Lattner  case PPC::LDtoc: {
354cb22fa6536bd17e54a89dc82cafc9fdf48321c36Chris Lattner    // Transform %X3 = LDtoc <ga:@min1>, %X2
355a68f58ab2bec6a024afae498e4082ddd8b01f178Ulrich Weigand    LowerPPCMachineInstrToMCInst(MI, TmpInst, *this, Subtarget.isDarwin());
3569fb8b49380e7cf6ce88400ad65051e830563bc81Roman Divacky
357cb22fa6536bd17e54a89dc82cafc9fdf48321c36Chris Lattner    // Change the opcode to LD, and the global address operand to be a
358cb22fa6536bd17e54a89dc82cafc9fdf48321c36Chris Lattner    // reference to the TOC entry we will synthesize later.
359cb22fa6536bd17e54a89dc82cafc9fdf48321c36Chris Lattner    TmpInst.setOpcode(PPC::LD);
360cb22fa6536bd17e54a89dc82cafc9fdf48321c36Chris Lattner    const MachineOperand &MO = MI->getOperand(1);
3619fb8b49380e7cf6ce88400ad65051e830563bc81Roman Divacky
3629fb8b49380e7cf6ce88400ad65051e830563bc81Roman Divacky    // Map symbol -> label of TOC entry
3639fb8b49380e7cf6ce88400ad65051e830563bc81Roman Divacky    assert(MO.isGlobal() || MO.isCPI() || MO.isJTI());
3649fb8b49380e7cf6ce88400ad65051e830563bc81Roman Divacky    MCSymbol *MOSymbol = 0;
3659fb8b49380e7cf6ce88400ad65051e830563bc81Roman Divacky    if (MO.isGlobal())
3669fb8b49380e7cf6ce88400ad65051e830563bc81Roman Divacky      MOSymbol = Mang->getSymbol(MO.getGlobal());
3679fb8b49380e7cf6ce88400ad65051e830563bc81Roman Divacky    else if (MO.isCPI())
3689fb8b49380e7cf6ce88400ad65051e830563bc81Roman Divacky      MOSymbol = GetCPISymbol(MO.getIndex());
3699fb8b49380e7cf6ce88400ad65051e830563bc81Roman Divacky    else if (MO.isJTI())
3709fb8b49380e7cf6ce88400ad65051e830563bc81Roman Divacky      MOSymbol = GetJTISymbol(MO.getIndex());
37134a9d4b3b9b7858b729a1af67afa721c048fe5e7Bill Schmidt
37234a9d4b3b9b7858b729a1af67afa721c048fe5e7Bill Schmidt    MCSymbol *TOCEntry = lookUpOrCreateTOCEntry(MOSymbol);
373f145c135f3a28e2c59bd02e475fbf09f4157c9fbRoman Divacky
374cb22fa6536bd17e54a89dc82cafc9fdf48321c36Chris Lattner    const MCExpr *Exp =
37592cfa61c50d01307d658753f8d47f4e8555a6fa9Ulrich Weigand      MCSymbolRefExpr::Create(TOCEntry, MCSymbolRefExpr::VK_PPC_TOC,
376cb22fa6536bd17e54a89dc82cafc9fdf48321c36Chris Lattner                              OutContext);
377cb22fa6536bd17e54a89dc82cafc9fdf48321c36Chris Lattner    TmpInst.getOperand(1) = MCOperand::CreateExpr(Exp);
378293ef9ae0fd533429dc54d94c895c39a564466f7Chris Lattner    OutStreamer.EmitInstruction(TmpInst);
379293ef9ae0fd533429dc54d94c895c39a564466f7Chris Lattner    return;
380293ef9ae0fd533429dc54d94c895c39a564466f7Chris Lattner  }
381cb22fa6536bd17e54a89dc82cafc9fdf48321c36Chris Lattner
38234a9d4b3b9b7858b729a1af67afa721c048fe5e7Bill Schmidt  case PPC::ADDIStocHA: {
38334a9d4b3b9b7858b729a1af67afa721c048fe5e7Bill Schmidt    // Transform %Xd = ADDIStocHA %X2, <ga:@sym>
384a68f58ab2bec6a024afae498e4082ddd8b01f178Ulrich Weigand    LowerPPCMachineInstrToMCInst(MI, TmpInst, *this, Subtarget.isDarwin());
38534a9d4b3b9b7858b729a1af67afa721c048fe5e7Bill Schmidt
38634a9d4b3b9b7858b729a1af67afa721c048fe5e7Bill Schmidt    // Change the opcode to ADDIS8.  If the global address is external,
38734a9d4b3b9b7858b729a1af67afa721c048fe5e7Bill Schmidt    // has common linkage, is a function address, or is a jump table
38834a9d4b3b9b7858b729a1af67afa721c048fe5e7Bill Schmidt    // address, then generate a TOC entry and reference that.  Otherwise
38934a9d4b3b9b7858b729a1af67afa721c048fe5e7Bill Schmidt    // reference the symbol directly.
39034a9d4b3b9b7858b729a1af67afa721c048fe5e7Bill Schmidt    TmpInst.setOpcode(PPC::ADDIS8);
39134a9d4b3b9b7858b729a1af67afa721c048fe5e7Bill Schmidt    const MachineOperand &MO = MI->getOperand(2);
39234a9d4b3b9b7858b729a1af67afa721c048fe5e7Bill Schmidt    assert((MO.isGlobal() || MO.isCPI() || MO.isJTI()) &&
39334a9d4b3b9b7858b729a1af67afa721c048fe5e7Bill Schmidt           "Invalid operand for ADDIStocHA!");
39434a9d4b3b9b7858b729a1af67afa721c048fe5e7Bill Schmidt    MCSymbol *MOSymbol = 0;
39534a9d4b3b9b7858b729a1af67afa721c048fe5e7Bill Schmidt    bool IsExternal = false;
39634a9d4b3b9b7858b729a1af67afa721c048fe5e7Bill Schmidt    bool IsFunction = false;
39734a9d4b3b9b7858b729a1af67afa721c048fe5e7Bill Schmidt    bool IsCommon = false;
3985b7f9216c357f1cdf507f300f396b44cb982eb3fBill Schmidt    bool IsAvailExt = false;
39934a9d4b3b9b7858b729a1af67afa721c048fe5e7Bill Schmidt
40034a9d4b3b9b7858b729a1af67afa721c048fe5e7Bill Schmidt    if (MO.isGlobal()) {
40134a9d4b3b9b7858b729a1af67afa721c048fe5e7Bill Schmidt      const GlobalValue *GValue = MO.getGlobal();
4025b7f9216c357f1cdf507f300f396b44cb982eb3fBill Schmidt      const GlobalAlias *GAlias = dyn_cast<GlobalAlias>(GValue);
4035b7f9216c357f1cdf507f300f396b44cb982eb3fBill Schmidt      const GlobalValue *RealGValue = GAlias ?
4045b7f9216c357f1cdf507f300f396b44cb982eb3fBill Schmidt        GAlias->resolveAliasedGlobal(false) : GValue;
4055b7f9216c357f1cdf507f300f396b44cb982eb3fBill Schmidt      MOSymbol = Mang->getSymbol(RealGValue);
4065b7f9216c357f1cdf507f300f396b44cb982eb3fBill Schmidt      const GlobalVariable *GVar = dyn_cast<GlobalVariable>(RealGValue);
40734a9d4b3b9b7858b729a1af67afa721c048fe5e7Bill Schmidt      IsExternal = GVar && !GVar->hasInitializer();
4085b7f9216c357f1cdf507f300f396b44cb982eb3fBill Schmidt      IsCommon = GVar && RealGValue->hasCommonLinkage();
40934a9d4b3b9b7858b729a1af67afa721c048fe5e7Bill Schmidt      IsFunction = !GVar;
4105b7f9216c357f1cdf507f300f396b44cb982eb3fBill Schmidt      IsAvailExt = GVar && RealGValue->hasAvailableExternallyLinkage();
41134a9d4b3b9b7858b729a1af67afa721c048fe5e7Bill Schmidt    } else if (MO.isCPI())
41234a9d4b3b9b7858b729a1af67afa721c048fe5e7Bill Schmidt      MOSymbol = GetCPISymbol(MO.getIndex());
41334a9d4b3b9b7858b729a1af67afa721c048fe5e7Bill Schmidt    else if (MO.isJTI())
41434a9d4b3b9b7858b729a1af67afa721c048fe5e7Bill Schmidt      MOSymbol = GetJTISymbol(MO.getIndex());
41534a9d4b3b9b7858b729a1af67afa721c048fe5e7Bill Schmidt
4165b7f9216c357f1cdf507f300f396b44cb982eb3fBill Schmidt    if (IsExternal || IsFunction || IsCommon || IsAvailExt || MO.isJTI())
41734a9d4b3b9b7858b729a1af67afa721c048fe5e7Bill Schmidt      MOSymbol = lookUpOrCreateTOCEntry(MOSymbol);
41834a9d4b3b9b7858b729a1af67afa721c048fe5e7Bill Schmidt
41934a9d4b3b9b7858b729a1af67afa721c048fe5e7Bill Schmidt    const MCExpr *Exp =
42092cfa61c50d01307d658753f8d47f4e8555a6fa9Ulrich Weigand      MCSymbolRefExpr::Create(MOSymbol, MCSymbolRefExpr::VK_PPC_TOC_HA,
42134a9d4b3b9b7858b729a1af67afa721c048fe5e7Bill Schmidt                              OutContext);
42234a9d4b3b9b7858b729a1af67afa721c048fe5e7Bill Schmidt    TmpInst.getOperand(2) = MCOperand::CreateExpr(Exp);
42334a9d4b3b9b7858b729a1af67afa721c048fe5e7Bill Schmidt    OutStreamer.EmitInstruction(TmpInst);
42434a9d4b3b9b7858b729a1af67afa721c048fe5e7Bill Schmidt    return;
42534a9d4b3b9b7858b729a1af67afa721c048fe5e7Bill Schmidt  }
42634a9d4b3b9b7858b729a1af67afa721c048fe5e7Bill Schmidt  case PPC::LDtocL: {
42734a9d4b3b9b7858b729a1af67afa721c048fe5e7Bill Schmidt    // Transform %Xd = LDtocL <ga:@sym>, %Xs
428a68f58ab2bec6a024afae498e4082ddd8b01f178Ulrich Weigand    LowerPPCMachineInstrToMCInst(MI, TmpInst, *this, Subtarget.isDarwin());
42934a9d4b3b9b7858b729a1af67afa721c048fe5e7Bill Schmidt
430d67768db809d6b1cfe6f7c484b3719a6103286eaUlrich Weigand    // Change the opcode to LD.  If the global address is external, has
43134a9d4b3b9b7858b729a1af67afa721c048fe5e7Bill Schmidt    // common linkage, or is a jump table address, then reference the
43234a9d4b3b9b7858b729a1af67afa721c048fe5e7Bill Schmidt    // associated TOC entry.  Otherwise reference the symbol directly.
433d67768db809d6b1cfe6f7c484b3719a6103286eaUlrich Weigand    TmpInst.setOpcode(PPC::LD);
43434a9d4b3b9b7858b729a1af67afa721c048fe5e7Bill Schmidt    const MachineOperand &MO = MI->getOperand(1);
43553b0b0e75480121e4e01a7a76e17909e92b1762aBill Schmidt    assert((MO.isGlobal() || MO.isJTI() || MO.isCPI()) &&
43653b0b0e75480121e4e01a7a76e17909e92b1762aBill Schmidt           "Invalid operand for LDtocL!");
43734a9d4b3b9b7858b729a1af67afa721c048fe5e7Bill Schmidt    MCSymbol *MOSymbol = 0;
43834a9d4b3b9b7858b729a1af67afa721c048fe5e7Bill Schmidt
43934a9d4b3b9b7858b729a1af67afa721c048fe5e7Bill Schmidt    if (MO.isJTI())
44034a9d4b3b9b7858b729a1af67afa721c048fe5e7Bill Schmidt      MOSymbol = lookUpOrCreateTOCEntry(GetJTISymbol(MO.getIndex()));
44153b0b0e75480121e4e01a7a76e17909e92b1762aBill Schmidt    else if (MO.isCPI())
44253b0b0e75480121e4e01a7a76e17909e92b1762aBill Schmidt      MOSymbol = GetCPISymbol(MO.getIndex());
44353b0b0e75480121e4e01a7a76e17909e92b1762aBill Schmidt    else if (MO.isGlobal()) {
44434a9d4b3b9b7858b729a1af67afa721c048fe5e7Bill Schmidt      const GlobalValue *GValue = MO.getGlobal();
4455b7f9216c357f1cdf507f300f396b44cb982eb3fBill Schmidt      const GlobalAlias *GAlias = dyn_cast<GlobalAlias>(GValue);
4465b7f9216c357f1cdf507f300f396b44cb982eb3fBill Schmidt      const GlobalValue *RealGValue = GAlias ?
4475b7f9216c357f1cdf507f300f396b44cb982eb3fBill Schmidt        GAlias->resolveAliasedGlobal(false) : GValue;
4485b7f9216c357f1cdf507f300f396b44cb982eb3fBill Schmidt      MOSymbol = Mang->getSymbol(RealGValue);
4495b7f9216c357f1cdf507f300f396b44cb982eb3fBill Schmidt      const GlobalVariable *GVar = dyn_cast<GlobalVariable>(RealGValue);
45034a9d4b3b9b7858b729a1af67afa721c048fe5e7Bill Schmidt
4515b7f9216c357f1cdf507f300f396b44cb982eb3fBill Schmidt      if (!GVar || !GVar->hasInitializer() || RealGValue->hasCommonLinkage() ||
4525b7f9216c357f1cdf507f300f396b44cb982eb3fBill Schmidt          RealGValue->hasAvailableExternallyLinkage())
45334a9d4b3b9b7858b729a1af67afa721c048fe5e7Bill Schmidt        MOSymbol = lookUpOrCreateTOCEntry(MOSymbol);
45434a9d4b3b9b7858b729a1af67afa721c048fe5e7Bill Schmidt    }
45534a9d4b3b9b7858b729a1af67afa721c048fe5e7Bill Schmidt
45634a9d4b3b9b7858b729a1af67afa721c048fe5e7Bill Schmidt    const MCExpr *Exp =
45792cfa61c50d01307d658753f8d47f4e8555a6fa9Ulrich Weigand      MCSymbolRefExpr::Create(MOSymbol, MCSymbolRefExpr::VK_PPC_TOC_LO,
45834a9d4b3b9b7858b729a1af67afa721c048fe5e7Bill Schmidt                              OutContext);
45934a9d4b3b9b7858b729a1af67afa721c048fe5e7Bill Schmidt    TmpInst.getOperand(1) = MCOperand::CreateExpr(Exp);
46034a9d4b3b9b7858b729a1af67afa721c048fe5e7Bill Schmidt    OutStreamer.EmitInstruction(TmpInst);
46134a9d4b3b9b7858b729a1af67afa721c048fe5e7Bill Schmidt    return;
46234a9d4b3b9b7858b729a1af67afa721c048fe5e7Bill Schmidt  }
46334a9d4b3b9b7858b729a1af67afa721c048fe5e7Bill Schmidt  case PPC::ADDItocL: {
46434a9d4b3b9b7858b729a1af67afa721c048fe5e7Bill Schmidt    // Transform %Xd = ADDItocL %Xs, <ga:@sym>
465a68f58ab2bec6a024afae498e4082ddd8b01f178Ulrich Weigand    LowerPPCMachineInstrToMCInst(MI, TmpInst, *this, Subtarget.isDarwin());
46634a9d4b3b9b7858b729a1af67afa721c048fe5e7Bill Schmidt
4672b0850b8305380244ec98e1b1c89aaf57adf3b09Ulrich Weigand    // Change the opcode to ADDI8.  If the global address is external, then
46834a9d4b3b9b7858b729a1af67afa721c048fe5e7Bill Schmidt    // generate a TOC entry and reference that.  Otherwise reference the
46934a9d4b3b9b7858b729a1af67afa721c048fe5e7Bill Schmidt    // symbol directly.
4702b0850b8305380244ec98e1b1c89aaf57adf3b09Ulrich Weigand    TmpInst.setOpcode(PPC::ADDI8);
47134a9d4b3b9b7858b729a1af67afa721c048fe5e7Bill Schmidt    const MachineOperand &MO = MI->getOperand(2);
47234a9d4b3b9b7858b729a1af67afa721c048fe5e7Bill Schmidt    assert((MO.isGlobal() || MO.isCPI()) && "Invalid operand for ADDItocL");
47334a9d4b3b9b7858b729a1af67afa721c048fe5e7Bill Schmidt    MCSymbol *MOSymbol = 0;
47434a9d4b3b9b7858b729a1af67afa721c048fe5e7Bill Schmidt    bool IsExternal = false;
47534a9d4b3b9b7858b729a1af67afa721c048fe5e7Bill Schmidt    bool IsFunction = false;
47634a9d4b3b9b7858b729a1af67afa721c048fe5e7Bill Schmidt
47734a9d4b3b9b7858b729a1af67afa721c048fe5e7Bill Schmidt    if (MO.isGlobal()) {
47834a9d4b3b9b7858b729a1af67afa721c048fe5e7Bill Schmidt      const GlobalValue *GValue = MO.getGlobal();
4795b7f9216c357f1cdf507f300f396b44cb982eb3fBill Schmidt      const GlobalAlias *GAlias = dyn_cast<GlobalAlias>(GValue);
4805b7f9216c357f1cdf507f300f396b44cb982eb3fBill Schmidt      const GlobalValue *RealGValue = GAlias ?
4815b7f9216c357f1cdf507f300f396b44cb982eb3fBill Schmidt        GAlias->resolveAliasedGlobal(false) : GValue;
4825b7f9216c357f1cdf507f300f396b44cb982eb3fBill Schmidt      MOSymbol = Mang->getSymbol(RealGValue);
4835b7f9216c357f1cdf507f300f396b44cb982eb3fBill Schmidt      const GlobalVariable *GVar = dyn_cast<GlobalVariable>(RealGValue);
48434a9d4b3b9b7858b729a1af67afa721c048fe5e7Bill Schmidt      IsExternal = GVar && !GVar->hasInitializer();
48534a9d4b3b9b7858b729a1af67afa721c048fe5e7Bill Schmidt      IsFunction = !GVar;
48634a9d4b3b9b7858b729a1af67afa721c048fe5e7Bill Schmidt    } else if (MO.isCPI())
48734a9d4b3b9b7858b729a1af67afa721c048fe5e7Bill Schmidt      MOSymbol = GetCPISymbol(MO.getIndex());
48834a9d4b3b9b7858b729a1af67afa721c048fe5e7Bill Schmidt
48934a9d4b3b9b7858b729a1af67afa721c048fe5e7Bill Schmidt    if (IsFunction || IsExternal)
49034a9d4b3b9b7858b729a1af67afa721c048fe5e7Bill Schmidt      MOSymbol = lookUpOrCreateTOCEntry(MOSymbol);
49134a9d4b3b9b7858b729a1af67afa721c048fe5e7Bill Schmidt
49234a9d4b3b9b7858b729a1af67afa721c048fe5e7Bill Schmidt    const MCExpr *Exp =
49392cfa61c50d01307d658753f8d47f4e8555a6fa9Ulrich Weigand      MCSymbolRefExpr::Create(MOSymbol, MCSymbolRefExpr::VK_PPC_TOC_LO,
49434a9d4b3b9b7858b729a1af67afa721c048fe5e7Bill Schmidt                              OutContext);
49534a9d4b3b9b7858b729a1af67afa721c048fe5e7Bill Schmidt    TmpInst.getOperand(2) = MCOperand::CreateExpr(Exp);
49634a9d4b3b9b7858b729a1af67afa721c048fe5e7Bill Schmidt    OutStreamer.EmitInstruction(TmpInst);
49734a9d4b3b9b7858b729a1af67afa721c048fe5e7Bill Schmidt    return;
49834a9d4b3b9b7858b729a1af67afa721c048fe5e7Bill Schmidt  }
499b453e16855f347e300f1dc0cd0dfbdd65c27b0d2Bill Schmidt  case PPC::ADDISgotTprelHA: {
500b453e16855f347e300f1dc0cd0dfbdd65c27b0d2Bill Schmidt    // Transform: %Xd = ADDISgotTprelHA %X2, <ga:@sym>
501b453e16855f347e300f1dc0cd0dfbdd65c27b0d2Bill Schmidt    // Into:      %Xd = ADDIS8 %X2, sym@got@tlsgd@ha
502b453e16855f347e300f1dc0cd0dfbdd65c27b0d2Bill Schmidt    assert(Subtarget.isPPC64() && "Not supported for 32-bit PowerPC");
503b453e16855f347e300f1dc0cd0dfbdd65c27b0d2Bill Schmidt    const MachineOperand &MO = MI->getOperand(2);
504b453e16855f347e300f1dc0cd0dfbdd65c27b0d2Bill Schmidt    const GlobalValue *GValue = MO.getGlobal();
505b453e16855f347e300f1dc0cd0dfbdd65c27b0d2Bill Schmidt    MCSymbol *MOSymbol = Mang->getSymbol(GValue);
506b453e16855f347e300f1dc0cd0dfbdd65c27b0d2Bill Schmidt    const MCExpr *SymGotTprel =
50792cfa61c50d01307d658753f8d47f4e8555a6fa9Ulrich Weigand      MCSymbolRefExpr::Create(MOSymbol, MCSymbolRefExpr::VK_PPC_GOT_TPREL_HA,
508b453e16855f347e300f1dc0cd0dfbdd65c27b0d2Bill Schmidt                              OutContext);
509b453e16855f347e300f1dc0cd0dfbdd65c27b0d2Bill Schmidt    OutStreamer.EmitInstruction(MCInstBuilder(PPC::ADDIS8)
510b453e16855f347e300f1dc0cd0dfbdd65c27b0d2Bill Schmidt                                .addReg(MI->getOperand(0).getReg())
511b453e16855f347e300f1dc0cd0dfbdd65c27b0d2Bill Schmidt                                .addReg(PPC::X2)
512b453e16855f347e300f1dc0cd0dfbdd65c27b0d2Bill Schmidt                                .addExpr(SymGotTprel));
513b453e16855f347e300f1dc0cd0dfbdd65c27b0d2Bill Schmidt    return;
514b453e16855f347e300f1dc0cd0dfbdd65c27b0d2Bill Schmidt  }
515b453e16855f347e300f1dc0cd0dfbdd65c27b0d2Bill Schmidt  case PPC::LDgotTprelL: {
516b453e16855f347e300f1dc0cd0dfbdd65c27b0d2Bill Schmidt    // Transform %Xd = LDgotTprelL <ga:@sym>, %Xs
517a68f58ab2bec6a024afae498e4082ddd8b01f178Ulrich Weigand    LowerPPCMachineInstrToMCInst(MI, TmpInst, *this, Subtarget.isDarwin());
518d7802bf0ddcac16ee910105922492aee86a53e1bBill Schmidt
519d67768db809d6b1cfe6f7c484b3719a6103286eaUlrich Weigand    // Change the opcode to LD.
520d67768db809d6b1cfe6f7c484b3719a6103286eaUlrich Weigand    TmpInst.setOpcode(PPC::LD);
521d7802bf0ddcac16ee910105922492aee86a53e1bBill Schmidt    const MachineOperand &MO = MI->getOperand(1);
522d7802bf0ddcac16ee910105922492aee86a53e1bBill Schmidt    const GlobalValue *GValue = MO.getGlobal();
523d7802bf0ddcac16ee910105922492aee86a53e1bBill Schmidt    MCSymbol *MOSymbol = Mang->getSymbol(GValue);
524d7802bf0ddcac16ee910105922492aee86a53e1bBill Schmidt    const MCExpr *Exp =
52592cfa61c50d01307d658753f8d47f4e8555a6fa9Ulrich Weigand      MCSymbolRefExpr::Create(MOSymbol, MCSymbolRefExpr::VK_PPC_GOT_TPREL_LO,
526d7802bf0ddcac16ee910105922492aee86a53e1bBill Schmidt                              OutContext);
527d7802bf0ddcac16ee910105922492aee86a53e1bBill Schmidt    TmpInst.getOperand(1) = MCOperand::CreateExpr(Exp);
528d7802bf0ddcac16ee910105922492aee86a53e1bBill Schmidt    OutStreamer.EmitInstruction(TmpInst);
529d7802bf0ddcac16ee910105922492aee86a53e1bBill Schmidt    return;
530d7802bf0ddcac16ee910105922492aee86a53e1bBill Schmidt  }
53157ac1f458a754f30cf500410b438fb260f9b8fe5Bill Schmidt  case PPC::ADDIStlsgdHA: {
53257ac1f458a754f30cf500410b438fb260f9b8fe5Bill Schmidt    // Transform: %Xd = ADDIStlsgdHA %X2, <ga:@sym>
53357ac1f458a754f30cf500410b438fb260f9b8fe5Bill Schmidt    // Into:      %Xd = ADDIS8 %X2, sym@got@tlsgd@ha
53457ac1f458a754f30cf500410b438fb260f9b8fe5Bill Schmidt    assert(Subtarget.isPPC64() && "Not supported for 32-bit PowerPC");
53557ac1f458a754f30cf500410b438fb260f9b8fe5Bill Schmidt    const MachineOperand &MO = MI->getOperand(2);
53657ac1f458a754f30cf500410b438fb260f9b8fe5Bill Schmidt    const GlobalValue *GValue = MO.getGlobal();
53757ac1f458a754f30cf500410b438fb260f9b8fe5Bill Schmidt    MCSymbol *MOSymbol = Mang->getSymbol(GValue);
53857ac1f458a754f30cf500410b438fb260f9b8fe5Bill Schmidt    const MCExpr *SymGotTlsGD =
53992cfa61c50d01307d658753f8d47f4e8555a6fa9Ulrich Weigand      MCSymbolRefExpr::Create(MOSymbol, MCSymbolRefExpr::VK_PPC_GOT_TLSGD_HA,
54057ac1f458a754f30cf500410b438fb260f9b8fe5Bill Schmidt                              OutContext);
54157ac1f458a754f30cf500410b438fb260f9b8fe5Bill Schmidt    OutStreamer.EmitInstruction(MCInstBuilder(PPC::ADDIS8)
54257ac1f458a754f30cf500410b438fb260f9b8fe5Bill Schmidt                                .addReg(MI->getOperand(0).getReg())
54357ac1f458a754f30cf500410b438fb260f9b8fe5Bill Schmidt                                .addReg(PPC::X2)
54457ac1f458a754f30cf500410b438fb260f9b8fe5Bill Schmidt                                .addExpr(SymGotTlsGD));
54557ac1f458a754f30cf500410b438fb260f9b8fe5Bill Schmidt    return;
54657ac1f458a754f30cf500410b438fb260f9b8fe5Bill Schmidt  }
54757ac1f458a754f30cf500410b438fb260f9b8fe5Bill Schmidt  case PPC::ADDItlsgdL: {
54857ac1f458a754f30cf500410b438fb260f9b8fe5Bill Schmidt    // Transform: %Xd = ADDItlsgdL %Xs, <ga:@sym>
5492b0850b8305380244ec98e1b1c89aaf57adf3b09Ulrich Weigand    // Into:      %Xd = ADDI8 %Xs, sym@got@tlsgd@l
55057ac1f458a754f30cf500410b438fb260f9b8fe5Bill Schmidt    assert(Subtarget.isPPC64() && "Not supported for 32-bit PowerPC");
55157ac1f458a754f30cf500410b438fb260f9b8fe5Bill Schmidt    const MachineOperand &MO = MI->getOperand(2);
55257ac1f458a754f30cf500410b438fb260f9b8fe5Bill Schmidt    const GlobalValue *GValue = MO.getGlobal();
55357ac1f458a754f30cf500410b438fb260f9b8fe5Bill Schmidt    MCSymbol *MOSymbol = Mang->getSymbol(GValue);
55457ac1f458a754f30cf500410b438fb260f9b8fe5Bill Schmidt    const MCExpr *SymGotTlsGD =
55592cfa61c50d01307d658753f8d47f4e8555a6fa9Ulrich Weigand      MCSymbolRefExpr::Create(MOSymbol, MCSymbolRefExpr::VK_PPC_GOT_TLSGD_LO,
55657ac1f458a754f30cf500410b438fb260f9b8fe5Bill Schmidt                              OutContext);
5572b0850b8305380244ec98e1b1c89aaf57adf3b09Ulrich Weigand    OutStreamer.EmitInstruction(MCInstBuilder(PPC::ADDI8)
55857ac1f458a754f30cf500410b438fb260f9b8fe5Bill Schmidt                                .addReg(MI->getOperand(0).getReg())
55957ac1f458a754f30cf500410b438fb260f9b8fe5Bill Schmidt                                .addReg(MI->getOperand(1).getReg())
56057ac1f458a754f30cf500410b438fb260f9b8fe5Bill Schmidt                                .addExpr(SymGotTlsGD));
56157ac1f458a754f30cf500410b438fb260f9b8fe5Bill Schmidt    return;
56257ac1f458a754f30cf500410b438fb260f9b8fe5Bill Schmidt  }
56357ac1f458a754f30cf500410b438fb260f9b8fe5Bill Schmidt  case PPC::GETtlsADDR: {
56457ac1f458a754f30cf500410b438fb260f9b8fe5Bill Schmidt    // Transform: %X3 = GETtlsADDR %X3, <ga:@sym>
565a17a7e1868076a4430cfa16694bcb42884130928Ulrich Weigand    // Into:      BL8_NOP_TLS __tls_get_addr(sym@tlsgd)
56657ac1f458a754f30cf500410b438fb260f9b8fe5Bill Schmidt    assert(Subtarget.isPPC64() && "Not supported for 32-bit PowerPC");
56757ac1f458a754f30cf500410b438fb260f9b8fe5Bill Schmidt
56857ac1f458a754f30cf500410b438fb260f9b8fe5Bill Schmidt    StringRef Name = "__tls_get_addr";
56957ac1f458a754f30cf500410b438fb260f9b8fe5Bill Schmidt    MCSymbol *TlsGetAddr = OutContext.GetOrCreateSymbol(Name);
57057ac1f458a754f30cf500410b438fb260f9b8fe5Bill Schmidt    const MCSymbolRefExpr *TlsRef =
57157ac1f458a754f30cf500410b438fb260f9b8fe5Bill Schmidt      MCSymbolRefExpr::Create(TlsGetAddr, MCSymbolRefExpr::VK_None, OutContext);
57257ac1f458a754f30cf500410b438fb260f9b8fe5Bill Schmidt    const MachineOperand &MO = MI->getOperand(2);
57357ac1f458a754f30cf500410b438fb260f9b8fe5Bill Schmidt    const GlobalValue *GValue = MO.getGlobal();
57457ac1f458a754f30cf500410b438fb260f9b8fe5Bill Schmidt    MCSymbol *MOSymbol = Mang->getSymbol(GValue);
57557ac1f458a754f30cf500410b438fb260f9b8fe5Bill Schmidt    const MCExpr *SymVar =
5767a34599db017a5486cf7cd11eb124984acec8286Ulrich Weigand      MCSymbolRefExpr::Create(MOSymbol, MCSymbolRefExpr::VK_PPC_TLSGD,
5777a34599db017a5486cf7cd11eb124984acec8286Ulrich Weigand                              OutContext);
578a17a7e1868076a4430cfa16694bcb42884130928Ulrich Weigand    OutStreamer.EmitInstruction(MCInstBuilder(PPC::BL8_NOP_TLS)
57957ac1f458a754f30cf500410b438fb260f9b8fe5Bill Schmidt                                .addExpr(TlsRef)
58057ac1f458a754f30cf500410b438fb260f9b8fe5Bill Schmidt                                .addExpr(SymVar));
58157ac1f458a754f30cf500410b438fb260f9b8fe5Bill Schmidt    return;
58257ac1f458a754f30cf500410b438fb260f9b8fe5Bill Schmidt  }
583349c2787cf9e174c8aa955bf8e3b09a405b2aeceBill Schmidt  case PPC::ADDIStlsldHA: {
584349c2787cf9e174c8aa955bf8e3b09a405b2aeceBill Schmidt    // Transform: %Xd = ADDIStlsldHA %X2, <ga:@sym>
585349c2787cf9e174c8aa955bf8e3b09a405b2aeceBill Schmidt    // Into:      %Xd = ADDIS8 %X2, sym@got@tlsld@ha
586349c2787cf9e174c8aa955bf8e3b09a405b2aeceBill Schmidt    assert(Subtarget.isPPC64() && "Not supported for 32-bit PowerPC");
587349c2787cf9e174c8aa955bf8e3b09a405b2aeceBill Schmidt    const MachineOperand &MO = MI->getOperand(2);
588349c2787cf9e174c8aa955bf8e3b09a405b2aeceBill Schmidt    const GlobalValue *GValue = MO.getGlobal();
589349c2787cf9e174c8aa955bf8e3b09a405b2aeceBill Schmidt    MCSymbol *MOSymbol = Mang->getSymbol(GValue);
590349c2787cf9e174c8aa955bf8e3b09a405b2aeceBill Schmidt    const MCExpr *SymGotTlsLD =
59192cfa61c50d01307d658753f8d47f4e8555a6fa9Ulrich Weigand      MCSymbolRefExpr::Create(MOSymbol, MCSymbolRefExpr::VK_PPC_GOT_TLSLD_HA,
592349c2787cf9e174c8aa955bf8e3b09a405b2aeceBill Schmidt                              OutContext);
593349c2787cf9e174c8aa955bf8e3b09a405b2aeceBill Schmidt    OutStreamer.EmitInstruction(MCInstBuilder(PPC::ADDIS8)
594349c2787cf9e174c8aa955bf8e3b09a405b2aeceBill Schmidt                                .addReg(MI->getOperand(0).getReg())
595349c2787cf9e174c8aa955bf8e3b09a405b2aeceBill Schmidt                                .addReg(PPC::X2)
596349c2787cf9e174c8aa955bf8e3b09a405b2aeceBill Schmidt                                .addExpr(SymGotTlsLD));
597349c2787cf9e174c8aa955bf8e3b09a405b2aeceBill Schmidt    return;
598349c2787cf9e174c8aa955bf8e3b09a405b2aeceBill Schmidt  }
599349c2787cf9e174c8aa955bf8e3b09a405b2aeceBill Schmidt  case PPC::ADDItlsldL: {
600349c2787cf9e174c8aa955bf8e3b09a405b2aeceBill Schmidt    // Transform: %Xd = ADDItlsldL %Xs, <ga:@sym>
6012b0850b8305380244ec98e1b1c89aaf57adf3b09Ulrich Weigand    // Into:      %Xd = ADDI8 %Xs, sym@got@tlsld@l
602349c2787cf9e174c8aa955bf8e3b09a405b2aeceBill Schmidt    assert(Subtarget.isPPC64() && "Not supported for 32-bit PowerPC");
603349c2787cf9e174c8aa955bf8e3b09a405b2aeceBill Schmidt    const MachineOperand &MO = MI->getOperand(2);
604349c2787cf9e174c8aa955bf8e3b09a405b2aeceBill Schmidt    const GlobalValue *GValue = MO.getGlobal();
605349c2787cf9e174c8aa955bf8e3b09a405b2aeceBill Schmidt    MCSymbol *MOSymbol = Mang->getSymbol(GValue);
606349c2787cf9e174c8aa955bf8e3b09a405b2aeceBill Schmidt    const MCExpr *SymGotTlsLD =
60792cfa61c50d01307d658753f8d47f4e8555a6fa9Ulrich Weigand      MCSymbolRefExpr::Create(MOSymbol, MCSymbolRefExpr::VK_PPC_GOT_TLSLD_LO,
608349c2787cf9e174c8aa955bf8e3b09a405b2aeceBill Schmidt                              OutContext);
6092b0850b8305380244ec98e1b1c89aaf57adf3b09Ulrich Weigand    OutStreamer.EmitInstruction(MCInstBuilder(PPC::ADDI8)
610349c2787cf9e174c8aa955bf8e3b09a405b2aeceBill Schmidt                                .addReg(MI->getOperand(0).getReg())
611349c2787cf9e174c8aa955bf8e3b09a405b2aeceBill Schmidt                                .addReg(MI->getOperand(1).getReg())
612349c2787cf9e174c8aa955bf8e3b09a405b2aeceBill Schmidt                                .addExpr(SymGotTlsLD));
613349c2787cf9e174c8aa955bf8e3b09a405b2aeceBill Schmidt    return;
614349c2787cf9e174c8aa955bf8e3b09a405b2aeceBill Schmidt  }
615349c2787cf9e174c8aa955bf8e3b09a405b2aeceBill Schmidt  case PPC::GETtlsldADDR: {
616349c2787cf9e174c8aa955bf8e3b09a405b2aeceBill Schmidt    // Transform: %X3 = GETtlsldADDR %X3, <ga:@sym>
617a17a7e1868076a4430cfa16694bcb42884130928Ulrich Weigand    // Into:      BL8_NOP_TLS __tls_get_addr(sym@tlsld)
618349c2787cf9e174c8aa955bf8e3b09a405b2aeceBill Schmidt    assert(Subtarget.isPPC64() && "Not supported for 32-bit PowerPC");
619349c2787cf9e174c8aa955bf8e3b09a405b2aeceBill Schmidt
620349c2787cf9e174c8aa955bf8e3b09a405b2aeceBill Schmidt    StringRef Name = "__tls_get_addr";
621349c2787cf9e174c8aa955bf8e3b09a405b2aeceBill Schmidt    MCSymbol *TlsGetAddr = OutContext.GetOrCreateSymbol(Name);
622349c2787cf9e174c8aa955bf8e3b09a405b2aeceBill Schmidt    const MCSymbolRefExpr *TlsRef =
623349c2787cf9e174c8aa955bf8e3b09a405b2aeceBill Schmidt      MCSymbolRefExpr::Create(TlsGetAddr, MCSymbolRefExpr::VK_None, OutContext);
624349c2787cf9e174c8aa955bf8e3b09a405b2aeceBill Schmidt    const MachineOperand &MO = MI->getOperand(2);
625349c2787cf9e174c8aa955bf8e3b09a405b2aeceBill Schmidt    const GlobalValue *GValue = MO.getGlobal();
626349c2787cf9e174c8aa955bf8e3b09a405b2aeceBill Schmidt    MCSymbol *MOSymbol = Mang->getSymbol(GValue);
627349c2787cf9e174c8aa955bf8e3b09a405b2aeceBill Schmidt    const MCExpr *SymVar =
6287a34599db017a5486cf7cd11eb124984acec8286Ulrich Weigand      MCSymbolRefExpr::Create(MOSymbol, MCSymbolRefExpr::VK_PPC_TLSLD,
6297a34599db017a5486cf7cd11eb124984acec8286Ulrich Weigand                              OutContext);
630a17a7e1868076a4430cfa16694bcb42884130928Ulrich Weigand    OutStreamer.EmitInstruction(MCInstBuilder(PPC::BL8_NOP_TLS)
631349c2787cf9e174c8aa955bf8e3b09a405b2aeceBill Schmidt                                .addExpr(TlsRef)
632349c2787cf9e174c8aa955bf8e3b09a405b2aeceBill Schmidt                                .addExpr(SymVar));
633349c2787cf9e174c8aa955bf8e3b09a405b2aeceBill Schmidt    return;
634349c2787cf9e174c8aa955bf8e3b09a405b2aeceBill Schmidt  }
635349c2787cf9e174c8aa955bf8e3b09a405b2aeceBill Schmidt  case PPC::ADDISdtprelHA: {
636349c2787cf9e174c8aa955bf8e3b09a405b2aeceBill Schmidt    // Transform: %Xd = ADDISdtprelHA %X3, <ga:@sym>
637349c2787cf9e174c8aa955bf8e3b09a405b2aeceBill Schmidt    // Into:      %Xd = ADDIS8 %X3, sym@dtprel@ha
638349c2787cf9e174c8aa955bf8e3b09a405b2aeceBill Schmidt    assert(Subtarget.isPPC64() && "Not supported for 32-bit PowerPC");
639349c2787cf9e174c8aa955bf8e3b09a405b2aeceBill Schmidt    const MachineOperand &MO = MI->getOperand(2);
640349c2787cf9e174c8aa955bf8e3b09a405b2aeceBill Schmidt    const GlobalValue *GValue = MO.getGlobal();
641349c2787cf9e174c8aa955bf8e3b09a405b2aeceBill Schmidt    MCSymbol *MOSymbol = Mang->getSymbol(GValue);
642349c2787cf9e174c8aa955bf8e3b09a405b2aeceBill Schmidt    const MCExpr *SymDtprel =
64392cfa61c50d01307d658753f8d47f4e8555a6fa9Ulrich Weigand      MCSymbolRefExpr::Create(MOSymbol, MCSymbolRefExpr::VK_PPC_DTPREL_HA,
644349c2787cf9e174c8aa955bf8e3b09a405b2aeceBill Schmidt                              OutContext);
645349c2787cf9e174c8aa955bf8e3b09a405b2aeceBill Schmidt    OutStreamer.EmitInstruction(MCInstBuilder(PPC::ADDIS8)
646349c2787cf9e174c8aa955bf8e3b09a405b2aeceBill Schmidt                                .addReg(MI->getOperand(0).getReg())
647349c2787cf9e174c8aa955bf8e3b09a405b2aeceBill Schmidt                                .addReg(PPC::X3)
648349c2787cf9e174c8aa955bf8e3b09a405b2aeceBill Schmidt                                .addExpr(SymDtprel));
649349c2787cf9e174c8aa955bf8e3b09a405b2aeceBill Schmidt    return;
650349c2787cf9e174c8aa955bf8e3b09a405b2aeceBill Schmidt  }
651349c2787cf9e174c8aa955bf8e3b09a405b2aeceBill Schmidt  case PPC::ADDIdtprelL: {
652349c2787cf9e174c8aa955bf8e3b09a405b2aeceBill Schmidt    // Transform: %Xd = ADDIdtprelL %Xs, <ga:@sym>
6532b0850b8305380244ec98e1b1c89aaf57adf3b09Ulrich Weigand    // Into:      %Xd = ADDI8 %Xs, sym@dtprel@l
654349c2787cf9e174c8aa955bf8e3b09a405b2aeceBill Schmidt    assert(Subtarget.isPPC64() && "Not supported for 32-bit PowerPC");
655349c2787cf9e174c8aa955bf8e3b09a405b2aeceBill Schmidt    const MachineOperand &MO = MI->getOperand(2);
656349c2787cf9e174c8aa955bf8e3b09a405b2aeceBill Schmidt    const GlobalValue *GValue = MO.getGlobal();
657349c2787cf9e174c8aa955bf8e3b09a405b2aeceBill Schmidt    MCSymbol *MOSymbol = Mang->getSymbol(GValue);
658349c2787cf9e174c8aa955bf8e3b09a405b2aeceBill Schmidt    const MCExpr *SymDtprel =
65992cfa61c50d01307d658753f8d47f4e8555a6fa9Ulrich Weigand      MCSymbolRefExpr::Create(MOSymbol, MCSymbolRefExpr::VK_PPC_DTPREL_LO,
660349c2787cf9e174c8aa955bf8e3b09a405b2aeceBill Schmidt                              OutContext);
6612b0850b8305380244ec98e1b1c89aaf57adf3b09Ulrich Weigand    OutStreamer.EmitInstruction(MCInstBuilder(PPC::ADDI8)
662349c2787cf9e174c8aa955bf8e3b09a405b2aeceBill Schmidt                                .addReg(MI->getOperand(0).getReg())
663349c2787cf9e174c8aa955bf8e3b09a405b2aeceBill Schmidt                                .addReg(MI->getOperand(1).getReg())
664349c2787cf9e174c8aa955bf8e3b09a405b2aeceBill Schmidt                                .addExpr(SymDtprel));
665349c2787cf9e174c8aa955bf8e3b09a405b2aeceBill Schmidt    return;
666349c2787cf9e174c8aa955bf8e3b09a405b2aeceBill Schmidt  }
667965b20e39c7fd73846e9b6ed55ba90e032ae3b1bUlrich Weigand  case PPC::MFOCRF:
668965b20e39c7fd73846e9b6ed55ba90e032ae3b1bUlrich Weigand  case PPC::MFOCRF8:
669965b20e39c7fd73846e9b6ed55ba90e032ae3b1bUlrich Weigand    if (!Subtarget.hasMFOCRF()) {
670965b20e39c7fd73846e9b6ed55ba90e032ae3b1bUlrich Weigand      // Transform: %R3 = MFOCRF %CR7
671965b20e39c7fd73846e9b6ed55ba90e032ae3b1bUlrich Weigand      // Into:      %R3 = MFCR   ;; cr7
672965b20e39c7fd73846e9b6ed55ba90e032ae3b1bUlrich Weigand      unsigned NewOpcode =
673965b20e39c7fd73846e9b6ed55ba90e032ae3b1bUlrich Weigand        MI->getOpcode() == PPC::MFOCRF ? PPC::MFCR : PPC::MFCR8;
674965b20e39c7fd73846e9b6ed55ba90e032ae3b1bUlrich Weigand      OutStreamer.AddComment(PPCInstPrinter::
675965b20e39c7fd73846e9b6ed55ba90e032ae3b1bUlrich Weigand                             getRegisterName(MI->getOperand(1).getReg()));
676965b20e39c7fd73846e9b6ed55ba90e032ae3b1bUlrich Weigand      OutStreamer.EmitInstruction(MCInstBuilder(NewOpcode)
677965b20e39c7fd73846e9b6ed55ba90e032ae3b1bUlrich Weigand                                  .addReg(MI->getOperand(0).getReg()));
678965b20e39c7fd73846e9b6ed55ba90e032ae3b1bUlrich Weigand      return;
679965b20e39c7fd73846e9b6ed55ba90e032ae3b1bUlrich Weigand    }
680965b20e39c7fd73846e9b6ed55ba90e032ae3b1bUlrich Weigand    break;
68133efedc0481c4b0d9866ff526eb1161372b5919fUlrich Weigand  case PPC::MTOCRF:
68233efedc0481c4b0d9866ff526eb1161372b5919fUlrich Weigand  case PPC::MTOCRF8:
68333efedc0481c4b0d9866ff526eb1161372b5919fUlrich Weigand    if (!Subtarget.hasMFOCRF()) {
68433efedc0481c4b0d9866ff526eb1161372b5919fUlrich Weigand      // Transform: %CR7 = MTOCRF %R3
68533efedc0481c4b0d9866ff526eb1161372b5919fUlrich Weigand      // Into:      MTCRF mask, %R3 ;; cr7
68633efedc0481c4b0d9866ff526eb1161372b5919fUlrich Weigand      unsigned NewOpcode =
68733efedc0481c4b0d9866ff526eb1161372b5919fUlrich Weigand        MI->getOpcode() == PPC::MTOCRF ? PPC::MTCRF : PPC::MTCRF8;
68833efedc0481c4b0d9866ff526eb1161372b5919fUlrich Weigand      unsigned Mask = 0x80 >> OutContext.getRegisterInfo()
68933efedc0481c4b0d9866ff526eb1161372b5919fUlrich Weigand                              ->getEncodingValue(MI->getOperand(0).getReg());
69033efedc0481c4b0d9866ff526eb1161372b5919fUlrich Weigand      OutStreamer.AddComment(PPCInstPrinter::
69133efedc0481c4b0d9866ff526eb1161372b5919fUlrich Weigand                             getRegisterName(MI->getOperand(0).getReg()));
69233efedc0481c4b0d9866ff526eb1161372b5919fUlrich Weigand      OutStreamer.EmitInstruction(MCInstBuilder(NewOpcode)
69333efedc0481c4b0d9866ff526eb1161372b5919fUlrich Weigand                                  .addImm(Mask)
69433efedc0481c4b0d9866ff526eb1161372b5919fUlrich Weigand                                  .addReg(MI->getOperand(1).getReg()));
69533efedc0481c4b0d9866ff526eb1161372b5919fUlrich Weigand      return;
69633efedc0481c4b0d9866ff526eb1161372b5919fUlrich Weigand    }
69733efedc0481c4b0d9866ff526eb1161372b5919fUlrich Weigand    break;
698c6d08f10bf797cc78068ef30bd0e8812a5bdc9a2Hal Finkel  case PPC::SYNC:
699c6d08f10bf797cc78068ef30bd0e8812a5bdc9a2Hal Finkel    // In Book E sync is called msync, handle this special case here...
700c6d08f10bf797cc78068ef30bd0e8812a5bdc9a2Hal Finkel    if (Subtarget.isBookE()) {
701c6d08f10bf797cc78068ef30bd0e8812a5bdc9a2Hal Finkel      OutStreamer.EmitRawText(StringRef("\tmsync"));
702c6d08f10bf797cc78068ef30bd0e8812a5bdc9a2Hal Finkel      return;
703c6d08f10bf797cc78068ef30bd0e8812a5bdc9a2Hal Finkel    }
704c38c1d135cb9d617254c396c22949baca024dd35Bill Schmidt    break;
705c38c1d135cb9d617254c396c22949baca024dd35Bill Schmidt  case PPC::LD:
706c38c1d135cb9d617254c396c22949baca024dd35Bill Schmidt  case PPC::STD:
707c38c1d135cb9d617254c396c22949baca024dd35Bill Schmidt  case PPC::LWA: {
708c38c1d135cb9d617254c396c22949baca024dd35Bill Schmidt    // Verify alignment is legal, so we don't create relocations
709c38c1d135cb9d617254c396c22949baca024dd35Bill Schmidt    // that can't be supported.
710c38c1d135cb9d617254c396c22949baca024dd35Bill Schmidt    // FIXME:  This test is currently disabled for Darwin.  The test
711c38c1d135cb9d617254c396c22949baca024dd35Bill Schmidt    // suite shows a handful of test cases that fail this check for
712c38c1d135cb9d617254c396c22949baca024dd35Bill Schmidt    // Darwin.  Those need to be investigated before this sanity test
713c38c1d135cb9d617254c396c22949baca024dd35Bill Schmidt    // can be enabled for those subtargets.
714c38c1d135cb9d617254c396c22949baca024dd35Bill Schmidt    if (!Subtarget.isDarwin()) {
715c38c1d135cb9d617254c396c22949baca024dd35Bill Schmidt      unsigned OpNum = (MI->getOpcode() == PPC::STD) ? 2 : 1;
716c38c1d135cb9d617254c396c22949baca024dd35Bill Schmidt      const MachineOperand &MO = MI->getOperand(OpNum);
717c38c1d135cb9d617254c396c22949baca024dd35Bill Schmidt      if (MO.isGlobal() && MO.getGlobal()->getAlignment() < 4)
718c38c1d135cb9d617254c396c22949baca024dd35Bill Schmidt        llvm_unreachable("Global must be word-aligned for LD, STD, LWA!");
719c38c1d135cb9d617254c396c22949baca024dd35Bill Schmidt    }
720c38c1d135cb9d617254c396c22949baca024dd35Bill Schmidt    // Now process the instruction normally.
721c38c1d135cb9d617254c396c22949baca024dd35Bill Schmidt    break;
722c38c1d135cb9d617254c396c22949baca024dd35Bill Schmidt  }
723d49fe1b6bc4615684c2ec71140a21e9c4cd69ce3Chris Lattner  }
724b5f662fa0314f7e7e690aae8ebff7136cc3a5ab0Misha Brukman
725a68f58ab2bec6a024afae498e4082ddd8b01f178Ulrich Weigand  LowerPPCMachineInstrToMCInst(MI, TmpInst, *this, Subtarget.isDarwin());
726cb22fa6536bd17e54a89dc82cafc9fdf48321c36Chris Lattner  OutStreamer.EmitInstruction(TmpInst);
727ed42853be1ef530890043da7c8966dc6678cf9bfNate Begeman}
728ed42853be1ef530890043da7c8966dc6678cf9bfNate Begeman
7292cf7251d39f28888af06b6f941eabd1d10995382Chris Lattnervoid PPCLinuxAsmPrinter::EmitFunctionEntryLabel() {
7302cf7251d39f28888af06b6f941eabd1d10995382Chris Lattner  if (!Subtarget.isPPC64())  // linux/ppc32 - Normal entry label.
7312cf7251d39f28888af06b6f941eabd1d10995382Chris Lattner    return AsmPrinter::EmitFunctionEntryLabel();
7322cf7251d39f28888af06b6f941eabd1d10995382Chris Lattner
7332cf7251d39f28888af06b6f941eabd1d10995382Chris Lattner  // Emit an official procedure descriptor.
734df39be6cb4eb44011db3d3e86f8fe463f81ce127Peter Collingbourne  MCSectionSubPair Current = OutStreamer.getCurrentSection();
7354328f9f1749698fcf7ec0339666f6129847d258bRoman Divacky  const MCSectionELF *Section = OutStreamer.getContext().getELFSection(".opd",
7364328f9f1749698fcf7ec0339666f6129847d258bRoman Divacky      ELF::SHT_PROGBITS, ELF::SHF_WRITE | ELF::SHF_ALLOC,
7374328f9f1749698fcf7ec0339666f6129847d258bRoman Divacky      SectionKind::getReadOnly());
7384328f9f1749698fcf7ec0339666f6129847d258bRoman Divacky  OutStreamer.SwitchSection(Section);
7392cf7251d39f28888af06b6f941eabd1d10995382Chris Lattner  OutStreamer.EmitLabel(CurrentFnSym);
7404328f9f1749698fcf7ec0339666f6129847d258bRoman Divacky  OutStreamer.EmitValueToAlignment(8);
7414328f9f1749698fcf7ec0339666f6129847d258bRoman Divacky  MCSymbol *Symbol1 =
7424328f9f1749698fcf7ec0339666f6129847d258bRoman Divacky    OutContext.GetOrCreateSymbol(".L." + Twine(CurrentFnSym->getName()));
743aa71428378c1cb491ca60041d8ba7aa110bc963dAdhemerval Zanella  // Generates a R_PPC64_ADDR64 (from FK_DATA_8) relocation for the function
744aa71428378c1cb491ca60041d8ba7aa110bc963dAdhemerval Zanella  // entry point.
7454328f9f1749698fcf7ec0339666f6129847d258bRoman Divacky  OutStreamer.EmitValue(MCSymbolRefExpr::Create(Symbol1, OutContext),
74668ca56285f9b6e82eb16ff8ea02a301f2c489faeEric Christopher			8 /*size*/);
747aa71428378c1cb491ca60041d8ba7aa110bc963dAdhemerval Zanella  MCSymbol *Symbol2 = OutContext.GetOrCreateSymbol(StringRef(".TOC."));
748aa71428378c1cb491ca60041d8ba7aa110bc963dAdhemerval Zanella  // Generates a R_PPC64_TOC relocation for TOC base insertion.
749aa71428378c1cb491ca60041d8ba7aa110bc963dAdhemerval Zanella  OutStreamer.EmitValue(MCSymbolRefExpr::Create(Symbol2,
750846565924a6f2932efc75c249b29c3619e587bbbUlrich Weigand                        MCSymbolRefExpr::VK_PPC_TOCBASE, OutContext),
75168ca56285f9b6e82eb16ff8ea02a301f2c489faeEric Christopher                        8/*size*/);
7524cd56014ae05a6ccc92cdcc66d457ce37558fc31Roman Divacky  // Emit a null environment pointer.
75368ca56285f9b6e82eb16ff8ea02a301f2c489faeEric Christopher  OutStreamer.EmitIntValue(0, 8 /* size */);
754df39be6cb4eb44011db3d3e86f8fe463f81ce127Peter Collingbourne  OutStreamer.SwitchSection(Current.first, Current.second);
755d55a2664f9493a4c3be242a75d339fac0ebe2e21Hal Finkel
756d55a2664f9493a4c3be242a75d339fac0ebe2e21Hal Finkel  MCSymbol *RealFnSym = OutContext.GetOrCreateSymbol(
757d55a2664f9493a4c3be242a75d339fac0ebe2e21Hal Finkel                          ".L." + Twine(CurrentFnSym->getName()));
758d55a2664f9493a4c3be242a75d339fac0ebe2e21Hal Finkel  OutStreamer.EmitLabel(RealFnSym);
759d55a2664f9493a4c3be242a75d339fac0ebe2e21Hal Finkel  CurrentFnSymForSize = RealFnSym;
7602cf7251d39f28888af06b6f941eabd1d10995382Chris Lattner}
7612cf7251d39f28888af06b6f941eabd1d10995382Chris Lattner
7622cf7251d39f28888af06b6f941eabd1d10995382Chris Lattner
7636b16eff207f99bbde3c0f7340452a5287218772cTilmann Schellerbool PPCLinuxAsmPrinter::doFinalization(Module &M) {
7643574eca1b02600bac4e625297f4ecf745f4c4f32Micah Villmow  const DataLayout *TD = TM.getDataLayout();
7656b16eff207f99bbde3c0f7340452a5287218772cTilmann Scheller
766426c2bf5cdd2173e4a33aea8cb92cf684a724f4bChandler Carruth  bool isPPC64 = TD->getPointerSizeInBits() == 64;
7676b16eff207f99bbde3c0f7340452a5287218772cTilmann Scheller
7686b16eff207f99bbde3c0f7340452a5287218772cTilmann Scheller  if (isPPC64 && !TOC.empty()) {
76921a1401413f074ffb216f74f94c5bc7a0e6cc1e1Roman Divacky    const MCSectionELF *Section = OutStreamer.getContext().getELFSection(".toc",
77021a1401413f074ffb216f74f94c5bc7a0e6cc1e1Roman Divacky        ELF::SHT_PROGBITS, ELF::SHF_WRITE | ELF::SHF_ALLOC,
77121a1401413f074ffb216f74f94c5bc7a0e6cc1e1Roman Divacky        SectionKind::getReadOnly());
77221a1401413f074ffb216f74f94c5bc7a0e6cc1e1Roman Divacky    OutStreamer.SwitchSection(Section);
7736b16eff207f99bbde3c0f7340452a5287218772cTilmann Scheller
77495d8afc5f2898b59240b0c0cd78d6f54140a91b8Ulrich Weigand    for (MapVector<MCSymbol*, MCSymbol*>::iterator I = TOC.begin(),
77575abc68d324158b72c58b5caf2224b1e35ac0c92Chris Lattner         E = TOC.end(); I != E; ++I) {
7769d7efd3081ef13b4d1ac7e0ad4854e92e5f132adChris Lattner      OutStreamer.EmitLabel(I->second);
777f35c62bf025411393c7df0803851010cc0e597baAdhemerval Zanella      MCSymbol *S = OutContext.GetOrCreateSymbol(I->first->getName());
778f35c62bf025411393c7df0803851010cc0e597baAdhemerval Zanella      OutStreamer.EmitTCEntry(*S);
7796b16eff207f99bbde3c0f7340452a5287218772cTilmann Scheller    }
7806b16eff207f99bbde3c0f7340452a5287218772cTilmann Scheller  }
7816b16eff207f99bbde3c0f7340452a5287218772cTilmann Scheller
782a1db5de9e70dd8ffda57b1a4373915ea866b6f1dAdhemerval Zanella  MachineModuleInfoELF &MMIELF =
783a1db5de9e70dd8ffda57b1a4373915ea866b6f1dAdhemerval Zanella    MMI->getObjFileInfo<MachineModuleInfoELF>();
784a1db5de9e70dd8ffda57b1a4373915ea866b6f1dAdhemerval Zanella
785a1db5de9e70dd8ffda57b1a4373915ea866b6f1dAdhemerval Zanella  MachineModuleInfoELF::SymbolListTy Stubs = MMIELF.GetGVStubList();
786a1db5de9e70dd8ffda57b1a4373915ea866b6f1dAdhemerval Zanella  if (!Stubs.empty()) {
787a1db5de9e70dd8ffda57b1a4373915ea866b6f1dAdhemerval Zanella    OutStreamer.SwitchSection(getObjFileLowering().getDataSection());
788a1db5de9e70dd8ffda57b1a4373915ea866b6f1dAdhemerval Zanella    for (unsigned i = 0, e = Stubs.size(); i != e; ++i) {
789a1db5de9e70dd8ffda57b1a4373915ea866b6f1dAdhemerval Zanella      // L_foo$stub:
790a1db5de9e70dd8ffda57b1a4373915ea866b6f1dAdhemerval Zanella      OutStreamer.EmitLabel(Stubs[i].first);
791a1db5de9e70dd8ffda57b1a4373915ea866b6f1dAdhemerval Zanella      //   .long _foo
792a1db5de9e70dd8ffda57b1a4373915ea866b6f1dAdhemerval Zanella      OutStreamer.EmitValue(MCSymbolRefExpr::Create(Stubs[i].second.getPointer(),
793a1db5de9e70dd8ffda57b1a4373915ea866b6f1dAdhemerval Zanella                                                    OutContext),
794a3863ea2dacafc925a8272ebf9884fc64bef686cRafael Espindola                            isPPC64 ? 8 : 4/*size*/);
795a1db5de9e70dd8ffda57b1a4373915ea866b6f1dAdhemerval Zanella    }
796a1db5de9e70dd8ffda57b1a4373915ea866b6f1dAdhemerval Zanella
797a1db5de9e70dd8ffda57b1a4373915ea866b6f1dAdhemerval Zanella    Stubs.clear();
798a1db5de9e70dd8ffda57b1a4373915ea866b6f1dAdhemerval Zanella    OutStreamer.AddBlankLine();
799a1db5de9e70dd8ffda57b1a4373915ea866b6f1dAdhemerval Zanella  }
800a1db5de9e70dd8ffda57b1a4373915ea866b6f1dAdhemerval Zanella
8016b16eff207f99bbde3c0f7340452a5287218772cTilmann Scheller  return AsmPrinter::doFinalization(M);
8026b16eff207f99bbde3c0f7340452a5287218772cTilmann Scheller}
803bf1118285c0f784b120a69b4a4207e15ef065eadJim Laskey
804c6c2ced38411215e5bf46ded787c23810160dfa7Roman Divacky/// EmitFunctionBodyEnd - Print the traceback table before the .size
805c6c2ced38411215e5bf46ded787c23810160dfa7Roman Divacky/// directive.
806c6c2ced38411215e5bf46ded787c23810160dfa7Roman Divacky///
807c6c2ced38411215e5bf46ded787c23810160dfa7Roman Divackyvoid PPCLinuxAsmPrinter::EmitFunctionBodyEnd() {
808c6c2ced38411215e5bf46ded787c23810160dfa7Roman Divacky  // Only the 64-bit target requires a traceback table.  For now,
809c6c2ced38411215e5bf46ded787c23810160dfa7Roman Divacky  // we only emit the word of zeroes that GDB requires to find
810bbd169b1d96e1012df9852d41b7fd00381ed9d48Hal Finkel  // the end of the function, and zeroes for the eight-byte
811bbd169b1d96e1012df9852d41b7fd00381ed9d48Hal Finkel  // mandatory fields.
812bbd169b1d96e1012df9852d41b7fd00381ed9d48Hal Finkel  // FIXME: We should fill in the eight-byte mandatory fields as described in
813bbd169b1d96e1012df9852d41b7fd00381ed9d48Hal Finkel  // the PPC64 ELF ABI (this is a low-priority item because GDB does not
814bbd169b1d96e1012df9852d41b7fd00381ed9d48Hal Finkel  // currently make use of these fields).
815bbd169b1d96e1012df9852d41b7fd00381ed9d48Hal Finkel  if (Subtarget.isPPC64()) {
816c6c2ced38411215e5bf46ded787c23810160dfa7Roman Divacky    OutStreamer.EmitIntValue(0, 4/*size*/);
817bbd169b1d96e1012df9852d41b7fd00381ed9d48Hal Finkel    OutStreamer.EmitIntValue(0, 8/*size*/);
818bbd169b1d96e1012df9852d41b7fd00381ed9d48Hal Finkel  }
819c6c2ced38411215e5bf46ded787c23810160dfa7Roman Divacky}
820c6c2ced38411215e5bf46ded787c23810160dfa7Roman Divacky
821812209a58c5520c604bc9279aa069e5ae066e860Bob Wilsonvoid PPCDarwinAsmPrinter::EmitStartOfAsmFile(Module &M) {
822cfbb2f074da2842e42956d3b4c21e91b37f36f06Dan Gohman  static const char *const CPUDirectives[] = {
823db01c8ba26f288636d3f574a96af3499ee6d2579Dale Johannesen    "",
824c35010d3a44397dd04ed3bff5287f9c718dacd4aJim Laskey    "ppc",
825c6d08f10bf797cc78068ef30bd0e8812a5bdc9a2Hal Finkel    "ppc440",
826c35010d3a44397dd04ed3bff5287f9c718dacd4aJim Laskey    "ppc601",
827c35010d3a44397dd04ed3bff5287f9c718dacd4aJim Laskey    "ppc602",
828c35010d3a44397dd04ed3bff5287f9c718dacd4aJim Laskey    "ppc603",
829c35010d3a44397dd04ed3bff5287f9c718dacd4aJim Laskey    "ppc7400",
830c35010d3a44397dd04ed3bff5287f9c718dacd4aJim Laskey    "ppc750",
831c35010d3a44397dd04ed3bff5287f9c718dacd4aJim Laskey    "ppc970",
8324d989ac93ce608057fb6b13a4068264ab037ecd5Hal Finkel    "ppcA2",
833621b77ade2ff46d1d8594bddee6931b2f4a14706Hal Finkel    "ppce500mc",
834621b77ade2ff46d1d8594bddee6931b2f4a14706Hal Finkel    "ppce5500",
835b516e9b64850e0e1a50f680fd1443ac12e56557bNAKAMURA Takumi    "power3",
836b516e9b64850e0e1a50f680fd1443ac12e56557bNAKAMURA Takumi    "power4",
837b516e9b64850e0e1a50f680fd1443ac12e56557bNAKAMURA Takumi    "power5",
838b516e9b64850e0e1a50f680fd1443ac12e56557bNAKAMURA Takumi    "power5x",
839622382fc5effb34ccad6e029c9612c598a3dc050Hal Finkel    "power6",
840b516e9b64850e0e1a50f680fd1443ac12e56557bNAKAMURA Takumi    "power6x",
841622382fc5effb34ccad6e029c9612c598a3dc050Hal Finkel    "power7",
842f38cc38fa647d4e72c053c39bbe0cdec1342535fBill Schmidt    "ppc64",
843f38cc38fa647d4e72c053c39bbe0cdec1342535fBill Schmidt    "ppc64le"
844c35010d3a44397dd04ed3bff5287f9c718dacd4aJim Laskey  };
845c35010d3a44397dd04ed3bff5287f9c718dacd4aJim Laskey
846c35010d3a44397dd04ed3bff5287f9c718dacd4aJim Laskey  unsigned Directive = Subtarget.getDarwinDirective();
847bd5cafd9bbba2180e7179436fb29071201d5ea9fHal Finkel  if (Subtarget.hasMFOCRF() && Directive < PPC::DIR_970)
848c35010d3a44397dd04ed3bff5287f9c718dacd4aJim Laskey    Directive = PPC::DIR_970;
849c35010d3a44397dd04ed3bff5287f9c718dacd4aJim Laskey  if (Subtarget.hasAltivec() && Directive < PPC::DIR_7400)
850c35010d3a44397dd04ed3bff5287f9c718dacd4aJim Laskey    Directive = PPC::DIR_7400;
85132e698cc104f4716dabddeae15133ba1b25969a1Eli Friedman  if (Subtarget.isPPC64() && Directive < PPC::DIR_64)
852c35010d3a44397dd04ed3bff5287f9c718dacd4aJim Laskey    Directive = PPC::DIR_64;
853c35010d3a44397dd04ed3bff5287f9c718dacd4aJim Laskey  assert(Directive <= PPC::DIR_64 && "Directive out of range.");
854b46443a686c29a1aa8f881c48c35d3f61a35f7acChris Lattner
855b46443a686c29a1aa8f881c48c35d3f61a35f7acChris Lattner  // FIXME: This is a total hack, finish mc'izing the PPC backend.
85687b1a453f08fd0d56a074d2d665f779232a6cac0NAKAMURA Takumi  if (OutStreamer.hasRawTextSupport()) {
857b9df53a40b22c74ce3f3a7b4a7c0676a38cf5e73Craig Topper    assert(Directive < array_lengthof(CPUDirectives) &&
85887b1a453f08fd0d56a074d2d665f779232a6cac0NAKAMURA Takumi           "CPUDirectives[] might not be up-to-date!");
859b46443a686c29a1aa8f881c48c35d3f61a35f7acChris Lattner    OutStreamer.EmitRawText("\t.machine " + Twine(CPUDirectives[Directive]));
86087b1a453f08fd0d56a074d2d665f779232a6cac0NAKAMURA Takumi  }
86134da127be57c4d153f3ceae7a04b31aec373641fAnton Korobeynikov
8622ada08536e30dbcbea21addc814f3bf8a394a4eeJim Laskey  // Prime text sections so they are adjacent.  This reduces the likelihood a
8632ada08536e30dbcbea21addc814f3bf8a394a4eeJim Laskey  // large data or debug section causes a branch to exceed 16M limit.
8640d805c33d134d88169e3dc4a3272cff9a5713ce7Dan Gohman  const TargetLoweringObjectFileMachO &TLOFMacho =
8650d805c33d134d88169e3dc4a3272cff9a5713ce7Dan Gohman    static_cast<const TargetLoweringObjectFileMachO &>(getObjFileLowering());
8666c2f9e14fdf14d8c1c687c6bd9918183fa7f8a7fChris Lattner  OutStreamer.SwitchSection(TLOFMacho.getTextCoalSection());
8672ada08536e30dbcbea21addc814f3bf8a394a4eeJim Laskey  if (TM.getRelocationModel() == Reloc::PIC_) {
8686c2f9e14fdf14d8c1c687c6bd9918183fa7f8a7fChris Lattner    OutStreamer.SwitchSection(
86922772214de79aa1c5ca38c4fb1da137d8fb30a05Chris Lattner           OutContext.getMachOSection("__TEXT", "__picsymbolstub1",
8706c2f9e14fdf14d8c1c687c6bd9918183fa7f8a7fChris Lattner                                      MCSectionMachO::S_SYMBOL_STUBS |
8716c2f9e14fdf14d8c1c687c6bd9918183fa7f8a7fChris Lattner                                      MCSectionMachO::S_ATTR_PURE_INSTRUCTIONS,
8726c2f9e14fdf14d8c1c687c6bd9918183fa7f8a7fChris Lattner                                      32, SectionKind::getText()));
8732ada08536e30dbcbea21addc814f3bf8a394a4eeJim Laskey  } else if (TM.getRelocationModel() == Reloc::DynamicNoPIC) {
8746c2f9e14fdf14d8c1c687c6bd9918183fa7f8a7fChris Lattner    OutStreamer.SwitchSection(
87522772214de79aa1c5ca38c4fb1da137d8fb30a05Chris Lattner           OutContext.getMachOSection("__TEXT","__symbol_stub1",
8766c2f9e14fdf14d8c1c687c6bd9918183fa7f8a7fChris Lattner                                      MCSectionMachO::S_SYMBOL_STUBS |
8776c2f9e14fdf14d8c1c687c6bd9918183fa7f8a7fChris Lattner                                      MCSectionMachO::S_ATTR_PURE_INSTRUCTIONS,
8786c2f9e14fdf14d8c1c687c6bd9918183fa7f8a7fChris Lattner                                      16, SectionKind::getText()));
8792ada08536e30dbcbea21addc814f3bf8a394a4eeJim Laskey  }
8806c2f9e14fdf14d8c1c687c6bd9918183fa7f8a7fChris Lattner  OutStreamer.SwitchSection(getObjFileLowering().getTextSection());
88118ed029a7b75b2a39d39cd4c7f2ec68284c10102Nate Begeman}
88218ed029a7b75b2a39d39cd4c7f2ec68284c10102Nate Begeman
8832dc6fa67ee80c0e948437ec20df1ca6cf5e1c713Chris Lattnerstatic MCSymbol *GetLazyPtr(MCSymbol *Sym, MCContext &Ctx) {
88473a1aa0966af7605b5a15585b1b88ffc7dbd3e3eChris Lattner  // Remove $stub suffix, add $lazy_ptr.
8858f2dce0cda89a18c65735a62b2059a6d22d9ffd8Benjamin Kramer  StringRef NoStub = Sym->getName().substr(0, Sym->getName().size()-5);
8868f2dce0cda89a18c65735a62b2059a6d22d9ffd8Benjamin Kramer  return Ctx.GetOrCreateSymbol(NoStub + "$lazy_ptr");
88773a1aa0966af7605b5a15585b1b88ffc7dbd3e3eChris Lattner}
88873a1aa0966af7605b5a15585b1b88ffc7dbd3e3eChris Lattner
8892dc6fa67ee80c0e948437ec20df1ca6cf5e1c713Chris Lattnerstatic MCSymbol *GetAnonSym(MCSymbol *Sym, MCContext &Ctx) {
89073a1aa0966af7605b5a15585b1b88ffc7dbd3e3eChris Lattner  // Add $tmp suffix to $stub, yielding $stub$tmp.
8918f2dce0cda89a18c65735a62b2059a6d22d9ffd8Benjamin Kramer  return Ctx.GetOrCreateSymbol(Sym->getName() + "$tmp");
89273a1aa0966af7605b5a15585b1b88ffc7dbd3e3eChris Lattner}
89373a1aa0966af7605b5a15585b1b88ffc7dbd3e3eChris Lattner
89473a1aa0966af7605b5a15585b1b88ffc7dbd3e3eChris Lattnervoid PPCDarwinAsmPrinter::
89573a1aa0966af7605b5a15585b1b88ffc7dbd3e3eChris LattnerEmitFunctionStubs(const MachineModuleInfoMachO::SymbolListTy &Stubs) {
896426c2bf5cdd2173e4a33aea8cb92cf684a724f4bChandler Carruth  bool isPPC64 = TM.getDataLayout()->getPointerSizeInBits() == 64;
897a68f58ab2bec6a024afae498e4082ddd8b01f178Ulrich Weigand  bool isDarwin = Subtarget.isDarwin();
898917d6282567e4d0bb0e0e4ef4b4cd153661fccfaChris Lattner
8990d805c33d134d88169e3dc4a3272cff9a5713ce7Dan Gohman  const TargetLoweringObjectFileMachO &TLOFMacho =
9000d805c33d134d88169e3dc4a3272cff9a5713ce7Dan Gohman    static_cast<const TargetLoweringObjectFileMachO &>(getObjFileLowering());
901917d6282567e4d0bb0e0e4ef4b4cd153661fccfaChris Lattner
902917d6282567e4d0bb0e0e4ef4b4cd153661fccfaChris Lattner  // .lazy_symbol_pointer
903917d6282567e4d0bb0e0e4ef4b4cd153661fccfaChris Lattner  const MCSection *LSPSection = TLOFMacho.getLazySymbolPointerSection();
904ff4bc460c52c1f285d8a56da173641bf92d49e3fChris Lattner
905da2b13f694b3866b7201b6ab9596981c9eaab983Misha Brukman  // Output stubs for dynamically-linked functions
906917d6282567e4d0bb0e0e4ef4b4cd153661fccfaChris Lattner  if (TM.getRelocationModel() == Reloc::PIC_) {
9072dfddee396d4e65c5458bcec8513a20336fbc5b4Chris Lattner    const MCSection *StubSection =
90822772214de79aa1c5ca38c4fb1da137d8fb30a05Chris Lattner    OutContext.getMachOSection("__TEXT", "__picsymbolstub1",
90922772214de79aa1c5ca38c4fb1da137d8fb30a05Chris Lattner                               MCSectionMachO::S_SYMBOL_STUBS |
91022772214de79aa1c5ca38c4fb1da137d8fb30a05Chris Lattner                               MCSectionMachO::S_ATTR_PURE_INSTRUCTIONS,
91122772214de79aa1c5ca38c4fb1da137d8fb30a05Chris Lattner                               32, SectionKind::getText());
91273a1aa0966af7605b5a15585b1b88ffc7dbd3e3eChris Lattner    for (unsigned i = 0, e = Stubs.size(); i != e; ++i) {
9136c2f9e14fdf14d8c1c687c6bd9918183fa7f8a7fChris Lattner      OutStreamer.SwitchSection(StubSection);
9147e097e463314baa3c964a977408aa51ecabe7796Chris Lattner      EmitAlignment(4);
91573a1aa0966af7605b5a15585b1b88ffc7dbd3e3eChris Lattner
9169d7efd3081ef13b4d1ac7e0ad4854e92e5f132adChris Lattner      MCSymbol *Stub = Stubs[i].first;
9172dc6fa67ee80c0e948437ec20df1ca6cf5e1c713Chris Lattner      MCSymbol *RawSym = Stubs[i].second.getPointer();
9182dc6fa67ee80c0e948437ec20df1ca6cf5e1c713Chris Lattner      MCSymbol *LazyPtr = GetLazyPtr(Stub, OutContext);
9192dc6fa67ee80c0e948437ec20df1ca6cf5e1c713Chris Lattner      MCSymbol *AnonSymbol = GetAnonSym(Stub, OutContext);
92073a1aa0966af7605b5a15585b1b88ffc7dbd3e3eChris Lattner
9219d7efd3081ef13b4d1ac7e0ad4854e92e5f132adChris Lattner      OutStreamer.EmitLabel(Stub);
9222dc6fa67ee80c0e948437ec20df1ca6cf5e1c713Chris Lattner      OutStreamer.EmitSymbolAttribute(RawSym, MCSA_IndirectSymbol);
923915558e77559bf76c57031729d244d319fdce3e6Benjamin Kramer
9247d35f74a5d5fafc66eafd945273153bf060a8bf4Hal Finkel      const MCExpr *Anon = MCSymbolRefExpr::Create(AnonSymbol, OutContext);
925edaa58ee66699b99841ee5dfdd485aedbae3bf90Ulrich Weigand      const MCExpr *LazyPtrExpr = MCSymbolRefExpr::Create(LazyPtr, OutContext);
926edaa58ee66699b99841ee5dfdd485aedbae3bf90Ulrich Weigand      const MCExpr *Sub =
927edaa58ee66699b99841ee5dfdd485aedbae3bf90Ulrich Weigand        MCBinaryExpr::CreateSub(LazyPtrExpr, Anon, OutContext);
9287d35f74a5d5fafc66eafd945273153bf060a8bf4Hal Finkel
929915558e77559bf76c57031729d244d319fdce3e6Benjamin Kramer      // mflr r0
930ed9e442cf098663ce213cb16778b44be466b441fBenjamin Kramer      OutStreamer.EmitInstruction(MCInstBuilder(PPC::MFLR).addReg(PPC::R0));
9317d35f74a5d5fafc66eafd945273153bf060a8bf4Hal Finkel      // bcl 20, 31, AnonSymbol
932caeeb1865043d5410b5b0356694fb1228a18ec78Hal Finkel      OutStreamer.EmitInstruction(MCInstBuilder(PPC::BCLalways).addExpr(Anon));
9332dc6fa67ee80c0e948437ec20df1ca6cf5e1c713Chris Lattner      OutStreamer.EmitLabel(AnonSymbol);
934915558e77559bf76c57031729d244d319fdce3e6Benjamin Kramer      // mflr r11
935ed9e442cf098663ce213cb16778b44be466b441fBenjamin Kramer      OutStreamer.EmitInstruction(MCInstBuilder(PPC::MFLR).addReg(PPC::R11));
936915558e77559bf76c57031729d244d319fdce3e6Benjamin Kramer      // addis r11, r11, ha16(LazyPtr - AnonSymbol)
937a68f58ab2bec6a024afae498e4082ddd8b01f178Ulrich Weigand      const MCExpr *SubHa16 = PPCMCExpr::CreateHa(Sub, isDarwin, OutContext);
938ed9e442cf098663ce213cb16778b44be466b441fBenjamin Kramer      OutStreamer.EmitInstruction(MCInstBuilder(PPC::ADDIS)
939391271f3bbcec02e0da26d7c246bfabff5cb4ddfBenjamin Kramer        .addReg(PPC::R11)
940391271f3bbcec02e0da26d7c246bfabff5cb4ddfBenjamin Kramer        .addReg(PPC::R11)
941edaa58ee66699b99841ee5dfdd485aedbae3bf90Ulrich Weigand        .addExpr(SubHa16));
942915558e77559bf76c57031729d244d319fdce3e6Benjamin Kramer      // mtlr r0
943ed9e442cf098663ce213cb16778b44be466b441fBenjamin Kramer      OutStreamer.EmitInstruction(MCInstBuilder(PPC::MTLR).addReg(PPC::R0));
944391271f3bbcec02e0da26d7c246bfabff5cb4ddfBenjamin Kramer
945391271f3bbcec02e0da26d7c246bfabff5cb4ddfBenjamin Kramer      // ldu r12, lo16(LazyPtr - AnonSymbol)(r11)
946391271f3bbcec02e0da26d7c246bfabff5cb4ddfBenjamin Kramer      // lwzu r12, lo16(LazyPtr - AnonSymbol)(r11)
947a68f58ab2bec6a024afae498e4082ddd8b01f178Ulrich Weigand      const MCExpr *SubLo16 = PPCMCExpr::CreateLo(Sub, isDarwin, OutContext);
948ed9e442cf098663ce213cb16778b44be466b441fBenjamin Kramer      OutStreamer.EmitInstruction(MCInstBuilder(isPPC64 ? PPC::LDU : PPC::LWZU)
949391271f3bbcec02e0da26d7c246bfabff5cb4ddfBenjamin Kramer        .addReg(PPC::R12)
950edaa58ee66699b99841ee5dfdd485aedbae3bf90Ulrich Weigand        .addExpr(SubLo16).addExpr(SubLo16)
951ed9e442cf098663ce213cb16778b44be466b441fBenjamin Kramer        .addReg(PPC::R11));
952915558e77559bf76c57031729d244d319fdce3e6Benjamin Kramer      // mtctr r12
953ed9e442cf098663ce213cb16778b44be466b441fBenjamin Kramer      OutStreamer.EmitInstruction(MCInstBuilder(PPC::MTCTR).addReg(PPC::R12));
954915558e77559bf76c57031729d244d319fdce3e6Benjamin Kramer      // bctr
955ed9e442cf098663ce213cb16778b44be466b441fBenjamin Kramer      OutStreamer.EmitInstruction(MCInstBuilder(PPC::BCTR));
956915558e77559bf76c57031729d244d319fdce3e6Benjamin Kramer
9576c2f9e14fdf14d8c1c687c6bd9918183fa7f8a7fChris Lattner      OutStreamer.SwitchSection(LSPSection);
9582dc6fa67ee80c0e948437ec20df1ca6cf5e1c713Chris Lattner      OutStreamer.EmitLabel(LazyPtr);
9592dc6fa67ee80c0e948437ec20df1ca6cf5e1c713Chris Lattner      OutStreamer.EmitSymbolAttribute(RawSym, MCSA_IndirectSymbol);
960915558e77559bf76c57031729d244d319fdce3e6Benjamin Kramer
961915558e77559bf76c57031729d244d319fdce3e6Benjamin Kramer      MCSymbol *DyldStubBindingHelper =
962915558e77559bf76c57031729d244d319fdce3e6Benjamin Kramer        OutContext.GetOrCreateSymbol(StringRef("dyld_stub_binding_helper"));
963915558e77559bf76c57031729d244d319fdce3e6Benjamin Kramer      if (isPPC64) {
964915558e77559bf76c57031729d244d319fdce3e6Benjamin Kramer        // .quad dyld_stub_binding_helper
965915558e77559bf76c57031729d244d319fdce3e6Benjamin Kramer        OutStreamer.EmitSymbolValue(DyldStubBindingHelper, 8);
966915558e77559bf76c57031729d244d319fdce3e6Benjamin Kramer      } else {
967915558e77559bf76c57031729d244d319fdce3e6Benjamin Kramer        // .long dyld_stub_binding_helper
968915558e77559bf76c57031729d244d319fdce3e6Benjamin Kramer        OutStreamer.EmitSymbolValue(DyldStubBindingHelper, 4);
969915558e77559bf76c57031729d244d319fdce3e6Benjamin Kramer      }
970deea416570f31a82081f1bbbc65f0c06d44462bfChris Lattner    }
9719d7efd3081ef13b4d1ac7e0ad4854e92e5f132adChris Lattner    OutStreamer.AddBlankLine();
972917d6282567e4d0bb0e0e4ef4b4cd153661fccfaChris Lattner    return;
97346fd00aec6a674003a565c60ae2894966ccb9a36Misha Brukman  }
974917d6282567e4d0bb0e0e4ef4b4cd153661fccfaChris Lattner
975917d6282567e4d0bb0e0e4ef4b4cd153661fccfaChris Lattner  const MCSection *StubSection =
97622772214de79aa1c5ca38c4fb1da137d8fb30a05Chris Lattner    OutContext.getMachOSection("__TEXT","__symbol_stub1",
97722772214de79aa1c5ca38c4fb1da137d8fb30a05Chris Lattner                               MCSectionMachO::S_SYMBOL_STUBS |
97822772214de79aa1c5ca38c4fb1da137d8fb30a05Chris Lattner                               MCSectionMachO::S_ATTR_PURE_INSTRUCTIONS,
97922772214de79aa1c5ca38c4fb1da137d8fb30a05Chris Lattner                               16, SectionKind::getText());
98073a1aa0966af7605b5a15585b1b88ffc7dbd3e3eChris Lattner  for (unsigned i = 0, e = Stubs.size(); i != e; ++i) {
9819d7efd3081ef13b4d1ac7e0ad4854e92e5f132adChris Lattner    MCSymbol *Stub = Stubs[i].first;
9822dc6fa67ee80c0e948437ec20df1ca6cf5e1c713Chris Lattner    MCSymbol *RawSym = Stubs[i].second.getPointer();
9832dc6fa67ee80c0e948437ec20df1ca6cf5e1c713Chris Lattner    MCSymbol *LazyPtr = GetLazyPtr(Stub, OutContext);
984edaa58ee66699b99841ee5dfdd485aedbae3bf90Ulrich Weigand    const MCExpr *LazyPtrExpr = MCSymbolRefExpr::Create(LazyPtr, OutContext);
98573a1aa0966af7605b5a15585b1b88ffc7dbd3e3eChris Lattner
986917d6282567e4d0bb0e0e4ef4b4cd153661fccfaChris Lattner    OutStreamer.SwitchSection(StubSection);
987917d6282567e4d0bb0e0e4ef4b4cd153661fccfaChris Lattner    EmitAlignment(4);
9889d7efd3081ef13b4d1ac7e0ad4854e92e5f132adChris Lattner    OutStreamer.EmitLabel(Stub);
9892dc6fa67ee80c0e948437ec20df1ca6cf5e1c713Chris Lattner    OutStreamer.EmitSymbolAttribute(RawSym, MCSA_IndirectSymbol);
990edaa58ee66699b99841ee5dfdd485aedbae3bf90Ulrich Weigand
991915558e77559bf76c57031729d244d319fdce3e6Benjamin Kramer    // lis r11, ha16(LazyPtr)
992a68f58ab2bec6a024afae498e4082ddd8b01f178Ulrich Weigand    const MCExpr *LazyPtrHa16 =
993a68f58ab2bec6a024afae498e4082ddd8b01f178Ulrich Weigand      PPCMCExpr::CreateHa(LazyPtrExpr, isDarwin, OutContext);
994ed9e442cf098663ce213cb16778b44be466b441fBenjamin Kramer    OutStreamer.EmitInstruction(MCInstBuilder(PPC::LIS)
995391271f3bbcec02e0da26d7c246bfabff5cb4ddfBenjamin Kramer      .addReg(PPC::R11)
996ed9e442cf098663ce213cb16778b44be466b441fBenjamin Kramer      .addExpr(LazyPtrHa16));
997391271f3bbcec02e0da26d7c246bfabff5cb4ddfBenjamin Kramer
998391271f3bbcec02e0da26d7c246bfabff5cb4ddfBenjamin Kramer    // ldu r12, lo16(LazyPtr)(r11)
999391271f3bbcec02e0da26d7c246bfabff5cb4ddfBenjamin Kramer    // lwzu r12, lo16(LazyPtr)(r11)
1000a68f58ab2bec6a024afae498e4082ddd8b01f178Ulrich Weigand    const MCExpr *LazyPtrLo16 =
1001a68f58ab2bec6a024afae498e4082ddd8b01f178Ulrich Weigand      PPCMCExpr::CreateLo(LazyPtrExpr, isDarwin, OutContext);
1002ed9e442cf098663ce213cb16778b44be466b441fBenjamin Kramer    OutStreamer.EmitInstruction(MCInstBuilder(isPPC64 ? PPC::LDU : PPC::LWZU)
1003391271f3bbcec02e0da26d7c246bfabff5cb4ddfBenjamin Kramer      .addReg(PPC::R12)
1004391271f3bbcec02e0da26d7c246bfabff5cb4ddfBenjamin Kramer      .addExpr(LazyPtrLo16).addExpr(LazyPtrLo16)
1005ed9e442cf098663ce213cb16778b44be466b441fBenjamin Kramer      .addReg(PPC::R11));
1006391271f3bbcec02e0da26d7c246bfabff5cb4ddfBenjamin Kramer
1007915558e77559bf76c57031729d244d319fdce3e6Benjamin Kramer    // mtctr r12
1008ed9e442cf098663ce213cb16778b44be466b441fBenjamin Kramer    OutStreamer.EmitInstruction(MCInstBuilder(PPC::MTCTR).addReg(PPC::R12));
1009915558e77559bf76c57031729d244d319fdce3e6Benjamin Kramer    // bctr
1010ed9e442cf098663ce213cb16778b44be466b441fBenjamin Kramer    OutStreamer.EmitInstruction(MCInstBuilder(PPC::BCTR));
1011391271f3bbcec02e0da26d7c246bfabff5cb4ddfBenjamin Kramer
1012917d6282567e4d0bb0e0e4ef4b4cd153661fccfaChris Lattner    OutStreamer.SwitchSection(LSPSection);
10132dc6fa67ee80c0e948437ec20df1ca6cf5e1c713Chris Lattner    OutStreamer.EmitLabel(LazyPtr);
10142dc6fa67ee80c0e948437ec20df1ca6cf5e1c713Chris Lattner    OutStreamer.EmitSymbolAttribute(RawSym, MCSA_IndirectSymbol);
1015915558e77559bf76c57031729d244d319fdce3e6Benjamin Kramer
1016915558e77559bf76c57031729d244d319fdce3e6Benjamin Kramer    MCSymbol *DyldStubBindingHelper =
1017915558e77559bf76c57031729d244d319fdce3e6Benjamin Kramer      OutContext.GetOrCreateSymbol(StringRef("dyld_stub_binding_helper"));
1018915558e77559bf76c57031729d244d319fdce3e6Benjamin Kramer    if (isPPC64) {
1019915558e77559bf76c57031729d244d319fdce3e6Benjamin Kramer      // .quad dyld_stub_binding_helper
1020915558e77559bf76c57031729d244d319fdce3e6Benjamin Kramer      OutStreamer.EmitSymbolValue(DyldStubBindingHelper, 8);
1021915558e77559bf76c57031729d244d319fdce3e6Benjamin Kramer    } else {
1022915558e77559bf76c57031729d244d319fdce3e6Benjamin Kramer      // .long dyld_stub_binding_helper
1023915558e77559bf76c57031729d244d319fdce3e6Benjamin Kramer      OutStreamer.EmitSymbolValue(DyldStubBindingHelper, 4);
1024915558e77559bf76c57031729d244d319fdce3e6Benjamin Kramer    }
1025917d6282567e4d0bb0e0e4ef4b4cd153661fccfaChris Lattner  }
1026917d6282567e4d0bb0e0e4ef4b4cd153661fccfaChris Lattner
10272dc6fa67ee80c0e948437ec20df1ca6cf5e1c713Chris Lattner  OutStreamer.AddBlankLine();
1028917d6282567e4d0bb0e0e4ef4b4cd153661fccfaChris Lattner}
1029917d6282567e4d0bb0e0e4ef4b4cd153661fccfaChris Lattner
1030917d6282567e4d0bb0e0e4ef4b4cd153661fccfaChris Lattner
1031917d6282567e4d0bb0e0e4ef4b4cd153661fccfaChris Lattnerbool PPCDarwinAsmPrinter::doFinalization(Module &M) {
1032426c2bf5cdd2173e4a33aea8cb92cf684a724f4bChandler Carruth  bool isPPC64 = TM.getDataLayout()->getPointerSizeInBits() == 64;
1033917d6282567e4d0bb0e0e4ef4b4cd153661fccfaChris Lattner
1034917d6282567e4d0bb0e0e4ef4b4cd153661fccfaChris Lattner  // Darwin/PPC always uses mach-o.
10350d805c33d134d88169e3dc4a3272cff9a5713ce7Dan Gohman  const TargetLoweringObjectFileMachO &TLOFMacho =
10360d805c33d134d88169e3dc4a3272cff9a5713ce7Dan Gohman    static_cast<const TargetLoweringObjectFileMachO &>(getObjFileLowering());
1037917d6282567e4d0bb0e0e4ef4b4cd153661fccfaChris Lattner  MachineModuleInfoMachO &MMIMacho =
1038917d6282567e4d0bb0e0e4ef4b4cd153661fccfaChris Lattner    MMI->getObjFileInfo<MachineModuleInfoMachO>();
1039917d6282567e4d0bb0e0e4ef4b4cd153661fccfaChris Lattner
104073a1aa0966af7605b5a15585b1b88ffc7dbd3e3eChris Lattner  MachineModuleInfoMachO::SymbolListTy Stubs = MMIMacho.GetFnStubList();
104173a1aa0966af7605b5a15585b1b88ffc7dbd3e3eChris Lattner  if (!Stubs.empty())
104273a1aa0966af7605b5a15585b1b88ffc7dbd3e3eChris Lattner    EmitFunctionStubs(Stubs);
1043da2b13f694b3866b7201b6ab9596981c9eaab983Misha Brukman
104433adcfb4d217f5f23d9bde8ba02b8e48f9605fc5Chris Lattner  if (MAI->doesSupportExceptionHandling() && MMI) {
10451d4ce2ab962fee691239d58c8157c12b8037f9deDale Johannesen    // Add the (possibly multiple) personalities to the set of global values.
10461532f3ddd77c362dd5f613af06b4de636e3c5b0eDale Johannesen    // Only referenced functions get into the Personalities list.
104746510a73e977273ec67747eb34cbdb43f815e451Dan Gohman    const std::vector<const Function*> &Personalities = MMI->getPersonalities();
104846510a73e977273ec67747eb34cbdb43f815e451Dan Gohman    for (std::vector<const Function*>::const_iterator I = Personalities.begin(),
10498f831cbf0d9d1eb7de08d50b5d55ef84fdacba2eChris Lattner         E = Personalities.end(); I != E; ++I) {
1050d3ec0b5446441f39988db4107cd37f6e7349f399Chris Lattner      if (*I) {
1051d269a6e460a71a6c5c361a26c56c91fdb9486f45Chris Lattner        MCSymbol *NLPSym = GetSymbolWithGlobalValueBase(*I, "$non_lazy_ptr");
1052cebae36f57456fe6b0e13726acd1e0250654f02dBill Wendling        MachineModuleInfoImpl::StubValueTy &StubSym =
1053cebae36f57456fe6b0e13726acd1e0250654f02dBill Wendling          MMIMacho.getGVStubEntry(NLPSym);
1054d62f1b4168d4327c119642d28c26c836ae6717abChris Lattner        StubSym = MachineModuleInfoImpl::StubValueTy(Mang->getSymbol(*I), true);
1055d3ec0b5446441f39988db4107cd37f6e7349f399Chris Lattner      }
10568f831cbf0d9d1eb7de08d50b5d55ef84fdacba2eChris Lattner    }
10571d4ce2ab962fee691239d58c8157c12b8037f9deDale Johannesen  }
10581d4ce2ab962fee691239d58c8157c12b8037f9deDale Johannesen
1059d3ec0b5446441f39988db4107cd37f6e7349f399Chris Lattner  // Output stubs for dynamically-linked functions.
106073a1aa0966af7605b5a15585b1b88ffc7dbd3e3eChris Lattner  Stubs = MMIMacho.GetGVStubList();
1061d3ec0b5446441f39988db4107cd37f6e7349f399Chris Lattner
10622dfddee396d4e65c5458bcec8513a20336fbc5b4Chris Lattner  // Output macho stubs for external and common global variables.
1063d3ec0b5446441f39988db4107cd37f6e7349f399Chris Lattner  if (!Stubs.empty()) {
1064ff4bc460c52c1f285d8a56da173641bf92d49e3fChris Lattner    // Switch with ".non_lazy_symbol_pointer" directive.
10656c2f9e14fdf14d8c1c687c6bd9918183fa7f8a7fChris Lattner    OutStreamer.SwitchSection(TLOFMacho.getNonLazySymbolPointerSection());
1066e1e8a82986e12f9cf841004c78ff051df9df11d8Chris Lattner    EmitAlignment(isPPC64 ? 3 : 2);
1067e1e8a82986e12f9cf841004c78ff051df9df11d8Chris Lattner
1068d3ec0b5446441f39988db4107cd37f6e7349f399Chris Lattner    for (unsigned i = 0, e = Stubs.size(); i != e; ++i) {
106908d726c912f74d6ea61bea97e7719fc635927dbfBill Wendling      // L_foo$stub:
107008d726c912f74d6ea61bea97e7719fc635927dbfBill Wendling      OutStreamer.EmitLabel(Stubs[i].first);
107108d726c912f74d6ea61bea97e7719fc635927dbfBill Wendling      //   .indirect_symbol _foo
107208d726c912f74d6ea61bea97e7719fc635927dbfBill Wendling      MachineModuleInfoImpl::StubValueTy &MCSym = Stubs[i].second;
107308d726c912f74d6ea61bea97e7719fc635927dbfBill Wendling      OutStreamer.EmitSymbolAttribute(MCSym.getPointer(), MCSA_IndirectSymbol);
107453351a175df59c0f8b96011f30842d87046fc9d6Bill Wendling
107553351a175df59c0f8b96011f30842d87046fc9d6Bill Wendling      if (MCSym.getInt())
107653351a175df59c0f8b96011f30842d87046fc9d6Bill Wendling        // External to current translation unit.
107768ca56285f9b6e82eb16ff8ea02a301f2c489faeEric Christopher        OutStreamer.EmitIntValue(0, isPPC64 ? 8 : 4/*size*/);
107853351a175df59c0f8b96011f30842d87046fc9d6Bill Wendling      else
107953351a175df59c0f8b96011f30842d87046fc9d6Bill Wendling        // Internal to current translation unit.
10805e1b55d67288874f8669621b9176814ce449f8f5Bill Wendling        //
10815e1b55d67288874f8669621b9176814ce449f8f5Bill Wendling        // When we place the LSDA into the TEXT section, the type info pointers
10825e1b55d67288874f8669621b9176814ce449f8f5Bill Wendling        // need to be indirect and pc-rel. We accomplish this by using NLPs.
10835e1b55d67288874f8669621b9176814ce449f8f5Bill Wendling        // However, sometimes the types are local to the file. So we need to
10845e1b55d67288874f8669621b9176814ce449f8f5Bill Wendling        // fill in the value for the NLP in those cases.
108553351a175df59c0f8b96011f30842d87046fc9d6Bill Wendling        OutStreamer.EmitValue(MCSymbolRefExpr::Create(MCSym.getPointer(),
108653351a175df59c0f8b96011f30842d87046fc9d6Bill Wendling                                                      OutContext),
108768ca56285f9b6e82eb16ff8ea02a301f2c489faeEric Christopher                              isPPC64 ? 8 : 4/*size*/);
1088deea416570f31a82081f1bbbc65f0c06d44462bfChris Lattner    }
108908d726c912f74d6ea61bea97e7719fc635927dbfBill Wendling
109008d726c912f74d6ea61bea97e7719fc635927dbfBill Wendling    Stubs.clear();
109108d726c912f74d6ea61bea97e7719fc635927dbfBill Wendling    OutStreamer.AddBlankLine();
1092e59bf59ba55c6bdba82a7126e91f5bb53118e84cNate Begeman  }
1093b5f662fa0314f7e7e690aae8ebff7136cc3a5ab0Misha Brukman
1094d3ec0b5446441f39988db4107cd37f6e7349f399Chris Lattner  Stubs = MMIMacho.GetHiddenGVStubList();
1095d3ec0b5446441f39988db4107cd37f6e7349f399Chris Lattner  if (!Stubs.empty()) {
10966c2f9e14fdf14d8c1c687c6bd9918183fa7f8a7fChris Lattner    OutStreamer.SwitchSection(getObjFileLowering().getDataSection());
10978f831cbf0d9d1eb7de08d50b5d55ef84fdacba2eChris Lattner    EmitAlignment(isPPC64 ? 3 : 2);
1098d3ec0b5446441f39988db4107cd37f6e7349f399Chris Lattner
1099d3ec0b5446441f39988db4107cd37f6e7349f399Chris Lattner    for (unsigned i = 0, e = Stubs.size(); i != e; ++i) {
110008d726c912f74d6ea61bea97e7719fc635927dbfBill Wendling      // L_foo$stub:
110108d726c912f74d6ea61bea97e7719fc635927dbfBill Wendling      OutStreamer.EmitLabel(Stubs[i].first);
110208d726c912f74d6ea61bea97e7719fc635927dbfBill Wendling      //   .long _foo
110308d726c912f74d6ea61bea97e7719fc635927dbfBill Wendling      OutStreamer.EmitValue(MCSymbolRefExpr::
110408d726c912f74d6ea61bea97e7719fc635927dbfBill Wendling                            Create(Stubs[i].second.getPointer(),
110508d726c912f74d6ea61bea97e7719fc635927dbfBill Wendling                                   OutContext),
110668ca56285f9b6e82eb16ff8ea02a301f2c489faeEric Christopher                            isPPC64 ? 8 : 4/*size*/);
1107ae94e594164b193236002516970aeec4c4574768Evan Cheng    }
110808d726c912f74d6ea61bea97e7719fc635927dbfBill Wendling
110908d726c912f74d6ea61bea97e7719fc635927dbfBill Wendling    Stubs.clear();
111008d726c912f74d6ea61bea97e7719fc635927dbfBill Wendling    OutStreamer.AddBlankLine();
1111ae94e594164b193236002516970aeec4c4574768Evan Cheng  }
1112ae94e594164b193236002516970aeec4c4574768Evan Cheng
11135b0ac99c9690d7534ade82848c207e202883831bChris Lattner  // Funny Darwin hack: This flag tells the linker that no global symbols
11145b0ac99c9690d7534ade82848c207e202883831bChris Lattner  // contain code that falls through to other global symbols (e.g. the obvious
11155b0ac99c9690d7534ade82848c207e202883831bChris Lattner  // implementation of multiple entry points).  If this doesn't occur, the
11165b0ac99c9690d7534ade82848c207e202883831bChris Lattner  // linker can safely perform dead code stripping.  Since LLVM never generates
11175b0ac99c9690d7534ade82848c207e202883831bChris Lattner  // code that does this, it is always safe to set.
1118a5ad93a10a5435f21090b09edb6b3a7e44967648Chris Lattner  OutStreamer.EmitAssemblerFlag(MCAF_SubsectionsViaSymbols);
11195b0ac99c9690d7534ade82848c207e202883831bChris Lattner
1120b8275a3f6f6497889653cb2452d82a46f92b4926Dan Gohman  return AsmPrinter::doFinalization(M);
11215dfe3a9c3bd9091f9adecc909665d52bdd4edd8cMisha Brukman}
1122ed42853be1ef530890043da7c8966dc6678cf9bfNate Begeman
1123b608a4dd4c9f8693054362ab8156b6039ee07a88Jim Laskey/// createPPCAsmPrinterPass - Returns a pass that prints the PPC assembly code
1124b608a4dd4c9f8693054362ab8156b6039ee07a88Jim Laskey/// for a MachineFunction to the given output stream, in a format that the
11254da1c82f724adba2832f79b3b49fc96c1467076dChris Lattner/// Darwin assembler can deal with.
11264da1c82f724adba2832f79b3b49fc96c1467076dChris Lattner///
1127b23569aff0a6d2b231cb93cc4acd0ac060ba560fChris Lattnerstatic AsmPrinter *createPPCAsmPrinterPass(TargetMachine &tm,
112811d53c129fc9c2a4510605ec0a1696f58750af52Chris Lattner                                           MCStreamer &Streamer) {
1129bf1118285c0f784b120a69b4a4207e15ef065eadJim Laskey  const PPCSubtarget *Subtarget = &tm.getSubtarget<PPCSubtarget>();
1130bf1118285c0f784b120a69b4a4207e15ef065eadJim Laskey
113140bbebde9d250b875a47a688d0c6552834ada48fChris Lattner  if (Subtarget->isDarwin())
1132b23569aff0a6d2b231cb93cc4acd0ac060ba560fChris Lattner    return new PPCDarwinAsmPrinter(tm, Streamer);
1133b23569aff0a6d2b231cb93cc4acd0ac060ba560fChris Lattner  return new PPCLinuxAsmPrinter(tm, Streamer);
11344da1c82f724adba2832f79b3b49fc96c1467076dChris Lattner}
113506be997654120c92f99850bf1a1704a2042ef639Anton Korobeynikov
1136a96751fc8ff1cc9a225ffbba73de53e2b9e1ae35Bob Wilson// Force static initialization.
113751b198af83cb0080c2709b04c129a3d774c07765Daniel Dunbarextern "C" void LLVMInitializePowerPCAsmPrinter() {
113851b198af83cb0080c2709b04c129a3d774c07765Daniel Dunbar  TargetRegistry::RegisterAsmPrinter(ThePPC32Target, createPPCAsmPrinterPass);
113951b198af83cb0080c2709b04c129a3d774c07765Daniel Dunbar  TargetRegistry::RegisterAsmPrinter(ThePPC64Target, createPPCAsmPrinterPass);
114051b198af83cb0080c2709b04c129a3d774c07765Daniel Dunbar}
1141