1*09467b48Spatrick //===-- PPCAsmPrinter.cpp - Print machine instrs to PowerPC assembly ------===// 2*09467b48Spatrick // 3*09467b48Spatrick // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4*09467b48Spatrick // See https://llvm.org/LICENSE.txt for license information. 5*09467b48Spatrick // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6*09467b48Spatrick // 7*09467b48Spatrick //===----------------------------------------------------------------------===// 8*09467b48Spatrick // 9*09467b48Spatrick // This file contains a printer that converts from our internal representation 10*09467b48Spatrick // of machine-dependent LLVM code to PowerPC assembly language. This printer is 11*09467b48Spatrick // the output mechanism used by `llc'. 12*09467b48Spatrick // 13*09467b48Spatrick // Documentation at http://developer.apple.com/documentation/DeveloperTools/ 14*09467b48Spatrick // Reference/Assembler/ASMIntroduction/chapter_1_section_1.html 15*09467b48Spatrick // 16*09467b48Spatrick //===----------------------------------------------------------------------===// 17*09467b48Spatrick 18*09467b48Spatrick #include "MCTargetDesc/PPCInstPrinter.h" 19*09467b48Spatrick #include "MCTargetDesc/PPCMCExpr.h" 20*09467b48Spatrick #include "MCTargetDesc/PPCMCTargetDesc.h" 21*09467b48Spatrick #include "MCTargetDesc/PPCPredicates.h" 22*09467b48Spatrick #include "PPC.h" 23*09467b48Spatrick #include "PPCInstrInfo.h" 24*09467b48Spatrick #include "PPCMachineFunctionInfo.h" 25*09467b48Spatrick #include "PPCSubtarget.h" 26*09467b48Spatrick #include "PPCTargetMachine.h" 27*09467b48Spatrick #include "PPCTargetStreamer.h" 28*09467b48Spatrick #include "TargetInfo/PowerPCTargetInfo.h" 29*09467b48Spatrick #include "llvm/ADT/MapVector.h" 30*09467b48Spatrick #include "llvm/ADT/StringRef.h" 31*09467b48Spatrick #include "llvm/ADT/Triple.h" 32*09467b48Spatrick #include "llvm/ADT/Twine.h" 33*09467b48Spatrick #include "llvm/BinaryFormat/ELF.h" 34*09467b48Spatrick #include "llvm/BinaryFormat/MachO.h" 35*09467b48Spatrick #include "llvm/CodeGen/AsmPrinter.h" 36*09467b48Spatrick #include "llvm/CodeGen/MachineBasicBlock.h" 37*09467b48Spatrick #include "llvm/CodeGen/MachineFunction.h" 38*09467b48Spatrick #include "llvm/CodeGen/MachineInstr.h" 39*09467b48Spatrick #include "llvm/CodeGen/MachineModuleInfoImpls.h" 40*09467b48Spatrick #include "llvm/CodeGen/MachineOperand.h" 41*09467b48Spatrick #include "llvm/CodeGen/MachineRegisterInfo.h" 42*09467b48Spatrick #include "llvm/CodeGen/StackMaps.h" 43*09467b48Spatrick #include "llvm/CodeGen/TargetLoweringObjectFileImpl.h" 44*09467b48Spatrick #include "llvm/IR/DataLayout.h" 45*09467b48Spatrick #include "llvm/IR/GlobalValue.h" 46*09467b48Spatrick #include "llvm/IR/GlobalVariable.h" 47*09467b48Spatrick #include "llvm/IR/Module.h" 48*09467b48Spatrick #include "llvm/MC/MCAsmInfo.h" 49*09467b48Spatrick #include "llvm/MC/MCContext.h" 50*09467b48Spatrick #include "llvm/MC/MCExpr.h" 51*09467b48Spatrick #include "llvm/MC/MCInst.h" 52*09467b48Spatrick #include "llvm/MC/MCInstBuilder.h" 53*09467b48Spatrick #include "llvm/MC/MCSectionELF.h" 54*09467b48Spatrick #include "llvm/MC/MCSectionMachO.h" 55*09467b48Spatrick #include "llvm/MC/MCSectionXCOFF.h" 56*09467b48Spatrick #include "llvm/MC/MCStreamer.h" 57*09467b48Spatrick #include "llvm/MC/MCSymbol.h" 58*09467b48Spatrick #include "llvm/MC/MCSymbolELF.h" 59*09467b48Spatrick #include "llvm/MC/MCSymbolXCOFF.h" 60*09467b48Spatrick #include "llvm/MC/SectionKind.h" 61*09467b48Spatrick #include "llvm/Support/Casting.h" 62*09467b48Spatrick #include "llvm/Support/CodeGen.h" 63*09467b48Spatrick #include "llvm/Support/Debug.h" 64*09467b48Spatrick #include "llvm/Support/ErrorHandling.h" 65*09467b48Spatrick #include "llvm/Support/TargetRegistry.h" 66*09467b48Spatrick #include "llvm/Support/raw_ostream.h" 67*09467b48Spatrick #include "llvm/Target/TargetMachine.h" 68*09467b48Spatrick #include <algorithm> 69*09467b48Spatrick #include <cassert> 70*09467b48Spatrick #include <cstdint> 71*09467b48Spatrick #include <memory> 72*09467b48Spatrick #include <new> 73*09467b48Spatrick 74*09467b48Spatrick using namespace llvm; 75*09467b48Spatrick 76*09467b48Spatrick #define DEBUG_TYPE "asmprinter" 77*09467b48Spatrick 78*09467b48Spatrick namespace { 79*09467b48Spatrick 80*09467b48Spatrick class PPCAsmPrinter : public AsmPrinter { 81*09467b48Spatrick protected: 82*09467b48Spatrick MapVector<const MCSymbol *, MCSymbol *> TOC; 83*09467b48Spatrick const PPCSubtarget *Subtarget = nullptr; 84*09467b48Spatrick StackMaps SM; 85*09467b48Spatrick 86*09467b48Spatrick virtual MCSymbol *getMCSymbolForTOCPseudoMO(const MachineOperand &MO); 87*09467b48Spatrick 88*09467b48Spatrick public: 89*09467b48Spatrick explicit PPCAsmPrinter(TargetMachine &TM, 90*09467b48Spatrick std::unique_ptr<MCStreamer> Streamer) 91*09467b48Spatrick : AsmPrinter(TM, std::move(Streamer)), SM(*this) {} 92*09467b48Spatrick 93*09467b48Spatrick StringRef getPassName() const override { return "PowerPC Assembly Printer"; } 94*09467b48Spatrick 95*09467b48Spatrick MCSymbol *lookUpOrCreateTOCEntry(const MCSymbol *Sym); 96*09467b48Spatrick 97*09467b48Spatrick bool doInitialization(Module &M) override { 98*09467b48Spatrick if (!TOC.empty()) 99*09467b48Spatrick TOC.clear(); 100*09467b48Spatrick return AsmPrinter::doInitialization(M); 101*09467b48Spatrick } 102*09467b48Spatrick 103*09467b48Spatrick void EmitInstruction(const MachineInstr *MI) override; 104*09467b48Spatrick 105*09467b48Spatrick /// This function is for PrintAsmOperand and PrintAsmMemoryOperand, 106*09467b48Spatrick /// invoked by EmitMSInlineAsmStr and EmitGCCInlineAsmStr only. 107*09467b48Spatrick /// The \p MI would be INLINEASM ONLY. 108*09467b48Spatrick void printOperand(const MachineInstr *MI, unsigned OpNo, raw_ostream &O); 109*09467b48Spatrick 110*09467b48Spatrick void PrintSymbolOperand(const MachineOperand &MO, raw_ostream &O) override; 111*09467b48Spatrick bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNo, 112*09467b48Spatrick const char *ExtraCode, raw_ostream &O) override; 113*09467b48Spatrick bool PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNo, 114*09467b48Spatrick const char *ExtraCode, raw_ostream &O) override; 115*09467b48Spatrick 116*09467b48Spatrick void EmitEndOfAsmFile(Module &M) override; 117*09467b48Spatrick 118*09467b48Spatrick void LowerSTACKMAP(StackMaps &SM, const MachineInstr &MI); 119*09467b48Spatrick void LowerPATCHPOINT(StackMaps &SM, const MachineInstr &MI); 120*09467b48Spatrick void EmitTlsCall(const MachineInstr *MI, MCSymbolRefExpr::VariantKind VK); 121*09467b48Spatrick bool runOnMachineFunction(MachineFunction &MF) override { 122*09467b48Spatrick Subtarget = &MF.getSubtarget<PPCSubtarget>(); 123*09467b48Spatrick bool Changed = AsmPrinter::runOnMachineFunction(MF); 124*09467b48Spatrick emitXRayTable(); 125*09467b48Spatrick return Changed; 126*09467b48Spatrick } 127*09467b48Spatrick }; 128*09467b48Spatrick 129*09467b48Spatrick /// PPCLinuxAsmPrinter - PowerPC assembly printer, customized for Linux 130*09467b48Spatrick class PPCLinuxAsmPrinter : public PPCAsmPrinter { 131*09467b48Spatrick public: 132*09467b48Spatrick explicit PPCLinuxAsmPrinter(TargetMachine &TM, 133*09467b48Spatrick std::unique_ptr<MCStreamer> Streamer) 134*09467b48Spatrick : PPCAsmPrinter(TM, std::move(Streamer)) {} 135*09467b48Spatrick 136*09467b48Spatrick StringRef getPassName() const override { 137*09467b48Spatrick return "Linux PPC Assembly Printer"; 138*09467b48Spatrick } 139*09467b48Spatrick 140*09467b48Spatrick bool doFinalization(Module &M) override; 141*09467b48Spatrick void EmitStartOfAsmFile(Module &M) override; 142*09467b48Spatrick 143*09467b48Spatrick void EmitFunctionEntryLabel() override; 144*09467b48Spatrick 145*09467b48Spatrick void EmitFunctionBodyStart() override; 146*09467b48Spatrick void EmitFunctionBodyEnd() override; 147*09467b48Spatrick void EmitInstruction(const MachineInstr *MI) override; 148*09467b48Spatrick }; 149*09467b48Spatrick 150*09467b48Spatrick class PPCAIXAsmPrinter : public PPCAsmPrinter { 151*09467b48Spatrick private: 152*09467b48Spatrick static void ValidateGV(const GlobalVariable *GV); 153*09467b48Spatrick protected: 154*09467b48Spatrick MCSymbol *getMCSymbolForTOCPseudoMO(const MachineOperand &MO) override; 155*09467b48Spatrick 156*09467b48Spatrick public: 157*09467b48Spatrick PPCAIXAsmPrinter(TargetMachine &TM, std::unique_ptr<MCStreamer> Streamer) 158*09467b48Spatrick : PPCAsmPrinter(TM, std::move(Streamer)) {} 159*09467b48Spatrick 160*09467b48Spatrick StringRef getPassName() const override { return "AIX PPC Assembly Printer"; } 161*09467b48Spatrick 162*09467b48Spatrick void SetupMachineFunction(MachineFunction &MF) override; 163*09467b48Spatrick 164*09467b48Spatrick const MCExpr *lowerConstant(const Constant *CV) override; 165*09467b48Spatrick 166*09467b48Spatrick void EmitGlobalVariable(const GlobalVariable *GV) override; 167*09467b48Spatrick 168*09467b48Spatrick void EmitFunctionDescriptor() override; 169*09467b48Spatrick 170*09467b48Spatrick void EmitEndOfAsmFile(Module &) override; 171*09467b48Spatrick }; 172*09467b48Spatrick 173*09467b48Spatrick } // end anonymous namespace 174*09467b48Spatrick 175*09467b48Spatrick void PPCAsmPrinter::PrintSymbolOperand(const MachineOperand &MO, 176*09467b48Spatrick raw_ostream &O) { 177*09467b48Spatrick // Computing the address of a global symbol, not calling it. 178*09467b48Spatrick const GlobalValue *GV = MO.getGlobal(); 179*09467b48Spatrick MCSymbol *SymToPrint; 180*09467b48Spatrick 181*09467b48Spatrick // External or weakly linked global variables need non-lazily-resolved stubs 182*09467b48Spatrick if (Subtarget->hasLazyResolverStub(GV)) { 183*09467b48Spatrick SymToPrint = getSymbolWithGlobalValueBase(GV, "$non_lazy_ptr"); 184*09467b48Spatrick MachineModuleInfoImpl::StubValueTy &StubSym = 185*09467b48Spatrick MMI->getObjFileInfo<MachineModuleInfoMachO>().getGVStubEntry( 186*09467b48Spatrick SymToPrint); 187*09467b48Spatrick if (!StubSym.getPointer()) 188*09467b48Spatrick StubSym = MachineModuleInfoImpl::StubValueTy(getSymbol(GV), 189*09467b48Spatrick !GV->hasInternalLinkage()); 190*09467b48Spatrick } else { 191*09467b48Spatrick SymToPrint = getSymbol(GV); 192*09467b48Spatrick } 193*09467b48Spatrick 194*09467b48Spatrick SymToPrint->print(O, MAI); 195*09467b48Spatrick 196*09467b48Spatrick printOffset(MO.getOffset(), O); 197*09467b48Spatrick } 198*09467b48Spatrick 199*09467b48Spatrick void PPCAsmPrinter::printOperand(const MachineInstr *MI, unsigned OpNo, 200*09467b48Spatrick raw_ostream &O) { 201*09467b48Spatrick const DataLayout &DL = getDataLayout(); 202*09467b48Spatrick const MachineOperand &MO = MI->getOperand(OpNo); 203*09467b48Spatrick 204*09467b48Spatrick switch (MO.getType()) { 205*09467b48Spatrick case MachineOperand::MO_Register: { 206*09467b48Spatrick // The MI is INLINEASM ONLY and UseVSXReg is always false. 207*09467b48Spatrick const char *RegName = PPCInstPrinter::getRegisterName(MO.getReg()); 208*09467b48Spatrick 209*09467b48Spatrick // Linux assembler (Others?) does not take register mnemonics. 210*09467b48Spatrick // FIXME - What about special registers used in mfspr/mtspr? 211*09467b48Spatrick if (!Subtarget->isDarwin()) 212*09467b48Spatrick RegName = PPCRegisterInfo::stripRegisterPrefix(RegName); 213*09467b48Spatrick O << RegName; 214*09467b48Spatrick return; 215*09467b48Spatrick } 216*09467b48Spatrick case MachineOperand::MO_Immediate: 217*09467b48Spatrick O << MO.getImm(); 218*09467b48Spatrick return; 219*09467b48Spatrick 220*09467b48Spatrick case MachineOperand::MO_MachineBasicBlock: 221*09467b48Spatrick MO.getMBB()->getSymbol()->print(O, MAI); 222*09467b48Spatrick return; 223*09467b48Spatrick case MachineOperand::MO_ConstantPoolIndex: 224*09467b48Spatrick O << DL.getPrivateGlobalPrefix() << "CPI" << getFunctionNumber() << '_' 225*09467b48Spatrick << MO.getIndex(); 226*09467b48Spatrick return; 227*09467b48Spatrick case MachineOperand::MO_BlockAddress: 228*09467b48Spatrick GetBlockAddressSymbol(MO.getBlockAddress())->print(O, MAI); 229*09467b48Spatrick return; 230*09467b48Spatrick case MachineOperand::MO_GlobalAddress: { 231*09467b48Spatrick PrintSymbolOperand(MO, O); 232*09467b48Spatrick return; 233*09467b48Spatrick } 234*09467b48Spatrick 235*09467b48Spatrick default: 236*09467b48Spatrick O << "<unknown operand type: " << (unsigned)MO.getType() << ">"; 237*09467b48Spatrick return; 238*09467b48Spatrick } 239*09467b48Spatrick } 240*09467b48Spatrick 241*09467b48Spatrick /// PrintAsmOperand - Print out an operand for an inline asm expression. 242*09467b48Spatrick /// 243*09467b48Spatrick bool PPCAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNo, 244*09467b48Spatrick const char *ExtraCode, raw_ostream &O) { 245*09467b48Spatrick // Does this asm operand have a single letter operand modifier? 246*09467b48Spatrick if (ExtraCode && ExtraCode[0]) { 247*09467b48Spatrick if (ExtraCode[1] != 0) return true; // Unknown modifier. 248*09467b48Spatrick 249*09467b48Spatrick switch (ExtraCode[0]) { 250*09467b48Spatrick default: 251*09467b48Spatrick // See if this is a generic print operand 252*09467b48Spatrick return AsmPrinter::PrintAsmOperand(MI, OpNo, ExtraCode, O); 253*09467b48Spatrick case 'L': // Write second word of DImode reference. 254*09467b48Spatrick // Verify that this operand has two consecutive registers. 255*09467b48Spatrick if (!MI->getOperand(OpNo).isReg() || 256*09467b48Spatrick OpNo+1 == MI->getNumOperands() || 257*09467b48Spatrick !MI->getOperand(OpNo+1).isReg()) 258*09467b48Spatrick return true; 259*09467b48Spatrick ++OpNo; // Return the high-part. 260*09467b48Spatrick break; 261*09467b48Spatrick case 'I': 262*09467b48Spatrick // Write 'i' if an integer constant, otherwise nothing. Used to print 263*09467b48Spatrick // addi vs add, etc. 264*09467b48Spatrick if (MI->getOperand(OpNo).isImm()) 265*09467b48Spatrick O << "i"; 266*09467b48Spatrick return false; 267*09467b48Spatrick case 'x': 268*09467b48Spatrick if(!MI->getOperand(OpNo).isReg()) 269*09467b48Spatrick return true; 270*09467b48Spatrick // This operand uses VSX numbering. 271*09467b48Spatrick // If the operand is a VMX register, convert it to a VSX register. 272*09467b48Spatrick Register Reg = MI->getOperand(OpNo).getReg(); 273*09467b48Spatrick if (PPCInstrInfo::isVRRegister(Reg)) 274*09467b48Spatrick Reg = PPC::VSX32 + (Reg - PPC::V0); 275*09467b48Spatrick else if (PPCInstrInfo::isVFRegister(Reg)) 276*09467b48Spatrick Reg = PPC::VSX32 + (Reg - PPC::VF0); 277*09467b48Spatrick const char *RegName; 278*09467b48Spatrick RegName = PPCInstPrinter::getRegisterName(Reg); 279*09467b48Spatrick RegName = PPCRegisterInfo::stripRegisterPrefix(RegName); 280*09467b48Spatrick O << RegName; 281*09467b48Spatrick return false; 282*09467b48Spatrick } 283*09467b48Spatrick } 284*09467b48Spatrick 285*09467b48Spatrick printOperand(MI, OpNo, O); 286*09467b48Spatrick return false; 287*09467b48Spatrick } 288*09467b48Spatrick 289*09467b48Spatrick // At the moment, all inline asm memory operands are a single register. 290*09467b48Spatrick // In any case, the output of this routine should always be just one 291*09467b48Spatrick // assembler operand. 292*09467b48Spatrick 293*09467b48Spatrick bool PPCAsmPrinter::PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNo, 294*09467b48Spatrick const char *ExtraCode, 295*09467b48Spatrick raw_ostream &O) { 296*09467b48Spatrick if (ExtraCode && ExtraCode[0]) { 297*09467b48Spatrick if (ExtraCode[1] != 0) return true; // Unknown modifier. 298*09467b48Spatrick 299*09467b48Spatrick switch (ExtraCode[0]) { 300*09467b48Spatrick default: return true; // Unknown modifier. 301*09467b48Spatrick case 'y': // A memory reference for an X-form instruction 302*09467b48Spatrick { 303*09467b48Spatrick const char *RegName = "r0"; 304*09467b48Spatrick if (!Subtarget->isDarwin()) 305*09467b48Spatrick RegName = PPCRegisterInfo::stripRegisterPrefix(RegName); 306*09467b48Spatrick O << RegName << ", "; 307*09467b48Spatrick printOperand(MI, OpNo, O); 308*09467b48Spatrick return false; 309*09467b48Spatrick } 310*09467b48Spatrick case 'U': // Print 'u' for update form. 311*09467b48Spatrick case 'X': // Print 'x' for indexed form. 312*09467b48Spatrick { 313*09467b48Spatrick // FIXME: Currently for PowerPC memory operands are always loaded 314*09467b48Spatrick // into a register, so we never get an update or indexed form. 315*09467b48Spatrick // This is bad even for offset forms, since even if we know we 316*09467b48Spatrick // have a value in -16(r1), we will generate a load into r<n> 317*09467b48Spatrick // and then load from 0(r<n>). Until that issue is fixed, 318*09467b48Spatrick // tolerate 'U' and 'X' but don't output anything. 319*09467b48Spatrick assert(MI->getOperand(OpNo).isReg()); 320*09467b48Spatrick return false; 321*09467b48Spatrick } 322*09467b48Spatrick } 323*09467b48Spatrick } 324*09467b48Spatrick 325*09467b48Spatrick assert(MI->getOperand(OpNo).isReg()); 326*09467b48Spatrick O << "0("; 327*09467b48Spatrick printOperand(MI, OpNo, O); 328*09467b48Spatrick O << ")"; 329*09467b48Spatrick return false; 330*09467b48Spatrick } 331*09467b48Spatrick 332*09467b48Spatrick /// lookUpOrCreateTOCEntry -- Given a symbol, look up whether a TOC entry 333*09467b48Spatrick /// exists for it. If not, create one. Then return a symbol that references 334*09467b48Spatrick /// the TOC entry. 335*09467b48Spatrick MCSymbol *PPCAsmPrinter::lookUpOrCreateTOCEntry(const MCSymbol *Sym) { 336*09467b48Spatrick MCSymbol *&TOCEntry = TOC[Sym]; 337*09467b48Spatrick if (!TOCEntry) 338*09467b48Spatrick TOCEntry = createTempSymbol("C"); 339*09467b48Spatrick return TOCEntry; 340*09467b48Spatrick } 341*09467b48Spatrick 342*09467b48Spatrick void PPCAsmPrinter::EmitEndOfAsmFile(Module &M) { 343*09467b48Spatrick emitStackMaps(SM); 344*09467b48Spatrick } 345*09467b48Spatrick 346*09467b48Spatrick void PPCAsmPrinter::LowerSTACKMAP(StackMaps &SM, const MachineInstr &MI) { 347*09467b48Spatrick unsigned NumNOPBytes = MI.getOperand(1).getImm(); 348*09467b48Spatrick 349*09467b48Spatrick auto &Ctx = OutStreamer->getContext(); 350*09467b48Spatrick MCSymbol *MILabel = Ctx.createTempSymbol(); 351*09467b48Spatrick OutStreamer->EmitLabel(MILabel); 352*09467b48Spatrick 353*09467b48Spatrick SM.recordStackMap(*MILabel, MI); 354*09467b48Spatrick assert(NumNOPBytes % 4 == 0 && "Invalid number of NOP bytes requested!"); 355*09467b48Spatrick 356*09467b48Spatrick // Scan ahead to trim the shadow. 357*09467b48Spatrick const MachineBasicBlock &MBB = *MI.getParent(); 358*09467b48Spatrick MachineBasicBlock::const_iterator MII(MI); 359*09467b48Spatrick ++MII; 360*09467b48Spatrick while (NumNOPBytes > 0) { 361*09467b48Spatrick if (MII == MBB.end() || MII->isCall() || 362*09467b48Spatrick MII->getOpcode() == PPC::DBG_VALUE || 363*09467b48Spatrick MII->getOpcode() == TargetOpcode::PATCHPOINT || 364*09467b48Spatrick MII->getOpcode() == TargetOpcode::STACKMAP) 365*09467b48Spatrick break; 366*09467b48Spatrick ++MII; 367*09467b48Spatrick NumNOPBytes -= 4; 368*09467b48Spatrick } 369*09467b48Spatrick 370*09467b48Spatrick // Emit nops. 371*09467b48Spatrick for (unsigned i = 0; i < NumNOPBytes; i += 4) 372*09467b48Spatrick EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::NOP)); 373*09467b48Spatrick } 374*09467b48Spatrick 375*09467b48Spatrick // Lower a patchpoint of the form: 376*09467b48Spatrick // [<def>], <id>, <numBytes>, <target>, <numArgs> 377*09467b48Spatrick void PPCAsmPrinter::LowerPATCHPOINT(StackMaps &SM, const MachineInstr &MI) { 378*09467b48Spatrick auto &Ctx = OutStreamer->getContext(); 379*09467b48Spatrick MCSymbol *MILabel = Ctx.createTempSymbol(); 380*09467b48Spatrick OutStreamer->EmitLabel(MILabel); 381*09467b48Spatrick 382*09467b48Spatrick SM.recordPatchPoint(*MILabel, MI); 383*09467b48Spatrick PatchPointOpers Opers(&MI); 384*09467b48Spatrick 385*09467b48Spatrick unsigned EncodedBytes = 0; 386*09467b48Spatrick const MachineOperand &CalleeMO = Opers.getCallTarget(); 387*09467b48Spatrick 388*09467b48Spatrick if (CalleeMO.isImm()) { 389*09467b48Spatrick int64_t CallTarget = CalleeMO.getImm(); 390*09467b48Spatrick if (CallTarget) { 391*09467b48Spatrick assert((CallTarget & 0xFFFFFFFFFFFF) == CallTarget && 392*09467b48Spatrick "High 16 bits of call target should be zero."); 393*09467b48Spatrick Register ScratchReg = MI.getOperand(Opers.getNextScratchIdx()).getReg(); 394*09467b48Spatrick EncodedBytes = 0; 395*09467b48Spatrick // Materialize the jump address: 396*09467b48Spatrick EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::LI8) 397*09467b48Spatrick .addReg(ScratchReg) 398*09467b48Spatrick .addImm((CallTarget >> 32) & 0xFFFF)); 399*09467b48Spatrick ++EncodedBytes; 400*09467b48Spatrick EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::RLDIC) 401*09467b48Spatrick .addReg(ScratchReg) 402*09467b48Spatrick .addReg(ScratchReg) 403*09467b48Spatrick .addImm(32).addImm(16)); 404*09467b48Spatrick ++EncodedBytes; 405*09467b48Spatrick EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::ORIS8) 406*09467b48Spatrick .addReg(ScratchReg) 407*09467b48Spatrick .addReg(ScratchReg) 408*09467b48Spatrick .addImm((CallTarget >> 16) & 0xFFFF)); 409*09467b48Spatrick ++EncodedBytes; 410*09467b48Spatrick EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::ORI8) 411*09467b48Spatrick .addReg(ScratchReg) 412*09467b48Spatrick .addReg(ScratchReg) 413*09467b48Spatrick .addImm(CallTarget & 0xFFFF)); 414*09467b48Spatrick 415*09467b48Spatrick // Save the current TOC pointer before the remote call. 416*09467b48Spatrick int TOCSaveOffset = Subtarget->getFrameLowering()->getTOCSaveOffset(); 417*09467b48Spatrick EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::STD) 418*09467b48Spatrick .addReg(PPC::X2) 419*09467b48Spatrick .addImm(TOCSaveOffset) 420*09467b48Spatrick .addReg(PPC::X1)); 421*09467b48Spatrick ++EncodedBytes; 422*09467b48Spatrick 423*09467b48Spatrick // If we're on ELFv1, then we need to load the actual function pointer 424*09467b48Spatrick // from the function descriptor. 425*09467b48Spatrick if (!Subtarget->isELFv2ABI()) { 426*09467b48Spatrick // Load the new TOC pointer and the function address, but not r11 427*09467b48Spatrick // (needing this is rare, and loading it here would prevent passing it 428*09467b48Spatrick // via a 'nest' parameter. 429*09467b48Spatrick EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::LD) 430*09467b48Spatrick .addReg(PPC::X2) 431*09467b48Spatrick .addImm(8) 432*09467b48Spatrick .addReg(ScratchReg)); 433*09467b48Spatrick ++EncodedBytes; 434*09467b48Spatrick EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::LD) 435*09467b48Spatrick .addReg(ScratchReg) 436*09467b48Spatrick .addImm(0) 437*09467b48Spatrick .addReg(ScratchReg)); 438*09467b48Spatrick ++EncodedBytes; 439*09467b48Spatrick } 440*09467b48Spatrick 441*09467b48Spatrick EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::MTCTR8) 442*09467b48Spatrick .addReg(ScratchReg)); 443*09467b48Spatrick ++EncodedBytes; 444*09467b48Spatrick EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::BCTRL8)); 445*09467b48Spatrick ++EncodedBytes; 446*09467b48Spatrick 447*09467b48Spatrick // Restore the TOC pointer after the call. 448*09467b48Spatrick EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::LD) 449*09467b48Spatrick .addReg(PPC::X2) 450*09467b48Spatrick .addImm(TOCSaveOffset) 451*09467b48Spatrick .addReg(PPC::X1)); 452*09467b48Spatrick ++EncodedBytes; 453*09467b48Spatrick } 454*09467b48Spatrick } else if (CalleeMO.isGlobal()) { 455*09467b48Spatrick const GlobalValue *GValue = CalleeMO.getGlobal(); 456*09467b48Spatrick MCSymbol *MOSymbol = getSymbol(GValue); 457*09467b48Spatrick const MCExpr *SymVar = MCSymbolRefExpr::create(MOSymbol, OutContext); 458*09467b48Spatrick 459*09467b48Spatrick EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::BL8_NOP) 460*09467b48Spatrick .addExpr(SymVar)); 461*09467b48Spatrick EncodedBytes += 2; 462*09467b48Spatrick } 463*09467b48Spatrick 464*09467b48Spatrick // Each instruction is 4 bytes. 465*09467b48Spatrick EncodedBytes *= 4; 466*09467b48Spatrick 467*09467b48Spatrick // Emit padding. 468*09467b48Spatrick unsigned NumBytes = Opers.getNumPatchBytes(); 469*09467b48Spatrick assert(NumBytes >= EncodedBytes && 470*09467b48Spatrick "Patchpoint can't request size less than the length of a call."); 471*09467b48Spatrick assert((NumBytes - EncodedBytes) % 4 == 0 && 472*09467b48Spatrick "Invalid number of NOP bytes requested!"); 473*09467b48Spatrick for (unsigned i = EncodedBytes; i < NumBytes; i += 4) 474*09467b48Spatrick EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::NOP)); 475*09467b48Spatrick } 476*09467b48Spatrick 477*09467b48Spatrick /// EmitTlsCall -- Given a GETtls[ld]ADDR[32] instruction, print a 478*09467b48Spatrick /// call to __tls_get_addr to the current output stream. 479*09467b48Spatrick void PPCAsmPrinter::EmitTlsCall(const MachineInstr *MI, 480*09467b48Spatrick MCSymbolRefExpr::VariantKind VK) { 481*09467b48Spatrick StringRef Name = "__tls_get_addr"; 482*09467b48Spatrick MCSymbol *TlsGetAddr = OutContext.getOrCreateSymbol(Name); 483*09467b48Spatrick MCSymbolRefExpr::VariantKind Kind = MCSymbolRefExpr::VK_None; 484*09467b48Spatrick const Module *M = MF->getFunction().getParent(); 485*09467b48Spatrick 486*09467b48Spatrick assert(MI->getOperand(0).isReg() && 487*09467b48Spatrick ((Subtarget->isPPC64() && MI->getOperand(0).getReg() == PPC::X3) || 488*09467b48Spatrick (!Subtarget->isPPC64() && MI->getOperand(0).getReg() == PPC::R3)) && 489*09467b48Spatrick "GETtls[ld]ADDR[32] must define GPR3"); 490*09467b48Spatrick assert(MI->getOperand(1).isReg() && 491*09467b48Spatrick ((Subtarget->isPPC64() && MI->getOperand(1).getReg() == PPC::X3) || 492*09467b48Spatrick (!Subtarget->isPPC64() && MI->getOperand(1).getReg() == PPC::R3)) && 493*09467b48Spatrick "GETtls[ld]ADDR[32] must read GPR3"); 494*09467b48Spatrick 495*09467b48Spatrick if (Subtarget->is32BitELFABI() && isPositionIndependent()) 496*09467b48Spatrick Kind = MCSymbolRefExpr::VK_PLT; 497*09467b48Spatrick 498*09467b48Spatrick const MCExpr *TlsRef = 499*09467b48Spatrick MCSymbolRefExpr::create(TlsGetAddr, Kind, OutContext); 500*09467b48Spatrick 501*09467b48Spatrick // Add 32768 offset to the symbol so we follow up the latest GOT/PLT ABI. 502*09467b48Spatrick if (Kind == MCSymbolRefExpr::VK_PLT && Subtarget->isSecurePlt() && 503*09467b48Spatrick M->getPICLevel() == PICLevel::BigPIC) 504*09467b48Spatrick TlsRef = MCBinaryExpr::createAdd( 505*09467b48Spatrick TlsRef, MCConstantExpr::create(32768, OutContext), OutContext); 506*09467b48Spatrick const MachineOperand &MO = MI->getOperand(2); 507*09467b48Spatrick const GlobalValue *GValue = MO.getGlobal(); 508*09467b48Spatrick MCSymbol *MOSymbol = getSymbol(GValue); 509*09467b48Spatrick const MCExpr *SymVar = MCSymbolRefExpr::create(MOSymbol, VK, OutContext); 510*09467b48Spatrick EmitToStreamer(*OutStreamer, 511*09467b48Spatrick MCInstBuilder(Subtarget->isPPC64() ? 512*09467b48Spatrick PPC::BL8_NOP_TLS : PPC::BL_TLS) 513*09467b48Spatrick .addExpr(TlsRef) 514*09467b48Spatrick .addExpr(SymVar)); 515*09467b48Spatrick } 516*09467b48Spatrick 517*09467b48Spatrick /// Map a machine operand for a TOC pseudo-machine instruction to its 518*09467b48Spatrick /// corresponding MCSymbol. 519*09467b48Spatrick MCSymbol *PPCAsmPrinter::getMCSymbolForTOCPseudoMO(const MachineOperand &MO) { 520*09467b48Spatrick switch (MO.getType()) { 521*09467b48Spatrick case MachineOperand::MO_GlobalAddress: 522*09467b48Spatrick return getSymbol(MO.getGlobal()); 523*09467b48Spatrick case MachineOperand::MO_ConstantPoolIndex: 524*09467b48Spatrick return GetCPISymbol(MO.getIndex()); 525*09467b48Spatrick case MachineOperand::MO_JumpTableIndex: 526*09467b48Spatrick return GetJTISymbol(MO.getIndex()); 527*09467b48Spatrick case MachineOperand::MO_BlockAddress: 528*09467b48Spatrick return GetBlockAddressSymbol(MO.getBlockAddress()); 529*09467b48Spatrick default: 530*09467b48Spatrick llvm_unreachable("Unexpected operand type to get symbol."); 531*09467b48Spatrick } 532*09467b48Spatrick } 533*09467b48Spatrick 534*09467b48Spatrick /// EmitInstruction -- Print out a single PowerPC MI in Darwin syntax to 535*09467b48Spatrick /// the current output stream. 536*09467b48Spatrick /// 537*09467b48Spatrick void PPCAsmPrinter::EmitInstruction(const MachineInstr *MI) { 538*09467b48Spatrick MCInst TmpInst; 539*09467b48Spatrick const bool IsDarwin = TM.getTargetTriple().isOSDarwin(); 540*09467b48Spatrick const bool IsPPC64 = Subtarget->isPPC64(); 541*09467b48Spatrick const bool IsAIX = Subtarget->isAIXABI(); 542*09467b48Spatrick const Module *M = MF->getFunction().getParent(); 543*09467b48Spatrick PICLevel::Level PL = M->getPICLevel(); 544*09467b48Spatrick 545*09467b48Spatrick #ifndef NDEBUG 546*09467b48Spatrick // Validate that SPE and FPU are mutually exclusive in codegen 547*09467b48Spatrick if (!MI->isInlineAsm()) { 548*09467b48Spatrick for (const MachineOperand &MO: MI->operands()) { 549*09467b48Spatrick if (MO.isReg()) { 550*09467b48Spatrick Register Reg = MO.getReg(); 551*09467b48Spatrick if (Subtarget->hasSPE()) { 552*09467b48Spatrick if (PPC::F4RCRegClass.contains(Reg) || 553*09467b48Spatrick PPC::F8RCRegClass.contains(Reg) || 554*09467b48Spatrick PPC::QBRCRegClass.contains(Reg) || 555*09467b48Spatrick PPC::QFRCRegClass.contains(Reg) || 556*09467b48Spatrick PPC::QSRCRegClass.contains(Reg) || 557*09467b48Spatrick PPC::VFRCRegClass.contains(Reg) || 558*09467b48Spatrick PPC::VRRCRegClass.contains(Reg) || 559*09467b48Spatrick PPC::VSFRCRegClass.contains(Reg) || 560*09467b48Spatrick PPC::VSSRCRegClass.contains(Reg) 561*09467b48Spatrick ) 562*09467b48Spatrick llvm_unreachable("SPE targets cannot have FPRegs!"); 563*09467b48Spatrick } else { 564*09467b48Spatrick if (PPC::SPERCRegClass.contains(Reg)) 565*09467b48Spatrick llvm_unreachable("SPE register found in FPU-targeted code!"); 566*09467b48Spatrick } 567*09467b48Spatrick } 568*09467b48Spatrick } 569*09467b48Spatrick } 570*09467b48Spatrick #endif 571*09467b48Spatrick // Lower multi-instruction pseudo operations. 572*09467b48Spatrick switch (MI->getOpcode()) { 573*09467b48Spatrick default: break; 574*09467b48Spatrick case TargetOpcode::DBG_VALUE: 575*09467b48Spatrick llvm_unreachable("Should be handled target independently"); 576*09467b48Spatrick case TargetOpcode::STACKMAP: 577*09467b48Spatrick return LowerSTACKMAP(SM, *MI); 578*09467b48Spatrick case TargetOpcode::PATCHPOINT: 579*09467b48Spatrick return LowerPATCHPOINT(SM, *MI); 580*09467b48Spatrick 581*09467b48Spatrick case PPC::MoveGOTtoLR: { 582*09467b48Spatrick // Transform %lr = MoveGOTtoLR 583*09467b48Spatrick // Into this: bl _GLOBAL_OFFSET_TABLE_@local-4 584*09467b48Spatrick // _GLOBAL_OFFSET_TABLE_@local-4 (instruction preceding 585*09467b48Spatrick // _GLOBAL_OFFSET_TABLE_) has exactly one instruction: 586*09467b48Spatrick // blrl 587*09467b48Spatrick // This will return the pointer to _GLOBAL_OFFSET_TABLE_@local 588*09467b48Spatrick MCSymbol *GOTSymbol = 589*09467b48Spatrick OutContext.getOrCreateSymbol(StringRef("_GLOBAL_OFFSET_TABLE_")); 590*09467b48Spatrick const MCExpr *OffsExpr = 591*09467b48Spatrick MCBinaryExpr::createSub(MCSymbolRefExpr::create(GOTSymbol, 592*09467b48Spatrick MCSymbolRefExpr::VK_PPC_LOCAL, 593*09467b48Spatrick OutContext), 594*09467b48Spatrick MCConstantExpr::create(4, OutContext), 595*09467b48Spatrick OutContext); 596*09467b48Spatrick 597*09467b48Spatrick // Emit the 'bl'. 598*09467b48Spatrick EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::BL).addExpr(OffsExpr)); 599*09467b48Spatrick return; 600*09467b48Spatrick } 601*09467b48Spatrick case PPC::MovePCtoLR: 602*09467b48Spatrick case PPC::MovePCtoLR8: { 603*09467b48Spatrick // Transform %lr = MovePCtoLR 604*09467b48Spatrick // Into this, where the label is the PIC base: 605*09467b48Spatrick // bl L1$pb 606*09467b48Spatrick // L1$pb: 607*09467b48Spatrick MCSymbol *PICBase = MF->getPICBaseSymbol(); 608*09467b48Spatrick 609*09467b48Spatrick // Emit the 'bl'. 610*09467b48Spatrick EmitToStreamer(*OutStreamer, 611*09467b48Spatrick MCInstBuilder(PPC::BL) 612*09467b48Spatrick // FIXME: We would like an efficient form for this, so we 613*09467b48Spatrick // don't have to do a lot of extra uniquing. 614*09467b48Spatrick .addExpr(MCSymbolRefExpr::create(PICBase, OutContext))); 615*09467b48Spatrick 616*09467b48Spatrick // Emit the label. 617*09467b48Spatrick OutStreamer->EmitLabel(PICBase); 618*09467b48Spatrick return; 619*09467b48Spatrick } 620*09467b48Spatrick case PPC::UpdateGBR: { 621*09467b48Spatrick // Transform %rd = UpdateGBR(%rt, %ri) 622*09467b48Spatrick // Into: lwz %rt, .L0$poff - .L0$pb(%ri) 623*09467b48Spatrick // add %rd, %rt, %ri 624*09467b48Spatrick // or into (if secure plt mode is on): 625*09467b48Spatrick // addis r30, r30, {.LTOC,_GLOBAL_OFFSET_TABLE} - .L0$pb@ha 626*09467b48Spatrick // addi r30, r30, {.LTOC,_GLOBAL_OFFSET_TABLE} - .L0$pb@l 627*09467b48Spatrick // Get the offset from the GOT Base Register to the GOT 628*09467b48Spatrick LowerPPCMachineInstrToMCInst(MI, TmpInst, *this, IsDarwin); 629*09467b48Spatrick if (Subtarget->isSecurePlt() && isPositionIndependent() ) { 630*09467b48Spatrick unsigned PICR = TmpInst.getOperand(0).getReg(); 631*09467b48Spatrick MCSymbol *BaseSymbol = OutContext.getOrCreateSymbol( 632*09467b48Spatrick M->getPICLevel() == PICLevel::SmallPIC ? "_GLOBAL_OFFSET_TABLE_" 633*09467b48Spatrick : ".LTOC"); 634*09467b48Spatrick const MCExpr *PB = 635*09467b48Spatrick MCSymbolRefExpr::create(MF->getPICBaseSymbol(), OutContext); 636*09467b48Spatrick 637*09467b48Spatrick const MCExpr *DeltaExpr = MCBinaryExpr::createSub( 638*09467b48Spatrick MCSymbolRefExpr::create(BaseSymbol, OutContext), PB, OutContext); 639*09467b48Spatrick 640*09467b48Spatrick const MCExpr *DeltaHi = PPCMCExpr::createHa(DeltaExpr, false, OutContext); 641*09467b48Spatrick EmitToStreamer( 642*09467b48Spatrick *OutStreamer, 643*09467b48Spatrick MCInstBuilder(PPC::ADDIS).addReg(PICR).addReg(PICR).addExpr(DeltaHi)); 644*09467b48Spatrick 645*09467b48Spatrick const MCExpr *DeltaLo = PPCMCExpr::createLo(DeltaExpr, false, OutContext); 646*09467b48Spatrick EmitToStreamer( 647*09467b48Spatrick *OutStreamer, 648*09467b48Spatrick MCInstBuilder(PPC::ADDI).addReg(PICR).addReg(PICR).addExpr(DeltaLo)); 649*09467b48Spatrick return; 650*09467b48Spatrick } else { 651*09467b48Spatrick MCSymbol *PICOffset = 652*09467b48Spatrick MF->getInfo<PPCFunctionInfo>()->getPICOffsetSymbol(); 653*09467b48Spatrick TmpInst.setOpcode(PPC::LWZ); 654*09467b48Spatrick const MCExpr *Exp = 655*09467b48Spatrick MCSymbolRefExpr::create(PICOffset, MCSymbolRefExpr::VK_None, OutContext); 656*09467b48Spatrick const MCExpr *PB = 657*09467b48Spatrick MCSymbolRefExpr::create(MF->getPICBaseSymbol(), 658*09467b48Spatrick MCSymbolRefExpr::VK_None, 659*09467b48Spatrick OutContext); 660*09467b48Spatrick const MCOperand TR = TmpInst.getOperand(1); 661*09467b48Spatrick const MCOperand PICR = TmpInst.getOperand(0); 662*09467b48Spatrick 663*09467b48Spatrick // Step 1: lwz %rt, .L$poff - .L$pb(%ri) 664*09467b48Spatrick TmpInst.getOperand(1) = 665*09467b48Spatrick MCOperand::createExpr(MCBinaryExpr::createSub(Exp, PB, OutContext)); 666*09467b48Spatrick TmpInst.getOperand(0) = TR; 667*09467b48Spatrick TmpInst.getOperand(2) = PICR; 668*09467b48Spatrick EmitToStreamer(*OutStreamer, TmpInst); 669*09467b48Spatrick 670*09467b48Spatrick TmpInst.setOpcode(PPC::ADD4); 671*09467b48Spatrick TmpInst.getOperand(0) = PICR; 672*09467b48Spatrick TmpInst.getOperand(1) = TR; 673*09467b48Spatrick TmpInst.getOperand(2) = PICR; 674*09467b48Spatrick EmitToStreamer(*OutStreamer, TmpInst); 675*09467b48Spatrick return; 676*09467b48Spatrick } 677*09467b48Spatrick } 678*09467b48Spatrick case PPC::LWZtoc: { 679*09467b48Spatrick assert(!IsDarwin && "TOC is an ELF/XCOFF construct."); 680*09467b48Spatrick 681*09467b48Spatrick // Transform %rN = LWZtoc @op1, %r2 682*09467b48Spatrick LowerPPCMachineInstrToMCInst(MI, TmpInst, *this, IsDarwin); 683*09467b48Spatrick 684*09467b48Spatrick // Change the opcode to LWZ. 685*09467b48Spatrick TmpInst.setOpcode(PPC::LWZ); 686*09467b48Spatrick 687*09467b48Spatrick const MachineOperand &MO = MI->getOperand(1); 688*09467b48Spatrick assert((MO.isGlobal() || MO.isCPI() || MO.isJTI() || MO.isBlockAddress()) && 689*09467b48Spatrick "Invalid operand for LWZtoc."); 690*09467b48Spatrick 691*09467b48Spatrick // Map the operand to its corresponding MCSymbol. 692*09467b48Spatrick const MCSymbol *const MOSymbol = getMCSymbolForTOCPseudoMO(MO); 693*09467b48Spatrick 694*09467b48Spatrick // Create a reference to the GOT entry for the symbol. The GOT entry will be 695*09467b48Spatrick // synthesized later. 696*09467b48Spatrick if (PL == PICLevel::SmallPIC && !IsAIX) { 697*09467b48Spatrick const MCExpr *Exp = 698*09467b48Spatrick MCSymbolRefExpr::create(MOSymbol, MCSymbolRefExpr::VK_GOT, 699*09467b48Spatrick OutContext); 700*09467b48Spatrick TmpInst.getOperand(1) = MCOperand::createExpr(Exp); 701*09467b48Spatrick EmitToStreamer(*OutStreamer, TmpInst); 702*09467b48Spatrick return; 703*09467b48Spatrick } 704*09467b48Spatrick 705*09467b48Spatrick // Otherwise, use the TOC. 'TOCEntry' is a label used to reference the 706*09467b48Spatrick // storage allocated in the TOC which contains the address of 707*09467b48Spatrick // 'MOSymbol'. Said TOC entry will be synthesized later. 708*09467b48Spatrick MCSymbol *TOCEntry = lookUpOrCreateTOCEntry(MOSymbol); 709*09467b48Spatrick const MCExpr *Exp = 710*09467b48Spatrick MCSymbolRefExpr::create(TOCEntry, MCSymbolRefExpr::VK_None, OutContext); 711*09467b48Spatrick 712*09467b48Spatrick // AIX uses the label directly as the lwz displacement operand for 713*09467b48Spatrick // references into the toc section. The displacement value will be generated 714*09467b48Spatrick // relative to the toc-base. 715*09467b48Spatrick if (IsAIX) { 716*09467b48Spatrick assert( 717*09467b48Spatrick TM.getCodeModel() == CodeModel::Small && 718*09467b48Spatrick "This pseudo should only be selected for 32-bit small code model."); 719*09467b48Spatrick TmpInst.getOperand(1) = MCOperand::createExpr(Exp); 720*09467b48Spatrick EmitToStreamer(*OutStreamer, TmpInst); 721*09467b48Spatrick return; 722*09467b48Spatrick } 723*09467b48Spatrick 724*09467b48Spatrick // Create an explicit subtract expression between the local symbol and 725*09467b48Spatrick // '.LTOC' to manifest the toc-relative offset. 726*09467b48Spatrick const MCExpr *PB = MCSymbolRefExpr::create( 727*09467b48Spatrick OutContext.getOrCreateSymbol(Twine(".LTOC")), OutContext); 728*09467b48Spatrick Exp = MCBinaryExpr::createSub(Exp, PB, OutContext); 729*09467b48Spatrick TmpInst.getOperand(1) = MCOperand::createExpr(Exp); 730*09467b48Spatrick EmitToStreamer(*OutStreamer, TmpInst); 731*09467b48Spatrick return; 732*09467b48Spatrick } 733*09467b48Spatrick case PPC::LDtocJTI: 734*09467b48Spatrick case PPC::LDtocCPT: 735*09467b48Spatrick case PPC::LDtocBA: 736*09467b48Spatrick case PPC::LDtoc: { 737*09467b48Spatrick assert(!IsDarwin && "TOC is an ELF/XCOFF construct"); 738*09467b48Spatrick 739*09467b48Spatrick // Transform %x3 = LDtoc @min1, %x2 740*09467b48Spatrick LowerPPCMachineInstrToMCInst(MI, TmpInst, *this, IsDarwin); 741*09467b48Spatrick 742*09467b48Spatrick // Change the opcode to LD. 743*09467b48Spatrick TmpInst.setOpcode(PPC::LD); 744*09467b48Spatrick 745*09467b48Spatrick const MachineOperand &MO = MI->getOperand(1); 746*09467b48Spatrick assert((MO.isGlobal() || MO.isCPI() || MO.isJTI() || MO.isBlockAddress()) && 747*09467b48Spatrick "Invalid operand!"); 748*09467b48Spatrick 749*09467b48Spatrick // Map the machine operand to its corresponding MCSymbol, then map the 750*09467b48Spatrick // global address operand to be a reference to the TOC entry we will 751*09467b48Spatrick // synthesize later. 752*09467b48Spatrick MCSymbol *TOCEntry = 753*09467b48Spatrick lookUpOrCreateTOCEntry(getMCSymbolForTOCPseudoMO(MO)); 754*09467b48Spatrick 755*09467b48Spatrick const MCSymbolRefExpr::VariantKind VK = 756*09467b48Spatrick IsAIX ? MCSymbolRefExpr::VK_None : MCSymbolRefExpr::VK_PPC_TOC; 757*09467b48Spatrick const MCExpr *Exp = 758*09467b48Spatrick MCSymbolRefExpr::create(TOCEntry, VK, OutContext); 759*09467b48Spatrick TmpInst.getOperand(1) = MCOperand::createExpr(Exp); 760*09467b48Spatrick EmitToStreamer(*OutStreamer, TmpInst); 761*09467b48Spatrick return; 762*09467b48Spatrick } 763*09467b48Spatrick case PPC::ADDIStocHA: { 764*09467b48Spatrick assert((IsAIX && !IsPPC64 && TM.getCodeModel() == CodeModel::Large) && 765*09467b48Spatrick "This pseudo should only be selected for 32-bit large code model on" 766*09467b48Spatrick " AIX."); 767*09467b48Spatrick 768*09467b48Spatrick // Transform %rd = ADDIStocHA %rA, @sym(%r2) 769*09467b48Spatrick LowerPPCMachineInstrToMCInst(MI, TmpInst, *this, IsDarwin); 770*09467b48Spatrick 771*09467b48Spatrick // Change the opcode to ADDIS. 772*09467b48Spatrick TmpInst.setOpcode(PPC::ADDIS); 773*09467b48Spatrick 774*09467b48Spatrick const MachineOperand &MO = MI->getOperand(2); 775*09467b48Spatrick assert((MO.isGlobal() || MO.isCPI() || MO.isJTI() || MO.isBlockAddress()) && 776*09467b48Spatrick "Invalid operand for ADDIStocHA."); 777*09467b48Spatrick 778*09467b48Spatrick // Map the machine operand to its corresponding MCSymbol. 779*09467b48Spatrick MCSymbol *MOSymbol = getMCSymbolForTOCPseudoMO(MO); 780*09467b48Spatrick 781*09467b48Spatrick // Always use TOC on AIX. Map the global address operand to be a reference 782*09467b48Spatrick // to the TOC entry we will synthesize later. 'TOCEntry' is a label used to 783*09467b48Spatrick // reference the storage allocated in the TOC which contains the address of 784*09467b48Spatrick // 'MOSymbol'. 785*09467b48Spatrick MCSymbol *TOCEntry = lookUpOrCreateTOCEntry(MOSymbol); 786*09467b48Spatrick const MCExpr *Exp = MCSymbolRefExpr::create(TOCEntry, 787*09467b48Spatrick MCSymbolRefExpr::VK_PPC_U, 788*09467b48Spatrick OutContext); 789*09467b48Spatrick TmpInst.getOperand(2) = MCOperand::createExpr(Exp); 790*09467b48Spatrick EmitToStreamer(*OutStreamer, TmpInst); 791*09467b48Spatrick return; 792*09467b48Spatrick } 793*09467b48Spatrick case PPC::LWZtocL: { 794*09467b48Spatrick assert(IsAIX && !IsPPC64 && TM.getCodeModel() == CodeModel::Large && 795*09467b48Spatrick "This pseudo should only be selected for 32-bit large code model on" 796*09467b48Spatrick " AIX."); 797*09467b48Spatrick 798*09467b48Spatrick // Transform %rd = LWZtocL @sym, %rs. 799*09467b48Spatrick LowerPPCMachineInstrToMCInst(MI, TmpInst, *this, IsDarwin); 800*09467b48Spatrick 801*09467b48Spatrick // Change the opcode to lwz. 802*09467b48Spatrick TmpInst.setOpcode(PPC::LWZ); 803*09467b48Spatrick 804*09467b48Spatrick const MachineOperand &MO = MI->getOperand(1); 805*09467b48Spatrick assert((MO.isGlobal() || MO.isCPI() || MO.isJTI() || MO.isBlockAddress()) && 806*09467b48Spatrick "Invalid operand for LWZtocL."); 807*09467b48Spatrick 808*09467b48Spatrick // Map the machine operand to its corresponding MCSymbol. 809*09467b48Spatrick MCSymbol *MOSymbol = getMCSymbolForTOCPseudoMO(MO); 810*09467b48Spatrick 811*09467b48Spatrick // Always use TOC on AIX. Map the global address operand to be a reference 812*09467b48Spatrick // to the TOC entry we will synthesize later. 'TOCEntry' is a label used to 813*09467b48Spatrick // reference the storage allocated in the TOC which contains the address of 814*09467b48Spatrick // 'MOSymbol'. 815*09467b48Spatrick MCSymbol *TOCEntry = lookUpOrCreateTOCEntry(MOSymbol); 816*09467b48Spatrick const MCExpr *Exp = MCSymbolRefExpr::create(TOCEntry, 817*09467b48Spatrick MCSymbolRefExpr::VK_PPC_L, 818*09467b48Spatrick OutContext); 819*09467b48Spatrick TmpInst.getOperand(1) = MCOperand::createExpr(Exp); 820*09467b48Spatrick EmitToStreamer(*OutStreamer, TmpInst); 821*09467b48Spatrick return; 822*09467b48Spatrick } 823*09467b48Spatrick case PPC::ADDIStocHA8: { 824*09467b48Spatrick assert(!IsDarwin && "TOC is an ELF/XCOFF construct"); 825*09467b48Spatrick 826*09467b48Spatrick // Transform %xd = ADDIStocHA8 %x2, @sym 827*09467b48Spatrick LowerPPCMachineInstrToMCInst(MI, TmpInst, *this, IsDarwin); 828*09467b48Spatrick 829*09467b48Spatrick // Change the opcode to ADDIS8. If the global address is the address of 830*09467b48Spatrick // an external symbol, is a jump table address, is a block address, or is a 831*09467b48Spatrick // constant pool index with large code model enabled, then generate a TOC 832*09467b48Spatrick // entry and reference that. Otherwise, reference the symbol directly. 833*09467b48Spatrick TmpInst.setOpcode(PPC::ADDIS8); 834*09467b48Spatrick 835*09467b48Spatrick const MachineOperand &MO = MI->getOperand(2); 836*09467b48Spatrick assert((MO.isGlobal() || MO.isCPI() || MO.isJTI() || MO.isBlockAddress()) && 837*09467b48Spatrick "Invalid operand for ADDIStocHA8!"); 838*09467b48Spatrick 839*09467b48Spatrick const MCSymbol *MOSymbol = getMCSymbolForTOCPseudoMO(MO); 840*09467b48Spatrick 841*09467b48Spatrick const bool GlobalToc = 842*09467b48Spatrick MO.isGlobal() && Subtarget->isGVIndirectSymbol(MO.getGlobal()); 843*09467b48Spatrick if (GlobalToc || MO.isJTI() || MO.isBlockAddress() || 844*09467b48Spatrick (MO.isCPI() && TM.getCodeModel() == CodeModel::Large)) 845*09467b48Spatrick MOSymbol = lookUpOrCreateTOCEntry(MOSymbol); 846*09467b48Spatrick 847*09467b48Spatrick const MCSymbolRefExpr::VariantKind VK = 848*09467b48Spatrick IsAIX ? MCSymbolRefExpr::VK_PPC_U : MCSymbolRefExpr::VK_PPC_TOC_HA; 849*09467b48Spatrick 850*09467b48Spatrick const MCExpr *Exp = 851*09467b48Spatrick MCSymbolRefExpr::create(MOSymbol, VK, OutContext); 852*09467b48Spatrick 853*09467b48Spatrick if (!MO.isJTI() && MO.getOffset()) 854*09467b48Spatrick Exp = MCBinaryExpr::createAdd(Exp, 855*09467b48Spatrick MCConstantExpr::create(MO.getOffset(), 856*09467b48Spatrick OutContext), 857*09467b48Spatrick OutContext); 858*09467b48Spatrick 859*09467b48Spatrick TmpInst.getOperand(2) = MCOperand::createExpr(Exp); 860*09467b48Spatrick EmitToStreamer(*OutStreamer, TmpInst); 861*09467b48Spatrick return; 862*09467b48Spatrick } 863*09467b48Spatrick case PPC::LDtocL: { 864*09467b48Spatrick assert(!IsDarwin && "TOC is an ELF/XCOFF construct"); 865*09467b48Spatrick 866*09467b48Spatrick // Transform %xd = LDtocL @sym, %xs 867*09467b48Spatrick LowerPPCMachineInstrToMCInst(MI, TmpInst, *this, IsDarwin); 868*09467b48Spatrick 869*09467b48Spatrick // Change the opcode to LD. If the global address is the address of 870*09467b48Spatrick // an external symbol, is a jump table address, is a block address, or is 871*09467b48Spatrick // a constant pool index with large code model enabled, then generate a 872*09467b48Spatrick // TOC entry and reference that. Otherwise, reference the symbol directly. 873*09467b48Spatrick TmpInst.setOpcode(PPC::LD); 874*09467b48Spatrick 875*09467b48Spatrick const MachineOperand &MO = MI->getOperand(1); 876*09467b48Spatrick assert((MO.isGlobal() || MO.isCPI() || MO.isJTI() || 877*09467b48Spatrick MO.isBlockAddress()) && 878*09467b48Spatrick "Invalid operand for LDtocL!"); 879*09467b48Spatrick 880*09467b48Spatrick LLVM_DEBUG(assert( 881*09467b48Spatrick (!MO.isGlobal() || Subtarget->isGVIndirectSymbol(MO.getGlobal())) && 882*09467b48Spatrick "LDtocL used on symbol that could be accessed directly is " 883*09467b48Spatrick "invalid. Must match ADDIStocHA8.")); 884*09467b48Spatrick 885*09467b48Spatrick const MCSymbol *MOSymbol = getMCSymbolForTOCPseudoMO(MO); 886*09467b48Spatrick 887*09467b48Spatrick if (!MO.isCPI() || TM.getCodeModel() == CodeModel::Large) 888*09467b48Spatrick MOSymbol = lookUpOrCreateTOCEntry(MOSymbol); 889*09467b48Spatrick 890*09467b48Spatrick const MCSymbolRefExpr::VariantKind VK = 891*09467b48Spatrick IsAIX ? MCSymbolRefExpr::VK_PPC_L : MCSymbolRefExpr::VK_PPC_TOC_LO; 892*09467b48Spatrick const MCExpr *Exp = 893*09467b48Spatrick MCSymbolRefExpr::create(MOSymbol, VK, OutContext); 894*09467b48Spatrick TmpInst.getOperand(1) = MCOperand::createExpr(Exp); 895*09467b48Spatrick EmitToStreamer(*OutStreamer, TmpInst); 896*09467b48Spatrick return; 897*09467b48Spatrick } 898*09467b48Spatrick case PPC::ADDItocL: { 899*09467b48Spatrick // Transform %xd = ADDItocL %xs, @sym 900*09467b48Spatrick LowerPPCMachineInstrToMCInst(MI, TmpInst, *this, IsDarwin); 901*09467b48Spatrick 902*09467b48Spatrick // Change the opcode to ADDI8. If the global address is external, then 903*09467b48Spatrick // generate a TOC entry and reference that. Otherwise, reference the 904*09467b48Spatrick // symbol directly. 905*09467b48Spatrick TmpInst.setOpcode(PPC::ADDI8); 906*09467b48Spatrick 907*09467b48Spatrick const MachineOperand &MO = MI->getOperand(2); 908*09467b48Spatrick assert((MO.isGlobal() || MO.isCPI()) && "Invalid operand for ADDItocL."); 909*09467b48Spatrick 910*09467b48Spatrick LLVM_DEBUG(assert( 911*09467b48Spatrick !(MO.isGlobal() && Subtarget->isGVIndirectSymbol(MO.getGlobal())) && 912*09467b48Spatrick "Interposable definitions must use indirect access.")); 913*09467b48Spatrick 914*09467b48Spatrick const MCExpr *Exp = 915*09467b48Spatrick MCSymbolRefExpr::create(getMCSymbolForTOCPseudoMO(MO), 916*09467b48Spatrick MCSymbolRefExpr::VK_PPC_TOC_LO, OutContext); 917*09467b48Spatrick TmpInst.getOperand(2) = MCOperand::createExpr(Exp); 918*09467b48Spatrick EmitToStreamer(*OutStreamer, TmpInst); 919*09467b48Spatrick return; 920*09467b48Spatrick } 921*09467b48Spatrick case PPC::ADDISgotTprelHA: { 922*09467b48Spatrick // Transform: %xd = ADDISgotTprelHA %x2, @sym 923*09467b48Spatrick // Into: %xd = ADDIS8 %x2, sym@got@tlsgd@ha 924*09467b48Spatrick assert(IsPPC64 && "Not supported for 32-bit PowerPC"); 925*09467b48Spatrick const MachineOperand &MO = MI->getOperand(2); 926*09467b48Spatrick const GlobalValue *GValue = MO.getGlobal(); 927*09467b48Spatrick MCSymbol *MOSymbol = getSymbol(GValue); 928*09467b48Spatrick const MCExpr *SymGotTprel = 929*09467b48Spatrick MCSymbolRefExpr::create(MOSymbol, MCSymbolRefExpr::VK_PPC_GOT_TPREL_HA, 930*09467b48Spatrick OutContext); 931*09467b48Spatrick EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::ADDIS8) 932*09467b48Spatrick .addReg(MI->getOperand(0).getReg()) 933*09467b48Spatrick .addReg(MI->getOperand(1).getReg()) 934*09467b48Spatrick .addExpr(SymGotTprel)); 935*09467b48Spatrick return; 936*09467b48Spatrick } 937*09467b48Spatrick case PPC::LDgotTprelL: 938*09467b48Spatrick case PPC::LDgotTprelL32: { 939*09467b48Spatrick // Transform %xd = LDgotTprelL @sym, %xs 940*09467b48Spatrick LowerPPCMachineInstrToMCInst(MI, TmpInst, *this, IsDarwin); 941*09467b48Spatrick 942*09467b48Spatrick // Change the opcode to LD. 943*09467b48Spatrick TmpInst.setOpcode(IsPPC64 ? PPC::LD : PPC::LWZ); 944*09467b48Spatrick const MachineOperand &MO = MI->getOperand(1); 945*09467b48Spatrick const GlobalValue *GValue = MO.getGlobal(); 946*09467b48Spatrick MCSymbol *MOSymbol = getSymbol(GValue); 947*09467b48Spatrick const MCExpr *Exp = MCSymbolRefExpr::create( 948*09467b48Spatrick MOSymbol, IsPPC64 ? MCSymbolRefExpr::VK_PPC_GOT_TPREL_LO 949*09467b48Spatrick : MCSymbolRefExpr::VK_PPC_GOT_TPREL, 950*09467b48Spatrick OutContext); 951*09467b48Spatrick TmpInst.getOperand(1) = MCOperand::createExpr(Exp); 952*09467b48Spatrick EmitToStreamer(*OutStreamer, TmpInst); 953*09467b48Spatrick return; 954*09467b48Spatrick } 955*09467b48Spatrick 956*09467b48Spatrick case PPC::PPC32PICGOT: { 957*09467b48Spatrick MCSymbol *GOTSymbol = OutContext.getOrCreateSymbol(StringRef("_GLOBAL_OFFSET_TABLE_")); 958*09467b48Spatrick MCSymbol *GOTRef = OutContext.createTempSymbol(); 959*09467b48Spatrick MCSymbol *NextInstr = OutContext.createTempSymbol(); 960*09467b48Spatrick 961*09467b48Spatrick EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::BL) 962*09467b48Spatrick // FIXME: We would like an efficient form for this, so we don't have to do 963*09467b48Spatrick // a lot of extra uniquing. 964*09467b48Spatrick .addExpr(MCSymbolRefExpr::create(NextInstr, OutContext))); 965*09467b48Spatrick const MCExpr *OffsExpr = 966*09467b48Spatrick MCBinaryExpr::createSub(MCSymbolRefExpr::create(GOTSymbol, OutContext), 967*09467b48Spatrick MCSymbolRefExpr::create(GOTRef, OutContext), 968*09467b48Spatrick OutContext); 969*09467b48Spatrick OutStreamer->EmitLabel(GOTRef); 970*09467b48Spatrick OutStreamer->EmitValue(OffsExpr, 4); 971*09467b48Spatrick OutStreamer->EmitLabel(NextInstr); 972*09467b48Spatrick EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::MFLR) 973*09467b48Spatrick .addReg(MI->getOperand(0).getReg())); 974*09467b48Spatrick EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::LWZ) 975*09467b48Spatrick .addReg(MI->getOperand(1).getReg()) 976*09467b48Spatrick .addImm(0) 977*09467b48Spatrick .addReg(MI->getOperand(0).getReg())); 978*09467b48Spatrick EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::ADD4) 979*09467b48Spatrick .addReg(MI->getOperand(0).getReg()) 980*09467b48Spatrick .addReg(MI->getOperand(1).getReg()) 981*09467b48Spatrick .addReg(MI->getOperand(0).getReg())); 982*09467b48Spatrick return; 983*09467b48Spatrick } 984*09467b48Spatrick case PPC::PPC32GOT: { 985*09467b48Spatrick MCSymbol *GOTSymbol = 986*09467b48Spatrick OutContext.getOrCreateSymbol(StringRef("_GLOBAL_OFFSET_TABLE_")); 987*09467b48Spatrick const MCExpr *SymGotTlsL = MCSymbolRefExpr::create( 988*09467b48Spatrick GOTSymbol, MCSymbolRefExpr::VK_PPC_LO, OutContext); 989*09467b48Spatrick const MCExpr *SymGotTlsHA = MCSymbolRefExpr::create( 990*09467b48Spatrick GOTSymbol, MCSymbolRefExpr::VK_PPC_HA, OutContext); 991*09467b48Spatrick EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::LI) 992*09467b48Spatrick .addReg(MI->getOperand(0).getReg()) 993*09467b48Spatrick .addExpr(SymGotTlsL)); 994*09467b48Spatrick EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::ADDIS) 995*09467b48Spatrick .addReg(MI->getOperand(0).getReg()) 996*09467b48Spatrick .addReg(MI->getOperand(0).getReg()) 997*09467b48Spatrick .addExpr(SymGotTlsHA)); 998*09467b48Spatrick return; 999*09467b48Spatrick } 1000*09467b48Spatrick case PPC::ADDIStlsgdHA: { 1001*09467b48Spatrick // Transform: %xd = ADDIStlsgdHA %x2, @sym 1002*09467b48Spatrick // Into: %xd = ADDIS8 %x2, sym@got@tlsgd@ha 1003*09467b48Spatrick assert(IsPPC64 && "Not supported for 32-bit PowerPC"); 1004*09467b48Spatrick const MachineOperand &MO = MI->getOperand(2); 1005*09467b48Spatrick const GlobalValue *GValue = MO.getGlobal(); 1006*09467b48Spatrick MCSymbol *MOSymbol = getSymbol(GValue); 1007*09467b48Spatrick const MCExpr *SymGotTlsGD = 1008*09467b48Spatrick MCSymbolRefExpr::create(MOSymbol, MCSymbolRefExpr::VK_PPC_GOT_TLSGD_HA, 1009*09467b48Spatrick OutContext); 1010*09467b48Spatrick EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::ADDIS8) 1011*09467b48Spatrick .addReg(MI->getOperand(0).getReg()) 1012*09467b48Spatrick .addReg(MI->getOperand(1).getReg()) 1013*09467b48Spatrick .addExpr(SymGotTlsGD)); 1014*09467b48Spatrick return; 1015*09467b48Spatrick } 1016*09467b48Spatrick case PPC::ADDItlsgdL: 1017*09467b48Spatrick // Transform: %xd = ADDItlsgdL %xs, @sym 1018*09467b48Spatrick // Into: %xd = ADDI8 %xs, sym@got@tlsgd@l 1019*09467b48Spatrick case PPC::ADDItlsgdL32: { 1020*09467b48Spatrick // Transform: %rd = ADDItlsgdL32 %rs, @sym 1021*09467b48Spatrick // Into: %rd = ADDI %rs, sym@got@tlsgd 1022*09467b48Spatrick const MachineOperand &MO = MI->getOperand(2); 1023*09467b48Spatrick const GlobalValue *GValue = MO.getGlobal(); 1024*09467b48Spatrick MCSymbol *MOSymbol = getSymbol(GValue); 1025*09467b48Spatrick const MCExpr *SymGotTlsGD = MCSymbolRefExpr::create( 1026*09467b48Spatrick MOSymbol, IsPPC64 ? MCSymbolRefExpr::VK_PPC_GOT_TLSGD_LO 1027*09467b48Spatrick : MCSymbolRefExpr::VK_PPC_GOT_TLSGD, 1028*09467b48Spatrick OutContext); 1029*09467b48Spatrick EmitToStreamer(*OutStreamer, 1030*09467b48Spatrick MCInstBuilder(IsPPC64 ? PPC::ADDI8 : PPC::ADDI) 1031*09467b48Spatrick .addReg(MI->getOperand(0).getReg()) 1032*09467b48Spatrick .addReg(MI->getOperand(1).getReg()) 1033*09467b48Spatrick .addExpr(SymGotTlsGD)); 1034*09467b48Spatrick return; 1035*09467b48Spatrick } 1036*09467b48Spatrick case PPC::GETtlsADDR: 1037*09467b48Spatrick // Transform: %x3 = GETtlsADDR %x3, @sym 1038*09467b48Spatrick // Into: BL8_NOP_TLS __tls_get_addr(sym at tlsgd) 1039*09467b48Spatrick case PPC::GETtlsADDR32: { 1040*09467b48Spatrick // Transform: %r3 = GETtlsADDR32 %r3, @sym 1041*09467b48Spatrick // Into: BL_TLS __tls_get_addr(sym at tlsgd)@PLT 1042*09467b48Spatrick EmitTlsCall(MI, MCSymbolRefExpr::VK_PPC_TLSGD); 1043*09467b48Spatrick return; 1044*09467b48Spatrick } 1045*09467b48Spatrick case PPC::ADDIStlsldHA: { 1046*09467b48Spatrick // Transform: %xd = ADDIStlsldHA %x2, @sym 1047*09467b48Spatrick // Into: %xd = ADDIS8 %x2, sym@got@tlsld@ha 1048*09467b48Spatrick assert(IsPPC64 && "Not supported for 32-bit PowerPC"); 1049*09467b48Spatrick const MachineOperand &MO = MI->getOperand(2); 1050*09467b48Spatrick const GlobalValue *GValue = MO.getGlobal(); 1051*09467b48Spatrick MCSymbol *MOSymbol = getSymbol(GValue); 1052*09467b48Spatrick const MCExpr *SymGotTlsLD = 1053*09467b48Spatrick MCSymbolRefExpr::create(MOSymbol, MCSymbolRefExpr::VK_PPC_GOT_TLSLD_HA, 1054*09467b48Spatrick OutContext); 1055*09467b48Spatrick EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::ADDIS8) 1056*09467b48Spatrick .addReg(MI->getOperand(0).getReg()) 1057*09467b48Spatrick .addReg(MI->getOperand(1).getReg()) 1058*09467b48Spatrick .addExpr(SymGotTlsLD)); 1059*09467b48Spatrick return; 1060*09467b48Spatrick } 1061*09467b48Spatrick case PPC::ADDItlsldL: 1062*09467b48Spatrick // Transform: %xd = ADDItlsldL %xs, @sym 1063*09467b48Spatrick // Into: %xd = ADDI8 %xs, sym@got@tlsld@l 1064*09467b48Spatrick case PPC::ADDItlsldL32: { 1065*09467b48Spatrick // Transform: %rd = ADDItlsldL32 %rs, @sym 1066*09467b48Spatrick // Into: %rd = ADDI %rs, sym@got@tlsld 1067*09467b48Spatrick const MachineOperand &MO = MI->getOperand(2); 1068*09467b48Spatrick const GlobalValue *GValue = MO.getGlobal(); 1069*09467b48Spatrick MCSymbol *MOSymbol = getSymbol(GValue); 1070*09467b48Spatrick const MCExpr *SymGotTlsLD = MCSymbolRefExpr::create( 1071*09467b48Spatrick MOSymbol, IsPPC64 ? MCSymbolRefExpr::VK_PPC_GOT_TLSLD_LO 1072*09467b48Spatrick : MCSymbolRefExpr::VK_PPC_GOT_TLSLD, 1073*09467b48Spatrick OutContext); 1074*09467b48Spatrick EmitToStreamer(*OutStreamer, 1075*09467b48Spatrick MCInstBuilder(IsPPC64 ? PPC::ADDI8 : PPC::ADDI) 1076*09467b48Spatrick .addReg(MI->getOperand(0).getReg()) 1077*09467b48Spatrick .addReg(MI->getOperand(1).getReg()) 1078*09467b48Spatrick .addExpr(SymGotTlsLD)); 1079*09467b48Spatrick return; 1080*09467b48Spatrick } 1081*09467b48Spatrick case PPC::GETtlsldADDR: 1082*09467b48Spatrick // Transform: %x3 = GETtlsldADDR %x3, @sym 1083*09467b48Spatrick // Into: BL8_NOP_TLS __tls_get_addr(sym at tlsld) 1084*09467b48Spatrick case PPC::GETtlsldADDR32: { 1085*09467b48Spatrick // Transform: %r3 = GETtlsldADDR32 %r3, @sym 1086*09467b48Spatrick // Into: BL_TLS __tls_get_addr(sym at tlsld)@PLT 1087*09467b48Spatrick EmitTlsCall(MI, MCSymbolRefExpr::VK_PPC_TLSLD); 1088*09467b48Spatrick return; 1089*09467b48Spatrick } 1090*09467b48Spatrick case PPC::ADDISdtprelHA: 1091*09467b48Spatrick // Transform: %xd = ADDISdtprelHA %xs, @sym 1092*09467b48Spatrick // Into: %xd = ADDIS8 %xs, sym@dtprel@ha 1093*09467b48Spatrick case PPC::ADDISdtprelHA32: { 1094*09467b48Spatrick // Transform: %rd = ADDISdtprelHA32 %rs, @sym 1095*09467b48Spatrick // Into: %rd = ADDIS %rs, sym@dtprel@ha 1096*09467b48Spatrick const MachineOperand &MO = MI->getOperand(2); 1097*09467b48Spatrick const GlobalValue *GValue = MO.getGlobal(); 1098*09467b48Spatrick MCSymbol *MOSymbol = getSymbol(GValue); 1099*09467b48Spatrick const MCExpr *SymDtprel = 1100*09467b48Spatrick MCSymbolRefExpr::create(MOSymbol, MCSymbolRefExpr::VK_PPC_DTPREL_HA, 1101*09467b48Spatrick OutContext); 1102*09467b48Spatrick EmitToStreamer( 1103*09467b48Spatrick *OutStreamer, 1104*09467b48Spatrick MCInstBuilder(IsPPC64 ? PPC::ADDIS8 : PPC::ADDIS) 1105*09467b48Spatrick .addReg(MI->getOperand(0).getReg()) 1106*09467b48Spatrick .addReg(MI->getOperand(1).getReg()) 1107*09467b48Spatrick .addExpr(SymDtprel)); 1108*09467b48Spatrick return; 1109*09467b48Spatrick } 1110*09467b48Spatrick case PPC::ADDIdtprelL: 1111*09467b48Spatrick // Transform: %xd = ADDIdtprelL %xs, @sym 1112*09467b48Spatrick // Into: %xd = ADDI8 %xs, sym@dtprel@l 1113*09467b48Spatrick case PPC::ADDIdtprelL32: { 1114*09467b48Spatrick // Transform: %rd = ADDIdtprelL32 %rs, @sym 1115*09467b48Spatrick // Into: %rd = ADDI %rs, sym@dtprel@l 1116*09467b48Spatrick const MachineOperand &MO = MI->getOperand(2); 1117*09467b48Spatrick const GlobalValue *GValue = MO.getGlobal(); 1118*09467b48Spatrick MCSymbol *MOSymbol = getSymbol(GValue); 1119*09467b48Spatrick const MCExpr *SymDtprel = 1120*09467b48Spatrick MCSymbolRefExpr::create(MOSymbol, MCSymbolRefExpr::VK_PPC_DTPREL_LO, 1121*09467b48Spatrick OutContext); 1122*09467b48Spatrick EmitToStreamer(*OutStreamer, 1123*09467b48Spatrick MCInstBuilder(IsPPC64 ? PPC::ADDI8 : PPC::ADDI) 1124*09467b48Spatrick .addReg(MI->getOperand(0).getReg()) 1125*09467b48Spatrick .addReg(MI->getOperand(1).getReg()) 1126*09467b48Spatrick .addExpr(SymDtprel)); 1127*09467b48Spatrick return; 1128*09467b48Spatrick } 1129*09467b48Spatrick case PPC::MFOCRF: 1130*09467b48Spatrick case PPC::MFOCRF8: 1131*09467b48Spatrick if (!Subtarget->hasMFOCRF()) { 1132*09467b48Spatrick // Transform: %r3 = MFOCRF %cr7 1133*09467b48Spatrick // Into: %r3 = MFCR ;; cr7 1134*09467b48Spatrick unsigned NewOpcode = 1135*09467b48Spatrick MI->getOpcode() == PPC::MFOCRF ? PPC::MFCR : PPC::MFCR8; 1136*09467b48Spatrick OutStreamer->AddComment(PPCInstPrinter:: 1137*09467b48Spatrick getRegisterName(MI->getOperand(1).getReg())); 1138*09467b48Spatrick EmitToStreamer(*OutStreamer, MCInstBuilder(NewOpcode) 1139*09467b48Spatrick .addReg(MI->getOperand(0).getReg())); 1140*09467b48Spatrick return; 1141*09467b48Spatrick } 1142*09467b48Spatrick break; 1143*09467b48Spatrick case PPC::MTOCRF: 1144*09467b48Spatrick case PPC::MTOCRF8: 1145*09467b48Spatrick if (!Subtarget->hasMFOCRF()) { 1146*09467b48Spatrick // Transform: %cr7 = MTOCRF %r3 1147*09467b48Spatrick // Into: MTCRF mask, %r3 ;; cr7 1148*09467b48Spatrick unsigned NewOpcode = 1149*09467b48Spatrick MI->getOpcode() == PPC::MTOCRF ? PPC::MTCRF : PPC::MTCRF8; 1150*09467b48Spatrick unsigned Mask = 0x80 >> OutContext.getRegisterInfo() 1151*09467b48Spatrick ->getEncodingValue(MI->getOperand(0).getReg()); 1152*09467b48Spatrick OutStreamer->AddComment(PPCInstPrinter:: 1153*09467b48Spatrick getRegisterName(MI->getOperand(0).getReg())); 1154*09467b48Spatrick EmitToStreamer(*OutStreamer, MCInstBuilder(NewOpcode) 1155*09467b48Spatrick .addImm(Mask) 1156*09467b48Spatrick .addReg(MI->getOperand(1).getReg())); 1157*09467b48Spatrick return; 1158*09467b48Spatrick } 1159*09467b48Spatrick break; 1160*09467b48Spatrick case PPC::LD: 1161*09467b48Spatrick case PPC::STD: 1162*09467b48Spatrick case PPC::LWA_32: 1163*09467b48Spatrick case PPC::LWA: { 1164*09467b48Spatrick // Verify alignment is legal, so we don't create relocations 1165*09467b48Spatrick // that can't be supported. 1166*09467b48Spatrick // FIXME: This test is currently disabled for Darwin. The test 1167*09467b48Spatrick // suite shows a handful of test cases that fail this check for 1168*09467b48Spatrick // Darwin. Those need to be investigated before this sanity test 1169*09467b48Spatrick // can be enabled for those subtargets. 1170*09467b48Spatrick if (!IsDarwin) { 1171*09467b48Spatrick unsigned OpNum = (MI->getOpcode() == PPC::STD) ? 2 : 1; 1172*09467b48Spatrick const MachineOperand &MO = MI->getOperand(OpNum); 1173*09467b48Spatrick if (MO.isGlobal() && MO.getGlobal()->getAlignment() < 4) 1174*09467b48Spatrick llvm_unreachable("Global must be word-aligned for LD, STD, LWA!"); 1175*09467b48Spatrick } 1176*09467b48Spatrick // Now process the instruction normally. 1177*09467b48Spatrick break; 1178*09467b48Spatrick } 1179*09467b48Spatrick } 1180*09467b48Spatrick 1181*09467b48Spatrick LowerPPCMachineInstrToMCInst(MI, TmpInst, *this, IsDarwin); 1182*09467b48Spatrick EmitToStreamer(*OutStreamer, TmpInst); 1183*09467b48Spatrick } 1184*09467b48Spatrick 1185*09467b48Spatrick void PPCLinuxAsmPrinter::EmitInstruction(const MachineInstr *MI) { 1186*09467b48Spatrick if (!Subtarget->isPPC64()) 1187*09467b48Spatrick return PPCAsmPrinter::EmitInstruction(MI); 1188*09467b48Spatrick 1189*09467b48Spatrick switch (MI->getOpcode()) { 1190*09467b48Spatrick default: 1191*09467b48Spatrick return PPCAsmPrinter::EmitInstruction(MI); 1192*09467b48Spatrick case TargetOpcode::PATCHABLE_FUNCTION_ENTER: { 1193*09467b48Spatrick // .begin: 1194*09467b48Spatrick // b .end # lis 0, FuncId[16..32] 1195*09467b48Spatrick // nop # li 0, FuncId[0..15] 1196*09467b48Spatrick // std 0, -8(1) 1197*09467b48Spatrick // mflr 0 1198*09467b48Spatrick // bl __xray_FunctionEntry 1199*09467b48Spatrick // mtlr 0 1200*09467b48Spatrick // .end: 1201*09467b48Spatrick // 1202*09467b48Spatrick // Update compiler-rt/lib/xray/xray_powerpc64.cc accordingly when number 1203*09467b48Spatrick // of instructions change. 1204*09467b48Spatrick MCSymbol *BeginOfSled = OutContext.createTempSymbol(); 1205*09467b48Spatrick MCSymbol *EndOfSled = OutContext.createTempSymbol(); 1206*09467b48Spatrick OutStreamer->EmitLabel(BeginOfSled); 1207*09467b48Spatrick EmitToStreamer(*OutStreamer, 1208*09467b48Spatrick MCInstBuilder(PPC::B).addExpr( 1209*09467b48Spatrick MCSymbolRefExpr::create(EndOfSled, OutContext))); 1210*09467b48Spatrick EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::NOP)); 1211*09467b48Spatrick EmitToStreamer( 1212*09467b48Spatrick *OutStreamer, 1213*09467b48Spatrick MCInstBuilder(PPC::STD).addReg(PPC::X0).addImm(-8).addReg(PPC::X1)); 1214*09467b48Spatrick EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::MFLR8).addReg(PPC::X0)); 1215*09467b48Spatrick EmitToStreamer(*OutStreamer, 1216*09467b48Spatrick MCInstBuilder(PPC::BL8_NOP) 1217*09467b48Spatrick .addExpr(MCSymbolRefExpr::create( 1218*09467b48Spatrick OutContext.getOrCreateSymbol("__xray_FunctionEntry"), 1219*09467b48Spatrick OutContext))); 1220*09467b48Spatrick EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::MTLR8).addReg(PPC::X0)); 1221*09467b48Spatrick OutStreamer->EmitLabel(EndOfSled); 1222*09467b48Spatrick recordSled(BeginOfSled, *MI, SledKind::FUNCTION_ENTER); 1223*09467b48Spatrick break; 1224*09467b48Spatrick } 1225*09467b48Spatrick case TargetOpcode::PATCHABLE_RET: { 1226*09467b48Spatrick unsigned RetOpcode = MI->getOperand(0).getImm(); 1227*09467b48Spatrick MCInst RetInst; 1228*09467b48Spatrick RetInst.setOpcode(RetOpcode); 1229*09467b48Spatrick for (const auto &MO : 1230*09467b48Spatrick make_range(std::next(MI->operands_begin()), MI->operands_end())) { 1231*09467b48Spatrick MCOperand MCOp; 1232*09467b48Spatrick if (LowerPPCMachineOperandToMCOperand(MO, MCOp, *this, false)) 1233*09467b48Spatrick RetInst.addOperand(MCOp); 1234*09467b48Spatrick } 1235*09467b48Spatrick 1236*09467b48Spatrick bool IsConditional; 1237*09467b48Spatrick if (RetOpcode == PPC::BCCLR) { 1238*09467b48Spatrick IsConditional = true; 1239*09467b48Spatrick } else if (RetOpcode == PPC::TCRETURNdi8 || RetOpcode == PPC::TCRETURNri8 || 1240*09467b48Spatrick RetOpcode == PPC::TCRETURNai8) { 1241*09467b48Spatrick break; 1242*09467b48Spatrick } else if (RetOpcode == PPC::BLR8 || RetOpcode == PPC::TAILB8) { 1243*09467b48Spatrick IsConditional = false; 1244*09467b48Spatrick } else { 1245*09467b48Spatrick EmitToStreamer(*OutStreamer, RetInst); 1246*09467b48Spatrick break; 1247*09467b48Spatrick } 1248*09467b48Spatrick 1249*09467b48Spatrick MCSymbol *FallthroughLabel; 1250*09467b48Spatrick if (IsConditional) { 1251*09467b48Spatrick // Before: 1252*09467b48Spatrick // bgtlr cr0 1253*09467b48Spatrick // 1254*09467b48Spatrick // After: 1255*09467b48Spatrick // ble cr0, .end 1256*09467b48Spatrick // .p2align 3 1257*09467b48Spatrick // .begin: 1258*09467b48Spatrick // blr # lis 0, FuncId[16..32] 1259*09467b48Spatrick // nop # li 0, FuncId[0..15] 1260*09467b48Spatrick // std 0, -8(1) 1261*09467b48Spatrick // mflr 0 1262*09467b48Spatrick // bl __xray_FunctionExit 1263*09467b48Spatrick // mtlr 0 1264*09467b48Spatrick // blr 1265*09467b48Spatrick // .end: 1266*09467b48Spatrick // 1267*09467b48Spatrick // Update compiler-rt/lib/xray/xray_powerpc64.cc accordingly when number 1268*09467b48Spatrick // of instructions change. 1269*09467b48Spatrick FallthroughLabel = OutContext.createTempSymbol(); 1270*09467b48Spatrick EmitToStreamer( 1271*09467b48Spatrick *OutStreamer, 1272*09467b48Spatrick MCInstBuilder(PPC::BCC) 1273*09467b48Spatrick .addImm(PPC::InvertPredicate( 1274*09467b48Spatrick static_cast<PPC::Predicate>(MI->getOperand(1).getImm()))) 1275*09467b48Spatrick .addReg(MI->getOperand(2).getReg()) 1276*09467b48Spatrick .addExpr(MCSymbolRefExpr::create(FallthroughLabel, OutContext))); 1277*09467b48Spatrick RetInst = MCInst(); 1278*09467b48Spatrick RetInst.setOpcode(PPC::BLR8); 1279*09467b48Spatrick } 1280*09467b48Spatrick // .p2align 3 1281*09467b48Spatrick // .begin: 1282*09467b48Spatrick // b(lr)? # lis 0, FuncId[16..32] 1283*09467b48Spatrick // nop # li 0, FuncId[0..15] 1284*09467b48Spatrick // std 0, -8(1) 1285*09467b48Spatrick // mflr 0 1286*09467b48Spatrick // bl __xray_FunctionExit 1287*09467b48Spatrick // mtlr 0 1288*09467b48Spatrick // b(lr)? 1289*09467b48Spatrick // 1290*09467b48Spatrick // Update compiler-rt/lib/xray/xray_powerpc64.cc accordingly when number 1291*09467b48Spatrick // of instructions change. 1292*09467b48Spatrick OutStreamer->EmitCodeAlignment(8); 1293*09467b48Spatrick MCSymbol *BeginOfSled = OutContext.createTempSymbol(); 1294*09467b48Spatrick OutStreamer->EmitLabel(BeginOfSled); 1295*09467b48Spatrick EmitToStreamer(*OutStreamer, RetInst); 1296*09467b48Spatrick EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::NOP)); 1297*09467b48Spatrick EmitToStreamer( 1298*09467b48Spatrick *OutStreamer, 1299*09467b48Spatrick MCInstBuilder(PPC::STD).addReg(PPC::X0).addImm(-8).addReg(PPC::X1)); 1300*09467b48Spatrick EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::MFLR8).addReg(PPC::X0)); 1301*09467b48Spatrick EmitToStreamer(*OutStreamer, 1302*09467b48Spatrick MCInstBuilder(PPC::BL8_NOP) 1303*09467b48Spatrick .addExpr(MCSymbolRefExpr::create( 1304*09467b48Spatrick OutContext.getOrCreateSymbol("__xray_FunctionExit"), 1305*09467b48Spatrick OutContext))); 1306*09467b48Spatrick EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::MTLR8).addReg(PPC::X0)); 1307*09467b48Spatrick EmitToStreamer(*OutStreamer, RetInst); 1308*09467b48Spatrick if (IsConditional) 1309*09467b48Spatrick OutStreamer->EmitLabel(FallthroughLabel); 1310*09467b48Spatrick recordSled(BeginOfSled, *MI, SledKind::FUNCTION_EXIT); 1311*09467b48Spatrick break; 1312*09467b48Spatrick } 1313*09467b48Spatrick case TargetOpcode::PATCHABLE_FUNCTION_EXIT: 1314*09467b48Spatrick llvm_unreachable("PATCHABLE_FUNCTION_EXIT should never be emitted"); 1315*09467b48Spatrick case TargetOpcode::PATCHABLE_TAIL_CALL: 1316*09467b48Spatrick // TODO: Define a trampoline `__xray_FunctionTailExit` and differentiate a 1317*09467b48Spatrick // normal function exit from a tail exit. 1318*09467b48Spatrick llvm_unreachable("Tail call is handled in the normal case. See comments " 1319*09467b48Spatrick "around this assert."); 1320*09467b48Spatrick } 1321*09467b48Spatrick } 1322*09467b48Spatrick 1323*09467b48Spatrick void PPCLinuxAsmPrinter::EmitStartOfAsmFile(Module &M) { 1324*09467b48Spatrick if (static_cast<const PPCTargetMachine &>(TM).isELFv2ABI()) { 1325*09467b48Spatrick PPCTargetStreamer *TS = 1326*09467b48Spatrick static_cast<PPCTargetStreamer *>(OutStreamer->getTargetStreamer()); 1327*09467b48Spatrick 1328*09467b48Spatrick if (TS) 1329*09467b48Spatrick TS->emitAbiVersion(2); 1330*09467b48Spatrick } 1331*09467b48Spatrick 1332*09467b48Spatrick if (static_cast<const PPCTargetMachine &>(TM).isPPC64() || 1333*09467b48Spatrick !isPositionIndependent()) 1334*09467b48Spatrick return AsmPrinter::EmitStartOfAsmFile(M); 1335*09467b48Spatrick 1336*09467b48Spatrick if (M.getPICLevel() == PICLevel::SmallPIC) 1337*09467b48Spatrick return AsmPrinter::EmitStartOfAsmFile(M); 1338*09467b48Spatrick 1339*09467b48Spatrick OutStreamer->SwitchSection(OutContext.getELFSection( 1340*09467b48Spatrick ".got2", ELF::SHT_PROGBITS, ELF::SHF_WRITE | ELF::SHF_ALLOC)); 1341*09467b48Spatrick 1342*09467b48Spatrick MCSymbol *TOCSym = OutContext.getOrCreateSymbol(Twine(".LTOC")); 1343*09467b48Spatrick MCSymbol *CurrentPos = OutContext.createTempSymbol(); 1344*09467b48Spatrick 1345*09467b48Spatrick OutStreamer->EmitLabel(CurrentPos); 1346*09467b48Spatrick 1347*09467b48Spatrick // The GOT pointer points to the middle of the GOT, in order to reference the 1348*09467b48Spatrick // entire 64kB range. 0x8000 is the midpoint. 1349*09467b48Spatrick const MCExpr *tocExpr = 1350*09467b48Spatrick MCBinaryExpr::createAdd(MCSymbolRefExpr::create(CurrentPos, OutContext), 1351*09467b48Spatrick MCConstantExpr::create(0x8000, OutContext), 1352*09467b48Spatrick OutContext); 1353*09467b48Spatrick 1354*09467b48Spatrick OutStreamer->EmitAssignment(TOCSym, tocExpr); 1355*09467b48Spatrick 1356*09467b48Spatrick OutStreamer->SwitchSection(getObjFileLowering().getTextSection()); 1357*09467b48Spatrick } 1358*09467b48Spatrick 1359*09467b48Spatrick void PPCLinuxAsmPrinter::EmitFunctionEntryLabel() { 1360*09467b48Spatrick // linux/ppc32 - Normal entry label. 1361*09467b48Spatrick if (!Subtarget->isPPC64() && 1362*09467b48Spatrick (!isPositionIndependent() || 1363*09467b48Spatrick MF->getFunction().getParent()->getPICLevel() == PICLevel::SmallPIC)) 1364*09467b48Spatrick return AsmPrinter::EmitFunctionEntryLabel(); 1365*09467b48Spatrick 1366*09467b48Spatrick if (!Subtarget->isPPC64()) { 1367*09467b48Spatrick const PPCFunctionInfo *PPCFI = MF->getInfo<PPCFunctionInfo>(); 1368*09467b48Spatrick if (PPCFI->usesPICBase() && !Subtarget->isSecurePlt()) { 1369*09467b48Spatrick MCSymbol *RelocSymbol = PPCFI->getPICOffsetSymbol(); 1370*09467b48Spatrick MCSymbol *PICBase = MF->getPICBaseSymbol(); 1371*09467b48Spatrick OutStreamer->EmitLabel(RelocSymbol); 1372*09467b48Spatrick 1373*09467b48Spatrick const MCExpr *OffsExpr = 1374*09467b48Spatrick MCBinaryExpr::createSub( 1375*09467b48Spatrick MCSymbolRefExpr::create(OutContext.getOrCreateSymbol(Twine(".LTOC")), 1376*09467b48Spatrick OutContext), 1377*09467b48Spatrick MCSymbolRefExpr::create(PICBase, OutContext), 1378*09467b48Spatrick OutContext); 1379*09467b48Spatrick OutStreamer->EmitValue(OffsExpr, 4); 1380*09467b48Spatrick OutStreamer->EmitLabel(CurrentFnSym); 1381*09467b48Spatrick return; 1382*09467b48Spatrick } else 1383*09467b48Spatrick return AsmPrinter::EmitFunctionEntryLabel(); 1384*09467b48Spatrick } 1385*09467b48Spatrick 1386*09467b48Spatrick // ELFv2 ABI - Normal entry label. 1387*09467b48Spatrick if (Subtarget->isELFv2ABI()) { 1388*09467b48Spatrick // In the Large code model, we allow arbitrary displacements between 1389*09467b48Spatrick // the text section and its associated TOC section. We place the 1390*09467b48Spatrick // full 8-byte offset to the TOC in memory immediately preceding 1391*09467b48Spatrick // the function global entry point. 1392*09467b48Spatrick if (TM.getCodeModel() == CodeModel::Large 1393*09467b48Spatrick && !MF->getRegInfo().use_empty(PPC::X2)) { 1394*09467b48Spatrick const PPCFunctionInfo *PPCFI = MF->getInfo<PPCFunctionInfo>(); 1395*09467b48Spatrick 1396*09467b48Spatrick MCSymbol *TOCSymbol = OutContext.getOrCreateSymbol(StringRef(".TOC.")); 1397*09467b48Spatrick MCSymbol *GlobalEPSymbol = PPCFI->getGlobalEPSymbol(); 1398*09467b48Spatrick const MCExpr *TOCDeltaExpr = 1399*09467b48Spatrick MCBinaryExpr::createSub(MCSymbolRefExpr::create(TOCSymbol, OutContext), 1400*09467b48Spatrick MCSymbolRefExpr::create(GlobalEPSymbol, 1401*09467b48Spatrick OutContext), 1402*09467b48Spatrick OutContext); 1403*09467b48Spatrick 1404*09467b48Spatrick OutStreamer->EmitLabel(PPCFI->getTOCOffsetSymbol()); 1405*09467b48Spatrick OutStreamer->EmitValue(TOCDeltaExpr, 8); 1406*09467b48Spatrick } 1407*09467b48Spatrick return AsmPrinter::EmitFunctionEntryLabel(); 1408*09467b48Spatrick } 1409*09467b48Spatrick 1410*09467b48Spatrick // Emit an official procedure descriptor. 1411*09467b48Spatrick MCSectionSubPair Current = OutStreamer->getCurrentSection(); 1412*09467b48Spatrick MCSectionELF *Section = OutStreamer->getContext().getELFSection( 1413*09467b48Spatrick ".opd", ELF::SHT_PROGBITS, ELF::SHF_WRITE | ELF::SHF_ALLOC); 1414*09467b48Spatrick OutStreamer->SwitchSection(Section); 1415*09467b48Spatrick OutStreamer->EmitLabel(CurrentFnSym); 1416*09467b48Spatrick OutStreamer->EmitValueToAlignment(8); 1417*09467b48Spatrick MCSymbol *Symbol1 = CurrentFnSymForSize; 1418*09467b48Spatrick // Generates a R_PPC64_ADDR64 (from FK_DATA_8) relocation for the function 1419*09467b48Spatrick // entry point. 1420*09467b48Spatrick OutStreamer->EmitValue(MCSymbolRefExpr::create(Symbol1, OutContext), 1421*09467b48Spatrick 8 /*size*/); 1422*09467b48Spatrick MCSymbol *Symbol2 = OutContext.getOrCreateSymbol(StringRef(".TOC.")); 1423*09467b48Spatrick // Generates a R_PPC64_TOC relocation for TOC base insertion. 1424*09467b48Spatrick OutStreamer->EmitValue( 1425*09467b48Spatrick MCSymbolRefExpr::create(Symbol2, MCSymbolRefExpr::VK_PPC_TOCBASE, OutContext), 1426*09467b48Spatrick 8/*size*/); 1427*09467b48Spatrick // Emit a null environment pointer. 1428*09467b48Spatrick OutStreamer->EmitIntValue(0, 8 /* size */); 1429*09467b48Spatrick OutStreamer->SwitchSection(Current.first, Current.second); 1430*09467b48Spatrick } 1431*09467b48Spatrick 1432*09467b48Spatrick bool PPCLinuxAsmPrinter::doFinalization(Module &M) { 1433*09467b48Spatrick const DataLayout &DL = getDataLayout(); 1434*09467b48Spatrick 1435*09467b48Spatrick bool isPPC64 = DL.getPointerSizeInBits() == 64; 1436*09467b48Spatrick 1437*09467b48Spatrick PPCTargetStreamer &TS = 1438*09467b48Spatrick static_cast<PPCTargetStreamer &>(*OutStreamer->getTargetStreamer()); 1439*09467b48Spatrick 1440*09467b48Spatrick if (!TOC.empty()) { 1441*09467b48Spatrick MCSectionELF *Section; 1442*09467b48Spatrick 1443*09467b48Spatrick if (isPPC64) 1444*09467b48Spatrick Section = OutStreamer->getContext().getELFSection( 1445*09467b48Spatrick ".toc", ELF::SHT_PROGBITS, ELF::SHF_WRITE | ELF::SHF_ALLOC); 1446*09467b48Spatrick else 1447*09467b48Spatrick Section = OutStreamer->getContext().getELFSection( 1448*09467b48Spatrick ".got2", ELF::SHT_PROGBITS, ELF::SHF_WRITE | ELF::SHF_ALLOC); 1449*09467b48Spatrick OutStreamer->SwitchSection(Section); 1450*09467b48Spatrick 1451*09467b48Spatrick for (const auto &TOCMapPair : TOC) { 1452*09467b48Spatrick const MCSymbol *const TOCEntryTarget = TOCMapPair.first; 1453*09467b48Spatrick MCSymbol *const TOCEntryLabel = TOCMapPair.second; 1454*09467b48Spatrick 1455*09467b48Spatrick OutStreamer->EmitLabel(TOCEntryLabel); 1456*09467b48Spatrick if (isPPC64) { 1457*09467b48Spatrick TS.emitTCEntry(*TOCEntryTarget); 1458*09467b48Spatrick } else { 1459*09467b48Spatrick OutStreamer->EmitValueToAlignment(4); 1460*09467b48Spatrick OutStreamer->EmitSymbolValue(TOCEntryTarget, 4); 1461*09467b48Spatrick } 1462*09467b48Spatrick } 1463*09467b48Spatrick } 1464*09467b48Spatrick 1465*09467b48Spatrick return AsmPrinter::doFinalization(M); 1466*09467b48Spatrick } 1467*09467b48Spatrick 1468*09467b48Spatrick /// EmitFunctionBodyStart - Emit a global entry point prefix for ELFv2. 1469*09467b48Spatrick void PPCLinuxAsmPrinter::EmitFunctionBodyStart() { 1470*09467b48Spatrick // In the ELFv2 ABI, in functions that use the TOC register, we need to 1471*09467b48Spatrick // provide two entry points. The ABI guarantees that when calling the 1472*09467b48Spatrick // local entry point, r2 is set up by the caller to contain the TOC base 1473*09467b48Spatrick // for this function, and when calling the global entry point, r12 is set 1474*09467b48Spatrick // up by the caller to hold the address of the global entry point. We 1475*09467b48Spatrick // thus emit a prefix sequence along the following lines: 1476*09467b48Spatrick // 1477*09467b48Spatrick // func: 1478*09467b48Spatrick // .Lfunc_gepNN: 1479*09467b48Spatrick // # global entry point 1480*09467b48Spatrick // addis r2,r12,(.TOC.-.Lfunc_gepNN)@ha 1481*09467b48Spatrick // addi r2,r2,(.TOC.-.Lfunc_gepNN)@l 1482*09467b48Spatrick // .Lfunc_lepNN: 1483*09467b48Spatrick // .localentry func, .Lfunc_lepNN-.Lfunc_gepNN 1484*09467b48Spatrick // # local entry point, followed by function body 1485*09467b48Spatrick // 1486*09467b48Spatrick // For the Large code model, we create 1487*09467b48Spatrick // 1488*09467b48Spatrick // .Lfunc_tocNN: 1489*09467b48Spatrick // .quad .TOC.-.Lfunc_gepNN # done by EmitFunctionEntryLabel 1490*09467b48Spatrick // func: 1491*09467b48Spatrick // .Lfunc_gepNN: 1492*09467b48Spatrick // # global entry point 1493*09467b48Spatrick // ld r2,.Lfunc_tocNN-.Lfunc_gepNN(r12) 1494*09467b48Spatrick // add r2,r2,r12 1495*09467b48Spatrick // .Lfunc_lepNN: 1496*09467b48Spatrick // .localentry func, .Lfunc_lepNN-.Lfunc_gepNN 1497*09467b48Spatrick // # local entry point, followed by function body 1498*09467b48Spatrick // 1499*09467b48Spatrick // This ensures we have r2 set up correctly while executing the function 1500*09467b48Spatrick // body, no matter which entry point is called. 1501*09467b48Spatrick if (Subtarget->isELFv2ABI() 1502*09467b48Spatrick // Only do all that if the function uses r2 in the first place. 1503*09467b48Spatrick && !MF->getRegInfo().use_empty(PPC::X2)) { 1504*09467b48Spatrick // Note: The logic here must be synchronized with the code in the 1505*09467b48Spatrick // branch-selection pass which sets the offset of the first block in the 1506*09467b48Spatrick // function. This matters because it affects the alignment. 1507*09467b48Spatrick const PPCFunctionInfo *PPCFI = MF->getInfo<PPCFunctionInfo>(); 1508*09467b48Spatrick 1509*09467b48Spatrick MCSymbol *GlobalEntryLabel = PPCFI->getGlobalEPSymbol(); 1510*09467b48Spatrick OutStreamer->EmitLabel(GlobalEntryLabel); 1511*09467b48Spatrick const MCSymbolRefExpr *GlobalEntryLabelExp = 1512*09467b48Spatrick MCSymbolRefExpr::create(GlobalEntryLabel, OutContext); 1513*09467b48Spatrick 1514*09467b48Spatrick if (TM.getCodeModel() != CodeModel::Large) { 1515*09467b48Spatrick MCSymbol *TOCSymbol = OutContext.getOrCreateSymbol(StringRef(".TOC.")); 1516*09467b48Spatrick const MCExpr *TOCDeltaExpr = 1517*09467b48Spatrick MCBinaryExpr::createSub(MCSymbolRefExpr::create(TOCSymbol, OutContext), 1518*09467b48Spatrick GlobalEntryLabelExp, OutContext); 1519*09467b48Spatrick 1520*09467b48Spatrick const MCExpr *TOCDeltaHi = 1521*09467b48Spatrick PPCMCExpr::createHa(TOCDeltaExpr, false, OutContext); 1522*09467b48Spatrick EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::ADDIS) 1523*09467b48Spatrick .addReg(PPC::X2) 1524*09467b48Spatrick .addReg(PPC::X12) 1525*09467b48Spatrick .addExpr(TOCDeltaHi)); 1526*09467b48Spatrick 1527*09467b48Spatrick const MCExpr *TOCDeltaLo = 1528*09467b48Spatrick PPCMCExpr::createLo(TOCDeltaExpr, false, OutContext); 1529*09467b48Spatrick EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::ADDI) 1530*09467b48Spatrick .addReg(PPC::X2) 1531*09467b48Spatrick .addReg(PPC::X2) 1532*09467b48Spatrick .addExpr(TOCDeltaLo)); 1533*09467b48Spatrick } else { 1534*09467b48Spatrick MCSymbol *TOCOffset = PPCFI->getTOCOffsetSymbol(); 1535*09467b48Spatrick const MCExpr *TOCOffsetDeltaExpr = 1536*09467b48Spatrick MCBinaryExpr::createSub(MCSymbolRefExpr::create(TOCOffset, OutContext), 1537*09467b48Spatrick GlobalEntryLabelExp, OutContext); 1538*09467b48Spatrick 1539*09467b48Spatrick EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::LD) 1540*09467b48Spatrick .addReg(PPC::X2) 1541*09467b48Spatrick .addExpr(TOCOffsetDeltaExpr) 1542*09467b48Spatrick .addReg(PPC::X12)); 1543*09467b48Spatrick EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::ADD8) 1544*09467b48Spatrick .addReg(PPC::X2) 1545*09467b48Spatrick .addReg(PPC::X2) 1546*09467b48Spatrick .addReg(PPC::X12)); 1547*09467b48Spatrick } 1548*09467b48Spatrick 1549*09467b48Spatrick MCSymbol *LocalEntryLabel = PPCFI->getLocalEPSymbol(); 1550*09467b48Spatrick OutStreamer->EmitLabel(LocalEntryLabel); 1551*09467b48Spatrick const MCSymbolRefExpr *LocalEntryLabelExp = 1552*09467b48Spatrick MCSymbolRefExpr::create(LocalEntryLabel, OutContext); 1553*09467b48Spatrick const MCExpr *LocalOffsetExp = 1554*09467b48Spatrick MCBinaryExpr::createSub(LocalEntryLabelExp, 1555*09467b48Spatrick GlobalEntryLabelExp, OutContext); 1556*09467b48Spatrick 1557*09467b48Spatrick PPCTargetStreamer *TS = 1558*09467b48Spatrick static_cast<PPCTargetStreamer *>(OutStreamer->getTargetStreamer()); 1559*09467b48Spatrick 1560*09467b48Spatrick if (TS) 1561*09467b48Spatrick TS->emitLocalEntry(cast<MCSymbolELF>(CurrentFnSym), LocalOffsetExp); 1562*09467b48Spatrick } 1563*09467b48Spatrick } 1564*09467b48Spatrick 1565*09467b48Spatrick /// EmitFunctionBodyEnd - Print the traceback table before the .size 1566*09467b48Spatrick /// directive. 1567*09467b48Spatrick /// 1568*09467b48Spatrick void PPCLinuxAsmPrinter::EmitFunctionBodyEnd() { 1569*09467b48Spatrick // Only the 64-bit target requires a traceback table. For now, 1570*09467b48Spatrick // we only emit the word of zeroes that GDB requires to find 1571*09467b48Spatrick // the end of the function, and zeroes for the eight-byte 1572*09467b48Spatrick // mandatory fields. 1573*09467b48Spatrick // FIXME: We should fill in the eight-byte mandatory fields as described in 1574*09467b48Spatrick // the PPC64 ELF ABI (this is a low-priority item because GDB does not 1575*09467b48Spatrick // currently make use of these fields). 1576*09467b48Spatrick if (Subtarget->isPPC64()) { 1577*09467b48Spatrick OutStreamer->EmitIntValue(0, 4/*size*/); 1578*09467b48Spatrick OutStreamer->EmitIntValue(0, 8/*size*/); 1579*09467b48Spatrick } 1580*09467b48Spatrick } 1581*09467b48Spatrick 1582*09467b48Spatrick void PPCAIXAsmPrinter::SetupMachineFunction(MachineFunction &MF) { 1583*09467b48Spatrick // Get the function descriptor symbol. 1584*09467b48Spatrick CurrentFnDescSym = getSymbol(&MF.getFunction()); 1585*09467b48Spatrick // Set the containing csect. 1586*09467b48Spatrick MCSectionXCOFF *FnDescSec = OutStreamer->getContext().getXCOFFSection( 1587*09467b48Spatrick CurrentFnDescSym->getName(), XCOFF::XMC_DS, XCOFF::XTY_SD, 1588*09467b48Spatrick XCOFF::C_HIDEXT, SectionKind::getData()); 1589*09467b48Spatrick cast<MCSymbolXCOFF>(CurrentFnDescSym)->setContainingCsect(FnDescSec); 1590*09467b48Spatrick 1591*09467b48Spatrick return AsmPrinter::SetupMachineFunction(MF); 1592*09467b48Spatrick } 1593*09467b48Spatrick 1594*09467b48Spatrick void PPCAIXAsmPrinter::ValidateGV(const GlobalVariable *GV) { 1595*09467b48Spatrick // Early error checking limiting what is supported. 1596*09467b48Spatrick if (GV->isThreadLocal()) 1597*09467b48Spatrick report_fatal_error("Thread local not yet supported on AIX."); 1598*09467b48Spatrick 1599*09467b48Spatrick if (GV->hasSection()) 1600*09467b48Spatrick report_fatal_error("Custom section for Data not yet supported."); 1601*09467b48Spatrick 1602*09467b48Spatrick if (GV->hasComdat()) 1603*09467b48Spatrick report_fatal_error("COMDAT not yet supported by AIX."); 1604*09467b48Spatrick } 1605*09467b48Spatrick 1606*09467b48Spatrick const MCExpr *PPCAIXAsmPrinter::lowerConstant(const Constant *CV) { 1607*09467b48Spatrick if (const Function *F = dyn_cast<Function>(CV)) { 1608*09467b48Spatrick MCSymbolXCOFF *FSym = cast<MCSymbolXCOFF>(getSymbol(F)); 1609*09467b48Spatrick if (!FSym->hasContainingCsect()) { 1610*09467b48Spatrick const XCOFF::StorageClass SC = 1611*09467b48Spatrick F->isDeclaration() 1612*09467b48Spatrick ? TargetLoweringObjectFileXCOFF::getStorageClassForGlobal(F) 1613*09467b48Spatrick : XCOFF::C_HIDEXT; 1614*09467b48Spatrick MCSectionXCOFF *Csect = OutStreamer->getContext().getXCOFFSection( 1615*09467b48Spatrick FSym->getName(), XCOFF::XMC_DS, 1616*09467b48Spatrick F->isDeclaration() ? XCOFF::XTY_ER : XCOFF::XTY_SD, SC, 1617*09467b48Spatrick SectionKind::getData()); 1618*09467b48Spatrick FSym->setContainingCsect(Csect); 1619*09467b48Spatrick } 1620*09467b48Spatrick return MCSymbolRefExpr::create( 1621*09467b48Spatrick FSym->getContainingCsect()->getQualNameSymbol(), OutContext); 1622*09467b48Spatrick } 1623*09467b48Spatrick return PPCAsmPrinter::lowerConstant(CV); 1624*09467b48Spatrick } 1625*09467b48Spatrick 1626*09467b48Spatrick void PPCAIXAsmPrinter::EmitGlobalVariable(const GlobalVariable *GV) { 1627*09467b48Spatrick ValidateGV(GV); 1628*09467b48Spatrick 1629*09467b48Spatrick // External global variables are already handled. 1630*09467b48Spatrick if (!GV->hasInitializer()) 1631*09467b48Spatrick return; 1632*09467b48Spatrick 1633*09467b48Spatrick // Create the symbol, set its storage class. 1634*09467b48Spatrick MCSymbolXCOFF *GVSym = cast<MCSymbolXCOFF>(getSymbol(GV)); 1635*09467b48Spatrick GVSym->setStorageClass( 1636*09467b48Spatrick TargetLoweringObjectFileXCOFF::getStorageClassForGlobal(GV)); 1637*09467b48Spatrick 1638*09467b48Spatrick SectionKind GVKind = getObjFileLowering().getKindForGlobal(GV, TM); 1639*09467b48Spatrick if ((!GVKind.isGlobalWriteableData() && !GVKind.isReadOnly()) || 1640*09467b48Spatrick GVKind.isMergeable2ByteCString() || GVKind.isMergeable4ByteCString()) 1641*09467b48Spatrick report_fatal_error("Encountered a global variable kind that is " 1642*09467b48Spatrick "not supported yet."); 1643*09467b48Spatrick 1644*09467b48Spatrick // Create the containing csect and switch to it. 1645*09467b48Spatrick MCSectionXCOFF *Csect = cast<MCSectionXCOFF>( 1646*09467b48Spatrick getObjFileLowering().SectionForGlobal(GV, GVKind, TM)); 1647*09467b48Spatrick OutStreamer->SwitchSection(Csect); 1648*09467b48Spatrick GVSym->setContainingCsect(Csect); 1649*09467b48Spatrick 1650*09467b48Spatrick const DataLayout &DL = GV->getParent()->getDataLayout(); 1651*09467b48Spatrick 1652*09467b48Spatrick // Handle common symbols. 1653*09467b48Spatrick if (GVKind.isCommon() || GVKind.isBSSLocal()) { 1654*09467b48Spatrick unsigned Align = 1655*09467b48Spatrick GV->getAlignment() ? GV->getAlignment() : DL.getPreferredAlignment(GV); 1656*09467b48Spatrick uint64_t Size = DL.getTypeAllocSize(GV->getType()->getElementType()); 1657*09467b48Spatrick 1658*09467b48Spatrick if (GVKind.isBSSLocal()) 1659*09467b48Spatrick OutStreamer->EmitXCOFFLocalCommonSymbol( 1660*09467b48Spatrick GVSym, Size, Csect->getQualNameSymbol(), Align); 1661*09467b48Spatrick else 1662*09467b48Spatrick OutStreamer->EmitCommonSymbol(Csect->getQualNameSymbol(), Size, Align); 1663*09467b48Spatrick return; 1664*09467b48Spatrick } 1665*09467b48Spatrick 1666*09467b48Spatrick MCSymbol *EmittedInitSym = GVSym; 1667*09467b48Spatrick EmitLinkage(GV, EmittedInitSym); 1668*09467b48Spatrick EmitAlignment(getGVAlignment(GV, DL), GV); 1669*09467b48Spatrick OutStreamer->EmitLabel(EmittedInitSym); 1670*09467b48Spatrick EmitGlobalConstant(GV->getParent()->getDataLayout(), GV->getInitializer()); 1671*09467b48Spatrick } 1672*09467b48Spatrick 1673*09467b48Spatrick void PPCAIXAsmPrinter::EmitFunctionDescriptor() { 1674*09467b48Spatrick const DataLayout &DL = getDataLayout(); 1675*09467b48Spatrick const unsigned PointerSize = DL.getPointerSizeInBits() == 64 ? 8 : 4; 1676*09467b48Spatrick 1677*09467b48Spatrick MCSectionSubPair Current = OutStreamer->getCurrentSection(); 1678*09467b48Spatrick // Emit function descriptor. 1679*09467b48Spatrick OutStreamer->SwitchSection( 1680*09467b48Spatrick cast<MCSymbolXCOFF>(CurrentFnDescSym)->getContainingCsect()); 1681*09467b48Spatrick OutStreamer->EmitLabel(CurrentFnDescSym); 1682*09467b48Spatrick // Emit function entry point address. 1683*09467b48Spatrick OutStreamer->EmitValue(MCSymbolRefExpr::create(CurrentFnSym, OutContext), 1684*09467b48Spatrick PointerSize); 1685*09467b48Spatrick // Emit TOC base address. 1686*09467b48Spatrick const MCSectionXCOFF *TOCBaseSec = OutStreamer->getContext().getXCOFFSection( 1687*09467b48Spatrick StringRef("TOC"), XCOFF::XMC_TC0, XCOFF::XTY_SD, XCOFF::C_HIDEXT, 1688*09467b48Spatrick SectionKind::getData()); 1689*09467b48Spatrick const MCSymbol *TOCBaseSym = TOCBaseSec->getQualNameSymbol(); 1690*09467b48Spatrick OutStreamer->EmitValue(MCSymbolRefExpr::create(TOCBaseSym, OutContext), 1691*09467b48Spatrick PointerSize); 1692*09467b48Spatrick // Emit a null environment pointer. 1693*09467b48Spatrick OutStreamer->EmitIntValue(0, PointerSize); 1694*09467b48Spatrick 1695*09467b48Spatrick OutStreamer->SwitchSection(Current.first, Current.second); 1696*09467b48Spatrick } 1697*09467b48Spatrick 1698*09467b48Spatrick void PPCAIXAsmPrinter::EmitEndOfAsmFile(Module &M) { 1699*09467b48Spatrick // If there are no functions in this module, we will never need to reference 1700*09467b48Spatrick // the TOC base. 1701*09467b48Spatrick if (M.empty()) 1702*09467b48Spatrick return; 1703*09467b48Spatrick 1704*09467b48Spatrick // Emit TOC base. 1705*09467b48Spatrick MCSectionXCOFF *TOCBaseSection = OutStreamer->getContext().getXCOFFSection( 1706*09467b48Spatrick StringRef("TOC"), XCOFF::XMC_TC0, XCOFF::XTY_SD, XCOFF::C_HIDEXT, 1707*09467b48Spatrick SectionKind::getData()); 1708*09467b48Spatrick // The TOC-base always has 0 size, but 4 byte alignment. 1709*09467b48Spatrick TOCBaseSection->setAlignment(Align(4)); 1710*09467b48Spatrick // Switch to section to emit TOC base. 1711*09467b48Spatrick OutStreamer->SwitchSection(TOCBaseSection); 1712*09467b48Spatrick 1713*09467b48Spatrick PPCTargetStreamer &TS = 1714*09467b48Spatrick static_cast<PPCTargetStreamer &>(*OutStreamer->getTargetStreamer()); 1715*09467b48Spatrick 1716*09467b48Spatrick for (auto &I : TOC) { 1717*09467b48Spatrick // Setup the csect for the current TC entry. 1718*09467b48Spatrick MCSectionXCOFF *TCEntry = OutStreamer->getContext().getXCOFFSection( 1719*09467b48Spatrick cast<MCSymbolXCOFF>(I.first)->getUnqualifiedName(), XCOFF::XMC_TC, 1720*09467b48Spatrick XCOFF::XTY_SD, XCOFF::C_HIDEXT, SectionKind::getData()); 1721*09467b48Spatrick cast<MCSymbolXCOFF>(I.second)->setContainingCsect(TCEntry); 1722*09467b48Spatrick OutStreamer->SwitchSection(TCEntry); 1723*09467b48Spatrick 1724*09467b48Spatrick OutStreamer->EmitLabel(I.second); 1725*09467b48Spatrick TS.emitTCEntry(*I.first); 1726*09467b48Spatrick } 1727*09467b48Spatrick } 1728*09467b48Spatrick 1729*09467b48Spatrick MCSymbol * 1730*09467b48Spatrick PPCAIXAsmPrinter::getMCSymbolForTOCPseudoMO(const MachineOperand &MO) { 1731*09467b48Spatrick const GlobalObject *GO = nullptr; 1732*09467b48Spatrick 1733*09467b48Spatrick // If the MO is a function or certain kind of globals, we want to make sure to 1734*09467b48Spatrick // refer to the csect symbol, otherwise we can just do the default handling. 1735*09467b48Spatrick if (MO.getType() != MachineOperand::MO_GlobalAddress || 1736*09467b48Spatrick !(GO = dyn_cast<const GlobalObject>(MO.getGlobal()))) 1737*09467b48Spatrick return PPCAsmPrinter::getMCSymbolForTOCPseudoMO(MO); 1738*09467b48Spatrick 1739*09467b48Spatrick // Do an early error check for globals we don't support. This will go away 1740*09467b48Spatrick // eventually. 1741*09467b48Spatrick const auto *GV = dyn_cast<const GlobalVariable>(GO); 1742*09467b48Spatrick if (GV) { 1743*09467b48Spatrick ValidateGV(GV); 1744*09467b48Spatrick } 1745*09467b48Spatrick 1746*09467b48Spatrick MCSymbolXCOFF *XSym = cast<MCSymbolXCOFF>(getSymbol(GO)); 1747*09467b48Spatrick 1748*09467b48Spatrick // If the global object is a global variable without initializer or is a 1749*09467b48Spatrick // declaration of a function, then XSym is an external referenced symbol. 1750*09467b48Spatrick // Hence we may need to explictly create a MCSectionXCOFF for it so that we 1751*09467b48Spatrick // can return its symbol later. 1752*09467b48Spatrick if (GO->isDeclaration()) { 1753*09467b48Spatrick if (!XSym->hasContainingCsect()) { 1754*09467b48Spatrick // Make sure the storage class is set. 1755*09467b48Spatrick const XCOFF::StorageClass SC = 1756*09467b48Spatrick TargetLoweringObjectFileXCOFF::getStorageClassForGlobal(GO); 1757*09467b48Spatrick XSym->setStorageClass(SC); 1758*09467b48Spatrick 1759*09467b48Spatrick MCSectionXCOFF *Csect = OutStreamer->getContext().getXCOFFSection( 1760*09467b48Spatrick XSym->getName(), isa<Function>(GO) ? XCOFF::XMC_DS : XCOFF::XMC_UA, 1761*09467b48Spatrick XCOFF::XTY_ER, SC, SectionKind::getMetadata()); 1762*09467b48Spatrick XSym->setContainingCsect(Csect); 1763*09467b48Spatrick } 1764*09467b48Spatrick 1765*09467b48Spatrick return XSym->getContainingCsect()->getQualNameSymbol(); 1766*09467b48Spatrick } 1767*09467b48Spatrick 1768*09467b48Spatrick // Handle initialized global variables and defined functions. 1769*09467b48Spatrick SectionKind GOKind = getObjFileLowering().getKindForGlobal(GO, TM); 1770*09467b48Spatrick 1771*09467b48Spatrick if (GOKind.isText()) { 1772*09467b48Spatrick // If the MO is a function, we want to make sure to refer to the function 1773*09467b48Spatrick // descriptor csect. 1774*09467b48Spatrick return OutStreamer->getContext() 1775*09467b48Spatrick .getXCOFFSection(XSym->getName(), XCOFF::XMC_DS, XCOFF::XTY_SD, 1776*09467b48Spatrick XCOFF::C_HIDEXT, SectionKind::getData()) 1777*09467b48Spatrick ->getQualNameSymbol(); 1778*09467b48Spatrick } else if (GOKind.isCommon() || GOKind.isBSSLocal()) { 1779*09467b48Spatrick // If the operand is a common then we should refer to the csect symbol. 1780*09467b48Spatrick return cast<MCSectionXCOFF>( 1781*09467b48Spatrick getObjFileLowering().SectionForGlobal(GO, GOKind, TM)) 1782*09467b48Spatrick ->getQualNameSymbol(); 1783*09467b48Spatrick } 1784*09467b48Spatrick 1785*09467b48Spatrick // Other global variables are refered to by labels inside of a single csect, 1786*09467b48Spatrick // so refer to the label directly. 1787*09467b48Spatrick return getSymbol(GV); 1788*09467b48Spatrick } 1789*09467b48Spatrick 1790*09467b48Spatrick /// createPPCAsmPrinterPass - Returns a pass that prints the PPC assembly code 1791*09467b48Spatrick /// for a MachineFunction to the given output stream, in a format that the 1792*09467b48Spatrick /// Darwin assembler can deal with. 1793*09467b48Spatrick /// 1794*09467b48Spatrick static AsmPrinter * 1795*09467b48Spatrick createPPCAsmPrinterPass(TargetMachine &tm, 1796*09467b48Spatrick std::unique_ptr<MCStreamer> &&Streamer) { 1797*09467b48Spatrick if (tm.getTargetTriple().isOSAIX()) 1798*09467b48Spatrick return new PPCAIXAsmPrinter(tm, std::move(Streamer)); 1799*09467b48Spatrick 1800*09467b48Spatrick return new PPCLinuxAsmPrinter(tm, std::move(Streamer)); 1801*09467b48Spatrick } 1802*09467b48Spatrick 1803*09467b48Spatrick // Force static initialization. 1804*09467b48Spatrick extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializePowerPCAsmPrinter() { 1805*09467b48Spatrick TargetRegistry::RegisterAsmPrinter(getThePPC32Target(), 1806*09467b48Spatrick createPPCAsmPrinterPass); 1807*09467b48Spatrick TargetRegistry::RegisterAsmPrinter(getThePPC64Target(), 1808*09467b48Spatrick createPPCAsmPrinterPass); 1809*09467b48Spatrick TargetRegistry::RegisterAsmPrinter(getThePPC64LETarget(), 1810*09467b48Spatrick createPPCAsmPrinterPass); 1811*09467b48Spatrick } 1812