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