1 //===-- PPCAsmPrinter.cpp - Print machine instrs to PowerPC assembly --------=//
3 // The LLVM Compiler Infrastructure
5 // This file was developed by the LLVM research group and is distributed under
6 // the University of Illinois Open Source 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 "PPCTargetMachine.h"
22 #include "PPCSubtarget.h"
23 #include "llvm/Constants.h"
24 #include "llvm/DerivedTypes.h"
25 #include "llvm/Module.h"
26 #include "llvm/Assembly/Writer.h"
27 #include "llvm/CodeGen/AsmPrinter.h"
28 #include "llvm/CodeGen/DwarfWriter.h"
29 #include "llvm/CodeGen/MachineDebugInfo.h"
30 #include "llvm/CodeGen/MachineFunctionPass.h"
31 #include "llvm/CodeGen/MachineInstr.h"
32 #include "llvm/Support/Mangler.h"
33 #include "llvm/Support/MathExtras.h"
34 #include "llvm/Support/CommandLine.h"
35 #include "llvm/Support/Debug.h"
36 #include "llvm/Target/MRegisterInfo.h"
37 #include "llvm/Target/TargetInstrInfo.h"
38 #include "llvm/Target/TargetOptions.h"
39 #include "llvm/ADT/Statistic.h"
40 #include "llvm/ADT/StringExtras.h"
46 Statistic
<> EmittedInsts("asm-printer", "Number of machine instrs printed");
48 class PPCAsmPrinter
: public AsmPrinter
{
50 std::set
<std::string
> FnStubs
, GVStubs
;
52 PPCAsmPrinter(std::ostream
&O
, TargetMachine
&TM
)
53 : AsmPrinter(O
, TM
) {}
55 virtual const char *getPassName() const {
56 return "PowerPC Assembly Printer";
59 PPCTargetMachine
&getTM() {
60 return static_cast<PPCTargetMachine
&>(TM
);
63 unsigned enumRegToMachineReg(unsigned enumReg
) {
65 default: assert(0 && "Unhandled register!"); break;
66 case PPC::CR0
: return 0;
67 case PPC::CR1
: return 1;
68 case PPC::CR2
: return 2;
69 case PPC::CR3
: return 3;
70 case PPC::CR4
: return 4;
71 case PPC::CR5
: return 5;
72 case PPC::CR6
: return 6;
73 case PPC::CR7
: return 7;
78 /// printInstruction - This method is automatically generated by tablegen
79 /// from the instruction set description. This method returns true if the
80 /// machine instruction was sufficiently described to print it, otherwise it
82 bool printInstruction(const MachineInstr
*MI
);
84 void printMachineInstruction(const MachineInstr
*MI
);
85 void printOp(const MachineOperand
&MO
);
87 void printOperand(const MachineInstr
*MI
, unsigned OpNo
) {
88 const MachineOperand
&MO
= MI
->getOperand(OpNo
);
89 if (MO
.getType() == MachineOperand::MO_MachineRegister
) {
90 assert(MRegisterInfo::isPhysicalRegister(MO
.getReg())&&"Not physreg??");
91 O
<< TM
.getRegisterInfo()->get(MO
.getReg()).Name
;
92 } else if (MO
.isImmediate()) {
93 O
<< MO
.getImmedValue();
99 bool PrintAsmOperand(const MachineInstr
*MI
, unsigned OpNo
,
100 unsigned AsmVariant
, const char *ExtraCode
);
101 bool PrintAsmMemoryOperand(const MachineInstr
*MI
, unsigned OpNo
,
102 unsigned AsmVariant
, const char *ExtraCode
);
105 void printS5ImmOperand(const MachineInstr
*MI
, unsigned OpNo
) {
106 char value
= MI
->getOperand(OpNo
).getImmedValue();
107 value
= (value
<< (32-5)) >> (32-5);
110 void printU5ImmOperand(const MachineInstr
*MI
, unsigned OpNo
) {
111 unsigned char value
= MI
->getOperand(OpNo
).getImmedValue();
112 assert(value
<= 31 && "Invalid u5imm argument!");
113 O
<< (unsigned int)value
;
115 void printU6ImmOperand(const MachineInstr
*MI
, unsigned OpNo
) {
116 unsigned char value
= MI
->getOperand(OpNo
).getImmedValue();
117 assert(value
<= 63 && "Invalid u6imm argument!");
118 O
<< (unsigned int)value
;
120 void printS16ImmOperand(const MachineInstr
*MI
, unsigned OpNo
) {
121 O
<< (short)MI
->getOperand(OpNo
).getImmedValue();
123 void printU16ImmOperand(const MachineInstr
*MI
, unsigned OpNo
) {
124 O
<< (unsigned short)MI
->getOperand(OpNo
).getImmedValue();
126 void printS16X4ImmOperand(const MachineInstr
*MI
, unsigned OpNo
) {
127 O
<< (short)MI
->getOperand(OpNo
).getImmedValue()*4;
129 void printBranchOperand(const MachineInstr
*MI
, unsigned OpNo
) {
130 // Branches can take an immediate operand. This is used by the branch
131 // selection pass to print $+8, an eight byte displacement from the PC.
132 if (MI
->getOperand(OpNo
).isImmediate()) {
133 O
<< "$+" << MI
->getOperand(OpNo
).getImmedValue();
135 printOp(MI
->getOperand(OpNo
));
138 void printCallOperand(const MachineInstr
*MI
, unsigned OpNo
) {
139 const MachineOperand
&MO
= MI
->getOperand(OpNo
);
140 if (TM
.getRelocationModel() != Reloc::Static
) {
141 if (MO
.getType() == MachineOperand::MO_GlobalAddress
) {
142 GlobalValue
*GV
= MO
.getGlobal();
143 if (((GV
->isExternal() || GV
->hasWeakLinkage() ||
144 GV
->hasLinkOnceLinkage()))) {
145 // Dynamically-resolved functions need a stub for the function.
146 std::string Name
= Mang
->getValueName(GV
);
147 FnStubs
.insert(Name
);
148 O
<< "L" << Name
<< "$stub";
152 if (MO
.getType() == MachineOperand::MO_ExternalSymbol
) {
153 std::string
Name(GlobalPrefix
); Name
+= MO
.getSymbolName();
154 FnStubs
.insert(Name
);
155 O
<< "L" << Name
<< "$stub";
160 printOp(MI
->getOperand(OpNo
));
162 void printAbsAddrOperand(const MachineInstr
*MI
, unsigned OpNo
) {
163 O
<< (int)MI
->getOperand(OpNo
).getImmedValue()*4;
165 void printPICLabel(const MachineInstr
*MI
, unsigned OpNo
) {
166 O
<< "\"L" << getFunctionNumber() << "$pb\"\n";
167 O
<< "\"L" << getFunctionNumber() << "$pb\":";
169 void printSymbolHi(const MachineInstr
*MI
, unsigned OpNo
) {
170 if (MI
->getOperand(OpNo
).isImmediate()) {
171 printS16ImmOperand(MI
, OpNo
);
174 printOp(MI
->getOperand(OpNo
));
175 if (TM
.getRelocationModel() == Reloc::PIC
)
176 O
<< "-\"L" << getFunctionNumber() << "$pb\")";
181 void printSymbolLo(const MachineInstr
*MI
, unsigned OpNo
) {
182 if (MI
->getOperand(OpNo
).isImmediate()) {
183 printS16ImmOperand(MI
, OpNo
);
186 printOp(MI
->getOperand(OpNo
));
187 if (TM
.getRelocationModel() == Reloc::PIC
)
188 O
<< "-\"L" << getFunctionNumber() << "$pb\")";
193 void printcrbitm(const MachineInstr
*MI
, unsigned OpNo
) {
194 unsigned CCReg
= MI
->getOperand(OpNo
).getReg();
195 unsigned RegNo
= enumRegToMachineReg(CCReg
);
196 O
<< (0x80 >> RegNo
);
198 // The new addressing mode printers.
199 void printMemRegImm(const MachineInstr
*MI
, unsigned OpNo
) {
200 printSymbolLo(MI
, OpNo
);
202 if (MI
->getOperand(OpNo
+1).isRegister() &&
203 MI
->getOperand(OpNo
+1).getReg() == PPC::R0
)
206 printOperand(MI
, OpNo
+1);
209 void printMemRegImmShifted(const MachineInstr
*MI
, unsigned OpNo
) {
210 if (MI
->getOperand(OpNo
).isImmediate())
211 printS16X4ImmOperand(MI
, OpNo
);
213 printSymbolLo(MI
, OpNo
);
215 if (MI
->getOperand(OpNo
+1).isRegister() &&
216 MI
->getOperand(OpNo
+1).getReg() == PPC::R0
)
219 printOperand(MI
, OpNo
+1);
223 void printMemRegReg(const MachineInstr
*MI
, unsigned OpNo
) {
224 // When used as the base register, r0 reads constant zero rather than
225 // the value contained in the register. For this reason, the darwin
226 // assembler requires that we print r0 as 0 (no r) when used as the base.
227 const MachineOperand
&MO
= MI
->getOperand(OpNo
);
228 if (MO
.getReg() == PPC::R0
)
231 O
<< TM
.getRegisterInfo()->get(MO
.getReg()).Name
;
233 printOperand(MI
, OpNo
+1);
236 virtual bool runOnMachineFunction(MachineFunction
&F
) = 0;
237 virtual bool doFinalization(Module
&M
) = 0;
241 /// DarwinDwarfWriter - Dwarf debug info writer customized for Darwin/Mac OS X
243 struct DarwinDwarfWriter
: public DwarfWriter
{
245 DarwinDwarfWriter(std::ostream
&o
, AsmPrinter
*ap
)
249 DwarfAbbrevSection
= ".section __DWARFA,__debug_abbrev";
250 DwarfInfoSection
= ".section __DWARFA,__debug_info";
251 DwarfLineSection
= ".section __DWARFA,__debug_line";
252 DwarfFrameSection
= ".section __DWARFA,__debug_frame";
253 DwarfPubNamesSection
= ".section __DWARFA,__debug_pubnames";
254 DwarfPubTypesSection
= ".section __DWARFA,__debug_pubtypes";
255 DwarfStrSection
= ".section __DWARFA,__debug_str";
256 DwarfLocSection
= ".section __DWARFA,__debug_loc";
257 DwarfARangesSection
= ".section __DWARFA,__debug_aranges";
258 DwarfRangesSection
= ".section __DWARFA,__debug_ranges";
259 DwarfMacInfoSection
= ".section __DWARFA,__debug_macinfo";
260 TextSection
= ".text";
261 DataSection
= ".data";
265 /// DarwinAsmPrinter - PowerPC assembly printer, customized for Darwin/Mac OS
267 struct DarwinAsmPrinter
: public PPCAsmPrinter
{
269 DarwinDwarfWriter DW
;
271 DarwinAsmPrinter(std::ostream
&O
, TargetMachine
&TM
)
272 : PPCAsmPrinter(O
, TM
), DW(O
, this) {
275 PrivateGlobalPrefix
= "L"; // Marker for constant pool idxs
276 ZeroDirective
= "\t.space\t"; // ".space N" emits N zeros.
277 Data64bitsDirective
= 0; // we can't emit a 64-bit unit
278 AlignmentIsInBytes
= false; // Alignment is by power of 2.
279 ConstantPoolSection
= "\t.const\t";
280 LCOMMDirective
= "\t.lcomm\t";
281 StaticCtorsSection
= ".mod_init_func";
282 StaticDtorsSection
= ".mod_term_func";
283 InlineAsmStart
= InlineAsmEnd
= ""; // Don't use #APP/#NO_APP
286 virtual const char *getPassName() const {
287 return "Darwin PPC Assembly Printer";
290 bool runOnMachineFunction(MachineFunction
&F
);
291 bool doInitialization(Module
&M
);
292 bool doFinalization(Module
&M
);
294 void getAnalysisUsage(AnalysisUsage
&AU
) const {
295 AU
.setPreservesAll();
296 AU
.addRequired
<MachineDebugInfo
>();
297 PPCAsmPrinter::getAnalysisUsage(AU
);
302 /// AIXAsmPrinter - PowerPC assembly printer, customized for AIX
304 struct AIXAsmPrinter
: public PPCAsmPrinter
{
305 /// Map for labels corresponding to global variables
307 std::map
<const GlobalVariable
*,std::string
> GVToLabelMap
;
309 AIXAsmPrinter(std::ostream
&O
, TargetMachine
&TM
)
310 : PPCAsmPrinter(O
, TM
) {
313 ZeroDirective
= "\t.space\t"; // ".space N" emits N zeros.
314 Data64bitsDirective
= 0; // we can't emit a 64-bit unit
315 AlignmentIsInBytes
= false; // Alignment is by power of 2.
316 ConstantPoolSection
= "\t.const\t";
319 virtual const char *getPassName() const {
320 return "AIX PPC Assembly Printer";
323 bool runOnMachineFunction(MachineFunction
&F
);
324 bool doInitialization(Module
&M
);
325 bool doFinalization(Module
&M
);
327 } // end of anonymous namespace
329 /// createDarwinAsmPrinterPass - Returns a pass that prints the PPC assembly
330 /// code for a MachineFunction to the given output stream, in a format that the
331 /// Darwin assembler can deal with.
333 FunctionPass
*llvm::createDarwinAsmPrinter(std::ostream
&o
,
334 PPCTargetMachine
&tm
) {
335 return new DarwinAsmPrinter(o
, tm
);
338 /// createAIXAsmPrinterPass - Returns a pass that prints the PPC assembly code
339 /// for a MachineFunction to the given output stream, in a format that the
340 /// AIX 5L assembler can deal with.
342 FunctionPass
*llvm::createAIXAsmPrinter(std::ostream
&o
, PPCTargetMachine
&tm
) {
343 return new AIXAsmPrinter(o
, tm
);
346 // Include the auto-generated portion of the assembly writer
347 #include "PPCGenAsmWriter.inc"
349 void PPCAsmPrinter::printOp(const MachineOperand
&MO
) {
350 const MRegisterInfo
&RI
= *TM
.getRegisterInfo();
353 switch (MO
.getType()) {
354 case MachineOperand::MO_VirtualRegister
:
355 if (Value
*V
= MO
.getVRegValueOrNull()) {
356 O
<< "<" << V
->getName() << ">";
360 case MachineOperand::MO_MachineRegister
:
361 case MachineOperand::MO_CCRegister
:
362 O
<< RI
.get(MO
.getReg()).Name
;
365 case MachineOperand::MO_SignExtendedImmed
:
366 case MachineOperand::MO_UnextendedImmed
:
367 std::cerr
<< "printOp() does not handle immediate values\n";
371 case MachineOperand::MO_PCRelativeDisp
:
372 std::cerr
<< "Shouldn't use addPCDisp() when building PPC MachineInstrs";
376 case MachineOperand::MO_MachineBasicBlock
: {
377 MachineBasicBlock
*MBBOp
= MO
.getMachineBasicBlock();
378 O
<< PrivateGlobalPrefix
<< "BB" << getFunctionNumber() << "_"
379 << MBBOp
->getNumber() << "\t; " << MBBOp
->getBasicBlock()->getName();
383 case MachineOperand::MO_ConstantPoolIndex
:
384 O
<< PrivateGlobalPrefix
<< "CPI" << getFunctionNumber()
385 << '_' << MO
.getConstantPoolIndex();
387 case MachineOperand::MO_ExternalSymbol
:
388 // Computing the address of an external symbol, not calling it.
389 if (TM
.getRelocationModel() != Reloc::Static
) {
390 std::string
Name(GlobalPrefix
); Name
+= MO
.getSymbolName();
391 GVStubs
.insert(Name
);
392 O
<< "L" << Name
<< "$non_lazy_ptr";
395 O
<< GlobalPrefix
<< MO
.getSymbolName();
397 case MachineOperand::MO_GlobalAddress
: {
398 // Computing the address of a global symbol, not calling it.
399 GlobalValue
*GV
= MO
.getGlobal();
400 std::string Name
= Mang
->getValueName(GV
);
401 int offset
= MO
.getOffset();
403 // External or weakly linked global variables need non-lazily-resolved stubs
404 if (TM
.getRelocationModel() != Reloc::Static
) {
405 if (((GV
->isExternal() || GV
->hasWeakLinkage() ||
406 GV
->hasLinkOnceLinkage()))) {
407 GVStubs
.insert(Name
);
408 O
<< "L" << Name
<< "$non_lazy_ptr";
418 O
<< "<unknown operand type: " << MO
.getType() << ">";
423 /// PrintAsmOperand - Print out an operand for an inline asm expression.
425 bool PPCAsmPrinter::PrintAsmOperand(const MachineInstr
*MI
, unsigned OpNo
,
427 const char *ExtraCode
) {
428 // Does this asm operand have a single letter operand modifier?
429 if (ExtraCode
&& ExtraCode
[0]) {
430 if (ExtraCode
[1] != 0) return true; // Unknown modifier.
432 switch (ExtraCode
[0]) {
433 default: return true; // Unknown modifier.
434 case 'L': // Write second word of DImode reference.
435 // Verify that this operand has two consecutive registers.
436 if (!MI
->getOperand(OpNo
).isRegister() ||
437 OpNo
+1 == MI
->getNumOperands() ||
438 !MI
->getOperand(OpNo
+1).isRegister())
440 ++OpNo
; // Return the high-part.
445 printOperand(MI
, OpNo
);
449 bool PPCAsmPrinter::PrintAsmMemoryOperand(const MachineInstr
*MI
, unsigned OpNo
,
451 const char *ExtraCode
) {
452 if (ExtraCode
&& ExtraCode
[0])
453 return true; // Unknown modifier.
454 printMemRegReg(MI
, OpNo
);
458 /// printMachineInstruction -- Print out a single PowerPC MI in Darwin syntax to
459 /// the current output stream.
461 void PPCAsmPrinter::printMachineInstruction(const MachineInstr
*MI
) {
464 // Check for slwi/srwi mnemonics.
465 if (MI
->getOpcode() == PPC::RLWINM
) {
466 bool FoundMnemonic
= false;
467 unsigned char SH
= MI
->getOperand(2).getImmedValue();
468 unsigned char MB
= MI
->getOperand(3).getImmedValue();
469 unsigned char ME
= MI
->getOperand(4).getImmedValue();
470 if (SH
<= 31 && MB
== 0 && ME
== (31-SH
)) {
471 O
<< "slwi "; FoundMnemonic
= true;
473 if (SH
<= 31 && MB
== (32-SH
) && ME
== 31) {
474 O
<< "srwi "; FoundMnemonic
= true;
481 O
<< ", " << (unsigned int)SH
<< "\n";
484 } else if (MI
->getOpcode() == PPC::OR4
|| MI
->getOpcode() == PPC::OR8
) {
485 if (MI
->getOperand(1).getReg() == MI
->getOperand(2).getReg()) {
495 if (printInstruction(MI
))
496 return; // Printer was automatically generated
498 assert(0 && "Unhandled instruction in asm writer!");
504 /// runOnMachineFunction - This uses the printMachineInstruction()
505 /// method to print assembly for each instruction.
507 bool DarwinAsmPrinter::runOnMachineFunction(MachineFunction
&MF
) {
508 // FIXME - is this the earliest this can be set?
509 DW
.SetDebugInfo(&getAnalysis
<MachineDebugInfo
>());
511 SetupMachineFunction(MF
);
514 // Print out constants referenced by the function
515 EmitConstantPool(MF
.getConstantPool());
517 // Print out labels for the function.
518 const Function
*F
= MF
.getFunction();
519 switch (F
->getLinkage()) {
520 default: assert(0 && "Unknown linkage type!");
521 case Function::InternalLinkage
: // Symbols default to internal.
522 SwitchSection(".text", F
);
524 case Function::ExternalLinkage
:
525 SwitchSection(".text", F
);
526 O
<< "\t.globl\t" << CurrentFnName
<< "\n";
528 case Function::WeakLinkage
:
529 case Function::LinkOnceLinkage
:
530 SwitchSection(".section __TEXT,__textcoal_nt,coalesced,pure_instructions",
532 O
<< "\t.globl\t" << CurrentFnName
<< "\n";
533 O
<< "\t.weak_definition\t" << CurrentFnName
<< "\n";
537 O
<< CurrentFnName
<< ":\n";
539 // Emit pre-function debug information.
540 DW
.BeginFunction(&MF
);
542 // Print out code for the function.
543 for (MachineFunction::const_iterator I
= MF
.begin(), E
= MF
.end();
545 // Print a label for the basic block.
546 if (I
!= MF
.begin()) {
547 O
<< PrivateGlobalPrefix
<< "BB" << getFunctionNumber() << '_'
548 << I
->getNumber() << ":\t";
549 if (!I
->getBasicBlock()->getName().empty())
550 O
<< CommentString
<< " " << I
->getBasicBlock()->getName();
553 for (MachineBasicBlock::const_iterator II
= I
->begin(), E
= I
->end();
555 // Print the assembly for the instruction.
557 printMachineInstruction(II
);
561 // Emit post-function debug information.
564 // We didn't modify anything.
569 bool DarwinAsmPrinter::doInitialization(Module
&M
) {
570 if (TM
.getSubtarget
<PPCSubtarget
>().isGigaProcessor())
571 O
<< "\t.machine ppc970\n";
572 AsmPrinter::doInitialization(M
);
574 // Darwin wants symbols to be quoted if they have complex names.
575 Mang
->setUseQuotes(true);
577 // Emit initial debug information.
582 bool DarwinAsmPrinter::doFinalization(Module
&M
) {
583 const TargetData
&TD
= TM
.getTargetData();
585 // Print out module-level global variables here.
586 for (Module::const_global_iterator I
= M
.global_begin(), E
= M
.global_end();
588 if (!I
->hasInitializer()) continue; // External global require no code
590 // Check to see if this is a special global used by LLVM, if so, emit it.
591 if (EmitSpecialLLVMGlobal(I
))
594 std::string name
= Mang
->getValueName(I
);
595 Constant
*C
= I
->getInitializer();
596 unsigned Size
= TD
.getTypeSize(C
->getType());
597 unsigned Align
= getPreferredAlignmentLog(I
);
599 if (C
->isNullValue() && /* FIXME: Verify correct */
600 (I
->hasInternalLinkage() || I
->hasWeakLinkage() ||
601 I
->hasLinkOnceLinkage() ||
602 (I
->hasExternalLinkage() && !I
->hasSection()))) {
603 if (Size
== 0) Size
= 1; // .comm Foo, 0 is undefined, avoid it.
604 if (I
->hasExternalLinkage()) {
605 O
<< "\t.globl " << name
<< '\n';
606 O
<< "\t.zerofill __DATA, __common, " << name
<< ", "
607 << Size
<< ", " << Align
;
608 } else if (I
->hasInternalLinkage()) {
609 SwitchSection(".data", I
);
610 O
<< LCOMMDirective
<< name
<< "," << Size
<< "," << Align
;
612 SwitchSection(".data", I
);
613 O
<< ".comm " << name
<< "," << Size
;
615 O
<< "\t\t; '" << I
->getName() << "'\n";
617 switch (I
->getLinkage()) {
618 case GlobalValue::LinkOnceLinkage
:
619 case GlobalValue::WeakLinkage
:
620 O
<< "\t.globl " << name
<< '\n'
621 << "\t.weak_definition " << name
<< '\n';
622 SwitchSection(".section __DATA,__datacoal_nt,coalesced", I
);
624 case GlobalValue::AppendingLinkage
:
625 // FIXME: appending linkage variables should go into a section of
626 // their name or something. For now, just emit them as external.
627 case GlobalValue::ExternalLinkage
:
628 // If external or appending, declare as a global symbol
629 O
<< "\t.globl " << name
<< "\n";
631 case GlobalValue::InternalLinkage
:
632 SwitchSection(".data", I
);
635 std::cerr
<< "Unknown linkage type!";
639 EmitAlignment(Align
, I
);
640 O
<< name
<< ":\t\t\t\t; '" << I
->getName() << "'\n";
641 EmitGlobalConstant(C
);
646 // Output stubs for dynamically-linked functions
647 if (TM
.getRelocationModel() == Reloc::PIC
) {
648 for (std::set
<std::string
>::iterator i
= FnStubs
.begin(), e
= FnStubs
.end();
650 SwitchSection(".section __TEXT,__picsymbolstub1,symbol_stubs,"
651 "pure_instructions,32", 0);
653 O
<< "L" << *i
<< "$stub:\n";
654 O
<< "\t.indirect_symbol " << *i
<< "\n";
656 O
<< "\tbcl 20,31,L0$" << *i
<< "\n";
657 O
<< "L0$" << *i
<< ":\n";
659 O
<< "\taddis r11,r11,ha16(L" << *i
<< "$lazy_ptr-L0$" << *i
<< ")\n";
661 O
<< "\tlwzu r12,lo16(L" << *i
<< "$lazy_ptr-L0$" << *i
<< ")(r11)\n";
662 O
<< "\tmtctr r12\n";
664 SwitchSection(".lazy_symbol_pointer", 0);
665 O
<< "L" << *i
<< "$lazy_ptr:\n";
666 O
<< "\t.indirect_symbol " << *i
<< "\n";
667 O
<< "\t.long dyld_stub_binding_helper\n";
670 for (std::set
<std::string
>::iterator i
= FnStubs
.begin(), e
= FnStubs
.end();
672 SwitchSection(".section __TEXT,__symbol_stub1,symbol_stubs,"
673 "pure_instructions,16", 0);
675 O
<< "L" << *i
<< "$stub:\n";
676 O
<< "\t.indirect_symbol " << *i
<< "\n";
677 O
<< "\tlis r11,ha16(L" << *i
<< "$lazy_ptr)\n";
678 O
<< "\tlwzu r12,lo16(L" << *i
<< "$lazy_ptr)(r11)\n";
679 O
<< "\tmtctr r12\n";
681 SwitchSection(".lazy_symbol_pointer", 0);
682 O
<< "L" << *i
<< "$lazy_ptr:\n";
683 O
<< "\t.indirect_symbol " << *i
<< "\n";
684 O
<< "\t.long dyld_stub_binding_helper\n";
690 // Output stubs for external and common global variables.
691 if (GVStubs
.begin() != GVStubs
.end()) {
692 SwitchSection(".non_lazy_symbol_pointer", 0);
693 for (std::set
<std::string
>::iterator I
= GVStubs
.begin(),
694 E
= GVStubs
.end(); I
!= E
; ++I
) {
695 O
<< "L" << *I
<< "$non_lazy_ptr:\n";
696 O
<< "\t.indirect_symbol " << *I
<< "\n";
701 // Emit initial debug information.
704 // Funny Darwin hack: This flag tells the linker that no global symbols
705 // contain code that falls through to other global symbols (e.g. the obvious
706 // implementation of multiple entry points). If this doesn't occur, the
707 // linker can safely perform dead code stripping. Since LLVM never generates
708 // code that does this, it is always safe to set.
709 O
<< "\t.subsections_via_symbols\n";
711 AsmPrinter::doFinalization(M
);
712 return false; // success
715 /// runOnMachineFunction - This uses the e()
716 /// method to print assembly for each instruction.
718 bool AIXAsmPrinter::runOnMachineFunction(MachineFunction
&MF
) {
719 SetupMachineFunction(MF
);
721 // Print out constants referenced by the function
722 EmitConstantPool(MF
.getConstantPool());
724 // Print out header for the function.
725 O
<< "\t.csect .text[PR]\n"
727 << "\t.globl " << CurrentFnName
<< '\n'
728 << "\t.globl ." << CurrentFnName
<< '\n'
729 << "\t.csect " << CurrentFnName
<< "[DS],3\n"
730 << CurrentFnName
<< ":\n"
731 << "\t.llong ." << CurrentFnName
<< ", TOC[tc0], 0\n"
732 << "\t.csect .text[PR]\n"
733 << '.' << CurrentFnName
<< ":\n";
735 // Print out code for the function.
736 for (MachineFunction::const_iterator I
= MF
.begin(), E
= MF
.end();
738 // Print a label for the basic block.
739 O
<< PrivateGlobalPrefix
<< "BB" << getFunctionNumber() << '_'
741 << ":\t" << CommentString
<< I
->getBasicBlock()->getName() << '\n';
742 for (MachineBasicBlock::const_iterator II
= I
->begin(), E
= I
->end();
744 // Print the assembly for the instruction.
746 printMachineInstruction(II
);
750 O
<< "LT.." << CurrentFnName
<< ":\n"
752 << "\t.byte 0,0,32,65,128,0,0,0\n"
753 << "\t.long LT.." << CurrentFnName
<< "-." << CurrentFnName
<< '\n'
755 << "\t.byte \"" << CurrentFnName
<< "\"\n"
758 // We didn't modify anything.
762 bool AIXAsmPrinter::doInitialization(Module
&M
) {
763 SwitchSection("", 0);
764 const TargetData
&TD
= TM
.getTargetData();
766 O
<< "\t.machine \"ppc64\"\n"
768 << "\t.csect .text[PR]\n";
770 // Print out module-level global variables
771 for (Module::const_global_iterator I
= M
.global_begin(), E
= M
.global_end();
773 if (!I
->hasInitializer())
776 std::string Name
= I
->getName();
777 Constant
*C
= I
->getInitializer();
778 // N.B.: We are defaulting to writable strings
779 if (I
->hasExternalLinkage()) {
780 O
<< "\t.globl " << Name
<< '\n'
781 << "\t.csect .data[RW],3\n";
783 O
<< "\t.csect _global.rw_c[RW],3\n";
786 EmitGlobalConstant(C
);
789 // Output labels for globals
790 if (M
.global_begin() != M
.global_end()) O
<< "\t.toc\n";
791 for (Module::const_global_iterator I
= M
.global_begin(), E
= M
.global_end();
793 const GlobalVariable
*GV
= I
;
794 // Do not output labels for unused variables
795 if (GV
->isExternal() && GV
->use_begin() == GV
->use_end())
798 IncrementFunctionNumber();
799 std::string Name
= GV
->getName();
800 std::string Label
= "LC.." + utostr(getFunctionNumber());
801 GVToLabelMap
[GV
] = Label
;
803 << "\t.tc " << Name
<< "[TC]," << Name
;
804 if (GV
->isExternal()) O
<< "[RW]";
808 AsmPrinter::doInitialization(M
);
809 return false; // success
812 bool AIXAsmPrinter::doFinalization(Module
&M
) {
813 const TargetData
&TD
= TM
.getTargetData();
814 // Print out module-level global variables
815 for (Module::const_global_iterator I
= M
.global_begin(), E
= M
.global_end();
817 if (I
->hasInitializer() || I
->hasExternalLinkage())
820 std::string Name
= I
->getName();
821 if (I
->hasInternalLinkage()) {
822 O
<< "\t.lcomm " << Name
<< ",16,_global.bss_c";
824 O
<< "\t.comm " << Name
<< "," << TD
.getTypeSize(I
->getType())
825 << "," << Log2_32((unsigned)TD
.getTypeAlignment(I
->getType()));
827 O
<< "\t\t" << CommentString
<< " ";
828 WriteAsOperand(O
, I
, false, true, &M
);
832 O
<< "_section_.text:\n"
833 << "\t.csect .data[RW],3\n"
834 << "\t.llong _section_.text\n";
835 AsmPrinter::doFinalization(M
);
836 return false; // success