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