[AMDGPU] Check for immediate SrcC in mfma in AsmParser
[llvm-core.git] / lib / Target / PowerPC / PPCAsmPrinter.cpp
blob8d23238e6159ef900988872dec89b8b63b462b8e
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'.
13 // Documentation at http://developer.apple.com/documentation/DeveloperTools/
14 // Reference/Assembler/ASMIntroduction/chapter_1_section_1.html
16 //===----------------------------------------------------------------------===//
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/Module.h"
47 #include "llvm/MC/MCAsmInfo.h"
48 #include "llvm/MC/MCContext.h"
49 #include "llvm/MC/MCExpr.h"
50 #include "llvm/MC/MCInst.h"
51 #include "llvm/MC/MCInstBuilder.h"
52 #include "llvm/MC/MCSectionELF.h"
53 #include "llvm/MC/MCSectionMachO.h"
54 #include "llvm/MC/MCSectionXCOFF.h"
55 #include "llvm/MC/MCStreamer.h"
56 #include "llvm/MC/MCSymbol.h"
57 #include "llvm/MC/MCSymbolELF.h"
58 #include "llvm/MC/MCSymbolXCOFF.h"
59 #include "llvm/MC/SectionKind.h"
60 #include "llvm/Support/Casting.h"
61 #include "llvm/Support/CodeGen.h"
62 #include "llvm/Support/Debug.h"
63 #include "llvm/Support/ErrorHandling.h"
64 #include "llvm/Support/TargetRegistry.h"
65 #include "llvm/Support/raw_ostream.h"
66 #include "llvm/Target/TargetMachine.h"
67 #include <algorithm>
68 #include <cassert>
69 #include <cstdint>
70 #include <memory>
71 #include <new>
73 using namespace llvm;
75 #define DEBUG_TYPE "asmprinter"
77 namespace {
79 class PPCAsmPrinter : public AsmPrinter {
80 protected:
81 MapVector<MCSymbol *, MCSymbol *> TOC;
82 const PPCSubtarget *Subtarget;
83 StackMaps SM;
85 public:
86 explicit PPCAsmPrinter(TargetMachine &TM,
87 std::unique_ptr<MCStreamer> Streamer)
88 : AsmPrinter(TM, std::move(Streamer)), SM(*this) {}
90 StringRef getPassName() const override { return "PowerPC Assembly Printer"; }
92 MCSymbol *lookUpOrCreateTOCEntry(MCSymbol *Sym);
94 bool doInitialization(Module &M) override {
95 if (!TOC.empty())
96 TOC.clear();
97 return AsmPrinter::doInitialization(M);
100 void EmitInstruction(const MachineInstr *MI) override;
102 /// This function is for PrintAsmOperand and PrintAsmMemoryOperand,
103 /// invoked by EmitMSInlineAsmStr and EmitGCCInlineAsmStr only.
104 /// The \p MI would be INLINEASM ONLY.
105 void printOperand(const MachineInstr *MI, unsigned OpNo, raw_ostream &O);
107 void PrintSymbolOperand(const MachineOperand &MO, raw_ostream &O) override;
108 bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,
109 const char *ExtraCode, raw_ostream &O) override;
110 bool PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNo,
111 const char *ExtraCode, raw_ostream &O) override;
113 void EmitEndOfAsmFile(Module &M) override;
115 void LowerSTACKMAP(StackMaps &SM, const MachineInstr &MI);
116 void LowerPATCHPOINT(StackMaps &SM, const MachineInstr &MI);
117 void EmitTlsCall(const MachineInstr *MI, MCSymbolRefExpr::VariantKind VK);
118 bool runOnMachineFunction(MachineFunction &MF) override {
119 Subtarget = &MF.getSubtarget<PPCSubtarget>();
120 bool Changed = AsmPrinter::runOnMachineFunction(MF);
121 emitXRayTable();
122 return Changed;
126 /// PPCLinuxAsmPrinter - PowerPC assembly printer, customized for Linux
127 class PPCLinuxAsmPrinter : public PPCAsmPrinter {
128 public:
129 explicit PPCLinuxAsmPrinter(TargetMachine &TM,
130 std::unique_ptr<MCStreamer> Streamer)
131 : PPCAsmPrinter(TM, std::move(Streamer)) {}
133 StringRef getPassName() const override {
134 return "Linux PPC Assembly Printer";
137 bool doFinalization(Module &M) override;
138 void EmitStartOfAsmFile(Module &M) override;
140 void EmitFunctionEntryLabel() override;
142 void EmitFunctionBodyStart() override;
143 void EmitFunctionBodyEnd() override;
144 void EmitInstruction(const MachineInstr *MI) override;
147 /// PPCDarwinAsmPrinter - PowerPC assembly printer, customized for Darwin/Mac
148 /// OS X
149 class PPCDarwinAsmPrinter : public PPCAsmPrinter {
150 public:
151 explicit PPCDarwinAsmPrinter(TargetMachine &TM,
152 std::unique_ptr<MCStreamer> Streamer)
153 : PPCAsmPrinter(TM, std::move(Streamer)) {}
155 StringRef getPassName() const override {
156 return "Darwin PPC Assembly Printer";
159 bool doFinalization(Module &M) override;
160 void EmitStartOfAsmFile(Module &M) override;
163 class PPCAIXAsmPrinter : public PPCAsmPrinter {
164 public:
165 PPCAIXAsmPrinter(TargetMachine &TM, std::unique_ptr<MCStreamer> Streamer)
166 : PPCAsmPrinter(TM, std::move(Streamer)) {}
168 StringRef getPassName() const override { return "AIX PPC Assembly Printer"; }
170 void EmitGlobalVariable(const GlobalVariable *GV) override;
173 } // end anonymous namespace
175 void PPCAsmPrinter::PrintSymbolOperand(const MachineOperand &MO,
176 raw_ostream &O) {
177 // Computing the address of a global symbol, not calling it.
178 const GlobalValue *GV = MO.getGlobal();
179 MCSymbol *SymToPrint;
181 // External or weakly linked global variables need non-lazily-resolved stubs
182 if (Subtarget->hasLazyResolverStub(GV)) {
183 SymToPrint = getSymbolWithGlobalValueBase(GV, "$non_lazy_ptr");
184 MachineModuleInfoImpl::StubValueTy &StubSym =
185 MMI->getObjFileInfo<MachineModuleInfoMachO>().getGVStubEntry(
186 SymToPrint);
187 if (!StubSym.getPointer())
188 StubSym = MachineModuleInfoImpl::StubValueTy(getSymbol(GV),
189 !GV->hasInternalLinkage());
190 } else {
191 SymToPrint = getSymbol(GV);
194 SymToPrint->print(O, MAI);
196 printOffset(MO.getOffset(), O);
199 void PPCAsmPrinter::printOperand(const MachineInstr *MI, unsigned OpNo,
200 raw_ostream &O) {
201 const DataLayout &DL = getDataLayout();
202 const MachineOperand &MO = MI->getOperand(OpNo);
204 switch (MO.getType()) {
205 case MachineOperand::MO_Register: {
206 // The MI is INLINEASM ONLY and UseVSXReg is always false.
207 const char *RegName = PPCInstPrinter::getRegisterName(MO.getReg());
209 // Linux assembler (Others?) does not take register mnemonics.
210 // FIXME - What about special registers used in mfspr/mtspr?
211 if (!Subtarget->isDarwin())
212 RegName = PPCRegisterInfo::stripRegisterPrefix(RegName);
213 O << RegName;
214 return;
216 case MachineOperand::MO_Immediate:
217 O << MO.getImm();
218 return;
220 case MachineOperand::MO_MachineBasicBlock:
221 MO.getMBB()->getSymbol()->print(O, MAI);
222 return;
223 case MachineOperand::MO_ConstantPoolIndex:
224 O << DL.getPrivateGlobalPrefix() << "CPI" << getFunctionNumber() << '_'
225 << MO.getIndex();
226 return;
227 case MachineOperand::MO_BlockAddress:
228 GetBlockAddressSymbol(MO.getBlockAddress())->print(O, MAI);
229 return;
230 case MachineOperand::MO_GlobalAddress: {
231 PrintSymbolOperand(MO, O);
232 return;
235 default:
236 O << "<unknown operand type: " << (unsigned)MO.getType() << ">";
237 return;
241 /// PrintAsmOperand - Print out an operand for an inline asm expression.
243 bool PPCAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,
244 const char *ExtraCode, raw_ostream &O) {
245 // Does this asm operand have a single letter operand modifier?
246 if (ExtraCode && ExtraCode[0]) {
247 if (ExtraCode[1] != 0) return true; // Unknown modifier.
249 switch (ExtraCode[0]) {
250 default:
251 // See if this is a generic print operand
252 return AsmPrinter::PrintAsmOperand(MI, OpNo, ExtraCode, O);
253 case 'L': // Write second word of DImode reference.
254 // Verify that this operand has two consecutive registers.
255 if (!MI->getOperand(OpNo).isReg() ||
256 OpNo+1 == MI->getNumOperands() ||
257 !MI->getOperand(OpNo+1).isReg())
258 return true;
259 ++OpNo; // Return the high-part.
260 break;
261 case 'I':
262 // Write 'i' if an integer constant, otherwise nothing. Used to print
263 // addi vs add, etc.
264 if (MI->getOperand(OpNo).isImm())
265 O << "i";
266 return false;
267 case 'x':
268 if(!MI->getOperand(OpNo).isReg())
269 return true;
270 // This operand uses VSX numbering.
271 // If the operand is a VMX register, convert it to a VSX register.
272 Register Reg = MI->getOperand(OpNo).getReg();
273 if (PPCInstrInfo::isVRRegister(Reg))
274 Reg = PPC::VSX32 + (Reg - PPC::V0);
275 else if (PPCInstrInfo::isVFRegister(Reg))
276 Reg = PPC::VSX32 + (Reg - PPC::VF0);
277 const char *RegName;
278 RegName = PPCInstPrinter::getRegisterName(Reg);
279 RegName = PPCRegisterInfo::stripRegisterPrefix(RegName);
280 O << RegName;
281 return false;
285 printOperand(MI, OpNo, O);
286 return false;
289 // At the moment, all inline asm memory operands are a single register.
290 // In any case, the output of this routine should always be just one
291 // assembler operand.
293 bool PPCAsmPrinter::PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNo,
294 const char *ExtraCode,
295 raw_ostream &O) {
296 if (ExtraCode && ExtraCode[0]) {
297 if (ExtraCode[1] != 0) return true; // Unknown modifier.
299 switch (ExtraCode[0]) {
300 default: return true; // Unknown modifier.
301 case 'y': // A memory reference for an X-form instruction
303 const char *RegName = "r0";
304 if (!Subtarget->isDarwin())
305 RegName = PPCRegisterInfo::stripRegisterPrefix(RegName);
306 O << RegName << ", ";
307 printOperand(MI, OpNo, O);
308 return false;
310 case 'U': // Print 'u' for update form.
311 case 'X': // Print 'x' for indexed form.
313 // FIXME: Currently for PowerPC memory operands are always loaded
314 // into a register, so we never get an update or indexed form.
315 // This is bad even for offset forms, since even if we know we
316 // have a value in -16(r1), we will generate a load into r<n>
317 // and then load from 0(r<n>). Until that issue is fixed,
318 // tolerate 'U' and 'X' but don't output anything.
319 assert(MI->getOperand(OpNo).isReg());
320 return false;
325 assert(MI->getOperand(OpNo).isReg());
326 O << "0(";
327 printOperand(MI, OpNo, O);
328 O << ")";
329 return false;
332 /// lookUpOrCreateTOCEntry -- Given a symbol, look up whether a TOC entry
333 /// exists for it. If not, create one. Then return a symbol that references
334 /// the TOC entry.
335 MCSymbol *PPCAsmPrinter::lookUpOrCreateTOCEntry(MCSymbol *Sym) {
336 MCSymbol *&TOCEntry = TOC[Sym];
337 if (!TOCEntry)
338 TOCEntry = createTempSymbol("C");
339 return TOCEntry;
342 void PPCAsmPrinter::EmitEndOfAsmFile(Module &M) {
343 emitStackMaps(SM);
346 void PPCAsmPrinter::LowerSTACKMAP(StackMaps &SM, const MachineInstr &MI) {
347 unsigned NumNOPBytes = MI.getOperand(1).getImm();
349 SM.recordStackMap(MI);
350 assert(NumNOPBytes % 4 == 0 && "Invalid number of NOP bytes requested!");
352 // Scan ahead to trim the shadow.
353 const MachineBasicBlock &MBB = *MI.getParent();
354 MachineBasicBlock::const_iterator MII(MI);
355 ++MII;
356 while (NumNOPBytes > 0) {
357 if (MII == MBB.end() || MII->isCall() ||
358 MII->getOpcode() == PPC::DBG_VALUE ||
359 MII->getOpcode() == TargetOpcode::PATCHPOINT ||
360 MII->getOpcode() == TargetOpcode::STACKMAP)
361 break;
362 ++MII;
363 NumNOPBytes -= 4;
366 // Emit nops.
367 for (unsigned i = 0; i < NumNOPBytes; i += 4)
368 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::NOP));
371 // Lower a patchpoint of the form:
372 // [<def>], <id>, <numBytes>, <target>, <numArgs>
373 void PPCAsmPrinter::LowerPATCHPOINT(StackMaps &SM, const MachineInstr &MI) {
374 SM.recordPatchPoint(MI);
375 PatchPointOpers Opers(&MI);
377 unsigned EncodedBytes = 0;
378 const MachineOperand &CalleeMO = Opers.getCallTarget();
380 if (CalleeMO.isImm()) {
381 int64_t CallTarget = CalleeMO.getImm();
382 if (CallTarget) {
383 assert((CallTarget & 0xFFFFFFFFFFFF) == CallTarget &&
384 "High 16 bits of call target should be zero.");
385 Register ScratchReg = MI.getOperand(Opers.getNextScratchIdx()).getReg();
386 EncodedBytes = 0;
387 // Materialize the jump address:
388 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::LI8)
389 .addReg(ScratchReg)
390 .addImm((CallTarget >> 32) & 0xFFFF));
391 ++EncodedBytes;
392 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::RLDIC)
393 .addReg(ScratchReg)
394 .addReg(ScratchReg)
395 .addImm(32).addImm(16));
396 ++EncodedBytes;
397 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::ORIS8)
398 .addReg(ScratchReg)
399 .addReg(ScratchReg)
400 .addImm((CallTarget >> 16) & 0xFFFF));
401 ++EncodedBytes;
402 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::ORI8)
403 .addReg(ScratchReg)
404 .addReg(ScratchReg)
405 .addImm(CallTarget & 0xFFFF));
407 // Save the current TOC pointer before the remote call.
408 int TOCSaveOffset = Subtarget->getFrameLowering()->getTOCSaveOffset();
409 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::STD)
410 .addReg(PPC::X2)
411 .addImm(TOCSaveOffset)
412 .addReg(PPC::X1));
413 ++EncodedBytes;
415 // If we're on ELFv1, then we need to load the actual function pointer
416 // from the function descriptor.
417 if (!Subtarget->isELFv2ABI()) {
418 // Load the new TOC pointer and the function address, but not r11
419 // (needing this is rare, and loading it here would prevent passing it
420 // via a 'nest' parameter.
421 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::LD)
422 .addReg(PPC::X2)
423 .addImm(8)
424 .addReg(ScratchReg));
425 ++EncodedBytes;
426 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::LD)
427 .addReg(ScratchReg)
428 .addImm(0)
429 .addReg(ScratchReg));
430 ++EncodedBytes;
433 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::MTCTR8)
434 .addReg(ScratchReg));
435 ++EncodedBytes;
436 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::BCTRL8));
437 ++EncodedBytes;
439 // Restore the TOC pointer after the call.
440 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::LD)
441 .addReg(PPC::X2)
442 .addImm(TOCSaveOffset)
443 .addReg(PPC::X1));
444 ++EncodedBytes;
446 } else if (CalleeMO.isGlobal()) {
447 const GlobalValue *GValue = CalleeMO.getGlobal();
448 MCSymbol *MOSymbol = getSymbol(GValue);
449 const MCExpr *SymVar = MCSymbolRefExpr::create(MOSymbol, OutContext);
451 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::BL8_NOP)
452 .addExpr(SymVar));
453 EncodedBytes += 2;
456 // Each instruction is 4 bytes.
457 EncodedBytes *= 4;
459 // Emit padding.
460 unsigned NumBytes = Opers.getNumPatchBytes();
461 assert(NumBytes >= EncodedBytes &&
462 "Patchpoint can't request size less than the length of a call.");
463 assert((NumBytes - EncodedBytes) % 4 == 0 &&
464 "Invalid number of NOP bytes requested!");
465 for (unsigned i = EncodedBytes; i < NumBytes; i += 4)
466 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::NOP));
469 /// EmitTlsCall -- Given a GETtls[ld]ADDR[32] instruction, print a
470 /// call to __tls_get_addr to the current output stream.
471 void PPCAsmPrinter::EmitTlsCall(const MachineInstr *MI,
472 MCSymbolRefExpr::VariantKind VK) {
473 StringRef Name = "__tls_get_addr";
474 MCSymbol *TlsGetAddr = OutContext.getOrCreateSymbol(Name);
475 MCSymbolRefExpr::VariantKind Kind = MCSymbolRefExpr::VK_None;
476 const Module *M = MF->getFunction().getParent();
478 assert(MI->getOperand(0).isReg() &&
479 ((Subtarget->isPPC64() && MI->getOperand(0).getReg() == PPC::X3) ||
480 (!Subtarget->isPPC64() && MI->getOperand(0).getReg() == PPC::R3)) &&
481 "GETtls[ld]ADDR[32] must define GPR3");
482 assert(MI->getOperand(1).isReg() &&
483 ((Subtarget->isPPC64() && MI->getOperand(1).getReg() == PPC::X3) ||
484 (!Subtarget->isPPC64() && MI->getOperand(1).getReg() == PPC::R3)) &&
485 "GETtls[ld]ADDR[32] must read GPR3");
487 if (!Subtarget->isPPC64() && !Subtarget->isDarwin() &&
488 isPositionIndependent())
489 Kind = MCSymbolRefExpr::VK_PLT;
490 const MCExpr *TlsRef =
491 MCSymbolRefExpr::create(TlsGetAddr, Kind, OutContext);
493 // Add 32768 offset to the symbol so we follow up the latest GOT/PLT ABI.
494 if (Kind == MCSymbolRefExpr::VK_PLT && Subtarget->isSecurePlt() &&
495 M->getPICLevel() == PICLevel::BigPIC)
496 TlsRef = MCBinaryExpr::createAdd(
497 TlsRef, MCConstantExpr::create(32768, OutContext), OutContext);
498 const MachineOperand &MO = MI->getOperand(2);
499 const GlobalValue *GValue = MO.getGlobal();
500 MCSymbol *MOSymbol = getSymbol(GValue);
501 const MCExpr *SymVar = MCSymbolRefExpr::create(MOSymbol, VK, OutContext);
502 EmitToStreamer(*OutStreamer,
503 MCInstBuilder(Subtarget->isPPC64() ?
504 PPC::BL8_NOP_TLS : PPC::BL_TLS)
505 .addExpr(TlsRef)
506 .addExpr(SymVar));
509 /// EmitInstruction -- Print out a single PowerPC MI in Darwin syntax to
510 /// the current output stream.
512 void PPCAsmPrinter::EmitInstruction(const MachineInstr *MI) {
513 MCInst TmpInst;
514 bool isPPC64 = Subtarget->isPPC64();
515 bool isDarwin = TM.getTargetTriple().isOSDarwin();
516 const Module *M = MF->getFunction().getParent();
517 PICLevel::Level PL = M->getPICLevel();
519 #ifndef NDEBUG
520 // Validate that SPE and FPU are mutually exclusive in codegen
521 if (!MI->isInlineAsm()) {
522 for (const MachineOperand &MO: MI->operands()) {
523 if (MO.isReg()) {
524 Register Reg = MO.getReg();
525 if (Subtarget->hasSPE()) {
526 if (PPC::F4RCRegClass.contains(Reg) ||
527 PPC::F8RCRegClass.contains(Reg) ||
528 PPC::QBRCRegClass.contains(Reg) ||
529 PPC::QFRCRegClass.contains(Reg) ||
530 PPC::QSRCRegClass.contains(Reg) ||
531 PPC::VFRCRegClass.contains(Reg) ||
532 PPC::VRRCRegClass.contains(Reg) ||
533 PPC::VSFRCRegClass.contains(Reg) ||
534 PPC::VSSRCRegClass.contains(Reg)
536 llvm_unreachable("SPE targets cannot have FPRegs!");
537 } else {
538 if (PPC::SPERCRegClass.contains(Reg))
539 llvm_unreachable("SPE register found in FPU-targeted code!");
544 #endif
545 // Lower multi-instruction pseudo operations.
546 switch (MI->getOpcode()) {
547 default: break;
548 case TargetOpcode::DBG_VALUE:
549 llvm_unreachable("Should be handled target independently");
550 case TargetOpcode::STACKMAP:
551 return LowerSTACKMAP(SM, *MI);
552 case TargetOpcode::PATCHPOINT:
553 return LowerPATCHPOINT(SM, *MI);
555 case PPC::MoveGOTtoLR: {
556 // Transform %lr = MoveGOTtoLR
557 // Into this: bl _GLOBAL_OFFSET_TABLE_@local-4
558 // _GLOBAL_OFFSET_TABLE_@local-4 (instruction preceding
559 // _GLOBAL_OFFSET_TABLE_) has exactly one instruction:
560 // blrl
561 // This will return the pointer to _GLOBAL_OFFSET_TABLE_@local
562 MCSymbol *GOTSymbol =
563 OutContext.getOrCreateSymbol(StringRef("_GLOBAL_OFFSET_TABLE_"));
564 const MCExpr *OffsExpr =
565 MCBinaryExpr::createSub(MCSymbolRefExpr::create(GOTSymbol,
566 MCSymbolRefExpr::VK_PPC_LOCAL,
567 OutContext),
568 MCConstantExpr::create(4, OutContext),
569 OutContext);
571 // Emit the 'bl'.
572 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::BL).addExpr(OffsExpr));
573 return;
575 case PPC::MovePCtoLR:
576 case PPC::MovePCtoLR8: {
577 // Transform %lr = MovePCtoLR
578 // Into this, where the label is the PIC base:
579 // bl L1$pb
580 // L1$pb:
581 MCSymbol *PICBase = MF->getPICBaseSymbol();
583 // Emit the 'bl'.
584 EmitToStreamer(*OutStreamer,
585 MCInstBuilder(PPC::BL)
586 // FIXME: We would like an efficient form for this, so we
587 // don't have to do a lot of extra uniquing.
588 .addExpr(MCSymbolRefExpr::create(PICBase, OutContext)));
590 // Emit the label.
591 OutStreamer->EmitLabel(PICBase);
592 return;
594 case PPC::UpdateGBR: {
595 // Transform %rd = UpdateGBR(%rt, %ri)
596 // Into: lwz %rt, .L0$poff - .L0$pb(%ri)
597 // add %rd, %rt, %ri
598 // or into (if secure plt mode is on):
599 // addis r30, r30, {.LTOC,_GLOBAL_OFFSET_TABLE} - .L0$pb@ha
600 // addi r30, r30, {.LTOC,_GLOBAL_OFFSET_TABLE} - .L0$pb@l
601 // Get the offset from the GOT Base Register to the GOT
602 LowerPPCMachineInstrToMCInst(MI, TmpInst, *this, isDarwin);
603 if (Subtarget->isSecurePlt() && isPositionIndependent() ) {
604 unsigned PICR = TmpInst.getOperand(0).getReg();
605 MCSymbol *BaseSymbol = OutContext.getOrCreateSymbol(
606 M->getPICLevel() == PICLevel::SmallPIC ? "_GLOBAL_OFFSET_TABLE_"
607 : ".LTOC");
608 const MCExpr *PB =
609 MCSymbolRefExpr::create(MF->getPICBaseSymbol(), OutContext);
611 const MCExpr *DeltaExpr = MCBinaryExpr::createSub(
612 MCSymbolRefExpr::create(BaseSymbol, OutContext), PB, OutContext);
614 const MCExpr *DeltaHi = PPCMCExpr::createHa(DeltaExpr, false, OutContext);
615 EmitToStreamer(
616 *OutStreamer,
617 MCInstBuilder(PPC::ADDIS).addReg(PICR).addReg(PICR).addExpr(DeltaHi));
619 const MCExpr *DeltaLo = PPCMCExpr::createLo(DeltaExpr, false, OutContext);
620 EmitToStreamer(
621 *OutStreamer,
622 MCInstBuilder(PPC::ADDI).addReg(PICR).addReg(PICR).addExpr(DeltaLo));
623 return;
624 } else {
625 MCSymbol *PICOffset =
626 MF->getInfo<PPCFunctionInfo>()->getPICOffsetSymbol();
627 TmpInst.setOpcode(PPC::LWZ);
628 const MCExpr *Exp =
629 MCSymbolRefExpr::create(PICOffset, MCSymbolRefExpr::VK_None, OutContext);
630 const MCExpr *PB =
631 MCSymbolRefExpr::create(MF->getPICBaseSymbol(),
632 MCSymbolRefExpr::VK_None,
633 OutContext);
634 const MCOperand TR = TmpInst.getOperand(1);
635 const MCOperand PICR = TmpInst.getOperand(0);
637 // Step 1: lwz %rt, .L$poff - .L$pb(%ri)
638 TmpInst.getOperand(1) =
639 MCOperand::createExpr(MCBinaryExpr::createSub(Exp, PB, OutContext));
640 TmpInst.getOperand(0) = TR;
641 TmpInst.getOperand(2) = PICR;
642 EmitToStreamer(*OutStreamer, TmpInst);
644 TmpInst.setOpcode(PPC::ADD4);
645 TmpInst.getOperand(0) = PICR;
646 TmpInst.getOperand(1) = TR;
647 TmpInst.getOperand(2) = PICR;
648 EmitToStreamer(*OutStreamer, TmpInst);
649 return;
652 case PPC::LWZtoc: {
653 // Transform %r3 = LWZtoc @min1, %r2
654 LowerPPCMachineInstrToMCInst(MI, TmpInst, *this, isDarwin);
656 // Change the opcode to LWZ, and the global address operand to be a
657 // reference to the GOT entry we will synthesize later.
658 TmpInst.setOpcode(PPC::LWZ);
659 const MachineOperand &MO = MI->getOperand(1);
661 // Map symbol -> label of TOC entry
662 assert(MO.isGlobal() || MO.isCPI() || MO.isJTI() || MO.isBlockAddress());
663 MCSymbol *MOSymbol = nullptr;
664 if (MO.isGlobal())
665 MOSymbol = getSymbol(MO.getGlobal());
666 else if (MO.isCPI())
667 MOSymbol = GetCPISymbol(MO.getIndex());
668 else if (MO.isJTI())
669 MOSymbol = GetJTISymbol(MO.getIndex());
670 else if (MO.isBlockAddress())
671 MOSymbol = GetBlockAddressSymbol(MO.getBlockAddress());
673 if (PL == PICLevel::SmallPIC) {
674 const MCExpr *Exp =
675 MCSymbolRefExpr::create(MOSymbol, MCSymbolRefExpr::VK_GOT,
676 OutContext);
677 TmpInst.getOperand(1) = MCOperand::createExpr(Exp);
678 } else {
679 MCSymbol *TOCEntry = lookUpOrCreateTOCEntry(MOSymbol);
681 const MCExpr *Exp =
682 MCSymbolRefExpr::create(TOCEntry, MCSymbolRefExpr::VK_None,
683 OutContext);
684 const MCExpr *PB =
685 MCSymbolRefExpr::create(OutContext.getOrCreateSymbol(Twine(".LTOC")),
686 OutContext);
687 Exp = MCBinaryExpr::createSub(Exp, PB, OutContext);
688 TmpInst.getOperand(1) = MCOperand::createExpr(Exp);
690 EmitToStreamer(*OutStreamer, TmpInst);
691 return;
693 case PPC::LDtocJTI:
694 case PPC::LDtocCPT:
695 case PPC::LDtocBA:
696 case PPC::LDtoc: {
697 // Transform %x3 = LDtoc @min1, %x2
698 LowerPPCMachineInstrToMCInst(MI, TmpInst, *this, isDarwin);
700 // Change the opcode to LD, and the global address operand to be a
701 // reference to the TOC entry we will synthesize later.
702 TmpInst.setOpcode(PPC::LD);
703 const MachineOperand &MO = MI->getOperand(1);
705 // Map symbol -> label of TOC entry
706 assert(MO.isGlobal() || MO.isCPI() || MO.isJTI() || MO.isBlockAddress());
707 MCSymbol *MOSymbol = nullptr;
708 if (MO.isGlobal())
709 MOSymbol = getSymbol(MO.getGlobal());
710 else if (MO.isCPI())
711 MOSymbol = GetCPISymbol(MO.getIndex());
712 else if (MO.isJTI())
713 MOSymbol = GetJTISymbol(MO.getIndex());
714 else if (MO.isBlockAddress())
715 MOSymbol = GetBlockAddressSymbol(MO.getBlockAddress());
717 MCSymbol *TOCEntry = lookUpOrCreateTOCEntry(MOSymbol);
719 const MCExpr *Exp =
720 MCSymbolRefExpr::create(TOCEntry, MCSymbolRefExpr::VK_PPC_TOC,
721 OutContext);
722 TmpInst.getOperand(1) = MCOperand::createExpr(Exp);
723 EmitToStreamer(*OutStreamer, TmpInst);
724 return;
727 case PPC::ADDIStocHA8: {
728 // Transform %xd = ADDIStocHA8 %x2, @sym
729 LowerPPCMachineInstrToMCInst(MI, TmpInst, *this, isDarwin);
731 // Change the opcode to ADDIS8. If the global address is external, has
732 // common linkage, is a non-local function address, or is a jump table
733 // address, then generate a TOC entry and reference that. Otherwise
734 // reference the symbol directly.
735 TmpInst.setOpcode(PPC::ADDIS8);
736 const MachineOperand &MO = MI->getOperand(2);
737 assert((MO.isGlobal() || MO.isCPI() || MO.isJTI() ||
738 MO.isBlockAddress()) &&
739 "Invalid operand for ADDIStocHA8!");
740 MCSymbol *MOSymbol = nullptr;
741 bool GlobalToc = false;
743 if (MO.isGlobal()) {
744 const GlobalValue *GV = MO.getGlobal();
745 MOSymbol = getSymbol(GV);
746 unsigned char GVFlags = Subtarget->classifyGlobalReference(GV);
747 GlobalToc = (GVFlags & PPCII::MO_NLP_FLAG);
748 } else if (MO.isCPI()) {
749 MOSymbol = GetCPISymbol(MO.getIndex());
750 } else if (MO.isJTI()) {
751 MOSymbol = GetJTISymbol(MO.getIndex());
752 } else if (MO.isBlockAddress()) {
753 MOSymbol = GetBlockAddressSymbol(MO.getBlockAddress());
756 if (GlobalToc || MO.isJTI() || MO.isBlockAddress() ||
757 TM.getCodeModel() == CodeModel::Large)
758 MOSymbol = lookUpOrCreateTOCEntry(MOSymbol);
760 const MCExpr *Exp =
761 MCSymbolRefExpr::create(MOSymbol, MCSymbolRefExpr::VK_PPC_TOC_HA,
762 OutContext);
764 if (!MO.isJTI() && MO.getOffset())
765 Exp = MCBinaryExpr::createAdd(Exp,
766 MCConstantExpr::create(MO.getOffset(),
767 OutContext),
768 OutContext);
770 TmpInst.getOperand(2) = MCOperand::createExpr(Exp);
771 EmitToStreamer(*OutStreamer, TmpInst);
772 return;
774 case PPC::LDtocL: {
775 // Transform %xd = LDtocL @sym, %xs
776 LowerPPCMachineInstrToMCInst(MI, TmpInst, *this, isDarwin);
778 // Change the opcode to LD. If the global address is external, has
779 // common linkage, or is a jump table address, then reference the
780 // associated TOC entry. Otherwise reference the symbol directly.
781 TmpInst.setOpcode(PPC::LD);
782 const MachineOperand &MO = MI->getOperand(1);
783 assert((MO.isGlobal() || MO.isCPI() || MO.isJTI() ||
784 MO.isBlockAddress()) &&
785 "Invalid operand for LDtocL!");
786 MCSymbol *MOSymbol = nullptr;
788 if (MO.isJTI())
789 MOSymbol = lookUpOrCreateTOCEntry(GetJTISymbol(MO.getIndex()));
790 else if (MO.isBlockAddress()) {
791 MOSymbol = GetBlockAddressSymbol(MO.getBlockAddress());
792 MOSymbol = lookUpOrCreateTOCEntry(MOSymbol);
794 else if (MO.isCPI()) {
795 MOSymbol = GetCPISymbol(MO.getIndex());
796 if (TM.getCodeModel() == CodeModel::Large)
797 MOSymbol = lookUpOrCreateTOCEntry(MOSymbol);
799 else if (MO.isGlobal()) {
800 const GlobalValue *GV = MO.getGlobal();
801 MOSymbol = getSymbol(GV);
802 LLVM_DEBUG(
803 unsigned char GVFlags = Subtarget->classifyGlobalReference(GV);
804 assert((GVFlags & PPCII::MO_NLP_FLAG) &&
805 "LDtocL used on symbol that could be accessed directly is "
806 "invalid. Must match ADDIStocHA8."));
807 MOSymbol = lookUpOrCreateTOCEntry(MOSymbol);
810 const MCExpr *Exp =
811 MCSymbolRefExpr::create(MOSymbol, MCSymbolRefExpr::VK_PPC_TOC_LO,
812 OutContext);
813 TmpInst.getOperand(1) = MCOperand::createExpr(Exp);
814 EmitToStreamer(*OutStreamer, TmpInst);
815 return;
817 case PPC::ADDItocL: {
818 // Transform %xd = ADDItocL %xs, @sym
819 LowerPPCMachineInstrToMCInst(MI, TmpInst, *this, isDarwin);
821 // Change the opcode to ADDI8. If the global address is external, then
822 // generate a TOC entry and reference that. Otherwise reference the
823 // symbol directly.
824 TmpInst.setOpcode(PPC::ADDI8);
825 const MachineOperand &MO = MI->getOperand(2);
826 assert((MO.isGlobal() || MO.isCPI()) && "Invalid operand for ADDItocL");
827 MCSymbol *MOSymbol = nullptr;
829 if (MO.isGlobal()) {
830 const GlobalValue *GV = MO.getGlobal();
831 LLVM_DEBUG(unsigned char GVFlags = Subtarget->classifyGlobalReference(GV);
832 assert(!(GVFlags & PPCII::MO_NLP_FLAG) &&
833 "Interposable definitions must use indirect access."));
834 MOSymbol = getSymbol(GV);
835 } else if (MO.isCPI()) {
836 MOSymbol = GetCPISymbol(MO.getIndex());
839 const MCExpr *Exp =
840 MCSymbolRefExpr::create(MOSymbol, MCSymbolRefExpr::VK_PPC_TOC_LO,
841 OutContext);
842 TmpInst.getOperand(2) = MCOperand::createExpr(Exp);
843 EmitToStreamer(*OutStreamer, TmpInst);
844 return;
846 case PPC::ADDISgotTprelHA: {
847 // Transform: %xd = ADDISgotTprelHA %x2, @sym
848 // Into: %xd = ADDIS8 %x2, sym@got@tlsgd@ha
849 assert(Subtarget->isPPC64() && "Not supported for 32-bit PowerPC");
850 const MachineOperand &MO = MI->getOperand(2);
851 const GlobalValue *GValue = MO.getGlobal();
852 MCSymbol *MOSymbol = getSymbol(GValue);
853 const MCExpr *SymGotTprel =
854 MCSymbolRefExpr::create(MOSymbol, MCSymbolRefExpr::VK_PPC_GOT_TPREL_HA,
855 OutContext);
856 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::ADDIS8)
857 .addReg(MI->getOperand(0).getReg())
858 .addReg(MI->getOperand(1).getReg())
859 .addExpr(SymGotTprel));
860 return;
862 case PPC::LDgotTprelL:
863 case PPC::LDgotTprelL32: {
864 // Transform %xd = LDgotTprelL @sym, %xs
865 LowerPPCMachineInstrToMCInst(MI, TmpInst, *this, isDarwin);
867 // Change the opcode to LD.
868 TmpInst.setOpcode(isPPC64 ? PPC::LD : PPC::LWZ);
869 const MachineOperand &MO = MI->getOperand(1);
870 const GlobalValue *GValue = MO.getGlobal();
871 MCSymbol *MOSymbol = getSymbol(GValue);
872 const MCExpr *Exp =
873 MCSymbolRefExpr::create(MOSymbol, MCSymbolRefExpr::VK_PPC_GOT_TPREL_LO,
874 OutContext);
875 TmpInst.getOperand(1) = MCOperand::createExpr(Exp);
876 EmitToStreamer(*OutStreamer, TmpInst);
877 return;
880 case PPC::PPC32PICGOT: {
881 MCSymbol *GOTSymbol = OutContext.getOrCreateSymbol(StringRef("_GLOBAL_OFFSET_TABLE_"));
882 MCSymbol *GOTRef = OutContext.createTempSymbol();
883 MCSymbol *NextInstr = OutContext.createTempSymbol();
885 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::BL)
886 // FIXME: We would like an efficient form for this, so we don't have to do
887 // a lot of extra uniquing.
888 .addExpr(MCSymbolRefExpr::create(NextInstr, OutContext)));
889 const MCExpr *OffsExpr =
890 MCBinaryExpr::createSub(MCSymbolRefExpr::create(GOTSymbol, OutContext),
891 MCSymbolRefExpr::create(GOTRef, OutContext),
892 OutContext);
893 OutStreamer->EmitLabel(GOTRef);
894 OutStreamer->EmitValue(OffsExpr, 4);
895 OutStreamer->EmitLabel(NextInstr);
896 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::MFLR)
897 .addReg(MI->getOperand(0).getReg()));
898 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::LWZ)
899 .addReg(MI->getOperand(1).getReg())
900 .addImm(0)
901 .addReg(MI->getOperand(0).getReg()));
902 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::ADD4)
903 .addReg(MI->getOperand(0).getReg())
904 .addReg(MI->getOperand(1).getReg())
905 .addReg(MI->getOperand(0).getReg()));
906 return;
908 case PPC::PPC32GOT: {
909 MCSymbol *GOTSymbol =
910 OutContext.getOrCreateSymbol(StringRef("_GLOBAL_OFFSET_TABLE_"));
911 const MCExpr *SymGotTlsL = MCSymbolRefExpr::create(
912 GOTSymbol, MCSymbolRefExpr::VK_PPC_LO, OutContext);
913 const MCExpr *SymGotTlsHA = MCSymbolRefExpr::create(
914 GOTSymbol, MCSymbolRefExpr::VK_PPC_HA, OutContext);
915 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::LI)
916 .addReg(MI->getOperand(0).getReg())
917 .addExpr(SymGotTlsL));
918 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::ADDIS)
919 .addReg(MI->getOperand(0).getReg())
920 .addReg(MI->getOperand(0).getReg())
921 .addExpr(SymGotTlsHA));
922 return;
924 case PPC::ADDIStlsgdHA: {
925 // Transform: %xd = ADDIStlsgdHA %x2, @sym
926 // Into: %xd = ADDIS8 %x2, sym@got@tlsgd@ha
927 assert(Subtarget->isPPC64() && "Not supported for 32-bit PowerPC");
928 const MachineOperand &MO = MI->getOperand(2);
929 const GlobalValue *GValue = MO.getGlobal();
930 MCSymbol *MOSymbol = getSymbol(GValue);
931 const MCExpr *SymGotTlsGD =
932 MCSymbolRefExpr::create(MOSymbol, MCSymbolRefExpr::VK_PPC_GOT_TLSGD_HA,
933 OutContext);
934 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::ADDIS8)
935 .addReg(MI->getOperand(0).getReg())
936 .addReg(MI->getOperand(1).getReg())
937 .addExpr(SymGotTlsGD));
938 return;
940 case PPC::ADDItlsgdL:
941 // Transform: %xd = ADDItlsgdL %xs, @sym
942 // Into: %xd = ADDI8 %xs, sym@got@tlsgd@l
943 case PPC::ADDItlsgdL32: {
944 // Transform: %rd = ADDItlsgdL32 %rs, @sym
945 // Into: %rd = ADDI %rs, sym@got@tlsgd
946 const MachineOperand &MO = MI->getOperand(2);
947 const GlobalValue *GValue = MO.getGlobal();
948 MCSymbol *MOSymbol = getSymbol(GValue);
949 const MCExpr *SymGotTlsGD = MCSymbolRefExpr::create(
950 MOSymbol, Subtarget->isPPC64() ? MCSymbolRefExpr::VK_PPC_GOT_TLSGD_LO
951 : MCSymbolRefExpr::VK_PPC_GOT_TLSGD,
952 OutContext);
953 EmitToStreamer(*OutStreamer,
954 MCInstBuilder(Subtarget->isPPC64() ? PPC::ADDI8 : PPC::ADDI)
955 .addReg(MI->getOperand(0).getReg())
956 .addReg(MI->getOperand(1).getReg())
957 .addExpr(SymGotTlsGD));
958 return;
960 case PPC::GETtlsADDR:
961 // Transform: %x3 = GETtlsADDR %x3, @sym
962 // Into: BL8_NOP_TLS __tls_get_addr(sym at tlsgd)
963 case PPC::GETtlsADDR32: {
964 // Transform: %r3 = GETtlsADDR32 %r3, @sym
965 // Into: BL_TLS __tls_get_addr(sym at tlsgd)@PLT
966 EmitTlsCall(MI, MCSymbolRefExpr::VK_PPC_TLSGD);
967 return;
969 case PPC::ADDIStlsldHA: {
970 // Transform: %xd = ADDIStlsldHA %x2, @sym
971 // Into: %xd = ADDIS8 %x2, sym@got@tlsld@ha
972 assert(Subtarget->isPPC64() && "Not supported for 32-bit PowerPC");
973 const MachineOperand &MO = MI->getOperand(2);
974 const GlobalValue *GValue = MO.getGlobal();
975 MCSymbol *MOSymbol = getSymbol(GValue);
976 const MCExpr *SymGotTlsLD =
977 MCSymbolRefExpr::create(MOSymbol, MCSymbolRefExpr::VK_PPC_GOT_TLSLD_HA,
978 OutContext);
979 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::ADDIS8)
980 .addReg(MI->getOperand(0).getReg())
981 .addReg(MI->getOperand(1).getReg())
982 .addExpr(SymGotTlsLD));
983 return;
985 case PPC::ADDItlsldL:
986 // Transform: %xd = ADDItlsldL %xs, @sym
987 // Into: %xd = ADDI8 %xs, sym@got@tlsld@l
988 case PPC::ADDItlsldL32: {
989 // Transform: %rd = ADDItlsldL32 %rs, @sym
990 // Into: %rd = ADDI %rs, sym@got@tlsld
991 const MachineOperand &MO = MI->getOperand(2);
992 const GlobalValue *GValue = MO.getGlobal();
993 MCSymbol *MOSymbol = getSymbol(GValue);
994 const MCExpr *SymGotTlsLD = MCSymbolRefExpr::create(
995 MOSymbol, Subtarget->isPPC64() ? MCSymbolRefExpr::VK_PPC_GOT_TLSLD_LO
996 : MCSymbolRefExpr::VK_PPC_GOT_TLSLD,
997 OutContext);
998 EmitToStreamer(*OutStreamer,
999 MCInstBuilder(Subtarget->isPPC64() ? PPC::ADDI8 : PPC::ADDI)
1000 .addReg(MI->getOperand(0).getReg())
1001 .addReg(MI->getOperand(1).getReg())
1002 .addExpr(SymGotTlsLD));
1003 return;
1005 case PPC::GETtlsldADDR:
1006 // Transform: %x3 = GETtlsldADDR %x3, @sym
1007 // Into: BL8_NOP_TLS __tls_get_addr(sym at tlsld)
1008 case PPC::GETtlsldADDR32: {
1009 // Transform: %r3 = GETtlsldADDR32 %r3, @sym
1010 // Into: BL_TLS __tls_get_addr(sym at tlsld)@PLT
1011 EmitTlsCall(MI, MCSymbolRefExpr::VK_PPC_TLSLD);
1012 return;
1014 case PPC::ADDISdtprelHA:
1015 // Transform: %xd = ADDISdtprelHA %xs, @sym
1016 // Into: %xd = ADDIS8 %xs, sym@dtprel@ha
1017 case PPC::ADDISdtprelHA32: {
1018 // Transform: %rd = ADDISdtprelHA32 %rs, @sym
1019 // Into: %rd = ADDIS %rs, sym@dtprel@ha
1020 const MachineOperand &MO = MI->getOperand(2);
1021 const GlobalValue *GValue = MO.getGlobal();
1022 MCSymbol *MOSymbol = getSymbol(GValue);
1023 const MCExpr *SymDtprel =
1024 MCSymbolRefExpr::create(MOSymbol, MCSymbolRefExpr::VK_PPC_DTPREL_HA,
1025 OutContext);
1026 EmitToStreamer(
1027 *OutStreamer,
1028 MCInstBuilder(Subtarget->isPPC64() ? PPC::ADDIS8 : PPC::ADDIS)
1029 .addReg(MI->getOperand(0).getReg())
1030 .addReg(MI->getOperand(1).getReg())
1031 .addExpr(SymDtprel));
1032 return;
1034 case PPC::ADDIdtprelL:
1035 // Transform: %xd = ADDIdtprelL %xs, @sym
1036 // Into: %xd = ADDI8 %xs, sym@dtprel@l
1037 case PPC::ADDIdtprelL32: {
1038 // Transform: %rd = ADDIdtprelL32 %rs, @sym
1039 // Into: %rd = ADDI %rs, sym@dtprel@l
1040 const MachineOperand &MO = MI->getOperand(2);
1041 const GlobalValue *GValue = MO.getGlobal();
1042 MCSymbol *MOSymbol = getSymbol(GValue);
1043 const MCExpr *SymDtprel =
1044 MCSymbolRefExpr::create(MOSymbol, MCSymbolRefExpr::VK_PPC_DTPREL_LO,
1045 OutContext);
1046 EmitToStreamer(*OutStreamer,
1047 MCInstBuilder(Subtarget->isPPC64() ? PPC::ADDI8 : PPC::ADDI)
1048 .addReg(MI->getOperand(0).getReg())
1049 .addReg(MI->getOperand(1).getReg())
1050 .addExpr(SymDtprel));
1051 return;
1053 case PPC::MFOCRF:
1054 case PPC::MFOCRF8:
1055 if (!Subtarget->hasMFOCRF()) {
1056 // Transform: %r3 = MFOCRF %cr7
1057 // Into: %r3 = MFCR ;; cr7
1058 unsigned NewOpcode =
1059 MI->getOpcode() == PPC::MFOCRF ? PPC::MFCR : PPC::MFCR8;
1060 OutStreamer->AddComment(PPCInstPrinter::
1061 getRegisterName(MI->getOperand(1).getReg()));
1062 EmitToStreamer(*OutStreamer, MCInstBuilder(NewOpcode)
1063 .addReg(MI->getOperand(0).getReg()));
1064 return;
1066 break;
1067 case PPC::MTOCRF:
1068 case PPC::MTOCRF8:
1069 if (!Subtarget->hasMFOCRF()) {
1070 // Transform: %cr7 = MTOCRF %r3
1071 // Into: MTCRF mask, %r3 ;; cr7
1072 unsigned NewOpcode =
1073 MI->getOpcode() == PPC::MTOCRF ? PPC::MTCRF : PPC::MTCRF8;
1074 unsigned Mask = 0x80 >> OutContext.getRegisterInfo()
1075 ->getEncodingValue(MI->getOperand(0).getReg());
1076 OutStreamer->AddComment(PPCInstPrinter::
1077 getRegisterName(MI->getOperand(0).getReg()));
1078 EmitToStreamer(*OutStreamer, MCInstBuilder(NewOpcode)
1079 .addImm(Mask)
1080 .addReg(MI->getOperand(1).getReg()));
1081 return;
1083 break;
1084 case PPC::LD:
1085 case PPC::STD:
1086 case PPC::LWA_32:
1087 case PPC::LWA: {
1088 // Verify alignment is legal, so we don't create relocations
1089 // that can't be supported.
1090 // FIXME: This test is currently disabled for Darwin. The test
1091 // suite shows a handful of test cases that fail this check for
1092 // Darwin. Those need to be investigated before this sanity test
1093 // can be enabled for those subtargets.
1094 if (!Subtarget->isDarwin()) {
1095 unsigned OpNum = (MI->getOpcode() == PPC::STD) ? 2 : 1;
1096 const MachineOperand &MO = MI->getOperand(OpNum);
1097 if (MO.isGlobal() && MO.getGlobal()->getAlignment() < 4)
1098 llvm_unreachable("Global must be word-aligned for LD, STD, LWA!");
1100 // Now process the instruction normally.
1101 break;
1105 LowerPPCMachineInstrToMCInst(MI, TmpInst, *this, isDarwin);
1106 EmitToStreamer(*OutStreamer, TmpInst);
1109 void PPCLinuxAsmPrinter::EmitInstruction(const MachineInstr *MI) {
1110 if (!Subtarget->isPPC64())
1111 return PPCAsmPrinter::EmitInstruction(MI);
1113 switch (MI->getOpcode()) {
1114 default:
1115 return PPCAsmPrinter::EmitInstruction(MI);
1116 case TargetOpcode::PATCHABLE_FUNCTION_ENTER: {
1117 // .begin:
1118 // b .end # lis 0, FuncId[16..32]
1119 // nop # li 0, FuncId[0..15]
1120 // std 0, -8(1)
1121 // mflr 0
1122 // bl __xray_FunctionEntry
1123 // mtlr 0
1124 // .end:
1126 // Update compiler-rt/lib/xray/xray_powerpc64.cc accordingly when number
1127 // of instructions change.
1128 MCSymbol *BeginOfSled = OutContext.createTempSymbol();
1129 MCSymbol *EndOfSled = OutContext.createTempSymbol();
1130 OutStreamer->EmitLabel(BeginOfSled);
1131 EmitToStreamer(*OutStreamer,
1132 MCInstBuilder(PPC::B).addExpr(
1133 MCSymbolRefExpr::create(EndOfSled, OutContext)));
1134 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::NOP));
1135 EmitToStreamer(
1136 *OutStreamer,
1137 MCInstBuilder(PPC::STD).addReg(PPC::X0).addImm(-8).addReg(PPC::X1));
1138 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::MFLR8).addReg(PPC::X0));
1139 EmitToStreamer(*OutStreamer,
1140 MCInstBuilder(PPC::BL8_NOP)
1141 .addExpr(MCSymbolRefExpr::create(
1142 OutContext.getOrCreateSymbol("__xray_FunctionEntry"),
1143 OutContext)));
1144 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::MTLR8).addReg(PPC::X0));
1145 OutStreamer->EmitLabel(EndOfSled);
1146 recordSled(BeginOfSled, *MI, SledKind::FUNCTION_ENTER);
1147 break;
1149 case TargetOpcode::PATCHABLE_RET: {
1150 unsigned RetOpcode = MI->getOperand(0).getImm();
1151 MCInst RetInst;
1152 RetInst.setOpcode(RetOpcode);
1153 for (const auto &MO :
1154 make_range(std::next(MI->operands_begin()), MI->operands_end())) {
1155 MCOperand MCOp;
1156 if (LowerPPCMachineOperandToMCOperand(MO, MCOp, *this, false))
1157 RetInst.addOperand(MCOp);
1160 bool IsConditional;
1161 if (RetOpcode == PPC::BCCLR) {
1162 IsConditional = true;
1163 } else if (RetOpcode == PPC::TCRETURNdi8 || RetOpcode == PPC::TCRETURNri8 ||
1164 RetOpcode == PPC::TCRETURNai8) {
1165 break;
1166 } else if (RetOpcode == PPC::BLR8 || RetOpcode == PPC::TAILB8) {
1167 IsConditional = false;
1168 } else {
1169 EmitToStreamer(*OutStreamer, RetInst);
1170 break;
1173 MCSymbol *FallthroughLabel;
1174 if (IsConditional) {
1175 // Before:
1176 // bgtlr cr0
1178 // After:
1179 // ble cr0, .end
1180 // .p2align 3
1181 // .begin:
1182 // blr # lis 0, FuncId[16..32]
1183 // nop # li 0, FuncId[0..15]
1184 // std 0, -8(1)
1185 // mflr 0
1186 // bl __xray_FunctionExit
1187 // mtlr 0
1188 // blr
1189 // .end:
1191 // Update compiler-rt/lib/xray/xray_powerpc64.cc accordingly when number
1192 // of instructions change.
1193 FallthroughLabel = OutContext.createTempSymbol();
1194 EmitToStreamer(
1195 *OutStreamer,
1196 MCInstBuilder(PPC::BCC)
1197 .addImm(PPC::InvertPredicate(
1198 static_cast<PPC::Predicate>(MI->getOperand(1).getImm())))
1199 .addReg(MI->getOperand(2).getReg())
1200 .addExpr(MCSymbolRefExpr::create(FallthroughLabel, OutContext)));
1201 RetInst = MCInst();
1202 RetInst.setOpcode(PPC::BLR8);
1204 // .p2align 3
1205 // .begin:
1206 // b(lr)? # lis 0, FuncId[16..32]
1207 // nop # li 0, FuncId[0..15]
1208 // std 0, -8(1)
1209 // mflr 0
1210 // bl __xray_FunctionExit
1211 // mtlr 0
1212 // b(lr)?
1214 // Update compiler-rt/lib/xray/xray_powerpc64.cc accordingly when number
1215 // of instructions change.
1216 OutStreamer->EmitCodeAlignment(8);
1217 MCSymbol *BeginOfSled = OutContext.createTempSymbol();
1218 OutStreamer->EmitLabel(BeginOfSled);
1219 EmitToStreamer(*OutStreamer, RetInst);
1220 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::NOP));
1221 EmitToStreamer(
1222 *OutStreamer,
1223 MCInstBuilder(PPC::STD).addReg(PPC::X0).addImm(-8).addReg(PPC::X1));
1224 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::MFLR8).addReg(PPC::X0));
1225 EmitToStreamer(*OutStreamer,
1226 MCInstBuilder(PPC::BL8_NOP)
1227 .addExpr(MCSymbolRefExpr::create(
1228 OutContext.getOrCreateSymbol("__xray_FunctionExit"),
1229 OutContext)));
1230 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::MTLR8).addReg(PPC::X0));
1231 EmitToStreamer(*OutStreamer, RetInst);
1232 if (IsConditional)
1233 OutStreamer->EmitLabel(FallthroughLabel);
1234 recordSled(BeginOfSled, *MI, SledKind::FUNCTION_EXIT);
1235 break;
1237 case TargetOpcode::PATCHABLE_FUNCTION_EXIT:
1238 llvm_unreachable("PATCHABLE_FUNCTION_EXIT should never be emitted");
1239 case TargetOpcode::PATCHABLE_TAIL_CALL:
1240 // TODO: Define a trampoline `__xray_FunctionTailExit` and differentiate a
1241 // normal function exit from a tail exit.
1242 llvm_unreachable("Tail call is handled in the normal case. See comments "
1243 "around this assert.");
1247 void PPCLinuxAsmPrinter::EmitStartOfAsmFile(Module &M) {
1248 if (static_cast<const PPCTargetMachine &>(TM).isELFv2ABI()) {
1249 PPCTargetStreamer *TS =
1250 static_cast<PPCTargetStreamer *>(OutStreamer->getTargetStreamer());
1252 if (TS)
1253 TS->emitAbiVersion(2);
1256 if (static_cast<const PPCTargetMachine &>(TM).isPPC64() ||
1257 !isPositionIndependent())
1258 return AsmPrinter::EmitStartOfAsmFile(M);
1260 if (M.getPICLevel() == PICLevel::SmallPIC)
1261 return AsmPrinter::EmitStartOfAsmFile(M);
1263 OutStreamer->SwitchSection(OutContext.getELFSection(
1264 ".got2", ELF::SHT_PROGBITS, ELF::SHF_WRITE | ELF::SHF_ALLOC));
1266 MCSymbol *TOCSym = OutContext.getOrCreateSymbol(Twine(".LTOC"));
1267 MCSymbol *CurrentPos = OutContext.createTempSymbol();
1269 OutStreamer->EmitLabel(CurrentPos);
1271 // The GOT pointer points to the middle of the GOT, in order to reference the
1272 // entire 64kB range. 0x8000 is the midpoint.
1273 const MCExpr *tocExpr =
1274 MCBinaryExpr::createAdd(MCSymbolRefExpr::create(CurrentPos, OutContext),
1275 MCConstantExpr::create(0x8000, OutContext),
1276 OutContext);
1278 OutStreamer->EmitAssignment(TOCSym, tocExpr);
1280 OutStreamer->SwitchSection(getObjFileLowering().getTextSection());
1283 void PPCLinuxAsmPrinter::EmitFunctionEntryLabel() {
1284 // linux/ppc32 - Normal entry label.
1285 if (!Subtarget->isPPC64() &&
1286 (!isPositionIndependent() ||
1287 MF->getFunction().getParent()->getPICLevel() == PICLevel::SmallPIC))
1288 return AsmPrinter::EmitFunctionEntryLabel();
1290 if (!Subtarget->isPPC64()) {
1291 const PPCFunctionInfo *PPCFI = MF->getInfo<PPCFunctionInfo>();
1292 if (PPCFI->usesPICBase() && !Subtarget->isSecurePlt()) {
1293 MCSymbol *RelocSymbol = PPCFI->getPICOffsetSymbol();
1294 MCSymbol *PICBase = MF->getPICBaseSymbol();
1295 OutStreamer->EmitLabel(RelocSymbol);
1297 const MCExpr *OffsExpr =
1298 MCBinaryExpr::createSub(
1299 MCSymbolRefExpr::create(OutContext.getOrCreateSymbol(Twine(".LTOC")),
1300 OutContext),
1301 MCSymbolRefExpr::create(PICBase, OutContext),
1302 OutContext);
1303 OutStreamer->EmitValue(OffsExpr, 4);
1304 OutStreamer->EmitLabel(CurrentFnSym);
1305 return;
1306 } else
1307 return AsmPrinter::EmitFunctionEntryLabel();
1310 // ELFv2 ABI - Normal entry label.
1311 if (Subtarget->isELFv2ABI()) {
1312 // In the Large code model, we allow arbitrary displacements between
1313 // the text section and its associated TOC section. We place the
1314 // full 8-byte offset to the TOC in memory immediately preceding
1315 // the function global entry point.
1316 if (TM.getCodeModel() == CodeModel::Large
1317 && !MF->getRegInfo().use_empty(PPC::X2)) {
1318 const PPCFunctionInfo *PPCFI = MF->getInfo<PPCFunctionInfo>();
1320 MCSymbol *TOCSymbol = OutContext.getOrCreateSymbol(StringRef(".TOC."));
1321 MCSymbol *GlobalEPSymbol = PPCFI->getGlobalEPSymbol();
1322 const MCExpr *TOCDeltaExpr =
1323 MCBinaryExpr::createSub(MCSymbolRefExpr::create(TOCSymbol, OutContext),
1324 MCSymbolRefExpr::create(GlobalEPSymbol,
1325 OutContext),
1326 OutContext);
1328 OutStreamer->EmitLabel(PPCFI->getTOCOffsetSymbol());
1329 OutStreamer->EmitValue(TOCDeltaExpr, 8);
1331 return AsmPrinter::EmitFunctionEntryLabel();
1334 // Emit an official procedure descriptor.
1335 MCSectionSubPair Current = OutStreamer->getCurrentSection();
1336 MCSectionELF *Section = OutStreamer->getContext().getELFSection(
1337 ".opd", ELF::SHT_PROGBITS, ELF::SHF_WRITE | ELF::SHF_ALLOC);
1338 OutStreamer->SwitchSection(Section);
1339 OutStreamer->EmitLabel(CurrentFnSym);
1340 OutStreamer->EmitValueToAlignment(8);
1341 MCSymbol *Symbol1 = CurrentFnSymForSize;
1342 // Generates a R_PPC64_ADDR64 (from FK_DATA_8) relocation for the function
1343 // entry point.
1344 OutStreamer->EmitValue(MCSymbolRefExpr::create(Symbol1, OutContext),
1345 8 /*size*/);
1346 MCSymbol *Symbol2 = OutContext.getOrCreateSymbol(StringRef(".TOC."));
1347 // Generates a R_PPC64_TOC relocation for TOC base insertion.
1348 OutStreamer->EmitValue(
1349 MCSymbolRefExpr::create(Symbol2, MCSymbolRefExpr::VK_PPC_TOCBASE, OutContext),
1350 8/*size*/);
1351 // Emit a null environment pointer.
1352 OutStreamer->EmitIntValue(0, 8 /* size */);
1353 OutStreamer->SwitchSection(Current.first, Current.second);
1356 bool PPCLinuxAsmPrinter::doFinalization(Module &M) {
1357 const DataLayout &DL = getDataLayout();
1359 bool isPPC64 = DL.getPointerSizeInBits() == 64;
1361 PPCTargetStreamer &TS =
1362 static_cast<PPCTargetStreamer &>(*OutStreamer->getTargetStreamer());
1364 if (!TOC.empty()) {
1365 MCSectionELF *Section;
1367 if (isPPC64)
1368 Section = OutStreamer->getContext().getELFSection(
1369 ".toc", ELF::SHT_PROGBITS, ELF::SHF_WRITE | ELF::SHF_ALLOC);
1370 else
1371 Section = OutStreamer->getContext().getELFSection(
1372 ".got2", ELF::SHT_PROGBITS, ELF::SHF_WRITE | ELF::SHF_ALLOC);
1373 OutStreamer->SwitchSection(Section);
1375 for (MapVector<MCSymbol*, MCSymbol*>::iterator I = TOC.begin(),
1376 E = TOC.end(); I != E; ++I) {
1377 OutStreamer->EmitLabel(I->second);
1378 MCSymbol *S = I->first;
1379 if (isPPC64) {
1380 TS.emitTCEntry(*S);
1381 } else {
1382 OutStreamer->EmitValueToAlignment(4);
1383 OutStreamer->EmitSymbolValue(S, 4);
1388 return AsmPrinter::doFinalization(M);
1391 /// EmitFunctionBodyStart - Emit a global entry point prefix for ELFv2.
1392 void PPCLinuxAsmPrinter::EmitFunctionBodyStart() {
1393 // In the ELFv2 ABI, in functions that use the TOC register, we need to
1394 // provide two entry points. The ABI guarantees that when calling the
1395 // local entry point, r2 is set up by the caller to contain the TOC base
1396 // for this function, and when calling the global entry point, r12 is set
1397 // up by the caller to hold the address of the global entry point. We
1398 // thus emit a prefix sequence along the following lines:
1400 // func:
1401 // .Lfunc_gepNN:
1402 // # global entry point
1403 // addis r2,r12,(.TOC.-.Lfunc_gepNN)@ha
1404 // addi r2,r2,(.TOC.-.Lfunc_gepNN)@l
1405 // .Lfunc_lepNN:
1406 // .localentry func, .Lfunc_lepNN-.Lfunc_gepNN
1407 // # local entry point, followed by function body
1409 // For the Large code model, we create
1411 // .Lfunc_tocNN:
1412 // .quad .TOC.-.Lfunc_gepNN # done by EmitFunctionEntryLabel
1413 // func:
1414 // .Lfunc_gepNN:
1415 // # global entry point
1416 // ld r2,.Lfunc_tocNN-.Lfunc_gepNN(r12)
1417 // add r2,r2,r12
1418 // .Lfunc_lepNN:
1419 // .localentry func, .Lfunc_lepNN-.Lfunc_gepNN
1420 // # local entry point, followed by function body
1422 // This ensures we have r2 set up correctly while executing the function
1423 // body, no matter which entry point is called.
1424 if (Subtarget->isELFv2ABI()
1425 // Only do all that if the function uses r2 in the first place.
1426 && !MF->getRegInfo().use_empty(PPC::X2)) {
1427 // Note: The logic here must be synchronized with the code in the
1428 // branch-selection pass which sets the offset of the first block in the
1429 // function. This matters because it affects the alignment.
1430 const PPCFunctionInfo *PPCFI = MF->getInfo<PPCFunctionInfo>();
1432 MCSymbol *GlobalEntryLabel = PPCFI->getGlobalEPSymbol();
1433 OutStreamer->EmitLabel(GlobalEntryLabel);
1434 const MCSymbolRefExpr *GlobalEntryLabelExp =
1435 MCSymbolRefExpr::create(GlobalEntryLabel, OutContext);
1437 if (TM.getCodeModel() != CodeModel::Large) {
1438 MCSymbol *TOCSymbol = OutContext.getOrCreateSymbol(StringRef(".TOC."));
1439 const MCExpr *TOCDeltaExpr =
1440 MCBinaryExpr::createSub(MCSymbolRefExpr::create(TOCSymbol, OutContext),
1441 GlobalEntryLabelExp, OutContext);
1443 const MCExpr *TOCDeltaHi =
1444 PPCMCExpr::createHa(TOCDeltaExpr, false, OutContext);
1445 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::ADDIS)
1446 .addReg(PPC::X2)
1447 .addReg(PPC::X12)
1448 .addExpr(TOCDeltaHi));
1450 const MCExpr *TOCDeltaLo =
1451 PPCMCExpr::createLo(TOCDeltaExpr, false, OutContext);
1452 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::ADDI)
1453 .addReg(PPC::X2)
1454 .addReg(PPC::X2)
1455 .addExpr(TOCDeltaLo));
1456 } else {
1457 MCSymbol *TOCOffset = PPCFI->getTOCOffsetSymbol();
1458 const MCExpr *TOCOffsetDeltaExpr =
1459 MCBinaryExpr::createSub(MCSymbolRefExpr::create(TOCOffset, OutContext),
1460 GlobalEntryLabelExp, OutContext);
1462 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::LD)
1463 .addReg(PPC::X2)
1464 .addExpr(TOCOffsetDeltaExpr)
1465 .addReg(PPC::X12));
1466 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::ADD8)
1467 .addReg(PPC::X2)
1468 .addReg(PPC::X2)
1469 .addReg(PPC::X12));
1472 MCSymbol *LocalEntryLabel = PPCFI->getLocalEPSymbol();
1473 OutStreamer->EmitLabel(LocalEntryLabel);
1474 const MCSymbolRefExpr *LocalEntryLabelExp =
1475 MCSymbolRefExpr::create(LocalEntryLabel, OutContext);
1476 const MCExpr *LocalOffsetExp =
1477 MCBinaryExpr::createSub(LocalEntryLabelExp,
1478 GlobalEntryLabelExp, OutContext);
1480 PPCTargetStreamer *TS =
1481 static_cast<PPCTargetStreamer *>(OutStreamer->getTargetStreamer());
1483 if (TS)
1484 TS->emitLocalEntry(cast<MCSymbolELF>(CurrentFnSym), LocalOffsetExp);
1488 /// EmitFunctionBodyEnd - Print the traceback table before the .size
1489 /// directive.
1491 void PPCLinuxAsmPrinter::EmitFunctionBodyEnd() {
1492 // Only the 64-bit target requires a traceback table. For now,
1493 // we only emit the word of zeroes that GDB requires to find
1494 // the end of the function, and zeroes for the eight-byte
1495 // mandatory fields.
1496 // FIXME: We should fill in the eight-byte mandatory fields as described in
1497 // the PPC64 ELF ABI (this is a low-priority item because GDB does not
1498 // currently make use of these fields).
1499 if (Subtarget->isPPC64()) {
1500 OutStreamer->EmitIntValue(0, 4/*size*/);
1501 OutStreamer->EmitIntValue(0, 8/*size*/);
1505 void PPCDarwinAsmPrinter::EmitStartOfAsmFile(Module &M) {
1506 static const char *const CPUDirectives[] = {
1508 "ppc",
1509 "ppc440",
1510 "ppc601",
1511 "ppc602",
1512 "ppc603",
1513 "ppc7400",
1514 "ppc750",
1515 "ppc970",
1516 "ppcA2",
1517 "ppce500",
1518 "ppce500mc",
1519 "ppce5500",
1520 "power3",
1521 "power4",
1522 "power5",
1523 "power5x",
1524 "power6",
1525 "power6x",
1526 "power7",
1527 // FIXME: why is power8 missing here?
1528 "ppc64",
1529 "ppc64le",
1530 "power9"
1533 // Get the numerically largest directive.
1534 // FIXME: How should we merge darwin directives?
1535 unsigned Directive = PPC::DIR_NONE;
1536 for (const Function &F : M) {
1537 const PPCSubtarget &STI = TM.getSubtarget<PPCSubtarget>(F);
1538 unsigned FDir = STI.getDarwinDirective();
1539 Directive = Directive > FDir ? FDir : STI.getDarwinDirective();
1540 if (STI.hasMFOCRF() && Directive < PPC::DIR_970)
1541 Directive = PPC::DIR_970;
1542 if (STI.hasAltivec() && Directive < PPC::DIR_7400)
1543 Directive = PPC::DIR_7400;
1544 if (STI.isPPC64() && Directive < PPC::DIR_64)
1545 Directive = PPC::DIR_64;
1548 assert(Directive <= PPC::DIR_64 && "Directive out of range.");
1550 assert(Directive < array_lengthof(CPUDirectives) &&
1551 "CPUDirectives[] might not be up-to-date!");
1552 PPCTargetStreamer &TStreamer =
1553 *static_cast<PPCTargetStreamer *>(OutStreamer->getTargetStreamer());
1554 TStreamer.emitMachine(CPUDirectives[Directive]);
1556 // Prime text sections so they are adjacent. This reduces the likelihood a
1557 // large data or debug section causes a branch to exceed 16M limit.
1558 const TargetLoweringObjectFileMachO &TLOFMacho =
1559 static_cast<const TargetLoweringObjectFileMachO &>(getObjFileLowering());
1560 OutStreamer->SwitchSection(TLOFMacho.getTextCoalSection());
1561 if (TM.getRelocationModel() == Reloc::PIC_) {
1562 OutStreamer->SwitchSection(
1563 OutContext.getMachOSection("__TEXT", "__picsymbolstub1",
1564 MachO::S_SYMBOL_STUBS |
1565 MachO::S_ATTR_PURE_INSTRUCTIONS,
1566 32, SectionKind::getText()));
1567 } else if (TM.getRelocationModel() == Reloc::DynamicNoPIC) {
1568 OutStreamer->SwitchSection(
1569 OutContext.getMachOSection("__TEXT","__symbol_stub1",
1570 MachO::S_SYMBOL_STUBS |
1571 MachO::S_ATTR_PURE_INSTRUCTIONS,
1572 16, SectionKind::getText()));
1574 OutStreamer->SwitchSection(getObjFileLowering().getTextSection());
1577 bool PPCDarwinAsmPrinter::doFinalization(Module &M) {
1578 bool isPPC64 = getDataLayout().getPointerSizeInBits() == 64;
1580 // Darwin/PPC always uses mach-o.
1581 const TargetLoweringObjectFileMachO &TLOFMacho =
1582 static_cast<const TargetLoweringObjectFileMachO &>(getObjFileLowering());
1583 if (MMI) {
1584 MachineModuleInfoMachO &MMIMacho =
1585 MMI->getObjFileInfo<MachineModuleInfoMachO>();
1587 if (MAI->doesSupportExceptionHandling()) {
1588 // Add the (possibly multiple) personalities to the set of global values.
1589 // Only referenced functions get into the Personalities list.
1590 for (const Function *Personality : MMI->getPersonalities()) {
1591 if (Personality) {
1592 MCSymbol *NLPSym =
1593 getSymbolWithGlobalValueBase(Personality, "$non_lazy_ptr");
1594 MachineModuleInfoImpl::StubValueTy &StubSym =
1595 MMIMacho.getGVStubEntry(NLPSym);
1596 StubSym =
1597 MachineModuleInfoImpl::StubValueTy(getSymbol(Personality), true);
1602 // Output stubs for dynamically-linked functions.
1603 MachineModuleInfoMachO::SymbolListTy Stubs = MMIMacho.GetGVStubList();
1605 // Output macho stubs for external and common global variables.
1606 if (!Stubs.empty()) {
1607 // Switch with ".non_lazy_symbol_pointer" directive.
1608 OutStreamer->SwitchSection(TLOFMacho.getNonLazySymbolPointerSection());
1609 EmitAlignment(isPPC64 ? 3 : 2);
1611 for (unsigned i = 0, e = Stubs.size(); i != e; ++i) {
1612 // L_foo$stub:
1613 OutStreamer->EmitLabel(Stubs[i].first);
1614 // .indirect_symbol _foo
1615 MachineModuleInfoImpl::StubValueTy &MCSym = Stubs[i].second;
1616 OutStreamer->EmitSymbolAttribute(MCSym.getPointer(),
1617 MCSA_IndirectSymbol);
1619 if (MCSym.getInt())
1620 // External to current translation unit.
1621 OutStreamer->EmitIntValue(0, isPPC64 ? 8 : 4 /*size*/);
1622 else
1623 // Internal to current translation unit.
1625 // When we place the LSDA into the TEXT section, the type info
1626 // pointers
1627 // need to be indirect and pc-rel. We accomplish this by using NLPs.
1628 // However, sometimes the types are local to the file. So we need to
1629 // fill in the value for the NLP in those cases.
1630 OutStreamer->EmitValue(
1631 MCSymbolRefExpr::create(MCSym.getPointer(), OutContext),
1632 isPPC64 ? 8 : 4 /*size*/);
1635 Stubs.clear();
1636 OutStreamer->AddBlankLine();
1640 // Funny Darwin hack: This flag tells the linker that no global symbols
1641 // contain code that falls through to other global symbols (e.g. the obvious
1642 // implementation of multiple entry points). If this doesn't occur, the
1643 // linker can safely perform dead code stripping. Since LLVM never generates
1644 // code that does this, it is always safe to set.
1645 OutStreamer->EmitAssemblerFlag(MCAF_SubsectionsViaSymbols);
1647 return AsmPrinter::doFinalization(M);
1650 void PPCAIXAsmPrinter::EmitGlobalVariable(const GlobalVariable *GV) {
1651 // Early error checking limiting what is supported.
1652 if (GV->isThreadLocal())
1653 report_fatal_error("Thread local not yet supported on AIX.");
1655 if (GV->hasSection())
1656 report_fatal_error("Custom section for Data not yet supported.");
1658 if (GV->hasComdat())
1659 report_fatal_error("COMDAT not yet supported by AIX.");
1661 SectionKind GVKind = getObjFileLowering().getKindForGlobal(GV, TM);
1662 if (!GVKind.isCommon() && !GVKind.isBSSLocal())
1663 report_fatal_error("Only common variables are supported on AIX for now.");
1665 // Create the containing csect and switch to it.
1666 MCSectionXCOFF *CSect = cast<MCSectionXCOFF>(
1667 getObjFileLowering().SectionForGlobal(GV, GVKind, TM));
1668 OutStreamer->SwitchSection(CSect);
1670 // Create the symbol, set its storage class, and emit it.
1671 MCSymbolXCOFF *XSym = cast<MCSymbolXCOFF>(getSymbol(GV));
1672 XSym->setStorageClass(
1673 TargetLoweringObjectFileXCOFF::getStorageClassForGlobal(GV));
1674 XSym->setContainingCsect(CSect);
1676 const DataLayout &DL = GV->getParent()->getDataLayout();
1677 unsigned Align =
1678 GV->getAlignment() ? GV->getAlignment() : DL.getPreferredAlignment(GV);
1679 uint64_t Size = DL.getTypeAllocSize(GV->getType()->getElementType());
1681 if (GVKind.isBSSLocal())
1682 OutStreamer->EmitXCOFFLocalCommonSymbol(XSym, Size, Align);
1683 else
1684 OutStreamer->EmitCommonSymbol(XSym, Size, Align);
1687 /// createPPCAsmPrinterPass - Returns a pass that prints the PPC assembly code
1688 /// for a MachineFunction to the given output stream, in a format that the
1689 /// Darwin assembler can deal with.
1691 static AsmPrinter *
1692 createPPCAsmPrinterPass(TargetMachine &tm,
1693 std::unique_ptr<MCStreamer> &&Streamer) {
1694 if (tm.getTargetTriple().isMacOSX())
1695 return new PPCDarwinAsmPrinter(tm, std::move(Streamer));
1696 if (tm.getTargetTriple().isOSAIX())
1697 return new PPCAIXAsmPrinter(tm, std::move(Streamer));
1699 return new PPCLinuxAsmPrinter(tm, std::move(Streamer));
1702 // Force static initialization.
1703 extern "C" void LLVMInitializePowerPCAsmPrinter() {
1704 TargetRegistry::RegisterAsmPrinter(getThePPC32Target(),
1705 createPPCAsmPrinterPass);
1706 TargetRegistry::RegisterAsmPrinter(getThePPC64Target(),
1707 createPPCAsmPrinterPass);
1708 TargetRegistry::RegisterAsmPrinter(getThePPC64LETarget(),
1709 createPPCAsmPrinterPass);