xref: /openbsd-src/gnu/llvm/llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp (revision 09467b48e8bc8b4905716062da846024139afbf2)
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