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