xref: /aosp_15_r20/external/llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp (revision 9880d6810fe72a1726cb53787c6711e909410d58)
1*9880d681SAndroid Build Coastguard Worker //===-- PPCAsmPrinter.cpp - Print machine instrs to PowerPC assembly ------===//
2*9880d681SAndroid Build Coastguard Worker //
3*9880d681SAndroid Build Coastguard Worker //                     The LLVM Compiler Infrastructure
4*9880d681SAndroid Build Coastguard Worker //
5*9880d681SAndroid Build Coastguard Worker // This file is distributed under the University of Illinois Open Source
6*9880d681SAndroid Build Coastguard Worker // License. See LICENSE.TXT for details.
7*9880d681SAndroid Build Coastguard Worker //
8*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
9*9880d681SAndroid Build Coastguard Worker //
10*9880d681SAndroid Build Coastguard Worker // This file contains a printer that converts from our internal representation
11*9880d681SAndroid Build Coastguard Worker // of machine-dependent LLVM code to PowerPC assembly language. This printer is
12*9880d681SAndroid Build Coastguard Worker // the output mechanism used by `llc'.
13*9880d681SAndroid Build Coastguard Worker //
14*9880d681SAndroid Build Coastguard Worker // Documentation at http://developer.apple.com/documentation/DeveloperTools/
15*9880d681SAndroid Build Coastguard Worker // Reference/Assembler/ASMIntroduction/chapter_1_section_1.html
16*9880d681SAndroid Build Coastguard Worker //
17*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
18*9880d681SAndroid Build Coastguard Worker 
19*9880d681SAndroid Build Coastguard Worker #include "PPC.h"
20*9880d681SAndroid Build Coastguard Worker #include "InstPrinter/PPCInstPrinter.h"
21*9880d681SAndroid Build Coastguard Worker #include "MCTargetDesc/PPCMCExpr.h"
22*9880d681SAndroid Build Coastguard Worker #include "MCTargetDesc/PPCPredicates.h"
23*9880d681SAndroid Build Coastguard Worker #include "PPCMachineFunctionInfo.h"
24*9880d681SAndroid Build Coastguard Worker #include "PPCSubtarget.h"
25*9880d681SAndroid Build Coastguard Worker #include "PPCTargetMachine.h"
26*9880d681SAndroid Build Coastguard Worker #include "PPCTargetStreamer.h"
27*9880d681SAndroid Build Coastguard Worker #include "llvm/ADT/MapVector.h"
28*9880d681SAndroid Build Coastguard Worker #include "llvm/ADT/StringExtras.h"
29*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/AsmPrinter.h"
30*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/MachineConstantPool.h"
31*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/MachineFunctionPass.h"
32*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/MachineInstr.h"
33*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/MachineInstrBuilder.h"
34*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/MachineModuleInfoImpls.h"
35*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/MachineRegisterInfo.h"
36*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/StackMaps.h"
37*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/TargetLoweringObjectFileImpl.h"
38*9880d681SAndroid Build Coastguard Worker #include "llvm/IR/Constants.h"
39*9880d681SAndroid Build Coastguard Worker #include "llvm/IR/DebugInfo.h"
40*9880d681SAndroid Build Coastguard Worker #include "llvm/IR/DerivedTypes.h"
41*9880d681SAndroid Build Coastguard Worker #include "llvm/IR/Mangler.h"
42*9880d681SAndroid Build Coastguard Worker #include "llvm/IR/Module.h"
43*9880d681SAndroid Build Coastguard Worker #include "llvm/MC/MCAsmInfo.h"
44*9880d681SAndroid Build Coastguard Worker #include "llvm/MC/MCContext.h"
45*9880d681SAndroid Build Coastguard Worker #include "llvm/MC/MCExpr.h"
46*9880d681SAndroid Build Coastguard Worker #include "llvm/MC/MCInst.h"
47*9880d681SAndroid Build Coastguard Worker #include "llvm/MC/MCInstBuilder.h"
48*9880d681SAndroid Build Coastguard Worker #include "llvm/MC/MCSectionELF.h"
49*9880d681SAndroid Build Coastguard Worker #include "llvm/MC/MCSectionMachO.h"
50*9880d681SAndroid Build Coastguard Worker #include "llvm/MC/MCStreamer.h"
51*9880d681SAndroid Build Coastguard Worker #include "llvm/MC/MCSymbolELF.h"
52*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/Debug.h"
53*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/ELF.h"
54*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/ErrorHandling.h"
55*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/MathExtras.h"
56*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/TargetRegistry.h"
57*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/raw_ostream.h"
58*9880d681SAndroid Build Coastguard Worker #include "llvm/Target/TargetInstrInfo.h"
59*9880d681SAndroid Build Coastguard Worker #include "llvm/Target/TargetOptions.h"
60*9880d681SAndroid Build Coastguard Worker #include "llvm/Target/TargetRegisterInfo.h"
61*9880d681SAndroid Build Coastguard Worker using namespace llvm;
62*9880d681SAndroid Build Coastguard Worker 
63*9880d681SAndroid Build Coastguard Worker #define DEBUG_TYPE "asmprinter"
64*9880d681SAndroid Build Coastguard Worker 
65*9880d681SAndroid Build Coastguard Worker namespace {
66*9880d681SAndroid Build Coastguard Worker class PPCAsmPrinter : public AsmPrinter {
67*9880d681SAndroid Build Coastguard Worker protected:
68*9880d681SAndroid Build Coastguard Worker   MapVector<MCSymbol *, MCSymbol *> TOC;
69*9880d681SAndroid Build Coastguard Worker   const PPCSubtarget *Subtarget;
70*9880d681SAndroid Build Coastguard Worker   StackMaps SM;
71*9880d681SAndroid Build Coastguard Worker 
72*9880d681SAndroid Build Coastguard Worker public:
PPCAsmPrinter(TargetMachine & TM,std::unique_ptr<MCStreamer> Streamer)73*9880d681SAndroid Build Coastguard Worker   explicit PPCAsmPrinter(TargetMachine &TM,
74*9880d681SAndroid Build Coastguard Worker                          std::unique_ptr<MCStreamer> Streamer)
75*9880d681SAndroid Build Coastguard Worker       : AsmPrinter(TM, std::move(Streamer)), SM(*this) {}
76*9880d681SAndroid Build Coastguard Worker 
getPassName() const77*9880d681SAndroid Build Coastguard Worker   const char *getPassName() const override {
78*9880d681SAndroid Build Coastguard Worker     return "PowerPC Assembly Printer";
79*9880d681SAndroid Build Coastguard Worker   }
80*9880d681SAndroid Build Coastguard Worker 
81*9880d681SAndroid Build Coastguard Worker     MCSymbol *lookUpOrCreateTOCEntry(MCSymbol *Sym);
82*9880d681SAndroid Build Coastguard Worker 
doInitialization(Module & M)83*9880d681SAndroid Build Coastguard Worker     virtual bool doInitialization(Module &M) override {
84*9880d681SAndroid Build Coastguard Worker       if (!TOC.empty())
85*9880d681SAndroid Build Coastguard Worker         TOC.clear();
86*9880d681SAndroid Build Coastguard Worker       return AsmPrinter::doInitialization(M);
87*9880d681SAndroid Build Coastguard Worker     }
88*9880d681SAndroid Build Coastguard Worker 
89*9880d681SAndroid Build Coastguard Worker     void EmitInstruction(const MachineInstr *MI) override;
90*9880d681SAndroid Build Coastguard Worker 
91*9880d681SAndroid Build Coastguard Worker     void printOperand(const MachineInstr *MI, unsigned OpNo, raw_ostream &O);
92*9880d681SAndroid Build Coastguard Worker 
93*9880d681SAndroid Build Coastguard Worker     bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,
94*9880d681SAndroid Build Coastguard Worker                          unsigned AsmVariant, const char *ExtraCode,
95*9880d681SAndroid Build Coastguard Worker                          raw_ostream &O) override;
96*9880d681SAndroid Build Coastguard Worker     bool PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNo,
97*9880d681SAndroid Build Coastguard Worker                                unsigned AsmVariant, const char *ExtraCode,
98*9880d681SAndroid Build Coastguard Worker                                raw_ostream &O) override;
99*9880d681SAndroid Build Coastguard Worker 
100*9880d681SAndroid Build Coastguard Worker     void EmitEndOfAsmFile(Module &M) override;
101*9880d681SAndroid Build Coastguard Worker 
102*9880d681SAndroid Build Coastguard Worker     void LowerSTACKMAP(StackMaps &SM, const MachineInstr &MI);
103*9880d681SAndroid Build Coastguard Worker     void LowerPATCHPOINT(StackMaps &SM, const MachineInstr &MI);
104*9880d681SAndroid Build Coastguard Worker     void EmitTlsCall(const MachineInstr *MI, MCSymbolRefExpr::VariantKind VK);
runOnMachineFunction(MachineFunction & MF)105*9880d681SAndroid Build Coastguard Worker     bool runOnMachineFunction(MachineFunction &MF) override {
106*9880d681SAndroid Build Coastguard Worker       Subtarget = &MF.getSubtarget<PPCSubtarget>();
107*9880d681SAndroid Build Coastguard Worker       return AsmPrinter::runOnMachineFunction(MF);
108*9880d681SAndroid Build Coastguard Worker     }
109*9880d681SAndroid Build Coastguard Worker   };
110*9880d681SAndroid Build Coastguard Worker 
111*9880d681SAndroid Build Coastguard Worker   /// PPCLinuxAsmPrinter - PowerPC assembly printer, customized for Linux
112*9880d681SAndroid Build Coastguard Worker   class PPCLinuxAsmPrinter : public PPCAsmPrinter {
113*9880d681SAndroid Build Coastguard Worker   public:
PPCLinuxAsmPrinter(TargetMachine & TM,std::unique_ptr<MCStreamer> Streamer)114*9880d681SAndroid Build Coastguard Worker     explicit PPCLinuxAsmPrinter(TargetMachine &TM,
115*9880d681SAndroid Build Coastguard Worker                                 std::unique_ptr<MCStreamer> Streamer)
116*9880d681SAndroid Build Coastguard Worker         : PPCAsmPrinter(TM, std::move(Streamer)) {}
117*9880d681SAndroid Build Coastguard Worker 
getPassName() const118*9880d681SAndroid Build Coastguard Worker     const char *getPassName() const override {
119*9880d681SAndroid Build Coastguard Worker       return "Linux PPC Assembly Printer";
120*9880d681SAndroid Build Coastguard Worker     }
121*9880d681SAndroid Build Coastguard Worker 
122*9880d681SAndroid Build Coastguard Worker     bool doFinalization(Module &M) override;
123*9880d681SAndroid Build Coastguard Worker     void EmitStartOfAsmFile(Module &M) override;
124*9880d681SAndroid Build Coastguard Worker 
125*9880d681SAndroid Build Coastguard Worker     void EmitFunctionEntryLabel() override;
126*9880d681SAndroid Build Coastguard Worker 
127*9880d681SAndroid Build Coastguard Worker     void EmitFunctionBodyStart() override;
128*9880d681SAndroid Build Coastguard Worker     void EmitFunctionBodyEnd() override;
129*9880d681SAndroid Build Coastguard Worker   };
130*9880d681SAndroid Build Coastguard Worker 
131*9880d681SAndroid Build Coastguard Worker   /// PPCDarwinAsmPrinter - PowerPC assembly printer, customized for Darwin/Mac
132*9880d681SAndroid Build Coastguard Worker   /// OS X
133*9880d681SAndroid Build Coastguard Worker   class PPCDarwinAsmPrinter : public PPCAsmPrinter {
134*9880d681SAndroid Build Coastguard Worker   public:
PPCDarwinAsmPrinter(TargetMachine & TM,std::unique_ptr<MCStreamer> Streamer)135*9880d681SAndroid Build Coastguard Worker     explicit PPCDarwinAsmPrinter(TargetMachine &TM,
136*9880d681SAndroid Build Coastguard Worker                                  std::unique_ptr<MCStreamer> Streamer)
137*9880d681SAndroid Build Coastguard Worker         : PPCAsmPrinter(TM, std::move(Streamer)) {}
138*9880d681SAndroid Build Coastguard Worker 
getPassName() const139*9880d681SAndroid Build Coastguard Worker     const char *getPassName() const override {
140*9880d681SAndroid Build Coastguard Worker       return "Darwin PPC Assembly Printer";
141*9880d681SAndroid Build Coastguard Worker     }
142*9880d681SAndroid Build Coastguard Worker 
143*9880d681SAndroid Build Coastguard Worker     bool doFinalization(Module &M) override;
144*9880d681SAndroid Build Coastguard Worker     void EmitStartOfAsmFile(Module &M) override;
145*9880d681SAndroid Build Coastguard Worker   };
146*9880d681SAndroid Build Coastguard Worker } // end of anonymous namespace
147*9880d681SAndroid Build Coastguard Worker 
148*9880d681SAndroid Build Coastguard Worker /// stripRegisterPrefix - This method strips the character prefix from a
149*9880d681SAndroid Build Coastguard Worker /// register name so that only the number is left.  Used by for linux asm.
stripRegisterPrefix(const char * RegName)150*9880d681SAndroid Build Coastguard Worker static const char *stripRegisterPrefix(const char *RegName) {
151*9880d681SAndroid Build Coastguard Worker   switch (RegName[0]) {
152*9880d681SAndroid Build Coastguard Worker     case 'r':
153*9880d681SAndroid Build Coastguard Worker     case 'f':
154*9880d681SAndroid Build Coastguard Worker     case 'q': // for QPX
155*9880d681SAndroid Build Coastguard Worker     case 'v':
156*9880d681SAndroid Build Coastguard Worker       if (RegName[1] == 's')
157*9880d681SAndroid Build Coastguard Worker         return RegName + 2;
158*9880d681SAndroid Build Coastguard Worker       return RegName + 1;
159*9880d681SAndroid Build Coastguard Worker     case 'c': if (RegName[1] == 'r') return RegName + 2;
160*9880d681SAndroid Build Coastguard Worker   }
161*9880d681SAndroid Build Coastguard Worker 
162*9880d681SAndroid Build Coastguard Worker   return RegName;
163*9880d681SAndroid Build Coastguard Worker }
164*9880d681SAndroid Build Coastguard Worker 
printOperand(const MachineInstr * MI,unsigned OpNo,raw_ostream & O)165*9880d681SAndroid Build Coastguard Worker void PPCAsmPrinter::printOperand(const MachineInstr *MI, unsigned OpNo,
166*9880d681SAndroid Build Coastguard Worker                                  raw_ostream &O) {
167*9880d681SAndroid Build Coastguard Worker   const DataLayout &DL = getDataLayout();
168*9880d681SAndroid Build Coastguard Worker   const MachineOperand &MO = MI->getOperand(OpNo);
169*9880d681SAndroid Build Coastguard Worker 
170*9880d681SAndroid Build Coastguard Worker   switch (MO.getType()) {
171*9880d681SAndroid Build Coastguard Worker   case MachineOperand::MO_Register: {
172*9880d681SAndroid Build Coastguard Worker     const char *RegName = PPCInstPrinter::getRegisterName(MO.getReg());
173*9880d681SAndroid Build Coastguard Worker     // Linux assembler (Others?) does not take register mnemonics.
174*9880d681SAndroid Build Coastguard Worker     // FIXME - What about special registers used in mfspr/mtspr?
175*9880d681SAndroid Build Coastguard Worker     if (!Subtarget->isDarwin())
176*9880d681SAndroid Build Coastguard Worker       RegName = stripRegisterPrefix(RegName);
177*9880d681SAndroid Build Coastguard Worker     O << RegName;
178*9880d681SAndroid Build Coastguard Worker     return;
179*9880d681SAndroid Build Coastguard Worker   }
180*9880d681SAndroid Build Coastguard Worker   case MachineOperand::MO_Immediate:
181*9880d681SAndroid Build Coastguard Worker     O << MO.getImm();
182*9880d681SAndroid Build Coastguard Worker     return;
183*9880d681SAndroid Build Coastguard Worker 
184*9880d681SAndroid Build Coastguard Worker   case MachineOperand::MO_MachineBasicBlock:
185*9880d681SAndroid Build Coastguard Worker     MO.getMBB()->getSymbol()->print(O, MAI);
186*9880d681SAndroid Build Coastguard Worker     return;
187*9880d681SAndroid Build Coastguard Worker   case MachineOperand::MO_ConstantPoolIndex:
188*9880d681SAndroid Build Coastguard Worker     O << DL.getPrivateGlobalPrefix() << "CPI" << getFunctionNumber() << '_'
189*9880d681SAndroid Build Coastguard Worker       << MO.getIndex();
190*9880d681SAndroid Build Coastguard Worker     return;
191*9880d681SAndroid Build Coastguard Worker   case MachineOperand::MO_BlockAddress:
192*9880d681SAndroid Build Coastguard Worker     GetBlockAddressSymbol(MO.getBlockAddress())->print(O, MAI);
193*9880d681SAndroid Build Coastguard Worker     return;
194*9880d681SAndroid Build Coastguard Worker   case MachineOperand::MO_GlobalAddress: {
195*9880d681SAndroid Build Coastguard Worker     // Computing the address of a global symbol, not calling it.
196*9880d681SAndroid Build Coastguard Worker     const GlobalValue *GV = MO.getGlobal();
197*9880d681SAndroid Build Coastguard Worker     MCSymbol *SymToPrint;
198*9880d681SAndroid Build Coastguard Worker 
199*9880d681SAndroid Build Coastguard Worker     // External or weakly linked global variables need non-lazily-resolved stubs
200*9880d681SAndroid Build Coastguard Worker     if (Subtarget->hasLazyResolverStub(GV)) {
201*9880d681SAndroid Build Coastguard Worker       SymToPrint = getSymbolWithGlobalValueBase(GV, "$non_lazy_ptr");
202*9880d681SAndroid Build Coastguard Worker       MachineModuleInfoImpl::StubValueTy &StubSym =
203*9880d681SAndroid Build Coastguard Worker           MMI->getObjFileInfo<MachineModuleInfoMachO>().getGVStubEntry(
204*9880d681SAndroid Build Coastguard Worker               SymToPrint);
205*9880d681SAndroid Build Coastguard Worker       if (!StubSym.getPointer())
206*9880d681SAndroid Build Coastguard Worker         StubSym = MachineModuleInfoImpl::StubValueTy(getSymbol(GV),
207*9880d681SAndroid Build Coastguard Worker                                                      !GV->hasInternalLinkage());
208*9880d681SAndroid Build Coastguard Worker     } else {
209*9880d681SAndroid Build Coastguard Worker       SymToPrint = getSymbol(GV);
210*9880d681SAndroid Build Coastguard Worker     }
211*9880d681SAndroid Build Coastguard Worker 
212*9880d681SAndroid Build Coastguard Worker     SymToPrint->print(O, MAI);
213*9880d681SAndroid Build Coastguard Worker 
214*9880d681SAndroid Build Coastguard Worker     printOffset(MO.getOffset(), O);
215*9880d681SAndroid Build Coastguard Worker     return;
216*9880d681SAndroid Build Coastguard Worker   }
217*9880d681SAndroid Build Coastguard Worker 
218*9880d681SAndroid Build Coastguard Worker   default:
219*9880d681SAndroid Build Coastguard Worker     O << "<unknown operand type: " << (unsigned)MO.getType() << ">";
220*9880d681SAndroid Build Coastguard Worker     return;
221*9880d681SAndroid Build Coastguard Worker   }
222*9880d681SAndroid Build Coastguard Worker }
223*9880d681SAndroid Build Coastguard Worker 
224*9880d681SAndroid Build Coastguard Worker /// PrintAsmOperand - Print out an operand for an inline asm expression.
225*9880d681SAndroid Build Coastguard Worker ///
PrintAsmOperand(const MachineInstr * MI,unsigned OpNo,unsigned AsmVariant,const char * ExtraCode,raw_ostream & O)226*9880d681SAndroid Build Coastguard Worker bool PPCAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,
227*9880d681SAndroid Build Coastguard Worker                                     unsigned AsmVariant,
228*9880d681SAndroid Build Coastguard Worker                                     const char *ExtraCode, raw_ostream &O) {
229*9880d681SAndroid Build Coastguard Worker   // Does this asm operand have a single letter operand modifier?
230*9880d681SAndroid Build Coastguard Worker   if (ExtraCode && ExtraCode[0]) {
231*9880d681SAndroid Build Coastguard Worker     if (ExtraCode[1] != 0) return true; // Unknown modifier.
232*9880d681SAndroid Build Coastguard Worker 
233*9880d681SAndroid Build Coastguard Worker     switch (ExtraCode[0]) {
234*9880d681SAndroid Build Coastguard Worker     default:
235*9880d681SAndroid Build Coastguard Worker       // See if this is a generic print operand
236*9880d681SAndroid Build Coastguard Worker       return AsmPrinter::PrintAsmOperand(MI, OpNo, AsmVariant, ExtraCode, O);
237*9880d681SAndroid Build Coastguard Worker     case 'c': // Don't print "$" before a global var name or constant.
238*9880d681SAndroid Build Coastguard Worker       break; // PPC never has a prefix.
239*9880d681SAndroid Build Coastguard Worker     case 'L': // Write second word of DImode reference.
240*9880d681SAndroid Build Coastguard Worker       // Verify that this operand has two consecutive registers.
241*9880d681SAndroid Build Coastguard Worker       if (!MI->getOperand(OpNo).isReg() ||
242*9880d681SAndroid Build Coastguard Worker           OpNo+1 == MI->getNumOperands() ||
243*9880d681SAndroid Build Coastguard Worker           !MI->getOperand(OpNo+1).isReg())
244*9880d681SAndroid Build Coastguard Worker         return true;
245*9880d681SAndroid Build Coastguard Worker       ++OpNo;   // Return the high-part.
246*9880d681SAndroid Build Coastguard Worker       break;
247*9880d681SAndroid Build Coastguard Worker     case 'I':
248*9880d681SAndroid Build Coastguard Worker       // Write 'i' if an integer constant, otherwise nothing.  Used to print
249*9880d681SAndroid Build Coastguard Worker       // addi vs add, etc.
250*9880d681SAndroid Build Coastguard Worker       if (MI->getOperand(OpNo).isImm())
251*9880d681SAndroid Build Coastguard Worker         O << "i";
252*9880d681SAndroid Build Coastguard Worker       return false;
253*9880d681SAndroid Build Coastguard Worker     }
254*9880d681SAndroid Build Coastguard Worker   }
255*9880d681SAndroid Build Coastguard Worker 
256*9880d681SAndroid Build Coastguard Worker   printOperand(MI, OpNo, O);
257*9880d681SAndroid Build Coastguard Worker   return false;
258*9880d681SAndroid Build Coastguard Worker }
259*9880d681SAndroid Build Coastguard Worker 
260*9880d681SAndroid Build Coastguard Worker // At the moment, all inline asm memory operands are a single register.
261*9880d681SAndroid Build Coastguard Worker // In any case, the output of this routine should always be just one
262*9880d681SAndroid Build Coastguard Worker // assembler operand.
263*9880d681SAndroid Build Coastguard Worker 
PrintAsmMemoryOperand(const MachineInstr * MI,unsigned OpNo,unsigned AsmVariant,const char * ExtraCode,raw_ostream & O)264*9880d681SAndroid Build Coastguard Worker bool PPCAsmPrinter::PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNo,
265*9880d681SAndroid Build Coastguard Worker                                           unsigned AsmVariant,
266*9880d681SAndroid Build Coastguard Worker                                           const char *ExtraCode,
267*9880d681SAndroid Build Coastguard Worker                                           raw_ostream &O) {
268*9880d681SAndroid Build Coastguard Worker   if (ExtraCode && ExtraCode[0]) {
269*9880d681SAndroid Build Coastguard Worker     if (ExtraCode[1] != 0) return true; // Unknown modifier.
270*9880d681SAndroid Build Coastguard Worker 
271*9880d681SAndroid Build Coastguard Worker     switch (ExtraCode[0]) {
272*9880d681SAndroid Build Coastguard Worker     default: return true;  // Unknown modifier.
273*9880d681SAndroid Build Coastguard Worker     case 'y': // A memory reference for an X-form instruction
274*9880d681SAndroid Build Coastguard Worker       {
275*9880d681SAndroid Build Coastguard Worker         const char *RegName = "r0";
276*9880d681SAndroid Build Coastguard Worker         if (!Subtarget->isDarwin())
277*9880d681SAndroid Build Coastguard Worker           RegName = stripRegisterPrefix(RegName);
278*9880d681SAndroid Build Coastguard Worker         O << RegName << ", ";
279*9880d681SAndroid Build Coastguard Worker         printOperand(MI, OpNo, O);
280*9880d681SAndroid Build Coastguard Worker         return false;
281*9880d681SAndroid Build Coastguard Worker       }
282*9880d681SAndroid Build Coastguard Worker     case 'U': // Print 'u' for update form.
283*9880d681SAndroid Build Coastguard Worker     case 'X': // Print 'x' for indexed form.
284*9880d681SAndroid Build Coastguard Worker     {
285*9880d681SAndroid Build Coastguard Worker       // FIXME: Currently for PowerPC memory operands are always loaded
286*9880d681SAndroid Build Coastguard Worker       // into a register, so we never get an update or indexed form.
287*9880d681SAndroid Build Coastguard Worker       // This is bad even for offset forms, since even if we know we
288*9880d681SAndroid Build Coastguard Worker       // have a value in -16(r1), we will generate a load into r<n>
289*9880d681SAndroid Build Coastguard Worker       // and then load from 0(r<n>).  Until that issue is fixed,
290*9880d681SAndroid Build Coastguard Worker       // tolerate 'U' and 'X' but don't output anything.
291*9880d681SAndroid Build Coastguard Worker       assert(MI->getOperand(OpNo).isReg());
292*9880d681SAndroid Build Coastguard Worker       return false;
293*9880d681SAndroid Build Coastguard Worker     }
294*9880d681SAndroid Build Coastguard Worker     }
295*9880d681SAndroid Build Coastguard Worker   }
296*9880d681SAndroid Build Coastguard Worker 
297*9880d681SAndroid Build Coastguard Worker   assert(MI->getOperand(OpNo).isReg());
298*9880d681SAndroid Build Coastguard Worker   O << "0(";
299*9880d681SAndroid Build Coastguard Worker   printOperand(MI, OpNo, O);
300*9880d681SAndroid Build Coastguard Worker   O << ")";
301*9880d681SAndroid Build Coastguard Worker   return false;
302*9880d681SAndroid Build Coastguard Worker }
303*9880d681SAndroid Build Coastguard Worker 
304*9880d681SAndroid Build Coastguard Worker /// lookUpOrCreateTOCEntry -- Given a symbol, look up whether a TOC entry
305*9880d681SAndroid Build Coastguard Worker /// exists for it.  If not, create one.  Then return a symbol that references
306*9880d681SAndroid Build Coastguard Worker /// the TOC entry.
lookUpOrCreateTOCEntry(MCSymbol * Sym)307*9880d681SAndroid Build Coastguard Worker MCSymbol *PPCAsmPrinter::lookUpOrCreateTOCEntry(MCSymbol *Sym) {
308*9880d681SAndroid Build Coastguard Worker   MCSymbol *&TOCEntry = TOC[Sym];
309*9880d681SAndroid Build Coastguard Worker   if (!TOCEntry)
310*9880d681SAndroid Build Coastguard Worker     TOCEntry = createTempSymbol("C");
311*9880d681SAndroid Build Coastguard Worker   return TOCEntry;
312*9880d681SAndroid Build Coastguard Worker }
313*9880d681SAndroid Build Coastguard Worker 
EmitEndOfAsmFile(Module & M)314*9880d681SAndroid Build Coastguard Worker void PPCAsmPrinter::EmitEndOfAsmFile(Module &M) {
315*9880d681SAndroid Build Coastguard Worker   SM.serializeToStackMapSection();
316*9880d681SAndroid Build Coastguard Worker }
317*9880d681SAndroid Build Coastguard Worker 
LowerSTACKMAP(StackMaps & SM,const MachineInstr & MI)318*9880d681SAndroid Build Coastguard Worker void PPCAsmPrinter::LowerSTACKMAP(StackMaps &SM, const MachineInstr &MI) {
319*9880d681SAndroid Build Coastguard Worker   unsigned NumNOPBytes = MI.getOperand(1).getImm();
320*9880d681SAndroid Build Coastguard Worker 
321*9880d681SAndroid Build Coastguard Worker   SM.recordStackMap(MI);
322*9880d681SAndroid Build Coastguard Worker   assert(NumNOPBytes % 4 == 0 && "Invalid number of NOP bytes requested!");
323*9880d681SAndroid Build Coastguard Worker 
324*9880d681SAndroid Build Coastguard Worker   // Scan ahead to trim the shadow.
325*9880d681SAndroid Build Coastguard Worker   const MachineBasicBlock &MBB = *MI.getParent();
326*9880d681SAndroid Build Coastguard Worker   MachineBasicBlock::const_iterator MII(MI);
327*9880d681SAndroid Build Coastguard Worker   ++MII;
328*9880d681SAndroid Build Coastguard Worker   while (NumNOPBytes > 0) {
329*9880d681SAndroid Build Coastguard Worker     if (MII == MBB.end() || MII->isCall() ||
330*9880d681SAndroid Build Coastguard Worker         MII->getOpcode() == PPC::DBG_VALUE ||
331*9880d681SAndroid Build Coastguard Worker         MII->getOpcode() == TargetOpcode::PATCHPOINT ||
332*9880d681SAndroid Build Coastguard Worker         MII->getOpcode() == TargetOpcode::STACKMAP)
333*9880d681SAndroid Build Coastguard Worker       break;
334*9880d681SAndroid Build Coastguard Worker     ++MII;
335*9880d681SAndroid Build Coastguard Worker     NumNOPBytes -= 4;
336*9880d681SAndroid Build Coastguard Worker   }
337*9880d681SAndroid Build Coastguard Worker 
338*9880d681SAndroid Build Coastguard Worker   // Emit nops.
339*9880d681SAndroid Build Coastguard Worker   for (unsigned i = 0; i < NumNOPBytes; i += 4)
340*9880d681SAndroid Build Coastguard Worker     EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::NOP));
341*9880d681SAndroid Build Coastguard Worker }
342*9880d681SAndroid Build Coastguard Worker 
343*9880d681SAndroid Build Coastguard Worker // Lower a patchpoint of the form:
344*9880d681SAndroid Build Coastguard Worker // [<def>], <id>, <numBytes>, <target>, <numArgs>
LowerPATCHPOINT(StackMaps & SM,const MachineInstr & MI)345*9880d681SAndroid Build Coastguard Worker void PPCAsmPrinter::LowerPATCHPOINT(StackMaps &SM, const MachineInstr &MI) {
346*9880d681SAndroid Build Coastguard Worker   SM.recordPatchPoint(MI);
347*9880d681SAndroid Build Coastguard Worker   PatchPointOpers Opers(&MI);
348*9880d681SAndroid Build Coastguard Worker 
349*9880d681SAndroid Build Coastguard Worker   unsigned EncodedBytes = 0;
350*9880d681SAndroid Build Coastguard Worker   const MachineOperand &CalleeMO =
351*9880d681SAndroid Build Coastguard Worker     Opers.getMetaOper(PatchPointOpers::TargetPos);
352*9880d681SAndroid Build Coastguard Worker 
353*9880d681SAndroid Build Coastguard Worker   if (CalleeMO.isImm()) {
354*9880d681SAndroid Build Coastguard Worker     int64_t CallTarget = Opers.getMetaOper(PatchPointOpers::TargetPos).getImm();
355*9880d681SAndroid Build Coastguard Worker     if (CallTarget) {
356*9880d681SAndroid Build Coastguard Worker       assert((CallTarget & 0xFFFFFFFFFFFF) == CallTarget &&
357*9880d681SAndroid Build Coastguard Worker              "High 16 bits of call target should be zero.");
358*9880d681SAndroid Build Coastguard Worker       unsigned ScratchReg = MI.getOperand(Opers.getNextScratchIdx()).getReg();
359*9880d681SAndroid Build Coastguard Worker       EncodedBytes = 0;
360*9880d681SAndroid Build Coastguard Worker       // Materialize the jump address:
361*9880d681SAndroid Build Coastguard Worker       EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::LI8)
362*9880d681SAndroid Build Coastguard Worker                                       .addReg(ScratchReg)
363*9880d681SAndroid Build Coastguard Worker                                       .addImm((CallTarget >> 32) & 0xFFFF));
364*9880d681SAndroid Build Coastguard Worker       ++EncodedBytes;
365*9880d681SAndroid Build Coastguard Worker       EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::RLDIC)
366*9880d681SAndroid Build Coastguard Worker                                       .addReg(ScratchReg)
367*9880d681SAndroid Build Coastguard Worker                                       .addReg(ScratchReg)
368*9880d681SAndroid Build Coastguard Worker                                       .addImm(32).addImm(16));
369*9880d681SAndroid Build Coastguard Worker       ++EncodedBytes;
370*9880d681SAndroid Build Coastguard Worker       EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::ORIS8)
371*9880d681SAndroid Build Coastguard Worker                                       .addReg(ScratchReg)
372*9880d681SAndroid Build Coastguard Worker                                       .addReg(ScratchReg)
373*9880d681SAndroid Build Coastguard Worker                                       .addImm((CallTarget >> 16) & 0xFFFF));
374*9880d681SAndroid Build Coastguard Worker       ++EncodedBytes;
375*9880d681SAndroid Build Coastguard Worker       EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::ORI8)
376*9880d681SAndroid Build Coastguard Worker                                       .addReg(ScratchReg)
377*9880d681SAndroid Build Coastguard Worker                                       .addReg(ScratchReg)
378*9880d681SAndroid Build Coastguard Worker                                       .addImm(CallTarget & 0xFFFF));
379*9880d681SAndroid Build Coastguard Worker 
380*9880d681SAndroid Build Coastguard Worker       // Save the current TOC pointer before the remote call.
381*9880d681SAndroid Build Coastguard Worker       int TOCSaveOffset = Subtarget->isELFv2ABI() ? 24 : 40;
382*9880d681SAndroid Build Coastguard Worker       EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::STD)
383*9880d681SAndroid Build Coastguard Worker                                       .addReg(PPC::X2)
384*9880d681SAndroid Build Coastguard Worker                                       .addImm(TOCSaveOffset)
385*9880d681SAndroid Build Coastguard Worker                                       .addReg(PPC::X1));
386*9880d681SAndroid Build Coastguard Worker       ++EncodedBytes;
387*9880d681SAndroid Build Coastguard Worker 
388*9880d681SAndroid Build Coastguard Worker       // If we're on ELFv1, then we need to load the actual function pointer
389*9880d681SAndroid Build Coastguard Worker       // from the function descriptor.
390*9880d681SAndroid Build Coastguard Worker       if (!Subtarget->isELFv2ABI()) {
391*9880d681SAndroid Build Coastguard Worker         // Load the new TOC pointer and the function address, but not r11
392*9880d681SAndroid Build Coastguard Worker         // (needing this is rare, and loading it here would prevent passing it
393*9880d681SAndroid Build Coastguard Worker         // via a 'nest' parameter.
394*9880d681SAndroid Build Coastguard Worker         EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::LD)
395*9880d681SAndroid Build Coastguard Worker                                         .addReg(PPC::X2)
396*9880d681SAndroid Build Coastguard Worker                                         .addImm(8)
397*9880d681SAndroid Build Coastguard Worker                                         .addReg(ScratchReg));
398*9880d681SAndroid Build Coastguard Worker         ++EncodedBytes;
399*9880d681SAndroid Build Coastguard Worker         EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::LD)
400*9880d681SAndroid Build Coastguard Worker                                         .addReg(ScratchReg)
401*9880d681SAndroid Build Coastguard Worker                                         .addImm(0)
402*9880d681SAndroid Build Coastguard Worker                                         .addReg(ScratchReg));
403*9880d681SAndroid Build Coastguard Worker         ++EncodedBytes;
404*9880d681SAndroid Build Coastguard Worker       }
405*9880d681SAndroid Build Coastguard Worker 
406*9880d681SAndroid Build Coastguard Worker       EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::MTCTR8)
407*9880d681SAndroid Build Coastguard Worker                                       .addReg(ScratchReg));
408*9880d681SAndroid Build Coastguard Worker       ++EncodedBytes;
409*9880d681SAndroid Build Coastguard Worker       EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::BCTRL8));
410*9880d681SAndroid Build Coastguard Worker       ++EncodedBytes;
411*9880d681SAndroid Build Coastguard Worker 
412*9880d681SAndroid Build Coastguard Worker       // Restore the TOC pointer after the call.
413*9880d681SAndroid Build Coastguard Worker       EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::LD)
414*9880d681SAndroid Build Coastguard Worker                                       .addReg(PPC::X2)
415*9880d681SAndroid Build Coastguard Worker                                       .addImm(TOCSaveOffset)
416*9880d681SAndroid Build Coastguard Worker                                       .addReg(PPC::X1));
417*9880d681SAndroid Build Coastguard Worker       ++EncodedBytes;
418*9880d681SAndroid Build Coastguard Worker     }
419*9880d681SAndroid Build Coastguard Worker   } else if (CalleeMO.isGlobal()) {
420*9880d681SAndroid Build Coastguard Worker     const GlobalValue *GValue = CalleeMO.getGlobal();
421*9880d681SAndroid Build Coastguard Worker     MCSymbol *MOSymbol = getSymbol(GValue);
422*9880d681SAndroid Build Coastguard Worker     const MCExpr *SymVar = MCSymbolRefExpr::create(MOSymbol, OutContext);
423*9880d681SAndroid Build Coastguard Worker 
424*9880d681SAndroid Build Coastguard Worker     EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::BL8_NOP)
425*9880d681SAndroid Build Coastguard Worker                                     .addExpr(SymVar));
426*9880d681SAndroid Build Coastguard Worker     EncodedBytes += 2;
427*9880d681SAndroid Build Coastguard Worker   }
428*9880d681SAndroid Build Coastguard Worker 
429*9880d681SAndroid Build Coastguard Worker   // Each instruction is 4 bytes.
430*9880d681SAndroid Build Coastguard Worker   EncodedBytes *= 4;
431*9880d681SAndroid Build Coastguard Worker 
432*9880d681SAndroid Build Coastguard Worker   // Emit padding.
433*9880d681SAndroid Build Coastguard Worker   unsigned NumBytes = Opers.getMetaOper(PatchPointOpers::NBytesPos).getImm();
434*9880d681SAndroid Build Coastguard Worker   assert(NumBytes >= EncodedBytes &&
435*9880d681SAndroid Build Coastguard Worker          "Patchpoint can't request size less than the length of a call.");
436*9880d681SAndroid Build Coastguard Worker   assert((NumBytes - EncodedBytes) % 4 == 0 &&
437*9880d681SAndroid Build Coastguard Worker          "Invalid number of NOP bytes requested!");
438*9880d681SAndroid Build Coastguard Worker   for (unsigned i = EncodedBytes; i < NumBytes; i += 4)
439*9880d681SAndroid Build Coastguard Worker     EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::NOP));
440*9880d681SAndroid Build Coastguard Worker }
441*9880d681SAndroid Build Coastguard Worker 
442*9880d681SAndroid Build Coastguard Worker /// EmitTlsCall -- Given a GETtls[ld]ADDR[32] instruction, print a
443*9880d681SAndroid Build Coastguard Worker /// call to __tls_get_addr to the current output stream.
EmitTlsCall(const MachineInstr * MI,MCSymbolRefExpr::VariantKind VK)444*9880d681SAndroid Build Coastguard Worker void PPCAsmPrinter::EmitTlsCall(const MachineInstr *MI,
445*9880d681SAndroid Build Coastguard Worker                                 MCSymbolRefExpr::VariantKind VK) {
446*9880d681SAndroid Build Coastguard Worker   StringRef Name = "__tls_get_addr";
447*9880d681SAndroid Build Coastguard Worker   MCSymbol *TlsGetAddr = OutContext.getOrCreateSymbol(Name);
448*9880d681SAndroid Build Coastguard Worker   MCSymbolRefExpr::VariantKind Kind = MCSymbolRefExpr::VK_None;
449*9880d681SAndroid Build Coastguard Worker 
450*9880d681SAndroid Build Coastguard Worker   assert(MI->getOperand(0).isReg() &&
451*9880d681SAndroid Build Coastguard Worker          ((Subtarget->isPPC64() && MI->getOperand(0).getReg() == PPC::X3) ||
452*9880d681SAndroid Build Coastguard Worker           (!Subtarget->isPPC64() && MI->getOperand(0).getReg() == PPC::R3)) &&
453*9880d681SAndroid Build Coastguard Worker          "GETtls[ld]ADDR[32] must define GPR3");
454*9880d681SAndroid Build Coastguard Worker   assert(MI->getOperand(1).isReg() &&
455*9880d681SAndroid Build Coastguard Worker          ((Subtarget->isPPC64() && MI->getOperand(1).getReg() == PPC::X3) ||
456*9880d681SAndroid Build Coastguard Worker           (!Subtarget->isPPC64() && MI->getOperand(1).getReg() == PPC::R3)) &&
457*9880d681SAndroid Build Coastguard Worker          "GETtls[ld]ADDR[32] must read GPR3");
458*9880d681SAndroid Build Coastguard Worker 
459*9880d681SAndroid Build Coastguard Worker   if (!Subtarget->isPPC64() && !Subtarget->isDarwin() &&
460*9880d681SAndroid Build Coastguard Worker       isPositionIndependent())
461*9880d681SAndroid Build Coastguard Worker     Kind = MCSymbolRefExpr::VK_PLT;
462*9880d681SAndroid Build Coastguard Worker   const MCSymbolRefExpr *TlsRef =
463*9880d681SAndroid Build Coastguard Worker     MCSymbolRefExpr::create(TlsGetAddr, Kind, OutContext);
464*9880d681SAndroid Build Coastguard Worker   const MachineOperand &MO = MI->getOperand(2);
465*9880d681SAndroid Build Coastguard Worker   const GlobalValue *GValue = MO.getGlobal();
466*9880d681SAndroid Build Coastguard Worker   MCSymbol *MOSymbol = getSymbol(GValue);
467*9880d681SAndroid Build Coastguard Worker   const MCExpr *SymVar = MCSymbolRefExpr::create(MOSymbol, VK, OutContext);
468*9880d681SAndroid Build Coastguard Worker   EmitToStreamer(*OutStreamer,
469*9880d681SAndroid Build Coastguard Worker                  MCInstBuilder(Subtarget->isPPC64() ?
470*9880d681SAndroid Build Coastguard Worker                                PPC::BL8_NOP_TLS : PPC::BL_TLS)
471*9880d681SAndroid Build Coastguard Worker                  .addExpr(TlsRef)
472*9880d681SAndroid Build Coastguard Worker                  .addExpr(SymVar));
473*9880d681SAndroid Build Coastguard Worker }
474*9880d681SAndroid Build Coastguard Worker 
475*9880d681SAndroid Build Coastguard Worker /// EmitInstruction -- Print out a single PowerPC MI in Darwin syntax to
476*9880d681SAndroid Build Coastguard Worker /// the current output stream.
477*9880d681SAndroid Build Coastguard Worker ///
EmitInstruction(const MachineInstr * MI)478*9880d681SAndroid Build Coastguard Worker void PPCAsmPrinter::EmitInstruction(const MachineInstr *MI) {
479*9880d681SAndroid Build Coastguard Worker   MCInst TmpInst;
480*9880d681SAndroid Build Coastguard Worker   bool isPPC64 = Subtarget->isPPC64();
481*9880d681SAndroid Build Coastguard Worker   bool isDarwin = TM.getTargetTriple().isOSDarwin();
482*9880d681SAndroid Build Coastguard Worker   const Module *M = MF->getFunction()->getParent();
483*9880d681SAndroid Build Coastguard Worker   PICLevel::Level PL = M->getPICLevel();
484*9880d681SAndroid Build Coastguard Worker 
485*9880d681SAndroid Build Coastguard Worker   // Lower multi-instruction pseudo operations.
486*9880d681SAndroid Build Coastguard Worker   switch (MI->getOpcode()) {
487*9880d681SAndroid Build Coastguard Worker   default: break;
488*9880d681SAndroid Build Coastguard Worker   case TargetOpcode::DBG_VALUE:
489*9880d681SAndroid Build Coastguard Worker     llvm_unreachable("Should be handled target independently");
490*9880d681SAndroid Build Coastguard Worker   case TargetOpcode::STACKMAP:
491*9880d681SAndroid Build Coastguard Worker     return LowerSTACKMAP(SM, *MI);
492*9880d681SAndroid Build Coastguard Worker   case TargetOpcode::PATCHPOINT:
493*9880d681SAndroid Build Coastguard Worker     return LowerPATCHPOINT(SM, *MI);
494*9880d681SAndroid Build Coastguard Worker 
495*9880d681SAndroid Build Coastguard Worker   case PPC::MoveGOTtoLR: {
496*9880d681SAndroid Build Coastguard Worker     // Transform %LR = MoveGOTtoLR
497*9880d681SAndroid Build Coastguard Worker     // Into this: bl _GLOBAL_OFFSET_TABLE_@local-4
498*9880d681SAndroid Build Coastguard Worker     // _GLOBAL_OFFSET_TABLE_@local-4 (instruction preceding
499*9880d681SAndroid Build Coastguard Worker     // _GLOBAL_OFFSET_TABLE_) has exactly one instruction:
500*9880d681SAndroid Build Coastguard Worker     //      blrl
501*9880d681SAndroid Build Coastguard Worker     // This will return the pointer to _GLOBAL_OFFSET_TABLE_@local
502*9880d681SAndroid Build Coastguard Worker     MCSymbol *GOTSymbol =
503*9880d681SAndroid Build Coastguard Worker       OutContext.getOrCreateSymbol(StringRef("_GLOBAL_OFFSET_TABLE_"));
504*9880d681SAndroid Build Coastguard Worker     const MCExpr *OffsExpr =
505*9880d681SAndroid Build Coastguard Worker       MCBinaryExpr::createSub(MCSymbolRefExpr::create(GOTSymbol,
506*9880d681SAndroid Build Coastguard Worker                                                       MCSymbolRefExpr::VK_PPC_LOCAL,
507*9880d681SAndroid Build Coastguard Worker                                                       OutContext),
508*9880d681SAndroid Build Coastguard Worker                               MCConstantExpr::create(4, OutContext),
509*9880d681SAndroid Build Coastguard Worker                               OutContext);
510*9880d681SAndroid Build Coastguard Worker 
511*9880d681SAndroid Build Coastguard Worker     // Emit the 'bl'.
512*9880d681SAndroid Build Coastguard Worker     EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::BL).addExpr(OffsExpr));
513*9880d681SAndroid Build Coastguard Worker     return;
514*9880d681SAndroid Build Coastguard Worker   }
515*9880d681SAndroid Build Coastguard Worker   case PPC::MovePCtoLR:
516*9880d681SAndroid Build Coastguard Worker   case PPC::MovePCtoLR8: {
517*9880d681SAndroid Build Coastguard Worker     // Transform %LR = MovePCtoLR
518*9880d681SAndroid Build Coastguard Worker     // Into this, where the label is the PIC base:
519*9880d681SAndroid Build Coastguard Worker     //     bl L1$pb
520*9880d681SAndroid Build Coastguard Worker     // L1$pb:
521*9880d681SAndroid Build Coastguard Worker     MCSymbol *PICBase = MF->getPICBaseSymbol();
522*9880d681SAndroid Build Coastguard Worker 
523*9880d681SAndroid Build Coastguard Worker     // Emit the 'bl'.
524*9880d681SAndroid Build Coastguard Worker     EmitToStreamer(*OutStreamer,
525*9880d681SAndroid Build Coastguard Worker                    MCInstBuilder(PPC::BL)
526*9880d681SAndroid Build Coastguard Worker                        // FIXME: We would like an efficient form for this, so we
527*9880d681SAndroid Build Coastguard Worker                        // don't have to do a lot of extra uniquing.
528*9880d681SAndroid Build Coastguard Worker                        .addExpr(MCSymbolRefExpr::create(PICBase, OutContext)));
529*9880d681SAndroid Build Coastguard Worker 
530*9880d681SAndroid Build Coastguard Worker     // Emit the label.
531*9880d681SAndroid Build Coastguard Worker     OutStreamer->EmitLabel(PICBase);
532*9880d681SAndroid Build Coastguard Worker     return;
533*9880d681SAndroid Build Coastguard Worker   }
534*9880d681SAndroid Build Coastguard Worker   case PPC::UpdateGBR: {
535*9880d681SAndroid Build Coastguard Worker     // Transform %Rd = UpdateGBR(%Rt, %Ri)
536*9880d681SAndroid Build Coastguard Worker     // Into: lwz %Rt, .L0$poff - .L0$pb(%Ri)
537*9880d681SAndroid Build Coastguard Worker     //       add %Rd, %Rt, %Ri
538*9880d681SAndroid Build Coastguard Worker     // Get the offset from the GOT Base Register to the GOT
539*9880d681SAndroid Build Coastguard Worker     LowerPPCMachineInstrToMCInst(MI, TmpInst, *this, isDarwin);
540*9880d681SAndroid Build Coastguard Worker     MCSymbol *PICOffset =
541*9880d681SAndroid Build Coastguard Worker       MF->getInfo<PPCFunctionInfo>()->getPICOffsetSymbol();
542*9880d681SAndroid Build Coastguard Worker     TmpInst.setOpcode(PPC::LWZ);
543*9880d681SAndroid Build Coastguard Worker     const MCExpr *Exp =
544*9880d681SAndroid Build Coastguard Worker       MCSymbolRefExpr::create(PICOffset, MCSymbolRefExpr::VK_None, OutContext);
545*9880d681SAndroid Build Coastguard Worker     const MCExpr *PB =
546*9880d681SAndroid Build Coastguard Worker       MCSymbolRefExpr::create(MF->getPICBaseSymbol(),
547*9880d681SAndroid Build Coastguard Worker                               MCSymbolRefExpr::VK_None,
548*9880d681SAndroid Build Coastguard Worker                               OutContext);
549*9880d681SAndroid Build Coastguard Worker     const MCOperand TR = TmpInst.getOperand(1);
550*9880d681SAndroid Build Coastguard Worker     const MCOperand PICR = TmpInst.getOperand(0);
551*9880d681SAndroid Build Coastguard Worker 
552*9880d681SAndroid Build Coastguard Worker     // Step 1: lwz %Rt, .L$poff - .L$pb(%Ri)
553*9880d681SAndroid Build Coastguard Worker     TmpInst.getOperand(1) =
554*9880d681SAndroid Build Coastguard Worker         MCOperand::createExpr(MCBinaryExpr::createSub(Exp, PB, OutContext));
555*9880d681SAndroid Build Coastguard Worker     TmpInst.getOperand(0) = TR;
556*9880d681SAndroid Build Coastguard Worker     TmpInst.getOperand(2) = PICR;
557*9880d681SAndroid Build Coastguard Worker     EmitToStreamer(*OutStreamer, TmpInst);
558*9880d681SAndroid Build Coastguard Worker 
559*9880d681SAndroid Build Coastguard Worker     TmpInst.setOpcode(PPC::ADD4);
560*9880d681SAndroid Build Coastguard Worker     TmpInst.getOperand(0) = PICR;
561*9880d681SAndroid Build Coastguard Worker     TmpInst.getOperand(1) = TR;
562*9880d681SAndroid Build Coastguard Worker     TmpInst.getOperand(2) = PICR;
563*9880d681SAndroid Build Coastguard Worker     EmitToStreamer(*OutStreamer, TmpInst);
564*9880d681SAndroid Build Coastguard Worker     return;
565*9880d681SAndroid Build Coastguard Worker   }
566*9880d681SAndroid Build Coastguard Worker   case PPC::LWZtoc: {
567*9880d681SAndroid Build Coastguard Worker     // Transform %R3 = LWZtoc <ga:@min1>, %R2
568*9880d681SAndroid Build Coastguard Worker     LowerPPCMachineInstrToMCInst(MI, TmpInst, *this, isDarwin);
569*9880d681SAndroid Build Coastguard Worker 
570*9880d681SAndroid Build Coastguard Worker     // Change the opcode to LWZ, and the global address operand to be a
571*9880d681SAndroid Build Coastguard Worker     // reference to the GOT entry we will synthesize later.
572*9880d681SAndroid Build Coastguard Worker     TmpInst.setOpcode(PPC::LWZ);
573*9880d681SAndroid Build Coastguard Worker     const MachineOperand &MO = MI->getOperand(1);
574*9880d681SAndroid Build Coastguard Worker 
575*9880d681SAndroid Build Coastguard Worker     // Map symbol -> label of TOC entry
576*9880d681SAndroid Build Coastguard Worker     assert(MO.isGlobal() || MO.isCPI() || MO.isJTI() || MO.isBlockAddress());
577*9880d681SAndroid Build Coastguard Worker     MCSymbol *MOSymbol = nullptr;
578*9880d681SAndroid Build Coastguard Worker     if (MO.isGlobal())
579*9880d681SAndroid Build Coastguard Worker       MOSymbol = getSymbol(MO.getGlobal());
580*9880d681SAndroid Build Coastguard Worker     else if (MO.isCPI())
581*9880d681SAndroid Build Coastguard Worker       MOSymbol = GetCPISymbol(MO.getIndex());
582*9880d681SAndroid Build Coastguard Worker     else if (MO.isJTI())
583*9880d681SAndroid Build Coastguard Worker       MOSymbol = GetJTISymbol(MO.getIndex());
584*9880d681SAndroid Build Coastguard Worker     else if (MO.isBlockAddress())
585*9880d681SAndroid Build Coastguard Worker       MOSymbol = GetBlockAddressSymbol(MO.getBlockAddress());
586*9880d681SAndroid Build Coastguard Worker 
587*9880d681SAndroid Build Coastguard Worker     if (PL == PICLevel::SmallPIC) {
588*9880d681SAndroid Build Coastguard Worker       const MCExpr *Exp =
589*9880d681SAndroid Build Coastguard Worker         MCSymbolRefExpr::create(MOSymbol, MCSymbolRefExpr::VK_GOT,
590*9880d681SAndroid Build Coastguard Worker                                 OutContext);
591*9880d681SAndroid Build Coastguard Worker       TmpInst.getOperand(1) = MCOperand::createExpr(Exp);
592*9880d681SAndroid Build Coastguard Worker     } else {
593*9880d681SAndroid Build Coastguard Worker       MCSymbol *TOCEntry = lookUpOrCreateTOCEntry(MOSymbol);
594*9880d681SAndroid Build Coastguard Worker 
595*9880d681SAndroid Build Coastguard Worker       const MCExpr *Exp =
596*9880d681SAndroid Build Coastguard Worker         MCSymbolRefExpr::create(TOCEntry, MCSymbolRefExpr::VK_None,
597*9880d681SAndroid Build Coastguard Worker                                 OutContext);
598*9880d681SAndroid Build Coastguard Worker       const MCExpr *PB =
599*9880d681SAndroid Build Coastguard Worker         MCSymbolRefExpr::create(OutContext.getOrCreateSymbol(Twine(".LTOC")),
600*9880d681SAndroid Build Coastguard Worker                                                              OutContext);
601*9880d681SAndroid Build Coastguard Worker       Exp = MCBinaryExpr::createSub(Exp, PB, OutContext);
602*9880d681SAndroid Build Coastguard Worker       TmpInst.getOperand(1) = MCOperand::createExpr(Exp);
603*9880d681SAndroid Build Coastguard Worker     }
604*9880d681SAndroid Build Coastguard Worker     EmitToStreamer(*OutStreamer, TmpInst);
605*9880d681SAndroid Build Coastguard Worker     return;
606*9880d681SAndroid Build Coastguard Worker   }
607*9880d681SAndroid Build Coastguard Worker   case PPC::LDtocJTI:
608*9880d681SAndroid Build Coastguard Worker   case PPC::LDtocCPT:
609*9880d681SAndroid Build Coastguard Worker   case PPC::LDtocBA:
610*9880d681SAndroid Build Coastguard Worker   case PPC::LDtoc: {
611*9880d681SAndroid Build Coastguard Worker     // Transform %X3 = LDtoc <ga:@min1>, %X2
612*9880d681SAndroid Build Coastguard Worker     LowerPPCMachineInstrToMCInst(MI, TmpInst, *this, isDarwin);
613*9880d681SAndroid Build Coastguard Worker 
614*9880d681SAndroid Build Coastguard Worker     // Change the opcode to LD, and the global address operand to be a
615*9880d681SAndroid Build Coastguard Worker     // reference to the TOC entry we will synthesize later.
616*9880d681SAndroid Build Coastguard Worker     TmpInst.setOpcode(PPC::LD);
617*9880d681SAndroid Build Coastguard Worker     const MachineOperand &MO = MI->getOperand(1);
618*9880d681SAndroid Build Coastguard Worker 
619*9880d681SAndroid Build Coastguard Worker     // Map symbol -> label of TOC entry
620*9880d681SAndroid Build Coastguard Worker     assert(MO.isGlobal() || MO.isCPI() || MO.isJTI() || MO.isBlockAddress());
621*9880d681SAndroid Build Coastguard Worker     MCSymbol *MOSymbol = nullptr;
622*9880d681SAndroid Build Coastguard Worker     if (MO.isGlobal())
623*9880d681SAndroid Build Coastguard Worker       MOSymbol = getSymbol(MO.getGlobal());
624*9880d681SAndroid Build Coastguard Worker     else if (MO.isCPI())
625*9880d681SAndroid Build Coastguard Worker       MOSymbol = GetCPISymbol(MO.getIndex());
626*9880d681SAndroid Build Coastguard Worker     else if (MO.isJTI())
627*9880d681SAndroid Build Coastguard Worker       MOSymbol = GetJTISymbol(MO.getIndex());
628*9880d681SAndroid Build Coastguard Worker     else if (MO.isBlockAddress())
629*9880d681SAndroid Build Coastguard Worker       MOSymbol = GetBlockAddressSymbol(MO.getBlockAddress());
630*9880d681SAndroid Build Coastguard Worker 
631*9880d681SAndroid Build Coastguard Worker     MCSymbol *TOCEntry = lookUpOrCreateTOCEntry(MOSymbol);
632*9880d681SAndroid Build Coastguard Worker 
633*9880d681SAndroid Build Coastguard Worker     const MCExpr *Exp =
634*9880d681SAndroid Build Coastguard Worker       MCSymbolRefExpr::create(TOCEntry, MCSymbolRefExpr::VK_PPC_TOC,
635*9880d681SAndroid Build Coastguard Worker                               OutContext);
636*9880d681SAndroid Build Coastguard Worker     TmpInst.getOperand(1) = MCOperand::createExpr(Exp);
637*9880d681SAndroid Build Coastguard Worker     EmitToStreamer(*OutStreamer, TmpInst);
638*9880d681SAndroid Build Coastguard Worker     return;
639*9880d681SAndroid Build Coastguard Worker   }
640*9880d681SAndroid Build Coastguard Worker 
641*9880d681SAndroid Build Coastguard Worker   case PPC::ADDIStocHA: {
642*9880d681SAndroid Build Coastguard Worker     // Transform %Xd = ADDIStocHA %X2, <ga:@sym>
643*9880d681SAndroid Build Coastguard Worker     LowerPPCMachineInstrToMCInst(MI, TmpInst, *this, isDarwin);
644*9880d681SAndroid Build Coastguard Worker 
645*9880d681SAndroid Build Coastguard Worker     // Change the opcode to ADDIS8.  If the global address is external, has
646*9880d681SAndroid Build Coastguard Worker     // common linkage, is a non-local function address, or is a jump table
647*9880d681SAndroid Build Coastguard Worker     // address, then generate a TOC entry and reference that.  Otherwise
648*9880d681SAndroid Build Coastguard Worker     // reference the symbol directly.
649*9880d681SAndroid Build Coastguard Worker     TmpInst.setOpcode(PPC::ADDIS8);
650*9880d681SAndroid Build Coastguard Worker     const MachineOperand &MO = MI->getOperand(2);
651*9880d681SAndroid Build Coastguard Worker     assert((MO.isGlobal() || MO.isCPI() || MO.isJTI() ||
652*9880d681SAndroid Build Coastguard Worker             MO.isBlockAddress()) &&
653*9880d681SAndroid Build Coastguard Worker            "Invalid operand for ADDIStocHA!");
654*9880d681SAndroid Build Coastguard Worker     MCSymbol *MOSymbol = nullptr;
655*9880d681SAndroid Build Coastguard Worker     bool GlobalToc = false;
656*9880d681SAndroid Build Coastguard Worker 
657*9880d681SAndroid Build Coastguard Worker     if (MO.isGlobal()) {
658*9880d681SAndroid Build Coastguard Worker       const GlobalValue *GV = MO.getGlobal();
659*9880d681SAndroid Build Coastguard Worker       MOSymbol = getSymbol(GV);
660*9880d681SAndroid Build Coastguard Worker       unsigned char GVFlags = Subtarget->classifyGlobalReference(GV);
661*9880d681SAndroid Build Coastguard Worker       GlobalToc = (GVFlags & PPCII::MO_NLP_FLAG);
662*9880d681SAndroid Build Coastguard Worker     } else if (MO.isCPI()) {
663*9880d681SAndroid Build Coastguard Worker       MOSymbol = GetCPISymbol(MO.getIndex());
664*9880d681SAndroid Build Coastguard Worker     } else if (MO.isJTI()) {
665*9880d681SAndroid Build Coastguard Worker       MOSymbol = GetJTISymbol(MO.getIndex());
666*9880d681SAndroid Build Coastguard Worker     } else if (MO.isBlockAddress()) {
667*9880d681SAndroid Build Coastguard Worker       MOSymbol = GetBlockAddressSymbol(MO.getBlockAddress());
668*9880d681SAndroid Build Coastguard Worker     }
669*9880d681SAndroid Build Coastguard Worker 
670*9880d681SAndroid Build Coastguard Worker     if (GlobalToc || MO.isJTI() || MO.isBlockAddress() ||
671*9880d681SAndroid Build Coastguard Worker         TM.getCodeModel() == CodeModel::Large)
672*9880d681SAndroid Build Coastguard Worker       MOSymbol = lookUpOrCreateTOCEntry(MOSymbol);
673*9880d681SAndroid Build Coastguard Worker 
674*9880d681SAndroid Build Coastguard Worker     const MCExpr *Exp =
675*9880d681SAndroid Build Coastguard Worker       MCSymbolRefExpr::create(MOSymbol, MCSymbolRefExpr::VK_PPC_TOC_HA,
676*9880d681SAndroid Build Coastguard Worker                               OutContext);
677*9880d681SAndroid Build Coastguard Worker     TmpInst.getOperand(2) = MCOperand::createExpr(Exp);
678*9880d681SAndroid Build Coastguard Worker     EmitToStreamer(*OutStreamer, TmpInst);
679*9880d681SAndroid Build Coastguard Worker     return;
680*9880d681SAndroid Build Coastguard Worker   }
681*9880d681SAndroid Build Coastguard Worker   case PPC::LDtocL: {
682*9880d681SAndroid Build Coastguard Worker     // Transform %Xd = LDtocL <ga:@sym>, %Xs
683*9880d681SAndroid Build Coastguard Worker     LowerPPCMachineInstrToMCInst(MI, TmpInst, *this, isDarwin);
684*9880d681SAndroid Build Coastguard Worker 
685*9880d681SAndroid Build Coastguard Worker     // Change the opcode to LD.  If the global address is external, has
686*9880d681SAndroid Build Coastguard Worker     // common linkage, or is a jump table address, then reference the
687*9880d681SAndroid Build Coastguard Worker     // associated TOC entry.  Otherwise reference the symbol directly.
688*9880d681SAndroid Build Coastguard Worker     TmpInst.setOpcode(PPC::LD);
689*9880d681SAndroid Build Coastguard Worker     const MachineOperand &MO = MI->getOperand(1);
690*9880d681SAndroid Build Coastguard Worker     assert((MO.isGlobal() || MO.isCPI() || MO.isJTI() ||
691*9880d681SAndroid Build Coastguard Worker             MO.isBlockAddress()) &&
692*9880d681SAndroid Build Coastguard Worker            "Invalid operand for LDtocL!");
693*9880d681SAndroid Build Coastguard Worker     MCSymbol *MOSymbol = nullptr;
694*9880d681SAndroid Build Coastguard Worker 
695*9880d681SAndroid Build Coastguard Worker     if (MO.isJTI())
696*9880d681SAndroid Build Coastguard Worker       MOSymbol = lookUpOrCreateTOCEntry(GetJTISymbol(MO.getIndex()));
697*9880d681SAndroid Build Coastguard Worker     else if (MO.isBlockAddress()) {
698*9880d681SAndroid Build Coastguard Worker       MOSymbol = GetBlockAddressSymbol(MO.getBlockAddress());
699*9880d681SAndroid Build Coastguard Worker       MOSymbol = lookUpOrCreateTOCEntry(MOSymbol);
700*9880d681SAndroid Build Coastguard Worker     }
701*9880d681SAndroid Build Coastguard Worker     else if (MO.isCPI()) {
702*9880d681SAndroid Build Coastguard Worker       MOSymbol = GetCPISymbol(MO.getIndex());
703*9880d681SAndroid Build Coastguard Worker       if (TM.getCodeModel() == CodeModel::Large)
704*9880d681SAndroid Build Coastguard Worker         MOSymbol = lookUpOrCreateTOCEntry(MOSymbol);
705*9880d681SAndroid Build Coastguard Worker     }
706*9880d681SAndroid Build Coastguard Worker     else if (MO.isGlobal()) {
707*9880d681SAndroid Build Coastguard Worker       const GlobalValue *GV = MO.getGlobal();
708*9880d681SAndroid Build Coastguard Worker       MOSymbol = getSymbol(GV);
709*9880d681SAndroid Build Coastguard Worker       DEBUG(
710*9880d681SAndroid Build Coastguard Worker         unsigned char GVFlags = Subtarget->classifyGlobalReference(GV);
711*9880d681SAndroid Build Coastguard Worker         assert((GVFlags & PPCII::MO_NLP_FLAG) &&
712*9880d681SAndroid Build Coastguard Worker                "LDtocL used on symbol that could be accessed directly is "
713*9880d681SAndroid Build Coastguard Worker                "invalid. Must match ADDIStocHA."));
714*9880d681SAndroid Build Coastguard Worker       MOSymbol = lookUpOrCreateTOCEntry(MOSymbol);
715*9880d681SAndroid Build Coastguard Worker     }
716*9880d681SAndroid Build Coastguard Worker 
717*9880d681SAndroid Build Coastguard Worker     const MCExpr *Exp =
718*9880d681SAndroid Build Coastguard Worker       MCSymbolRefExpr::create(MOSymbol, MCSymbolRefExpr::VK_PPC_TOC_LO,
719*9880d681SAndroid Build Coastguard Worker                               OutContext);
720*9880d681SAndroid Build Coastguard Worker     TmpInst.getOperand(1) = MCOperand::createExpr(Exp);
721*9880d681SAndroid Build Coastguard Worker     EmitToStreamer(*OutStreamer, TmpInst);
722*9880d681SAndroid Build Coastguard Worker     return;
723*9880d681SAndroid Build Coastguard Worker   }
724*9880d681SAndroid Build Coastguard Worker   case PPC::ADDItocL: {
725*9880d681SAndroid Build Coastguard Worker     // Transform %Xd = ADDItocL %Xs, <ga:@sym>
726*9880d681SAndroid Build Coastguard Worker     LowerPPCMachineInstrToMCInst(MI, TmpInst, *this, isDarwin);
727*9880d681SAndroid Build Coastguard Worker 
728*9880d681SAndroid Build Coastguard Worker     // Change the opcode to ADDI8.  If the global address is external, then
729*9880d681SAndroid Build Coastguard Worker     // generate a TOC entry and reference that.  Otherwise reference the
730*9880d681SAndroid Build Coastguard Worker     // symbol directly.
731*9880d681SAndroid Build Coastguard Worker     TmpInst.setOpcode(PPC::ADDI8);
732*9880d681SAndroid Build Coastguard Worker     const MachineOperand &MO = MI->getOperand(2);
733*9880d681SAndroid Build Coastguard Worker     assert((MO.isGlobal() || MO.isCPI()) && "Invalid operand for ADDItocL");
734*9880d681SAndroid Build Coastguard Worker     MCSymbol *MOSymbol = nullptr;
735*9880d681SAndroid Build Coastguard Worker 
736*9880d681SAndroid Build Coastguard Worker     if (MO.isGlobal()) {
737*9880d681SAndroid Build Coastguard Worker       const GlobalValue *GV = MO.getGlobal();
738*9880d681SAndroid Build Coastguard Worker       DEBUG(
739*9880d681SAndroid Build Coastguard Worker         unsigned char GVFlags = Subtarget->classifyGlobalReference(GV);
740*9880d681SAndroid Build Coastguard Worker         assert (
741*9880d681SAndroid Build Coastguard Worker             !(GVFlags & PPCII::MO_NLP_FLAG) &&
742*9880d681SAndroid Build Coastguard Worker             "Interposable definitions must use indirect access."));
743*9880d681SAndroid Build Coastguard Worker       MOSymbol = getSymbol(GV);
744*9880d681SAndroid Build Coastguard Worker     } else if (MO.isCPI()) {
745*9880d681SAndroid Build Coastguard Worker       MOSymbol = GetCPISymbol(MO.getIndex());
746*9880d681SAndroid Build Coastguard Worker     }
747*9880d681SAndroid Build Coastguard Worker 
748*9880d681SAndroid Build Coastguard Worker     const MCExpr *Exp =
749*9880d681SAndroid Build Coastguard Worker       MCSymbolRefExpr::create(MOSymbol, MCSymbolRefExpr::VK_PPC_TOC_LO,
750*9880d681SAndroid Build Coastguard Worker                               OutContext);
751*9880d681SAndroid Build Coastguard Worker     TmpInst.getOperand(2) = MCOperand::createExpr(Exp);
752*9880d681SAndroid Build Coastguard Worker     EmitToStreamer(*OutStreamer, TmpInst);
753*9880d681SAndroid Build Coastguard Worker     return;
754*9880d681SAndroid Build Coastguard Worker   }
755*9880d681SAndroid Build Coastguard Worker   case PPC::ADDISgotTprelHA: {
756*9880d681SAndroid Build Coastguard Worker     // Transform: %Xd = ADDISgotTprelHA %X2, <ga:@sym>
757*9880d681SAndroid Build Coastguard Worker     // Into:      %Xd = ADDIS8 %X2, sym@got@tlsgd@ha
758*9880d681SAndroid Build Coastguard Worker     assert(Subtarget->isPPC64() && "Not supported for 32-bit PowerPC");
759*9880d681SAndroid Build Coastguard Worker     const MachineOperand &MO = MI->getOperand(2);
760*9880d681SAndroid Build Coastguard Worker     const GlobalValue *GValue = MO.getGlobal();
761*9880d681SAndroid Build Coastguard Worker     MCSymbol *MOSymbol = getSymbol(GValue);
762*9880d681SAndroid Build Coastguard Worker     const MCExpr *SymGotTprel =
763*9880d681SAndroid Build Coastguard Worker       MCSymbolRefExpr::create(MOSymbol, MCSymbolRefExpr::VK_PPC_GOT_TPREL_HA,
764*9880d681SAndroid Build Coastguard Worker                               OutContext);
765*9880d681SAndroid Build Coastguard Worker     EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::ADDIS8)
766*9880d681SAndroid Build Coastguard Worker                                  .addReg(MI->getOperand(0).getReg())
767*9880d681SAndroid Build Coastguard Worker                                  .addReg(MI->getOperand(1).getReg())
768*9880d681SAndroid Build Coastguard Worker                                  .addExpr(SymGotTprel));
769*9880d681SAndroid Build Coastguard Worker     return;
770*9880d681SAndroid Build Coastguard Worker   }
771*9880d681SAndroid Build Coastguard Worker   case PPC::LDgotTprelL:
772*9880d681SAndroid Build Coastguard Worker   case PPC::LDgotTprelL32: {
773*9880d681SAndroid Build Coastguard Worker     // Transform %Xd = LDgotTprelL <ga:@sym>, %Xs
774*9880d681SAndroid Build Coastguard Worker     LowerPPCMachineInstrToMCInst(MI, TmpInst, *this, isDarwin);
775*9880d681SAndroid Build Coastguard Worker 
776*9880d681SAndroid Build Coastguard Worker     // Change the opcode to LD.
777*9880d681SAndroid Build Coastguard Worker     TmpInst.setOpcode(isPPC64 ? PPC::LD : PPC::LWZ);
778*9880d681SAndroid Build Coastguard Worker     const MachineOperand &MO = MI->getOperand(1);
779*9880d681SAndroid Build Coastguard Worker     const GlobalValue *GValue = MO.getGlobal();
780*9880d681SAndroid Build Coastguard Worker     MCSymbol *MOSymbol = getSymbol(GValue);
781*9880d681SAndroid Build Coastguard Worker     const MCExpr *Exp =
782*9880d681SAndroid Build Coastguard Worker       MCSymbolRefExpr::create(MOSymbol, MCSymbolRefExpr::VK_PPC_GOT_TPREL_LO,
783*9880d681SAndroid Build Coastguard Worker                               OutContext);
784*9880d681SAndroid Build Coastguard Worker     TmpInst.getOperand(1) = MCOperand::createExpr(Exp);
785*9880d681SAndroid Build Coastguard Worker     EmitToStreamer(*OutStreamer, TmpInst);
786*9880d681SAndroid Build Coastguard Worker     return;
787*9880d681SAndroid Build Coastguard Worker   }
788*9880d681SAndroid Build Coastguard Worker 
789*9880d681SAndroid Build Coastguard Worker   case PPC::PPC32PICGOT: {
790*9880d681SAndroid Build Coastguard Worker     MCSymbol *GOTSymbol = OutContext.getOrCreateSymbol(StringRef("_GLOBAL_OFFSET_TABLE_"));
791*9880d681SAndroid Build Coastguard Worker     MCSymbol *GOTRef = OutContext.createTempSymbol();
792*9880d681SAndroid Build Coastguard Worker     MCSymbol *NextInstr = OutContext.createTempSymbol();
793*9880d681SAndroid Build Coastguard Worker 
794*9880d681SAndroid Build Coastguard Worker     EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::BL)
795*9880d681SAndroid Build Coastguard Worker       // FIXME: We would like an efficient form for this, so we don't have to do
796*9880d681SAndroid Build Coastguard Worker       // a lot of extra uniquing.
797*9880d681SAndroid Build Coastguard Worker       .addExpr(MCSymbolRefExpr::create(NextInstr, OutContext)));
798*9880d681SAndroid Build Coastguard Worker     const MCExpr *OffsExpr =
799*9880d681SAndroid Build Coastguard Worker       MCBinaryExpr::createSub(MCSymbolRefExpr::create(GOTSymbol, OutContext),
800*9880d681SAndroid Build Coastguard Worker                                 MCSymbolRefExpr::create(GOTRef, OutContext),
801*9880d681SAndroid Build Coastguard Worker         OutContext);
802*9880d681SAndroid Build Coastguard Worker     OutStreamer->EmitLabel(GOTRef);
803*9880d681SAndroid Build Coastguard Worker     OutStreamer->EmitValue(OffsExpr, 4);
804*9880d681SAndroid Build Coastguard Worker     OutStreamer->EmitLabel(NextInstr);
805*9880d681SAndroid Build Coastguard Worker     EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::MFLR)
806*9880d681SAndroid Build Coastguard Worker                                  .addReg(MI->getOperand(0).getReg()));
807*9880d681SAndroid Build Coastguard Worker     EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::LWZ)
808*9880d681SAndroid Build Coastguard Worker                                  .addReg(MI->getOperand(1).getReg())
809*9880d681SAndroid Build Coastguard Worker                                  .addImm(0)
810*9880d681SAndroid Build Coastguard Worker                                  .addReg(MI->getOperand(0).getReg()));
811*9880d681SAndroid Build Coastguard Worker     EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::ADD4)
812*9880d681SAndroid Build Coastguard Worker                                  .addReg(MI->getOperand(0).getReg())
813*9880d681SAndroid Build Coastguard Worker                                  .addReg(MI->getOperand(1).getReg())
814*9880d681SAndroid Build Coastguard Worker                                  .addReg(MI->getOperand(0).getReg()));
815*9880d681SAndroid Build Coastguard Worker     return;
816*9880d681SAndroid Build Coastguard Worker   }
817*9880d681SAndroid Build Coastguard Worker   case PPC::PPC32GOT: {
818*9880d681SAndroid Build Coastguard Worker     MCSymbol *GOTSymbol =
819*9880d681SAndroid Build Coastguard Worker         OutContext.getOrCreateSymbol(StringRef("_GLOBAL_OFFSET_TABLE_"));
820*9880d681SAndroid Build Coastguard Worker     const MCExpr *SymGotTlsL = MCSymbolRefExpr::create(
821*9880d681SAndroid Build Coastguard Worker         GOTSymbol, MCSymbolRefExpr::VK_PPC_LO, OutContext);
822*9880d681SAndroid Build Coastguard Worker     const MCExpr *SymGotTlsHA = MCSymbolRefExpr::create(
823*9880d681SAndroid Build Coastguard Worker         GOTSymbol, MCSymbolRefExpr::VK_PPC_HA, OutContext);
824*9880d681SAndroid Build Coastguard Worker     EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::LI)
825*9880d681SAndroid Build Coastguard Worker                                  .addReg(MI->getOperand(0).getReg())
826*9880d681SAndroid Build Coastguard Worker                                  .addExpr(SymGotTlsL));
827*9880d681SAndroid Build Coastguard Worker     EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::ADDIS)
828*9880d681SAndroid Build Coastguard Worker                                  .addReg(MI->getOperand(0).getReg())
829*9880d681SAndroid Build Coastguard Worker                                  .addReg(MI->getOperand(0).getReg())
830*9880d681SAndroid Build Coastguard Worker                                  .addExpr(SymGotTlsHA));
831*9880d681SAndroid Build Coastguard Worker     return;
832*9880d681SAndroid Build Coastguard Worker   }
833*9880d681SAndroid Build Coastguard Worker   case PPC::ADDIStlsgdHA: {
834*9880d681SAndroid Build Coastguard Worker     // Transform: %Xd = ADDIStlsgdHA %X2, <ga:@sym>
835*9880d681SAndroid Build Coastguard Worker     // Into:      %Xd = ADDIS8 %X2, sym@got@tlsgd@ha
836*9880d681SAndroid Build Coastguard Worker     assert(Subtarget->isPPC64() && "Not supported for 32-bit PowerPC");
837*9880d681SAndroid Build Coastguard Worker     const MachineOperand &MO = MI->getOperand(2);
838*9880d681SAndroid Build Coastguard Worker     const GlobalValue *GValue = MO.getGlobal();
839*9880d681SAndroid Build Coastguard Worker     MCSymbol *MOSymbol = getSymbol(GValue);
840*9880d681SAndroid Build Coastguard Worker     const MCExpr *SymGotTlsGD =
841*9880d681SAndroid Build Coastguard Worker       MCSymbolRefExpr::create(MOSymbol, MCSymbolRefExpr::VK_PPC_GOT_TLSGD_HA,
842*9880d681SAndroid Build Coastguard Worker                               OutContext);
843*9880d681SAndroid Build Coastguard Worker     EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::ADDIS8)
844*9880d681SAndroid Build Coastguard Worker                                  .addReg(MI->getOperand(0).getReg())
845*9880d681SAndroid Build Coastguard Worker                                  .addReg(MI->getOperand(1).getReg())
846*9880d681SAndroid Build Coastguard Worker                                  .addExpr(SymGotTlsGD));
847*9880d681SAndroid Build Coastguard Worker     return;
848*9880d681SAndroid Build Coastguard Worker   }
849*9880d681SAndroid Build Coastguard Worker   case PPC::ADDItlsgdL:
850*9880d681SAndroid Build Coastguard Worker     // Transform: %Xd = ADDItlsgdL %Xs, <ga:@sym>
851*9880d681SAndroid Build Coastguard Worker     // Into:      %Xd = ADDI8 %Xs, sym@got@tlsgd@l
852*9880d681SAndroid Build Coastguard Worker   case PPC::ADDItlsgdL32: {
853*9880d681SAndroid Build Coastguard Worker     // Transform: %Rd = ADDItlsgdL32 %Rs, <ga:@sym>
854*9880d681SAndroid Build Coastguard Worker     // Into:      %Rd = ADDI %Rs, sym@got@tlsgd
855*9880d681SAndroid Build Coastguard Worker     const MachineOperand &MO = MI->getOperand(2);
856*9880d681SAndroid Build Coastguard Worker     const GlobalValue *GValue = MO.getGlobal();
857*9880d681SAndroid Build Coastguard Worker     MCSymbol *MOSymbol = getSymbol(GValue);
858*9880d681SAndroid Build Coastguard Worker     const MCExpr *SymGotTlsGD = MCSymbolRefExpr::create(
859*9880d681SAndroid Build Coastguard Worker         MOSymbol, Subtarget->isPPC64() ? MCSymbolRefExpr::VK_PPC_GOT_TLSGD_LO
860*9880d681SAndroid Build Coastguard Worker                                        : MCSymbolRefExpr::VK_PPC_GOT_TLSGD,
861*9880d681SAndroid Build Coastguard Worker         OutContext);
862*9880d681SAndroid Build Coastguard Worker     EmitToStreamer(*OutStreamer,
863*9880d681SAndroid Build Coastguard Worker                    MCInstBuilder(Subtarget->isPPC64() ? PPC::ADDI8 : PPC::ADDI)
864*9880d681SAndroid Build Coastguard Worker                    .addReg(MI->getOperand(0).getReg())
865*9880d681SAndroid Build Coastguard Worker                    .addReg(MI->getOperand(1).getReg())
866*9880d681SAndroid Build Coastguard Worker                    .addExpr(SymGotTlsGD));
867*9880d681SAndroid Build Coastguard Worker     return;
868*9880d681SAndroid Build Coastguard Worker   }
869*9880d681SAndroid Build Coastguard Worker   case PPC::GETtlsADDR:
870*9880d681SAndroid Build Coastguard Worker     // Transform: %X3 = GETtlsADDR %X3, <ga:@sym>
871*9880d681SAndroid Build Coastguard Worker     // Into: BL8_NOP_TLS __tls_get_addr(sym at tlsgd)
872*9880d681SAndroid Build Coastguard Worker   case PPC::GETtlsADDR32: {
873*9880d681SAndroid Build Coastguard Worker     // Transform: %R3 = GETtlsADDR32 %R3, <ga:@sym>
874*9880d681SAndroid Build Coastguard Worker     // Into: BL_TLS __tls_get_addr(sym at tlsgd)@PLT
875*9880d681SAndroid Build Coastguard Worker     EmitTlsCall(MI, MCSymbolRefExpr::VK_PPC_TLSGD);
876*9880d681SAndroid Build Coastguard Worker     return;
877*9880d681SAndroid Build Coastguard Worker   }
878*9880d681SAndroid Build Coastguard Worker   case PPC::ADDIStlsldHA: {
879*9880d681SAndroid Build Coastguard Worker     // Transform: %Xd = ADDIStlsldHA %X2, <ga:@sym>
880*9880d681SAndroid Build Coastguard Worker     // Into:      %Xd = ADDIS8 %X2, sym@got@tlsld@ha
881*9880d681SAndroid Build Coastguard Worker     assert(Subtarget->isPPC64() && "Not supported for 32-bit PowerPC");
882*9880d681SAndroid Build Coastguard Worker     const MachineOperand &MO = MI->getOperand(2);
883*9880d681SAndroid Build Coastguard Worker     const GlobalValue *GValue = MO.getGlobal();
884*9880d681SAndroid Build Coastguard Worker     MCSymbol *MOSymbol = getSymbol(GValue);
885*9880d681SAndroid Build Coastguard Worker     const MCExpr *SymGotTlsLD =
886*9880d681SAndroid Build Coastguard Worker       MCSymbolRefExpr::create(MOSymbol, MCSymbolRefExpr::VK_PPC_GOT_TLSLD_HA,
887*9880d681SAndroid Build Coastguard Worker                               OutContext);
888*9880d681SAndroid Build Coastguard Worker     EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::ADDIS8)
889*9880d681SAndroid Build Coastguard Worker                                  .addReg(MI->getOperand(0).getReg())
890*9880d681SAndroid Build Coastguard Worker                                  .addReg(MI->getOperand(1).getReg())
891*9880d681SAndroid Build Coastguard Worker                                  .addExpr(SymGotTlsLD));
892*9880d681SAndroid Build Coastguard Worker     return;
893*9880d681SAndroid Build Coastguard Worker   }
894*9880d681SAndroid Build Coastguard Worker   case PPC::ADDItlsldL:
895*9880d681SAndroid Build Coastguard Worker     // Transform: %Xd = ADDItlsldL %Xs, <ga:@sym>
896*9880d681SAndroid Build Coastguard Worker     // Into:      %Xd = ADDI8 %Xs, sym@got@tlsld@l
897*9880d681SAndroid Build Coastguard Worker   case PPC::ADDItlsldL32: {
898*9880d681SAndroid Build Coastguard Worker     // Transform: %Rd = ADDItlsldL32 %Rs, <ga:@sym>
899*9880d681SAndroid Build Coastguard Worker     // Into:      %Rd = ADDI %Rs, sym@got@tlsld
900*9880d681SAndroid Build Coastguard Worker     const MachineOperand &MO = MI->getOperand(2);
901*9880d681SAndroid Build Coastguard Worker     const GlobalValue *GValue = MO.getGlobal();
902*9880d681SAndroid Build Coastguard Worker     MCSymbol *MOSymbol = getSymbol(GValue);
903*9880d681SAndroid Build Coastguard Worker     const MCExpr *SymGotTlsLD = MCSymbolRefExpr::create(
904*9880d681SAndroid Build Coastguard Worker         MOSymbol, Subtarget->isPPC64() ? MCSymbolRefExpr::VK_PPC_GOT_TLSLD_LO
905*9880d681SAndroid Build Coastguard Worker                                        : MCSymbolRefExpr::VK_PPC_GOT_TLSLD,
906*9880d681SAndroid Build Coastguard Worker         OutContext);
907*9880d681SAndroid Build Coastguard Worker     EmitToStreamer(*OutStreamer,
908*9880d681SAndroid Build Coastguard Worker                    MCInstBuilder(Subtarget->isPPC64() ? PPC::ADDI8 : PPC::ADDI)
909*9880d681SAndroid Build Coastguard Worker                        .addReg(MI->getOperand(0).getReg())
910*9880d681SAndroid Build Coastguard Worker                        .addReg(MI->getOperand(1).getReg())
911*9880d681SAndroid Build Coastguard Worker                        .addExpr(SymGotTlsLD));
912*9880d681SAndroid Build Coastguard Worker     return;
913*9880d681SAndroid Build Coastguard Worker   }
914*9880d681SAndroid Build Coastguard Worker   case PPC::GETtlsldADDR:
915*9880d681SAndroid Build Coastguard Worker     // Transform: %X3 = GETtlsldADDR %X3, <ga:@sym>
916*9880d681SAndroid Build Coastguard Worker     // Into: BL8_NOP_TLS __tls_get_addr(sym at tlsld)
917*9880d681SAndroid Build Coastguard Worker   case PPC::GETtlsldADDR32: {
918*9880d681SAndroid Build Coastguard Worker     // Transform: %R3 = GETtlsldADDR32 %R3, <ga:@sym>
919*9880d681SAndroid Build Coastguard Worker     // Into: BL_TLS __tls_get_addr(sym at tlsld)@PLT
920*9880d681SAndroid Build Coastguard Worker     EmitTlsCall(MI, MCSymbolRefExpr::VK_PPC_TLSLD);
921*9880d681SAndroid Build Coastguard Worker     return;
922*9880d681SAndroid Build Coastguard Worker   }
923*9880d681SAndroid Build Coastguard Worker   case PPC::ADDISdtprelHA:
924*9880d681SAndroid Build Coastguard Worker     // Transform: %Xd = ADDISdtprelHA %Xs, <ga:@sym>
925*9880d681SAndroid Build Coastguard Worker     // Into:      %Xd = ADDIS8 %Xs, sym@dtprel@ha
926*9880d681SAndroid Build Coastguard Worker   case PPC::ADDISdtprelHA32: {
927*9880d681SAndroid Build Coastguard Worker     // Transform: %Rd = ADDISdtprelHA32 %Rs, <ga:@sym>
928*9880d681SAndroid Build Coastguard Worker     // Into:      %Rd = ADDIS %Rs, sym@dtprel@ha
929*9880d681SAndroid Build Coastguard Worker     const MachineOperand &MO = MI->getOperand(2);
930*9880d681SAndroid Build Coastguard Worker     const GlobalValue *GValue = MO.getGlobal();
931*9880d681SAndroid Build Coastguard Worker     MCSymbol *MOSymbol = getSymbol(GValue);
932*9880d681SAndroid Build Coastguard Worker     const MCExpr *SymDtprel =
933*9880d681SAndroid Build Coastguard Worker       MCSymbolRefExpr::create(MOSymbol, MCSymbolRefExpr::VK_PPC_DTPREL_HA,
934*9880d681SAndroid Build Coastguard Worker                               OutContext);
935*9880d681SAndroid Build Coastguard Worker     EmitToStreamer(
936*9880d681SAndroid Build Coastguard Worker         *OutStreamer,
937*9880d681SAndroid Build Coastguard Worker         MCInstBuilder(Subtarget->isPPC64() ? PPC::ADDIS8 : PPC::ADDIS)
938*9880d681SAndroid Build Coastguard Worker             .addReg(MI->getOperand(0).getReg())
939*9880d681SAndroid Build Coastguard Worker             .addReg(MI->getOperand(1).getReg())
940*9880d681SAndroid Build Coastguard Worker             .addExpr(SymDtprel));
941*9880d681SAndroid Build Coastguard Worker     return;
942*9880d681SAndroid Build Coastguard Worker   }
943*9880d681SAndroid Build Coastguard Worker   case PPC::ADDIdtprelL:
944*9880d681SAndroid Build Coastguard Worker     // Transform: %Xd = ADDIdtprelL %Xs, <ga:@sym>
945*9880d681SAndroid Build Coastguard Worker     // Into:      %Xd = ADDI8 %Xs, sym@dtprel@l
946*9880d681SAndroid Build Coastguard Worker   case PPC::ADDIdtprelL32: {
947*9880d681SAndroid Build Coastguard Worker     // Transform: %Rd = ADDIdtprelL32 %Rs, <ga:@sym>
948*9880d681SAndroid Build Coastguard Worker     // Into:      %Rd = ADDI %Rs, sym@dtprel@l
949*9880d681SAndroid Build Coastguard Worker     const MachineOperand &MO = MI->getOperand(2);
950*9880d681SAndroid Build Coastguard Worker     const GlobalValue *GValue = MO.getGlobal();
951*9880d681SAndroid Build Coastguard Worker     MCSymbol *MOSymbol = getSymbol(GValue);
952*9880d681SAndroid Build Coastguard Worker     const MCExpr *SymDtprel =
953*9880d681SAndroid Build Coastguard Worker       MCSymbolRefExpr::create(MOSymbol, MCSymbolRefExpr::VK_PPC_DTPREL_LO,
954*9880d681SAndroid Build Coastguard Worker                               OutContext);
955*9880d681SAndroid Build Coastguard Worker     EmitToStreamer(*OutStreamer,
956*9880d681SAndroid Build Coastguard Worker                    MCInstBuilder(Subtarget->isPPC64() ? PPC::ADDI8 : PPC::ADDI)
957*9880d681SAndroid Build Coastguard Worker                        .addReg(MI->getOperand(0).getReg())
958*9880d681SAndroid Build Coastguard Worker                        .addReg(MI->getOperand(1).getReg())
959*9880d681SAndroid Build Coastguard Worker                        .addExpr(SymDtprel));
960*9880d681SAndroid Build Coastguard Worker     return;
961*9880d681SAndroid Build Coastguard Worker   }
962*9880d681SAndroid Build Coastguard Worker   case PPC::MFOCRF:
963*9880d681SAndroid Build Coastguard Worker   case PPC::MFOCRF8:
964*9880d681SAndroid Build Coastguard Worker     if (!Subtarget->hasMFOCRF()) {
965*9880d681SAndroid Build Coastguard Worker       // Transform: %R3 = MFOCRF %CR7
966*9880d681SAndroid Build Coastguard Worker       // Into:      %R3 = MFCR   ;; cr7
967*9880d681SAndroid Build Coastguard Worker       unsigned NewOpcode =
968*9880d681SAndroid Build Coastguard Worker         MI->getOpcode() == PPC::MFOCRF ? PPC::MFCR : PPC::MFCR8;
969*9880d681SAndroid Build Coastguard Worker       OutStreamer->AddComment(PPCInstPrinter::
970*9880d681SAndroid Build Coastguard Worker                               getRegisterName(MI->getOperand(1).getReg()));
971*9880d681SAndroid Build Coastguard Worker       EmitToStreamer(*OutStreamer, MCInstBuilder(NewOpcode)
972*9880d681SAndroid Build Coastguard Worker                                   .addReg(MI->getOperand(0).getReg()));
973*9880d681SAndroid Build Coastguard Worker       return;
974*9880d681SAndroid Build Coastguard Worker     }
975*9880d681SAndroid Build Coastguard Worker     break;
976*9880d681SAndroid Build Coastguard Worker   case PPC::MTOCRF:
977*9880d681SAndroid Build Coastguard Worker   case PPC::MTOCRF8:
978*9880d681SAndroid Build Coastguard Worker     if (!Subtarget->hasMFOCRF()) {
979*9880d681SAndroid Build Coastguard Worker       // Transform: %CR7 = MTOCRF %R3
980*9880d681SAndroid Build Coastguard Worker       // Into:      MTCRF mask, %R3 ;; cr7
981*9880d681SAndroid Build Coastguard Worker       unsigned NewOpcode =
982*9880d681SAndroid Build Coastguard Worker         MI->getOpcode() == PPC::MTOCRF ? PPC::MTCRF : PPC::MTCRF8;
983*9880d681SAndroid Build Coastguard Worker       unsigned Mask = 0x80 >> OutContext.getRegisterInfo()
984*9880d681SAndroid Build Coastguard Worker                               ->getEncodingValue(MI->getOperand(0).getReg());
985*9880d681SAndroid Build Coastguard Worker       OutStreamer->AddComment(PPCInstPrinter::
986*9880d681SAndroid Build Coastguard Worker                               getRegisterName(MI->getOperand(0).getReg()));
987*9880d681SAndroid Build Coastguard Worker       EmitToStreamer(*OutStreamer, MCInstBuilder(NewOpcode)
988*9880d681SAndroid Build Coastguard Worker                                      .addImm(Mask)
989*9880d681SAndroid Build Coastguard Worker                                      .addReg(MI->getOperand(1).getReg()));
990*9880d681SAndroid Build Coastguard Worker       return;
991*9880d681SAndroid Build Coastguard Worker     }
992*9880d681SAndroid Build Coastguard Worker     break;
993*9880d681SAndroid Build Coastguard Worker   case PPC::LD:
994*9880d681SAndroid Build Coastguard Worker   case PPC::STD:
995*9880d681SAndroid Build Coastguard Worker   case PPC::LWA_32:
996*9880d681SAndroid Build Coastguard Worker   case PPC::LWA: {
997*9880d681SAndroid Build Coastguard Worker     // Verify alignment is legal, so we don't create relocations
998*9880d681SAndroid Build Coastguard Worker     // that can't be supported.
999*9880d681SAndroid Build Coastguard Worker     // FIXME:  This test is currently disabled for Darwin.  The test
1000*9880d681SAndroid Build Coastguard Worker     // suite shows a handful of test cases that fail this check for
1001*9880d681SAndroid Build Coastguard Worker     // Darwin.  Those need to be investigated before this sanity test
1002*9880d681SAndroid Build Coastguard Worker     // can be enabled for those subtargets.
1003*9880d681SAndroid Build Coastguard Worker     if (!Subtarget->isDarwin()) {
1004*9880d681SAndroid Build Coastguard Worker       unsigned OpNum = (MI->getOpcode() == PPC::STD) ? 2 : 1;
1005*9880d681SAndroid Build Coastguard Worker       const MachineOperand &MO = MI->getOperand(OpNum);
1006*9880d681SAndroid Build Coastguard Worker       if (MO.isGlobal() && MO.getGlobal()->getAlignment() < 4)
1007*9880d681SAndroid Build Coastguard Worker         llvm_unreachable("Global must be word-aligned for LD, STD, LWA!");
1008*9880d681SAndroid Build Coastguard Worker     }
1009*9880d681SAndroid Build Coastguard Worker     // Now process the instruction normally.
1010*9880d681SAndroid Build Coastguard Worker     break;
1011*9880d681SAndroid Build Coastguard Worker   }
1012*9880d681SAndroid Build Coastguard Worker   }
1013*9880d681SAndroid Build Coastguard Worker 
1014*9880d681SAndroid Build Coastguard Worker   LowerPPCMachineInstrToMCInst(MI, TmpInst, *this, isDarwin);
1015*9880d681SAndroid Build Coastguard Worker   EmitToStreamer(*OutStreamer, TmpInst);
1016*9880d681SAndroid Build Coastguard Worker }
1017*9880d681SAndroid Build Coastguard Worker 
EmitStartOfAsmFile(Module & M)1018*9880d681SAndroid Build Coastguard Worker void PPCLinuxAsmPrinter::EmitStartOfAsmFile(Module &M) {
1019*9880d681SAndroid Build Coastguard Worker   if (static_cast<const PPCTargetMachine &>(TM).isELFv2ABI()) {
1020*9880d681SAndroid Build Coastguard Worker     PPCTargetStreamer *TS =
1021*9880d681SAndroid Build Coastguard Worker       static_cast<PPCTargetStreamer *>(OutStreamer->getTargetStreamer());
1022*9880d681SAndroid Build Coastguard Worker 
1023*9880d681SAndroid Build Coastguard Worker     if (TS)
1024*9880d681SAndroid Build Coastguard Worker       TS->emitAbiVersion(2);
1025*9880d681SAndroid Build Coastguard Worker   }
1026*9880d681SAndroid Build Coastguard Worker 
1027*9880d681SAndroid Build Coastguard Worker   if (static_cast<const PPCTargetMachine &>(TM).isPPC64() ||
1028*9880d681SAndroid Build Coastguard Worker       !isPositionIndependent())
1029*9880d681SAndroid Build Coastguard Worker     return AsmPrinter::EmitStartOfAsmFile(M);
1030*9880d681SAndroid Build Coastguard Worker 
1031*9880d681SAndroid Build Coastguard Worker   if (M.getPICLevel() == PICLevel::SmallPIC)
1032*9880d681SAndroid Build Coastguard Worker     return AsmPrinter::EmitStartOfAsmFile(M);
1033*9880d681SAndroid Build Coastguard Worker 
1034*9880d681SAndroid Build Coastguard Worker   OutStreamer->SwitchSection(OutContext.getELFSection(
1035*9880d681SAndroid Build Coastguard Worker       ".got2", ELF::SHT_PROGBITS, ELF::SHF_WRITE | ELF::SHF_ALLOC));
1036*9880d681SAndroid Build Coastguard Worker 
1037*9880d681SAndroid Build Coastguard Worker   MCSymbol *TOCSym = OutContext.getOrCreateSymbol(Twine(".LTOC"));
1038*9880d681SAndroid Build Coastguard Worker   MCSymbol *CurrentPos = OutContext.createTempSymbol();
1039*9880d681SAndroid Build Coastguard Worker 
1040*9880d681SAndroid Build Coastguard Worker   OutStreamer->EmitLabel(CurrentPos);
1041*9880d681SAndroid Build Coastguard Worker 
1042*9880d681SAndroid Build Coastguard Worker   // The GOT pointer points to the middle of the GOT, in order to reference the
1043*9880d681SAndroid Build Coastguard Worker   // entire 64kB range.  0x8000 is the midpoint.
1044*9880d681SAndroid Build Coastguard Worker   const MCExpr *tocExpr =
1045*9880d681SAndroid Build Coastguard Worker     MCBinaryExpr::createAdd(MCSymbolRefExpr::create(CurrentPos, OutContext),
1046*9880d681SAndroid Build Coastguard Worker                             MCConstantExpr::create(0x8000, OutContext),
1047*9880d681SAndroid Build Coastguard Worker                             OutContext);
1048*9880d681SAndroid Build Coastguard Worker 
1049*9880d681SAndroid Build Coastguard Worker   OutStreamer->EmitAssignment(TOCSym, tocExpr);
1050*9880d681SAndroid Build Coastguard Worker 
1051*9880d681SAndroid Build Coastguard Worker   OutStreamer->SwitchSection(getObjFileLowering().getTextSection());
1052*9880d681SAndroid Build Coastguard Worker }
1053*9880d681SAndroid Build Coastguard Worker 
EmitFunctionEntryLabel()1054*9880d681SAndroid Build Coastguard Worker void PPCLinuxAsmPrinter::EmitFunctionEntryLabel() {
1055*9880d681SAndroid Build Coastguard Worker   // linux/ppc32 - Normal entry label.
1056*9880d681SAndroid Build Coastguard Worker   if (!Subtarget->isPPC64() &&
1057*9880d681SAndroid Build Coastguard Worker       (!isPositionIndependent() ||
1058*9880d681SAndroid Build Coastguard Worker        MF->getFunction()->getParent()->getPICLevel() == PICLevel::SmallPIC))
1059*9880d681SAndroid Build Coastguard Worker     return AsmPrinter::EmitFunctionEntryLabel();
1060*9880d681SAndroid Build Coastguard Worker 
1061*9880d681SAndroid Build Coastguard Worker   if (!Subtarget->isPPC64()) {
1062*9880d681SAndroid Build Coastguard Worker     const PPCFunctionInfo *PPCFI = MF->getInfo<PPCFunctionInfo>();
1063*9880d681SAndroid Build Coastguard Worker     if (PPCFI->usesPICBase()) {
1064*9880d681SAndroid Build Coastguard Worker       MCSymbol *RelocSymbol = PPCFI->getPICOffsetSymbol();
1065*9880d681SAndroid Build Coastguard Worker       MCSymbol *PICBase = MF->getPICBaseSymbol();
1066*9880d681SAndroid Build Coastguard Worker       OutStreamer->EmitLabel(RelocSymbol);
1067*9880d681SAndroid Build Coastguard Worker 
1068*9880d681SAndroid Build Coastguard Worker       const MCExpr *OffsExpr =
1069*9880d681SAndroid Build Coastguard Worker         MCBinaryExpr::createSub(
1070*9880d681SAndroid Build Coastguard Worker           MCSymbolRefExpr::create(OutContext.getOrCreateSymbol(Twine(".LTOC")),
1071*9880d681SAndroid Build Coastguard Worker                                                                OutContext),
1072*9880d681SAndroid Build Coastguard Worker                                   MCSymbolRefExpr::create(PICBase, OutContext),
1073*9880d681SAndroid Build Coastguard Worker           OutContext);
1074*9880d681SAndroid Build Coastguard Worker       OutStreamer->EmitValue(OffsExpr, 4);
1075*9880d681SAndroid Build Coastguard Worker       OutStreamer->EmitLabel(CurrentFnSym);
1076*9880d681SAndroid Build Coastguard Worker       return;
1077*9880d681SAndroid Build Coastguard Worker     } else
1078*9880d681SAndroid Build Coastguard Worker       return AsmPrinter::EmitFunctionEntryLabel();
1079*9880d681SAndroid Build Coastguard Worker   }
1080*9880d681SAndroid Build Coastguard Worker 
1081*9880d681SAndroid Build Coastguard Worker   // ELFv2 ABI - Normal entry label.
1082*9880d681SAndroid Build Coastguard Worker   if (Subtarget->isELFv2ABI()) {
1083*9880d681SAndroid Build Coastguard Worker     // In the Large code model, we allow arbitrary displacements between
1084*9880d681SAndroid Build Coastguard Worker     // the text section and its associated TOC section.  We place the
1085*9880d681SAndroid Build Coastguard Worker     // full 8-byte offset to the TOC in memory immediatedly preceding
1086*9880d681SAndroid Build Coastguard Worker     // the function global entry point.
1087*9880d681SAndroid Build Coastguard Worker     if (TM.getCodeModel() == CodeModel::Large
1088*9880d681SAndroid Build Coastguard Worker         && !MF->getRegInfo().use_empty(PPC::X2)) {
1089*9880d681SAndroid Build Coastguard Worker       const PPCFunctionInfo *PPCFI = MF->getInfo<PPCFunctionInfo>();
1090*9880d681SAndroid Build Coastguard Worker 
1091*9880d681SAndroid Build Coastguard Worker       MCSymbol *TOCSymbol = OutContext.getOrCreateSymbol(StringRef(".TOC."));
1092*9880d681SAndroid Build Coastguard Worker       MCSymbol *GlobalEPSymbol = PPCFI->getGlobalEPSymbol();
1093*9880d681SAndroid Build Coastguard Worker       const MCExpr *TOCDeltaExpr =
1094*9880d681SAndroid Build Coastguard Worker         MCBinaryExpr::createSub(MCSymbolRefExpr::create(TOCSymbol, OutContext),
1095*9880d681SAndroid Build Coastguard Worker                                 MCSymbolRefExpr::create(GlobalEPSymbol,
1096*9880d681SAndroid Build Coastguard Worker                                                         OutContext),
1097*9880d681SAndroid Build Coastguard Worker                                 OutContext);
1098*9880d681SAndroid Build Coastguard Worker 
1099*9880d681SAndroid Build Coastguard Worker       OutStreamer->EmitLabel(PPCFI->getTOCOffsetSymbol());
1100*9880d681SAndroid Build Coastguard Worker       OutStreamer->EmitValue(TOCDeltaExpr, 8);
1101*9880d681SAndroid Build Coastguard Worker     }
1102*9880d681SAndroid Build Coastguard Worker     return AsmPrinter::EmitFunctionEntryLabel();
1103*9880d681SAndroid Build Coastguard Worker   }
1104*9880d681SAndroid Build Coastguard Worker 
1105*9880d681SAndroid Build Coastguard Worker   // Emit an official procedure descriptor.
1106*9880d681SAndroid Build Coastguard Worker   MCSectionSubPair Current = OutStreamer->getCurrentSection();
1107*9880d681SAndroid Build Coastguard Worker   MCSectionELF *Section = OutStreamer->getContext().getELFSection(
1108*9880d681SAndroid Build Coastguard Worker       ".opd", ELF::SHT_PROGBITS, ELF::SHF_WRITE | ELF::SHF_ALLOC);
1109*9880d681SAndroid Build Coastguard Worker   OutStreamer->SwitchSection(Section);
1110*9880d681SAndroid Build Coastguard Worker   OutStreamer->EmitLabel(CurrentFnSym);
1111*9880d681SAndroid Build Coastguard Worker   OutStreamer->EmitValueToAlignment(8);
1112*9880d681SAndroid Build Coastguard Worker   MCSymbol *Symbol1 = CurrentFnSymForSize;
1113*9880d681SAndroid Build Coastguard Worker   // Generates a R_PPC64_ADDR64 (from FK_DATA_8) relocation for the function
1114*9880d681SAndroid Build Coastguard Worker   // entry point.
1115*9880d681SAndroid Build Coastguard Worker   OutStreamer->EmitValue(MCSymbolRefExpr::create(Symbol1, OutContext),
1116*9880d681SAndroid Build Coastguard Worker                          8 /*size*/);
1117*9880d681SAndroid Build Coastguard Worker   MCSymbol *Symbol2 = OutContext.getOrCreateSymbol(StringRef(".TOC."));
1118*9880d681SAndroid Build Coastguard Worker   // Generates a R_PPC64_TOC relocation for TOC base insertion.
1119*9880d681SAndroid Build Coastguard Worker   OutStreamer->EmitValue(
1120*9880d681SAndroid Build Coastguard Worker     MCSymbolRefExpr::create(Symbol2, MCSymbolRefExpr::VK_PPC_TOCBASE, OutContext),
1121*9880d681SAndroid Build Coastguard Worker     8/*size*/);
1122*9880d681SAndroid Build Coastguard Worker   // Emit a null environment pointer.
1123*9880d681SAndroid Build Coastguard Worker   OutStreamer->EmitIntValue(0, 8 /* size */);
1124*9880d681SAndroid Build Coastguard Worker   OutStreamer->SwitchSection(Current.first, Current.second);
1125*9880d681SAndroid Build Coastguard Worker }
1126*9880d681SAndroid Build Coastguard Worker 
doFinalization(Module & M)1127*9880d681SAndroid Build Coastguard Worker bool PPCLinuxAsmPrinter::doFinalization(Module &M) {
1128*9880d681SAndroid Build Coastguard Worker   const DataLayout &DL = getDataLayout();
1129*9880d681SAndroid Build Coastguard Worker 
1130*9880d681SAndroid Build Coastguard Worker   bool isPPC64 = DL.getPointerSizeInBits() == 64;
1131*9880d681SAndroid Build Coastguard Worker 
1132*9880d681SAndroid Build Coastguard Worker   PPCTargetStreamer &TS =
1133*9880d681SAndroid Build Coastguard Worker       static_cast<PPCTargetStreamer &>(*OutStreamer->getTargetStreamer());
1134*9880d681SAndroid Build Coastguard Worker 
1135*9880d681SAndroid Build Coastguard Worker   if (!TOC.empty()) {
1136*9880d681SAndroid Build Coastguard Worker     MCSectionELF *Section;
1137*9880d681SAndroid Build Coastguard Worker 
1138*9880d681SAndroid Build Coastguard Worker     if (isPPC64)
1139*9880d681SAndroid Build Coastguard Worker       Section = OutStreamer->getContext().getELFSection(
1140*9880d681SAndroid Build Coastguard Worker           ".toc", ELF::SHT_PROGBITS, ELF::SHF_WRITE | ELF::SHF_ALLOC);
1141*9880d681SAndroid Build Coastguard Worker         else
1142*9880d681SAndroid Build Coastguard Worker           Section = OutStreamer->getContext().getELFSection(
1143*9880d681SAndroid Build Coastguard Worker               ".got2", ELF::SHT_PROGBITS, ELF::SHF_WRITE | ELF::SHF_ALLOC);
1144*9880d681SAndroid Build Coastguard Worker     OutStreamer->SwitchSection(Section);
1145*9880d681SAndroid Build Coastguard Worker 
1146*9880d681SAndroid Build Coastguard Worker     for (MapVector<MCSymbol*, MCSymbol*>::iterator I = TOC.begin(),
1147*9880d681SAndroid Build Coastguard Worker          E = TOC.end(); I != E; ++I) {
1148*9880d681SAndroid Build Coastguard Worker       OutStreamer->EmitLabel(I->second);
1149*9880d681SAndroid Build Coastguard Worker       MCSymbol *S = I->first;
1150*9880d681SAndroid Build Coastguard Worker       if (isPPC64)
1151*9880d681SAndroid Build Coastguard Worker         TS.emitTCEntry(*S);
1152*9880d681SAndroid Build Coastguard Worker       else
1153*9880d681SAndroid Build Coastguard Worker         OutStreamer->EmitSymbolValue(S, 4);
1154*9880d681SAndroid Build Coastguard Worker     }
1155*9880d681SAndroid Build Coastguard Worker   }
1156*9880d681SAndroid Build Coastguard Worker 
1157*9880d681SAndroid Build Coastguard Worker   return AsmPrinter::doFinalization(M);
1158*9880d681SAndroid Build Coastguard Worker }
1159*9880d681SAndroid Build Coastguard Worker 
1160*9880d681SAndroid Build Coastguard Worker /// EmitFunctionBodyStart - Emit a global entry point prefix for ELFv2.
EmitFunctionBodyStart()1161*9880d681SAndroid Build Coastguard Worker void PPCLinuxAsmPrinter::EmitFunctionBodyStart() {
1162*9880d681SAndroid Build Coastguard Worker   // In the ELFv2 ABI, in functions that use the TOC register, we need to
1163*9880d681SAndroid Build Coastguard Worker   // provide two entry points.  The ABI guarantees that when calling the
1164*9880d681SAndroid Build Coastguard Worker   // local entry point, r2 is set up by the caller to contain the TOC base
1165*9880d681SAndroid Build Coastguard Worker   // for this function, and when calling the global entry point, r12 is set
1166*9880d681SAndroid Build Coastguard Worker   // up by the caller to hold the address of the global entry point.  We
1167*9880d681SAndroid Build Coastguard Worker   // thus emit a prefix sequence along the following lines:
1168*9880d681SAndroid Build Coastguard Worker   //
1169*9880d681SAndroid Build Coastguard Worker   // func:
1170*9880d681SAndroid Build Coastguard Worker   // .Lfunc_gepNN:
1171*9880d681SAndroid Build Coastguard Worker   //         # global entry point
1172*9880d681SAndroid Build Coastguard Worker   //         addis r2,r12,(.TOC.-.Lfunc_gepNN)@ha
1173*9880d681SAndroid Build Coastguard Worker   //         addi  r2,r2,(.TOC.-.Lfunc_gepNN)@l
1174*9880d681SAndroid Build Coastguard Worker   // .Lfunc_lepNN:
1175*9880d681SAndroid Build Coastguard Worker   //         .localentry func, .Lfunc_lepNN-.Lfunc_gepNN
1176*9880d681SAndroid Build Coastguard Worker   //         # local entry point, followed by function body
1177*9880d681SAndroid Build Coastguard Worker   //
1178*9880d681SAndroid Build Coastguard Worker   // For the Large code model, we create
1179*9880d681SAndroid Build Coastguard Worker   //
1180*9880d681SAndroid Build Coastguard Worker   // .Lfunc_tocNN:
1181*9880d681SAndroid Build Coastguard Worker   //         .quad .TOC.-.Lfunc_gepNN      # done by EmitFunctionEntryLabel
1182*9880d681SAndroid Build Coastguard Worker   // func:
1183*9880d681SAndroid Build Coastguard Worker   // .Lfunc_gepNN:
1184*9880d681SAndroid Build Coastguard Worker   //         # global entry point
1185*9880d681SAndroid Build Coastguard Worker   //         ld    r2,.Lfunc_tocNN-.Lfunc_gepNN(r12)
1186*9880d681SAndroid Build Coastguard Worker   //         add   r2,r2,r12
1187*9880d681SAndroid Build Coastguard Worker   // .Lfunc_lepNN:
1188*9880d681SAndroid Build Coastguard Worker   //         .localentry func, .Lfunc_lepNN-.Lfunc_gepNN
1189*9880d681SAndroid Build Coastguard Worker   //         # local entry point, followed by function body
1190*9880d681SAndroid Build Coastguard Worker   //
1191*9880d681SAndroid Build Coastguard Worker   // This ensures we have r2 set up correctly while executing the function
1192*9880d681SAndroid Build Coastguard Worker   // body, no matter which entry point is called.
1193*9880d681SAndroid Build Coastguard Worker   if (Subtarget->isELFv2ABI()
1194*9880d681SAndroid Build Coastguard Worker       // Only do all that if the function uses r2 in the first place.
1195*9880d681SAndroid Build Coastguard Worker       && !MF->getRegInfo().use_empty(PPC::X2)) {
1196*9880d681SAndroid Build Coastguard Worker     const PPCFunctionInfo *PPCFI = MF->getInfo<PPCFunctionInfo>();
1197*9880d681SAndroid Build Coastguard Worker 
1198*9880d681SAndroid Build Coastguard Worker     MCSymbol *GlobalEntryLabel = PPCFI->getGlobalEPSymbol();
1199*9880d681SAndroid Build Coastguard Worker     OutStreamer->EmitLabel(GlobalEntryLabel);
1200*9880d681SAndroid Build Coastguard Worker     const MCSymbolRefExpr *GlobalEntryLabelExp =
1201*9880d681SAndroid Build Coastguard Worker       MCSymbolRefExpr::create(GlobalEntryLabel, OutContext);
1202*9880d681SAndroid Build Coastguard Worker 
1203*9880d681SAndroid Build Coastguard Worker     if (TM.getCodeModel() != CodeModel::Large) {
1204*9880d681SAndroid Build Coastguard Worker       MCSymbol *TOCSymbol = OutContext.getOrCreateSymbol(StringRef(".TOC."));
1205*9880d681SAndroid Build Coastguard Worker       const MCExpr *TOCDeltaExpr =
1206*9880d681SAndroid Build Coastguard Worker         MCBinaryExpr::createSub(MCSymbolRefExpr::create(TOCSymbol, OutContext),
1207*9880d681SAndroid Build Coastguard Worker                                 GlobalEntryLabelExp, OutContext);
1208*9880d681SAndroid Build Coastguard Worker 
1209*9880d681SAndroid Build Coastguard Worker       const MCExpr *TOCDeltaHi =
1210*9880d681SAndroid Build Coastguard Worker         PPCMCExpr::createHa(TOCDeltaExpr, false, OutContext);
1211*9880d681SAndroid Build Coastguard Worker       EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::ADDIS)
1212*9880d681SAndroid Build Coastguard Worker                                    .addReg(PPC::X2)
1213*9880d681SAndroid Build Coastguard Worker                                    .addReg(PPC::X12)
1214*9880d681SAndroid Build Coastguard Worker                                    .addExpr(TOCDeltaHi));
1215*9880d681SAndroid Build Coastguard Worker 
1216*9880d681SAndroid Build Coastguard Worker       const MCExpr *TOCDeltaLo =
1217*9880d681SAndroid Build Coastguard Worker         PPCMCExpr::createLo(TOCDeltaExpr, false, OutContext);
1218*9880d681SAndroid Build Coastguard Worker       EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::ADDI)
1219*9880d681SAndroid Build Coastguard Worker                                    .addReg(PPC::X2)
1220*9880d681SAndroid Build Coastguard Worker                                    .addReg(PPC::X2)
1221*9880d681SAndroid Build Coastguard Worker                                    .addExpr(TOCDeltaLo));
1222*9880d681SAndroid Build Coastguard Worker     } else {
1223*9880d681SAndroid Build Coastguard Worker       MCSymbol *TOCOffset = PPCFI->getTOCOffsetSymbol();
1224*9880d681SAndroid Build Coastguard Worker       const MCExpr *TOCOffsetDeltaExpr =
1225*9880d681SAndroid Build Coastguard Worker         MCBinaryExpr::createSub(MCSymbolRefExpr::create(TOCOffset, OutContext),
1226*9880d681SAndroid Build Coastguard Worker                                 GlobalEntryLabelExp, OutContext);
1227*9880d681SAndroid Build Coastguard Worker 
1228*9880d681SAndroid Build Coastguard Worker       EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::LD)
1229*9880d681SAndroid Build Coastguard Worker                                    .addReg(PPC::X2)
1230*9880d681SAndroid Build Coastguard Worker                                    .addExpr(TOCOffsetDeltaExpr)
1231*9880d681SAndroid Build Coastguard Worker                                    .addReg(PPC::X12));
1232*9880d681SAndroid Build Coastguard Worker       EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::ADD8)
1233*9880d681SAndroid Build Coastguard Worker                                    .addReg(PPC::X2)
1234*9880d681SAndroid Build Coastguard Worker                                    .addReg(PPC::X2)
1235*9880d681SAndroid Build Coastguard Worker                                    .addReg(PPC::X12));
1236*9880d681SAndroid Build Coastguard Worker     }
1237*9880d681SAndroid Build Coastguard Worker 
1238*9880d681SAndroid Build Coastguard Worker     MCSymbol *LocalEntryLabel = PPCFI->getLocalEPSymbol();
1239*9880d681SAndroid Build Coastguard Worker     OutStreamer->EmitLabel(LocalEntryLabel);
1240*9880d681SAndroid Build Coastguard Worker     const MCSymbolRefExpr *LocalEntryLabelExp =
1241*9880d681SAndroid Build Coastguard Worker        MCSymbolRefExpr::create(LocalEntryLabel, OutContext);
1242*9880d681SAndroid Build Coastguard Worker     const MCExpr *LocalOffsetExp =
1243*9880d681SAndroid Build Coastguard Worker       MCBinaryExpr::createSub(LocalEntryLabelExp,
1244*9880d681SAndroid Build Coastguard Worker                               GlobalEntryLabelExp, OutContext);
1245*9880d681SAndroid Build Coastguard Worker 
1246*9880d681SAndroid Build Coastguard Worker     PPCTargetStreamer *TS =
1247*9880d681SAndroid Build Coastguard Worker       static_cast<PPCTargetStreamer *>(OutStreamer->getTargetStreamer());
1248*9880d681SAndroid Build Coastguard Worker 
1249*9880d681SAndroid Build Coastguard Worker     if (TS)
1250*9880d681SAndroid Build Coastguard Worker       TS->emitLocalEntry(cast<MCSymbolELF>(CurrentFnSym), LocalOffsetExp);
1251*9880d681SAndroid Build Coastguard Worker   }
1252*9880d681SAndroid Build Coastguard Worker }
1253*9880d681SAndroid Build Coastguard Worker 
1254*9880d681SAndroid Build Coastguard Worker /// EmitFunctionBodyEnd - Print the traceback table before the .size
1255*9880d681SAndroid Build Coastguard Worker /// directive.
1256*9880d681SAndroid Build Coastguard Worker ///
EmitFunctionBodyEnd()1257*9880d681SAndroid Build Coastguard Worker void PPCLinuxAsmPrinter::EmitFunctionBodyEnd() {
1258*9880d681SAndroid Build Coastguard Worker   // Only the 64-bit target requires a traceback table.  For now,
1259*9880d681SAndroid Build Coastguard Worker   // we only emit the word of zeroes that GDB requires to find
1260*9880d681SAndroid Build Coastguard Worker   // the end of the function, and zeroes for the eight-byte
1261*9880d681SAndroid Build Coastguard Worker   // mandatory fields.
1262*9880d681SAndroid Build Coastguard Worker   // FIXME: We should fill in the eight-byte mandatory fields as described in
1263*9880d681SAndroid Build Coastguard Worker   // the PPC64 ELF ABI (this is a low-priority item because GDB does not
1264*9880d681SAndroid Build Coastguard Worker   // currently make use of these fields).
1265*9880d681SAndroid Build Coastguard Worker   if (Subtarget->isPPC64()) {
1266*9880d681SAndroid Build Coastguard Worker     OutStreamer->EmitIntValue(0, 4/*size*/);
1267*9880d681SAndroid Build Coastguard Worker     OutStreamer->EmitIntValue(0, 8/*size*/);
1268*9880d681SAndroid Build Coastguard Worker   }
1269*9880d681SAndroid Build Coastguard Worker }
1270*9880d681SAndroid Build Coastguard Worker 
EmitStartOfAsmFile(Module & M)1271*9880d681SAndroid Build Coastguard Worker void PPCDarwinAsmPrinter::EmitStartOfAsmFile(Module &M) {
1272*9880d681SAndroid Build Coastguard Worker   static const char *const CPUDirectives[] = {
1273*9880d681SAndroid Build Coastguard Worker     "",
1274*9880d681SAndroid Build Coastguard Worker     "ppc",
1275*9880d681SAndroid Build Coastguard Worker     "ppc440",
1276*9880d681SAndroid Build Coastguard Worker     "ppc601",
1277*9880d681SAndroid Build Coastguard Worker     "ppc602",
1278*9880d681SAndroid Build Coastguard Worker     "ppc603",
1279*9880d681SAndroid Build Coastguard Worker     "ppc7400",
1280*9880d681SAndroid Build Coastguard Worker     "ppc750",
1281*9880d681SAndroid Build Coastguard Worker     "ppc970",
1282*9880d681SAndroid Build Coastguard Worker     "ppcA2",
1283*9880d681SAndroid Build Coastguard Worker     "ppce500mc",
1284*9880d681SAndroid Build Coastguard Worker     "ppce5500",
1285*9880d681SAndroid Build Coastguard Worker     "power3",
1286*9880d681SAndroid Build Coastguard Worker     "power4",
1287*9880d681SAndroid Build Coastguard Worker     "power5",
1288*9880d681SAndroid Build Coastguard Worker     "power5x",
1289*9880d681SAndroid Build Coastguard Worker     "power6",
1290*9880d681SAndroid Build Coastguard Worker     "power6x",
1291*9880d681SAndroid Build Coastguard Worker     "power7",
1292*9880d681SAndroid Build Coastguard Worker     // FIXME: why is power8 missing here?
1293*9880d681SAndroid Build Coastguard Worker     "ppc64",
1294*9880d681SAndroid Build Coastguard Worker     "ppc64le",
1295*9880d681SAndroid Build Coastguard Worker     "power9"
1296*9880d681SAndroid Build Coastguard Worker   };
1297*9880d681SAndroid Build Coastguard Worker 
1298*9880d681SAndroid Build Coastguard Worker   // Get the numerically largest directive.
1299*9880d681SAndroid Build Coastguard Worker   // FIXME: How should we merge darwin directives?
1300*9880d681SAndroid Build Coastguard Worker   unsigned Directive = PPC::DIR_NONE;
1301*9880d681SAndroid Build Coastguard Worker   for (const Function &F : M) {
1302*9880d681SAndroid Build Coastguard Worker     const PPCSubtarget &STI = TM.getSubtarget<PPCSubtarget>(F);
1303*9880d681SAndroid Build Coastguard Worker     unsigned FDir = STI.getDarwinDirective();
1304*9880d681SAndroid Build Coastguard Worker     Directive = Directive > FDir ? FDir : STI.getDarwinDirective();
1305*9880d681SAndroid Build Coastguard Worker     if (STI.hasMFOCRF() && Directive < PPC::DIR_970)
1306*9880d681SAndroid Build Coastguard Worker       Directive = PPC::DIR_970;
1307*9880d681SAndroid Build Coastguard Worker     if (STI.hasAltivec() && Directive < PPC::DIR_7400)
1308*9880d681SAndroid Build Coastguard Worker       Directive = PPC::DIR_7400;
1309*9880d681SAndroid Build Coastguard Worker     if (STI.isPPC64() && Directive < PPC::DIR_64)
1310*9880d681SAndroid Build Coastguard Worker       Directive = PPC::DIR_64;
1311*9880d681SAndroid Build Coastguard Worker   }
1312*9880d681SAndroid Build Coastguard Worker 
1313*9880d681SAndroid Build Coastguard Worker   assert(Directive <= PPC::DIR_64 && "Directive out of range.");
1314*9880d681SAndroid Build Coastguard Worker 
1315*9880d681SAndroid Build Coastguard Worker   assert(Directive < array_lengthof(CPUDirectives) &&
1316*9880d681SAndroid Build Coastguard Worker          "CPUDirectives[] might not be up-to-date!");
1317*9880d681SAndroid Build Coastguard Worker   PPCTargetStreamer &TStreamer =
1318*9880d681SAndroid Build Coastguard Worker       *static_cast<PPCTargetStreamer *>(OutStreamer->getTargetStreamer());
1319*9880d681SAndroid Build Coastguard Worker   TStreamer.emitMachine(CPUDirectives[Directive]);
1320*9880d681SAndroid Build Coastguard Worker 
1321*9880d681SAndroid Build Coastguard Worker   // Prime text sections so they are adjacent.  This reduces the likelihood a
1322*9880d681SAndroid Build Coastguard Worker   // large data or debug section causes a branch to exceed 16M limit.
1323*9880d681SAndroid Build Coastguard Worker   const TargetLoweringObjectFileMachO &TLOFMacho =
1324*9880d681SAndroid Build Coastguard Worker       static_cast<const TargetLoweringObjectFileMachO &>(getObjFileLowering());
1325*9880d681SAndroid Build Coastguard Worker   OutStreamer->SwitchSection(TLOFMacho.getTextCoalSection());
1326*9880d681SAndroid Build Coastguard Worker   if (TM.getRelocationModel() == Reloc::PIC_) {
1327*9880d681SAndroid Build Coastguard Worker     OutStreamer->SwitchSection(
1328*9880d681SAndroid Build Coastguard Worker            OutContext.getMachOSection("__TEXT", "__picsymbolstub1",
1329*9880d681SAndroid Build Coastguard Worker                                       MachO::S_SYMBOL_STUBS |
1330*9880d681SAndroid Build Coastguard Worker                                       MachO::S_ATTR_PURE_INSTRUCTIONS,
1331*9880d681SAndroid Build Coastguard Worker                                       32, SectionKind::getText()));
1332*9880d681SAndroid Build Coastguard Worker   } else if (TM.getRelocationModel() == Reloc::DynamicNoPIC) {
1333*9880d681SAndroid Build Coastguard Worker     OutStreamer->SwitchSection(
1334*9880d681SAndroid Build Coastguard Worker            OutContext.getMachOSection("__TEXT","__symbol_stub1",
1335*9880d681SAndroid Build Coastguard Worker                                       MachO::S_SYMBOL_STUBS |
1336*9880d681SAndroid Build Coastguard Worker                                       MachO::S_ATTR_PURE_INSTRUCTIONS,
1337*9880d681SAndroid Build Coastguard Worker                                       16, SectionKind::getText()));
1338*9880d681SAndroid Build Coastguard Worker   }
1339*9880d681SAndroid Build Coastguard Worker   OutStreamer->SwitchSection(getObjFileLowering().getTextSection());
1340*9880d681SAndroid Build Coastguard Worker }
1341*9880d681SAndroid Build Coastguard Worker 
doFinalization(Module & M)1342*9880d681SAndroid Build Coastguard Worker bool PPCDarwinAsmPrinter::doFinalization(Module &M) {
1343*9880d681SAndroid Build Coastguard Worker   bool isPPC64 = getDataLayout().getPointerSizeInBits() == 64;
1344*9880d681SAndroid Build Coastguard Worker 
1345*9880d681SAndroid Build Coastguard Worker   // Darwin/PPC always uses mach-o.
1346*9880d681SAndroid Build Coastguard Worker   const TargetLoweringObjectFileMachO &TLOFMacho =
1347*9880d681SAndroid Build Coastguard Worker       static_cast<const TargetLoweringObjectFileMachO &>(getObjFileLowering());
1348*9880d681SAndroid Build Coastguard Worker   MachineModuleInfoMachO &MMIMacho =
1349*9880d681SAndroid Build Coastguard Worker       MMI->getObjFileInfo<MachineModuleInfoMachO>();
1350*9880d681SAndroid Build Coastguard Worker 
1351*9880d681SAndroid Build Coastguard Worker   if (MAI->doesSupportExceptionHandling() && MMI) {
1352*9880d681SAndroid Build Coastguard Worker     // Add the (possibly multiple) personalities to the set of global values.
1353*9880d681SAndroid Build Coastguard Worker     // Only referenced functions get into the Personalities list.
1354*9880d681SAndroid Build Coastguard Worker     for (const Function *Personality : MMI->getPersonalities()) {
1355*9880d681SAndroid Build Coastguard Worker       if (Personality) {
1356*9880d681SAndroid Build Coastguard Worker         MCSymbol *NLPSym =
1357*9880d681SAndroid Build Coastguard Worker             getSymbolWithGlobalValueBase(Personality, "$non_lazy_ptr");
1358*9880d681SAndroid Build Coastguard Worker         MachineModuleInfoImpl::StubValueTy &StubSym =
1359*9880d681SAndroid Build Coastguard Worker             MMIMacho.getGVStubEntry(NLPSym);
1360*9880d681SAndroid Build Coastguard Worker         StubSym =
1361*9880d681SAndroid Build Coastguard Worker             MachineModuleInfoImpl::StubValueTy(getSymbol(Personality), true);
1362*9880d681SAndroid Build Coastguard Worker       }
1363*9880d681SAndroid Build Coastguard Worker     }
1364*9880d681SAndroid Build Coastguard Worker   }
1365*9880d681SAndroid Build Coastguard Worker 
1366*9880d681SAndroid Build Coastguard Worker   // Output stubs for dynamically-linked functions.
1367*9880d681SAndroid Build Coastguard Worker   MachineModuleInfoMachO::SymbolListTy Stubs = MMIMacho.GetGVStubList();
1368*9880d681SAndroid Build Coastguard Worker 
1369*9880d681SAndroid Build Coastguard Worker   // Output macho stubs for external and common global variables.
1370*9880d681SAndroid Build Coastguard Worker   if (!Stubs.empty()) {
1371*9880d681SAndroid Build Coastguard Worker     // Switch with ".non_lazy_symbol_pointer" directive.
1372*9880d681SAndroid Build Coastguard Worker     OutStreamer->SwitchSection(TLOFMacho.getNonLazySymbolPointerSection());
1373*9880d681SAndroid Build Coastguard Worker     EmitAlignment(isPPC64 ? 3 : 2);
1374*9880d681SAndroid Build Coastguard Worker 
1375*9880d681SAndroid Build Coastguard Worker     for (unsigned i = 0, e = Stubs.size(); i != e; ++i) {
1376*9880d681SAndroid Build Coastguard Worker       // L_foo$stub:
1377*9880d681SAndroid Build Coastguard Worker       OutStreamer->EmitLabel(Stubs[i].first);
1378*9880d681SAndroid Build Coastguard Worker       //   .indirect_symbol _foo
1379*9880d681SAndroid Build Coastguard Worker       MachineModuleInfoImpl::StubValueTy &MCSym = Stubs[i].second;
1380*9880d681SAndroid Build Coastguard Worker       OutStreamer->EmitSymbolAttribute(MCSym.getPointer(), MCSA_IndirectSymbol);
1381*9880d681SAndroid Build Coastguard Worker 
1382*9880d681SAndroid Build Coastguard Worker       if (MCSym.getInt())
1383*9880d681SAndroid Build Coastguard Worker         // External to current translation unit.
1384*9880d681SAndroid Build Coastguard Worker         OutStreamer->EmitIntValue(0, isPPC64 ? 8 : 4/*size*/);
1385*9880d681SAndroid Build Coastguard Worker       else
1386*9880d681SAndroid Build Coastguard Worker         // Internal to current translation unit.
1387*9880d681SAndroid Build Coastguard Worker         //
1388*9880d681SAndroid Build Coastguard Worker         // When we place the LSDA into the TEXT section, the type info pointers
1389*9880d681SAndroid Build Coastguard Worker         // need to be indirect and pc-rel. We accomplish this by using NLPs.
1390*9880d681SAndroid Build Coastguard Worker         // However, sometimes the types are local to the file. So we need to
1391*9880d681SAndroid Build Coastguard Worker         // fill in the value for the NLP in those cases.
1392*9880d681SAndroid Build Coastguard Worker         OutStreamer->EmitValue(MCSymbolRefExpr::create(MCSym.getPointer(),
1393*9880d681SAndroid Build Coastguard Worker                                                        OutContext),
1394*9880d681SAndroid Build Coastguard Worker                               isPPC64 ? 8 : 4/*size*/);
1395*9880d681SAndroid Build Coastguard Worker     }
1396*9880d681SAndroid Build Coastguard Worker 
1397*9880d681SAndroid Build Coastguard Worker     Stubs.clear();
1398*9880d681SAndroid Build Coastguard Worker     OutStreamer->AddBlankLine();
1399*9880d681SAndroid Build Coastguard Worker   }
1400*9880d681SAndroid Build Coastguard Worker 
1401*9880d681SAndroid Build Coastguard Worker   // Funny Darwin hack: This flag tells the linker that no global symbols
1402*9880d681SAndroid Build Coastguard Worker   // contain code that falls through to other global symbols (e.g. the obvious
1403*9880d681SAndroid Build Coastguard Worker   // implementation of multiple entry points).  If this doesn't occur, the
1404*9880d681SAndroid Build Coastguard Worker   // linker can safely perform dead code stripping.  Since LLVM never generates
1405*9880d681SAndroid Build Coastguard Worker   // code that does this, it is always safe to set.
1406*9880d681SAndroid Build Coastguard Worker   OutStreamer->EmitAssemblerFlag(MCAF_SubsectionsViaSymbols);
1407*9880d681SAndroid Build Coastguard Worker 
1408*9880d681SAndroid Build Coastguard Worker   return AsmPrinter::doFinalization(M);
1409*9880d681SAndroid Build Coastguard Worker }
1410*9880d681SAndroid Build Coastguard Worker 
1411*9880d681SAndroid Build Coastguard Worker /// createPPCAsmPrinterPass - Returns a pass that prints the PPC assembly code
1412*9880d681SAndroid Build Coastguard Worker /// for a MachineFunction to the given output stream, in a format that the
1413*9880d681SAndroid Build Coastguard Worker /// Darwin assembler can deal with.
1414*9880d681SAndroid Build Coastguard Worker ///
1415*9880d681SAndroid Build Coastguard Worker static AsmPrinter *
createPPCAsmPrinterPass(TargetMachine & tm,std::unique_ptr<MCStreamer> && Streamer)1416*9880d681SAndroid Build Coastguard Worker createPPCAsmPrinterPass(TargetMachine &tm,
1417*9880d681SAndroid Build Coastguard Worker                         std::unique_ptr<MCStreamer> &&Streamer) {
1418*9880d681SAndroid Build Coastguard Worker   if (tm.getTargetTriple().isMacOSX())
1419*9880d681SAndroid Build Coastguard Worker     return new PPCDarwinAsmPrinter(tm, std::move(Streamer));
1420*9880d681SAndroid Build Coastguard Worker   return new PPCLinuxAsmPrinter(tm, std::move(Streamer));
1421*9880d681SAndroid Build Coastguard Worker }
1422*9880d681SAndroid Build Coastguard Worker 
1423*9880d681SAndroid Build Coastguard Worker // Force static initialization.
LLVMInitializePowerPCAsmPrinter()1424*9880d681SAndroid Build Coastguard Worker extern "C" void LLVMInitializePowerPCAsmPrinter() {
1425*9880d681SAndroid Build Coastguard Worker   TargetRegistry::RegisterAsmPrinter(ThePPC32Target, createPPCAsmPrinterPass);
1426*9880d681SAndroid Build Coastguard Worker   TargetRegistry::RegisterAsmPrinter(ThePPC64Target, createPPCAsmPrinterPass);
1427*9880d681SAndroid Build Coastguard Worker   TargetRegistry::RegisterAsmPrinter(ThePPC64LETarget, createPPCAsmPrinterPass);
1428*9880d681SAndroid Build Coastguard Worker }
1429