1 //===-- PPCAsmPrinter.cpp - Print machine instrs to PowerPC assembly --------=//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
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'.
14 // Documentation at http://developer.apple.com/documentation/DeveloperTools/
15 // Reference/Assembler/ASMIntroduction/chapter_1_section_1.html
17 //===----------------------------------------------------------------------===//
19 #define DEBUG_TYPE "asmprinter"
21 #include "PPCPredicates.h"
22 #include "PPCTargetMachine.h"
23 #include "PPCSubtarget.h"
24 #include "llvm/Analysis/DebugInfo.h"
25 #include "llvm/Constants.h"
26 #include "llvm/DerivedTypes.h"
27 #include "llvm/Module.h"
28 #include "llvm/Assembly/Writer.h"
29 #include "llvm/CodeGen/AsmPrinter.h"
30 #include "llvm/CodeGen/MachineFunctionPass.h"
31 #include "llvm/CodeGen/MachineInstr.h"
32 #include "llvm/CodeGen/MachineInstrBuilder.h"
33 #include "llvm/CodeGen/MachineModuleInfoImpls.h"
34 #include "llvm/CodeGen/TargetLoweringObjectFileImpl.h"
35 #include "llvm/MC/MCAsmInfo.h"
36 #include "llvm/MC/MCContext.h"
37 #include "llvm/MC/MCExpr.h"
38 #include "llvm/MC/MCInst.h"
39 #include "llvm/MC/MCSectionMachO.h"
40 #include "llvm/MC/MCStreamer.h"
41 #include "llvm/MC/MCSymbol.h"
42 #include "llvm/Target/Mangler.h"
43 #include "llvm/Target/TargetRegisterInfo.h"
44 #include "llvm/Target/TargetInstrInfo.h"
45 #include "llvm/Target/TargetOptions.h"
46 #include "llvm/Target/TargetRegistry.h"
47 #include "llvm/Support/CommandLine.h"
48 #include "llvm/Support/Debug.h"
49 #include "llvm/Support/MathExtras.h"
50 #include "llvm/Support/ErrorHandling.h"
51 #include "llvm/Support/raw_ostream.h"
52 #include "llvm/ADT/StringExtras.h"
53 #include "llvm/ADT/StringSet.h"
54 #include "llvm/ADT/SmallString.h"
55 #include "InstPrinter/PPCInstPrinter.h"
59 class PPCAsmPrinter
: public AsmPrinter
{
61 DenseMap
<MCSymbol
*, MCSymbol
*> TOC
;
62 const PPCSubtarget
&Subtarget
;
65 explicit PPCAsmPrinter(TargetMachine
&TM
, MCStreamer
&Streamer
)
66 : AsmPrinter(TM
, Streamer
),
67 Subtarget(TM
.getSubtarget
<PPCSubtarget
>()), TOCLabelID(0) {}
69 virtual const char *getPassName() const {
70 return "PowerPC Assembly Printer";
74 virtual void EmitInstruction(const MachineInstr
*MI
);
76 void printOperand(const MachineInstr
*MI
, unsigned OpNo
, raw_ostream
&O
);
78 bool PrintAsmOperand(const MachineInstr
*MI
, unsigned OpNo
,
79 unsigned AsmVariant
, const char *ExtraCode
,
81 bool PrintAsmMemoryOperand(const MachineInstr
*MI
, unsigned OpNo
,
82 unsigned AsmVariant
, const char *ExtraCode
,
85 MachineLocation
getDebugValueLocation(const MachineInstr
*MI
) const {
86 MachineLocation Location
;
87 assert(MI
->getNumOperands() == 4 && "Invalid no. of machine operands!");
88 // Frame address. Currently handles register +- offset only.
89 if (MI
->getOperand(0).isReg() && MI
->getOperand(2).isImm())
90 Location
.set(MI
->getOperand(0).getReg(), MI
->getOperand(2).getImm());
92 DEBUG(dbgs() << "DBG_VALUE instruction ignored! " << *MI
<< "\n");
98 /// PPCLinuxAsmPrinter - PowerPC assembly printer, customized for Linux
99 class PPCLinuxAsmPrinter
: public PPCAsmPrinter
{
101 explicit PPCLinuxAsmPrinter(TargetMachine
&TM
, MCStreamer
&Streamer
)
102 : PPCAsmPrinter(TM
, Streamer
) {}
104 virtual const char *getPassName() const {
105 return "Linux PPC Assembly Printer";
108 bool doFinalization(Module
&M
);
110 virtual void EmitFunctionEntryLabel();
113 /// PPCDarwinAsmPrinter - PowerPC assembly printer, customized for Darwin/Mac
115 class PPCDarwinAsmPrinter
: public PPCAsmPrinter
{
117 explicit PPCDarwinAsmPrinter(TargetMachine
&TM
, MCStreamer
&Streamer
)
118 : PPCAsmPrinter(TM
, Streamer
) {}
120 virtual const char *getPassName() const {
121 return "Darwin PPC Assembly Printer";
124 bool doFinalization(Module
&M
);
125 void EmitStartOfAsmFile(Module
&M
);
127 void EmitFunctionStubs(const MachineModuleInfoMachO::SymbolListTy
&Stubs
);
129 } // end of anonymous namespace
131 /// stripRegisterPrefix - This method strips the character prefix from a
132 /// register name so that only the number is left. Used by for linux asm.
133 static const char *stripRegisterPrefix(const char *RegName
) {
134 switch (RegName
[0]) {
137 case 'v': return RegName
+ 1;
138 case 'c': if (RegName
[1] == 'r') return RegName
+ 2;
144 void PPCAsmPrinter::printOperand(const MachineInstr
*MI
, unsigned OpNo
,
146 const MachineOperand
&MO
= MI
->getOperand(OpNo
);
148 switch (MO
.getType()) {
149 case MachineOperand::MO_Register
: {
150 const char *RegName
= PPCInstPrinter::getRegisterName(MO
.getReg());
151 // Linux assembler (Others?) does not take register mnemonics.
152 // FIXME - What about special registers used in mfspr/mtspr?
153 if (!Subtarget
.isDarwin()) RegName
= stripRegisterPrefix(RegName
);
157 case MachineOperand::MO_Immediate
:
161 case MachineOperand::MO_MachineBasicBlock
:
162 O
<< *MO
.getMBB()->getSymbol();
164 case MachineOperand::MO_JumpTableIndex
:
165 O
<< MAI
->getPrivateGlobalPrefix() << "JTI" << getFunctionNumber()
166 << '_' << MO
.getIndex();
167 // FIXME: PIC relocation model
169 case MachineOperand::MO_ConstantPoolIndex
:
170 O
<< MAI
->getPrivateGlobalPrefix() << "CPI" << getFunctionNumber()
171 << '_' << MO
.getIndex();
173 case MachineOperand::MO_BlockAddress
:
174 O
<< *GetBlockAddressSymbol(MO
.getBlockAddress());
176 case MachineOperand::MO_ExternalSymbol
: {
177 // Computing the address of an external symbol, not calling it.
178 if (TM
.getRelocationModel() == Reloc::Static
) {
179 O
<< *GetExternalSymbolSymbol(MO
.getSymbolName());
184 OutContext
.GetOrCreateSymbol(StringRef(MAI
->getGlobalPrefix())+
185 MO
.getSymbolName()+"$non_lazy_ptr");
186 MachineModuleInfoImpl::StubValueTy
&StubSym
=
187 MMI
->getObjFileInfo
<MachineModuleInfoMachO
>().getGVStubEntry(NLPSym
);
188 if (StubSym
.getPointer() == 0)
189 StubSym
= MachineModuleInfoImpl::
190 StubValueTy(GetExternalSymbolSymbol(MO
.getSymbolName()), true);
195 case MachineOperand::MO_GlobalAddress
: {
196 // Computing the address of a global symbol, not calling it.
197 const GlobalValue
*GV
= MO
.getGlobal();
198 MCSymbol
*SymToPrint
;
200 // External or weakly linked global variables need non-lazily-resolved stubs
201 if (TM
.getRelocationModel() != Reloc::Static
&&
202 (GV
->isDeclaration() || GV
->isWeakForLinker())) {
203 if (!GV
->hasHiddenVisibility()) {
204 SymToPrint
= GetSymbolWithGlobalValueBase(GV
, "$non_lazy_ptr");
205 MachineModuleInfoImpl::StubValueTy
&StubSym
=
206 MMI
->getObjFileInfo
<MachineModuleInfoMachO
>()
207 .getGVStubEntry(SymToPrint
);
208 if (StubSym
.getPointer() == 0)
209 StubSym
= MachineModuleInfoImpl::
210 StubValueTy(Mang
->getSymbol(GV
), !GV
->hasInternalLinkage());
211 } else if (GV
->isDeclaration() || GV
->hasCommonLinkage() ||
212 GV
->hasAvailableExternallyLinkage()) {
213 SymToPrint
= GetSymbolWithGlobalValueBase(GV
, "$non_lazy_ptr");
215 MachineModuleInfoImpl::StubValueTy
&StubSym
=
216 MMI
->getObjFileInfo
<MachineModuleInfoMachO
>().
217 getHiddenGVStubEntry(SymToPrint
);
218 if (StubSym
.getPointer() == 0)
219 StubSym
= MachineModuleInfoImpl::
220 StubValueTy(Mang
->getSymbol(GV
), !GV
->hasInternalLinkage());
222 SymToPrint
= Mang
->getSymbol(GV
);
225 SymToPrint
= Mang
->getSymbol(GV
);
230 printOffset(MO
.getOffset(), O
);
235 O
<< "<unknown operand type: " << MO
.getType() << ">";
240 /// PrintAsmOperand - Print out an operand for an inline asm expression.
242 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: return true; // Unknown modifier.
251 case 'c': // Don't print "$" before a global var name or constant.
252 break; // PPC never has a prefix.
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())
259 ++OpNo
; // Return the high-part.
262 // Write 'i' if an integer constant, otherwise nothing. Used to print
264 if (MI
->getOperand(OpNo
).isImm())
270 printOperand(MI
, OpNo
, O
);
274 // At the moment, all inline asm memory operands are a single register.
275 // In any case, the output of this routine should always be just one
276 // assembler operand.
278 bool PPCAsmPrinter::PrintAsmMemoryOperand(const MachineInstr
*MI
, unsigned OpNo
,
280 const char *ExtraCode
,
282 if (ExtraCode
&& ExtraCode
[0])
283 return true; // Unknown modifier.
284 assert(MI
->getOperand(OpNo
).isReg());
286 printOperand(MI
, OpNo
, O
);
292 /// EmitInstruction -- Print out a single PowerPC MI in Darwin syntax to
293 /// the current output stream.
295 void PPCAsmPrinter::EmitInstruction(const MachineInstr
*MI
) {
298 // Lower multi-instruction pseudo operations.
299 switch (MI
->getOpcode()) {
301 case TargetOpcode::DBG_VALUE
: {
302 if (!isVerbose() || !OutStreamer
.hasRawTextSupport()) return;
305 raw_svector_ostream
O(Str
);
306 unsigned NOps
= MI
->getNumOperands();
308 O
<< '\t' << MAI
->getCommentString() << "DEBUG_VALUE: ";
309 // cast away const; DIetc do not take const operands for some reason.
310 DIVariable
V(const_cast<MDNode
*>(MI
->getOperand(NOps
-1).getMetadata()));
313 // Frame address. Currently handles register +- offset only.
314 assert(MI
->getOperand(0).isReg() && MI
->getOperand(1).isImm());
315 O
<< '['; printOperand(MI
, 0, O
); O
<< '+'; printOperand(MI
, 1, O
);
318 printOperand(MI
, NOps
-2, O
);
319 OutStreamer
.EmitRawText(O
.str());
323 case PPC::MovePCtoLR
:
324 case PPC::MovePCtoLR8
: {
325 // Transform %LR = MovePCtoLR
326 // Into this, where the label is the PIC base:
329 MCSymbol
*PICBase
= MF
->getPICBaseSymbol();
332 TmpInst
.setOpcode(PPC::BL_Darwin
); // Darwin vs SVR4 doesn't matter here.
335 // FIXME: We would like an efficient form for this, so we don't have to do
336 // a lot of extra uniquing.
337 TmpInst
.addOperand(MCOperand::CreateExpr(MCSymbolRefExpr::
338 Create(PICBase
, OutContext
)));
339 OutStreamer
.EmitInstruction(TmpInst
);
342 OutStreamer
.EmitLabel(PICBase
);
346 // Transform %X3 = LDtoc <ga:@min1>, %X2
347 LowerPPCMachineInstrToMCInst(MI
, TmpInst
, *this, Subtarget
.isDarwin());
349 // Change the opcode to LD, and the global address operand to be a
350 // reference to the TOC entry we will synthesize later.
351 TmpInst
.setOpcode(PPC::LD
);
352 const MachineOperand
&MO
= MI
->getOperand(1);
353 assert(MO
.isGlobal());
355 // Map symbol -> label of TOC entry.
356 MCSymbol
*&TOCEntry
= TOC
[Mang
->getSymbol(MO
.getGlobal())];
358 TOCEntry
= GetTempSymbol("C", TOCLabelID
++);
361 MCSymbolRefExpr::Create(TOCEntry
, MCSymbolRefExpr::VK_PPC_TOC
,
363 TmpInst
.getOperand(1) = MCOperand::CreateExpr(Exp
);
364 OutStreamer
.EmitInstruction(TmpInst
);
369 // Transform: %R3 = MFCRpseud %CR7
370 // Into: %R3 = MFCR ;; cr7
371 OutStreamer
.AddComment(PPCInstPrinter::
372 getRegisterName(MI
->getOperand(1).getReg()));
373 TmpInst
.setOpcode(PPC::MFCR
);
374 TmpInst
.addOperand(MCOperand::CreateReg(MI
->getOperand(0).getReg()));
375 OutStreamer
.EmitInstruction(TmpInst
);
379 LowerPPCMachineInstrToMCInst(MI
, TmpInst
, *this, Subtarget
.isDarwin());
380 OutStreamer
.EmitInstruction(TmpInst
);
383 void PPCLinuxAsmPrinter::EmitFunctionEntryLabel() {
384 if (!Subtarget
.isPPC64()) // linux/ppc32 - Normal entry label.
385 return AsmPrinter::EmitFunctionEntryLabel();
387 // Emit an official procedure descriptor.
388 // FIXME 64-bit SVR4: Use MCSection here!
389 OutStreamer
.EmitRawText(StringRef("\t.section\t\".opd\",\"aw\""));
390 OutStreamer
.EmitRawText(StringRef("\t.align 3"));
391 OutStreamer
.EmitLabel(CurrentFnSym
);
392 OutStreamer
.EmitRawText("\t.quad .L." + Twine(CurrentFnSym
->getName()) +
394 OutStreamer
.EmitRawText(StringRef("\t.previous"));
395 OutStreamer
.EmitRawText(".L." + Twine(CurrentFnSym
->getName()) + ":");
399 bool PPCLinuxAsmPrinter::doFinalization(Module
&M
) {
400 const TargetData
*TD
= TM
.getTargetData();
402 bool isPPC64
= TD
->getPointerSizeInBits() == 64;
404 if (isPPC64
&& !TOC
.empty()) {
405 // FIXME 64-bit SVR4: Use MCSection here?
406 OutStreamer
.EmitRawText(StringRef("\t.section\t\".toc\",\"aw\""));
408 // FIXME: This is nondeterminstic!
409 for (DenseMap
<MCSymbol
*, MCSymbol
*>::iterator I
= TOC
.begin(),
410 E
= TOC
.end(); I
!= E
; ++I
) {
411 OutStreamer
.EmitLabel(I
->second
);
412 OutStreamer
.EmitRawText("\t.tc " + Twine(I
->first
->getName()) +
413 "[TC]," + I
->first
->getName());
417 return AsmPrinter::doFinalization(M
);
420 void PPCDarwinAsmPrinter::EmitStartOfAsmFile(Module
&M
) {
421 static const char *const CPUDirectives
[] = {
433 unsigned Directive
= Subtarget
.getDarwinDirective();
434 if (Subtarget
.isGigaProcessor() && Directive
< PPC::DIR_970
)
435 Directive
= PPC::DIR_970
;
436 if (Subtarget
.hasAltivec() && Directive
< PPC::DIR_7400
)
437 Directive
= PPC::DIR_7400
;
438 if (Subtarget
.isPPC64() && Directive
< PPC::DIR_970
)
439 Directive
= PPC::DIR_64
;
440 assert(Directive
<= PPC::DIR_64
&& "Directive out of range.");
442 // FIXME: This is a total hack, finish mc'izing the PPC backend.
443 if (OutStreamer
.hasRawTextSupport())
444 OutStreamer
.EmitRawText("\t.machine " + Twine(CPUDirectives
[Directive
]));
446 // Prime text sections so they are adjacent. This reduces the likelihood a
447 // large data or debug section causes a branch to exceed 16M limit.
448 const TargetLoweringObjectFileMachO
&TLOFMacho
=
449 static_cast<const TargetLoweringObjectFileMachO
&>(getObjFileLowering());
450 OutStreamer
.SwitchSection(TLOFMacho
.getTextCoalSection());
451 if (TM
.getRelocationModel() == Reloc::PIC_
) {
452 OutStreamer
.SwitchSection(
453 OutContext
.getMachOSection("__TEXT", "__picsymbolstub1",
454 MCSectionMachO::S_SYMBOL_STUBS
|
455 MCSectionMachO::S_ATTR_PURE_INSTRUCTIONS
,
456 32, SectionKind::getText()));
457 } else if (TM
.getRelocationModel() == Reloc::DynamicNoPIC
) {
458 OutStreamer
.SwitchSection(
459 OutContext
.getMachOSection("__TEXT","__symbol_stub1",
460 MCSectionMachO::S_SYMBOL_STUBS
|
461 MCSectionMachO::S_ATTR_PURE_INSTRUCTIONS
,
462 16, SectionKind::getText()));
464 OutStreamer
.SwitchSection(getObjFileLowering().getTextSection());
467 static MCSymbol
*GetLazyPtr(MCSymbol
*Sym
, MCContext
&Ctx
) {
468 // Remove $stub suffix, add $lazy_ptr.
469 SmallString
<128> TmpStr(Sym
->getName().begin(), Sym
->getName().end()-5);
470 TmpStr
+= "$lazy_ptr";
471 return Ctx
.GetOrCreateSymbol(TmpStr
.str());
474 static MCSymbol
*GetAnonSym(MCSymbol
*Sym
, MCContext
&Ctx
) {
475 // Add $tmp suffix to $stub, yielding $stub$tmp.
476 SmallString
<128> TmpStr(Sym
->getName().begin(), Sym
->getName().end());
478 return Ctx
.GetOrCreateSymbol(TmpStr
.str());
481 void PPCDarwinAsmPrinter::
482 EmitFunctionStubs(const MachineModuleInfoMachO::SymbolListTy
&Stubs
) {
483 bool isPPC64
= TM
.getTargetData()->getPointerSizeInBits() == 64;
485 const TargetLoweringObjectFileMachO
&TLOFMacho
=
486 static_cast<const TargetLoweringObjectFileMachO
&>(getObjFileLowering());
488 // .lazy_symbol_pointer
489 const MCSection
*LSPSection
= TLOFMacho
.getLazySymbolPointerSection();
491 // Output stubs for dynamically-linked functions
492 if (TM
.getRelocationModel() == Reloc::PIC_
) {
493 const MCSection
*StubSection
=
494 OutContext
.getMachOSection("__TEXT", "__picsymbolstub1",
495 MCSectionMachO::S_SYMBOL_STUBS
|
496 MCSectionMachO::S_ATTR_PURE_INSTRUCTIONS
,
497 32, SectionKind::getText());
498 for (unsigned i
= 0, e
= Stubs
.size(); i
!= e
; ++i
) {
499 OutStreamer
.SwitchSection(StubSection
);
502 MCSymbol
*Stub
= Stubs
[i
].first
;
503 MCSymbol
*RawSym
= Stubs
[i
].second
.getPointer();
504 MCSymbol
*LazyPtr
= GetLazyPtr(Stub
, OutContext
);
505 MCSymbol
*AnonSymbol
= GetAnonSym(Stub
, OutContext
);
507 OutStreamer
.EmitLabel(Stub
);
508 OutStreamer
.EmitSymbolAttribute(RawSym
, MCSA_IndirectSymbol
);
509 // FIXME: MCize this.
510 OutStreamer
.EmitRawText(StringRef("\tmflr r0"));
511 OutStreamer
.EmitRawText("\tbcl 20,31," + Twine(AnonSymbol
->getName()));
512 OutStreamer
.EmitLabel(AnonSymbol
);
513 OutStreamer
.EmitRawText(StringRef("\tmflr r11"));
514 OutStreamer
.EmitRawText("\taddis r11,r11,ha16("+Twine(LazyPtr
->getName())+
515 "-" + AnonSymbol
->getName() + ")");
516 OutStreamer
.EmitRawText(StringRef("\tmtlr r0"));
519 OutStreamer
.EmitRawText("\tldu r12,lo16(" + Twine(LazyPtr
->getName()) +
520 "-" + AnonSymbol
->getName() + ")(r11)");
522 OutStreamer
.EmitRawText("\tlwzu r12,lo16(" + Twine(LazyPtr
->getName()) +
523 "-" + AnonSymbol
->getName() + ")(r11)");
524 OutStreamer
.EmitRawText(StringRef("\tmtctr r12"));
525 OutStreamer
.EmitRawText(StringRef("\tbctr"));
527 OutStreamer
.SwitchSection(LSPSection
);
528 OutStreamer
.EmitLabel(LazyPtr
);
529 OutStreamer
.EmitSymbolAttribute(RawSym
, MCSA_IndirectSymbol
);
532 OutStreamer
.EmitRawText(StringRef("\t.quad dyld_stub_binding_helper"));
534 OutStreamer
.EmitRawText(StringRef("\t.long dyld_stub_binding_helper"));
536 OutStreamer
.AddBlankLine();
540 const MCSection
*StubSection
=
541 OutContext
.getMachOSection("__TEXT","__symbol_stub1",
542 MCSectionMachO::S_SYMBOL_STUBS
|
543 MCSectionMachO::S_ATTR_PURE_INSTRUCTIONS
,
544 16, SectionKind::getText());
545 for (unsigned i
= 0, e
= Stubs
.size(); i
!= e
; ++i
) {
546 MCSymbol
*Stub
= Stubs
[i
].first
;
547 MCSymbol
*RawSym
= Stubs
[i
].second
.getPointer();
548 MCSymbol
*LazyPtr
= GetLazyPtr(Stub
, OutContext
);
550 OutStreamer
.SwitchSection(StubSection
);
552 OutStreamer
.EmitLabel(Stub
);
553 OutStreamer
.EmitSymbolAttribute(RawSym
, MCSA_IndirectSymbol
);
554 OutStreamer
.EmitRawText("\tlis r11,ha16(" + Twine(LazyPtr
->getName()) +")");
556 OutStreamer
.EmitRawText("\tldu r12,lo16(" + Twine(LazyPtr
->getName()) +
559 OutStreamer
.EmitRawText("\tlwzu r12,lo16(" + Twine(LazyPtr
->getName()) +
561 OutStreamer
.EmitRawText(StringRef("\tmtctr r12"));
562 OutStreamer
.EmitRawText(StringRef("\tbctr"));
563 OutStreamer
.SwitchSection(LSPSection
);
564 OutStreamer
.EmitLabel(LazyPtr
);
565 OutStreamer
.EmitSymbolAttribute(RawSym
, MCSA_IndirectSymbol
);
568 OutStreamer
.EmitRawText(StringRef("\t.quad dyld_stub_binding_helper"));
570 OutStreamer
.EmitRawText(StringRef("\t.long dyld_stub_binding_helper"));
573 OutStreamer
.AddBlankLine();
577 bool PPCDarwinAsmPrinter::doFinalization(Module
&M
) {
578 bool isPPC64
= TM
.getTargetData()->getPointerSizeInBits() == 64;
580 // Darwin/PPC always uses mach-o.
581 const TargetLoweringObjectFileMachO
&TLOFMacho
=
582 static_cast<const TargetLoweringObjectFileMachO
&>(getObjFileLowering());
583 MachineModuleInfoMachO
&MMIMacho
=
584 MMI
->getObjFileInfo
<MachineModuleInfoMachO
>();
586 MachineModuleInfoMachO::SymbolListTy Stubs
= MMIMacho
.GetFnStubList();
588 EmitFunctionStubs(Stubs
);
590 if (MAI
->doesSupportExceptionHandling() && MMI
) {
591 // Add the (possibly multiple) personalities to the set of global values.
592 // Only referenced functions get into the Personalities list.
593 const std::vector
<const Function
*> &Personalities
= MMI
->getPersonalities();
594 for (std::vector
<const Function
*>::const_iterator I
= Personalities
.begin(),
595 E
= Personalities
.end(); I
!= E
; ++I
) {
597 MCSymbol
*NLPSym
= GetSymbolWithGlobalValueBase(*I
, "$non_lazy_ptr");
598 MachineModuleInfoImpl::StubValueTy
&StubSym
=
599 MMIMacho
.getGVStubEntry(NLPSym
);
600 StubSym
= MachineModuleInfoImpl::StubValueTy(Mang
->getSymbol(*I
), true);
605 // Output stubs for dynamically-linked functions.
606 Stubs
= MMIMacho
.GetGVStubList();
608 // Output macho stubs for external and common global variables.
609 if (!Stubs
.empty()) {
610 // Switch with ".non_lazy_symbol_pointer" directive.
611 OutStreamer
.SwitchSection(TLOFMacho
.getNonLazySymbolPointerSection());
612 EmitAlignment(isPPC64
? 3 : 2);
614 for (unsigned i
= 0, e
= Stubs
.size(); i
!= e
; ++i
) {
616 OutStreamer
.EmitLabel(Stubs
[i
].first
);
617 // .indirect_symbol _foo
618 MachineModuleInfoImpl::StubValueTy
&MCSym
= Stubs
[i
].second
;
619 OutStreamer
.EmitSymbolAttribute(MCSym
.getPointer(), MCSA_IndirectSymbol
);
622 // External to current translation unit.
623 OutStreamer
.EmitIntValue(0, isPPC64
? 8 : 4/*size*/, 0/*addrspace*/);
625 // Internal to current translation unit.
627 // When we place the LSDA into the TEXT section, the type info pointers
628 // need to be indirect and pc-rel. We accomplish this by using NLPs.
629 // However, sometimes the types are local to the file. So we need to
630 // fill in the value for the NLP in those cases.
631 OutStreamer
.EmitValue(MCSymbolRefExpr::Create(MCSym
.getPointer(),
633 isPPC64
? 8 : 4/*size*/, 0/*addrspace*/);
637 OutStreamer
.AddBlankLine();
640 Stubs
= MMIMacho
.GetHiddenGVStubList();
641 if (!Stubs
.empty()) {
642 OutStreamer
.SwitchSection(getObjFileLowering().getDataSection());
643 EmitAlignment(isPPC64
? 3 : 2);
645 for (unsigned i
= 0, e
= Stubs
.size(); i
!= e
; ++i
) {
647 OutStreamer
.EmitLabel(Stubs
[i
].first
);
649 OutStreamer
.EmitValue(MCSymbolRefExpr::
650 Create(Stubs
[i
].second
.getPointer(),
652 isPPC64
? 8 : 4/*size*/, 0/*addrspace*/);
656 OutStreamer
.AddBlankLine();
659 // Funny Darwin hack: This flag tells the linker that no global symbols
660 // contain code that falls through to other global symbols (e.g. the obvious
661 // implementation of multiple entry points). If this doesn't occur, the
662 // linker can safely perform dead code stripping. Since LLVM never generates
663 // code that does this, it is always safe to set.
664 OutStreamer
.EmitAssemblerFlag(MCAF_SubsectionsViaSymbols
);
666 return AsmPrinter::doFinalization(M
);
669 /// createPPCAsmPrinterPass - Returns a pass that prints the PPC assembly code
670 /// for a MachineFunction to the given output stream, in a format that the
671 /// Darwin assembler can deal with.
673 static AsmPrinter
*createPPCAsmPrinterPass(TargetMachine
&tm
,
674 MCStreamer
&Streamer
) {
675 const PPCSubtarget
*Subtarget
= &tm
.getSubtarget
<PPCSubtarget
>();
677 if (Subtarget
->isDarwin())
678 return new PPCDarwinAsmPrinter(tm
, Streamer
);
679 return new PPCLinuxAsmPrinter(tm
, Streamer
);
682 static MCInstPrinter
*createPPCMCInstPrinter(const Target
&T
,
683 unsigned SyntaxVariant
,
684 const MCAsmInfo
&MAI
) {
685 return new PPCInstPrinter(MAI
, SyntaxVariant
);
689 // Force static initialization.
690 extern "C" void LLVMInitializePowerPCAsmPrinter() {
691 TargetRegistry::RegisterAsmPrinter(ThePPC32Target
, createPPCAsmPrinterPass
);
692 TargetRegistry::RegisterAsmPrinter(ThePPC64Target
, createPPCAsmPrinterPass
);
694 TargetRegistry::RegisterMCInstPrinter(ThePPC32Target
, createPPCMCInstPrinter
);
695 TargetRegistry::RegisterMCInstPrinter(ThePPC64Target
, createPPCMCInstPrinter
);