1 //===-- ARMAsmPrinter.cpp - ARM LLVM assembly writer ----------------------===//
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 GAS-format ARM assembly language.
13 //===----------------------------------------------------------------------===//
15 #define DEBUG_TYPE "asm-printer"
17 #include "ARMBuildAttrs.h"
18 #include "ARMTargetMachine.h"
19 #include "ARMAddressingModes.h"
20 #include "ARMConstantPoolValue.h"
21 #include "ARMMachineFunctionInfo.h"
22 #include "llvm/Constants.h"
23 #include "llvm/Module.h"
24 #include "llvm/Metadata.h"
25 #include "llvm/CodeGen/AsmPrinter.h"
26 #include "llvm/CodeGen/DwarfWriter.h"
27 #include "llvm/CodeGen/MachineModuleInfo.h"
28 #include "llvm/CodeGen/MachineFunctionPass.h"
29 #include "llvm/CodeGen/MachineJumpTableInfo.h"
30 #include "llvm/MC/MCSection.h"
31 #include "llvm/Target/TargetAsmInfo.h"
32 #include "llvm/Target/TargetData.h"
33 #include "llvm/Target/TargetLoweringObjectFile.h"
34 #include "llvm/Target/TargetMachine.h"
35 #include "llvm/Target/TargetOptions.h"
36 #include "llvm/Target/TargetRegistry.h"
37 #include "llvm/ADT/SmallPtrSet.h"
38 #include "llvm/ADT/Statistic.h"
39 #include "llvm/ADT/StringSet.h"
40 #include "llvm/Support/Compiler.h"
41 #include "llvm/Support/ErrorHandling.h"
42 #include "llvm/Support/Mangler.h"
43 #include "llvm/Support/MathExtras.h"
44 #include "llvm/Support/FormattedStream.h"
48 STATISTIC(EmittedInsts
, "Number of machine instrs printed");
51 class VISIBILITY_HIDDEN ARMAsmPrinter
: public AsmPrinter
{
54 /// Subtarget - Keep a pointer to the ARMSubtarget around so that we can
55 /// make the right decision when printing asm code for different targets.
56 const ARMSubtarget
*Subtarget
;
58 /// AFI - Keep a pointer to ARMFunctionInfo for the current
62 /// MCP - Keep a pointer to constantpool entries of the current
64 const MachineConstantPool
*MCP
;
66 /// We name each basic block in a Function with a unique number, so
67 /// that we can consistently refer to them later. This is cleared
68 /// at the beginning of each call to runOnMachineFunction().
70 typedef std::map
<const Value
*, unsigned> ValueMapTy
;
71 ValueMapTy NumberForBB
;
73 /// GVNonLazyPtrs - Keeps the set of GlobalValues that require
74 /// non-lazy-pointers for indirect access.
75 StringMap
<std::string
> GVNonLazyPtrs
;
77 /// HiddenGVNonLazyPtrs - Keeps the set of GlobalValues with hidden
78 /// visibility that require non-lazy-pointers for indirect access.
79 StringMap
<std::string
> HiddenGVNonLazyPtrs
;
82 std::string Stub
, LazyPtr
, SLP
, SCV
;
86 void Init(const GlobalValue
*GV
, Mangler
*Mang
) {
87 // Already initialized.
88 if (!Stub
.empty()) return;
89 Stub
= Mang
->getMangledName(GV
, "$stub", true);
90 LazyPtr
= Mang
->getMangledName(GV
, "$lazy_ptr", true);
91 SLP
= Mang
->getMangledName(GV
, "$slp", true);
92 SCV
= Mang
->getMangledName(GV
, "$scv", true);
95 void Init(const std::string
&GV
, Mangler
*Mang
) {
96 // Already initialized.
97 if (!Stub
.empty()) return;
98 Stub
= Mang
->makeNameProper(GV
+ "$stub", Mangler::Private
);
99 LazyPtr
= Mang
->makeNameProper(GV
+ "$lazy_ptr", Mangler::Private
);
100 SLP
= Mang
->makeNameProper(GV
+ "$slp", Mangler::Private
);
101 SCV
= Mang
->makeNameProper(GV
+ "$scv", Mangler::Private
);
105 /// FnStubs - Keeps the set of external function GlobalAddresses that the
106 /// asm printer should generate stubs for.
107 StringMap
<FnStubInfo
> FnStubs
;
109 /// True if asm printer is printing a series of CONSTPOOL_ENTRY.
112 explicit ARMAsmPrinter(formatted_raw_ostream
&O
, TargetMachine
&TM
,
113 const TargetAsmInfo
*T
, bool V
)
114 : AsmPrinter(O
, TM
, T
, V
), DW(0), AFI(NULL
), MCP(NULL
),
116 Subtarget
= &TM
.getSubtarget
<ARMSubtarget
>();
119 virtual const char *getPassName() const {
120 return "ARM Assembly Printer";
123 void printOperand(const MachineInstr
*MI
, int OpNum
,
124 const char *Modifier
= 0);
125 void printSOImmOperand(const MachineInstr
*MI
, int OpNum
);
126 void printSOImm2PartOperand(const MachineInstr
*MI
, int OpNum
);
127 void printSORegOperand(const MachineInstr
*MI
, int OpNum
);
128 void printAddrMode2Operand(const MachineInstr
*MI
, int OpNum
);
129 void printAddrMode2OffsetOperand(const MachineInstr
*MI
, int OpNum
);
130 void printAddrMode3Operand(const MachineInstr
*MI
, int OpNum
);
131 void printAddrMode3OffsetOperand(const MachineInstr
*MI
, int OpNum
);
132 void printAddrMode4Operand(const MachineInstr
*MI
, int OpNum
,
133 const char *Modifier
= 0);
134 void printAddrMode5Operand(const MachineInstr
*MI
, int OpNum
,
135 const char *Modifier
= 0);
136 void printAddrMode6Operand(const MachineInstr
*MI
, int OpNum
);
137 void printAddrModePCOperand(const MachineInstr
*MI
, int OpNum
,
138 const char *Modifier
= 0);
139 void printBitfieldInvMaskImmOperand (const MachineInstr
*MI
, int OpNum
);
141 void printThumbITMask(const MachineInstr
*MI
, int OpNum
);
142 void printThumbAddrModeRROperand(const MachineInstr
*MI
, int OpNum
);
143 void printThumbAddrModeRI5Operand(const MachineInstr
*MI
, int OpNum
,
145 void printThumbAddrModeS1Operand(const MachineInstr
*MI
, int OpNum
);
146 void printThumbAddrModeS2Operand(const MachineInstr
*MI
, int OpNum
);
147 void printThumbAddrModeS4Operand(const MachineInstr
*MI
, int OpNum
);
148 void printThumbAddrModeSPOperand(const MachineInstr
*MI
, int OpNum
);
150 void printT2SOOperand(const MachineInstr
*MI
, int OpNum
);
151 void printT2AddrModeImm12Operand(const MachineInstr
*MI
, int OpNum
);
152 void printT2AddrModeImm8Operand(const MachineInstr
*MI
, int OpNum
);
153 void printT2AddrModeImm8s4Operand(const MachineInstr
*MI
, int OpNum
);
154 void printT2AddrModeImm8OffsetOperand(const MachineInstr
*MI
, int OpNum
);
155 void printT2AddrModeSoRegOperand(const MachineInstr
*MI
, int OpNum
);
157 void printPredicateOperand(const MachineInstr
*MI
, int OpNum
);
158 void printSBitModifierOperand(const MachineInstr
*MI
, int OpNum
);
159 void printPCLabel(const MachineInstr
*MI
, int OpNum
);
160 void printRegisterList(const MachineInstr
*MI
, int OpNum
);
161 void printCPInstOperand(const MachineInstr
*MI
, int OpNum
,
162 const char *Modifier
);
163 void printJTBlockOperand(const MachineInstr
*MI
, int OpNum
);
164 void printJT2BlockOperand(const MachineInstr
*MI
, int OpNum
);
165 void printTBAddrMode(const MachineInstr
*MI
, int OpNum
);
167 virtual bool PrintAsmOperand(const MachineInstr
*MI
, unsigned OpNum
,
168 unsigned AsmVariant
, const char *ExtraCode
);
169 virtual bool PrintAsmMemoryOperand(const MachineInstr
*MI
, unsigned OpNum
,
171 const char *ExtraCode
);
173 void PrintGlobalVariable(const GlobalVariable
* GVar
);
174 bool printInstruction(const MachineInstr
*MI
); // autogenerated.
175 void printMachineInstruction(const MachineInstr
*MI
);
176 bool runOnMachineFunction(MachineFunction
&F
);
177 bool doInitialization(Module
&M
);
178 bool doFinalization(Module
&M
);
180 /// EmitMachineConstantPoolValue - Print a machine constantpool value to
182 virtual void EmitMachineConstantPoolValue(MachineConstantPoolValue
*MCPV
) {
183 printDataDirective(MCPV
->getType());
185 ARMConstantPoolValue
*ACPV
= static_cast<ARMConstantPoolValue
*>(MCPV
);
186 GlobalValue
*GV
= ACPV
->getGV();
190 if (ACPV
->isNonLazyPointer()) {
191 std::string SymName
= Mang
->getMangledName(GV
);
192 Name
= Mang
->getMangledName(GV
, "$non_lazy_ptr", true);
194 if (GV
->hasHiddenVisibility())
195 HiddenGVNonLazyPtrs
[SymName
] = Name
;
197 GVNonLazyPtrs
[SymName
] = Name
;
198 } else if (ACPV
->isStub()) {
200 FnStubInfo
&FnInfo
= FnStubs
[Mang
->getMangledName(GV
)];
201 FnInfo
.Init(GV
, Mang
);
204 FnStubInfo
&FnInfo
= FnStubs
[Mang
->makeNameProper(ACPV
->getSymbol())];
205 FnInfo
.Init(ACPV
->getSymbol(), Mang
);
210 Name
= Mang
->getMangledName(GV
);
212 Name
= Mang
->makeNameProper(ACPV
->getSymbol());
218 if (ACPV
->hasModifier()) O
<< "(" << ACPV
->getModifier() << ")";
219 if (ACPV
->getPCAdjustment() != 0) {
220 O
<< "-(" << TAI
->getPrivateGlobalPrefix() << "PC"
221 << ACPV
->getLabelId()
222 << "+" << (unsigned)ACPV
->getPCAdjustment();
223 if (ACPV
->mustAddCurrentAddress())
230 void getAnalysisUsage(AnalysisUsage
&AU
) const {
231 AsmPrinter::getAnalysisUsage(AU
);
232 AU
.setPreservesAll();
233 AU
.addRequired
<MachineModuleInfo
>();
234 AU
.addRequired
<DwarfWriter
>();
237 } // end of anonymous namespace
239 #include "ARMGenAsmWriter.inc"
241 /// runOnMachineFunction - This uses the printInstruction()
242 /// method to print assembly for each instruction.
244 bool ARMAsmPrinter::runOnMachineFunction(MachineFunction
&MF
) {
247 AFI
= MF
.getInfo
<ARMFunctionInfo
>();
248 MCP
= MF
.getConstantPool();
250 SetupMachineFunction(MF
);
253 // NOTE: we don't print out constant pools here, they are handled as
258 // Print out labels for the function.
259 const Function
*F
= MF
.getFunction();
260 SwitchToSection(getObjFileLowering().SectionForGlobal(F
, Mang
, TM
));
262 switch (F
->getLinkage()) {
263 default: llvm_unreachable("Unknown linkage type!");
264 case Function::PrivateLinkage
:
265 case Function::LinkerPrivateLinkage
:
266 case Function::InternalLinkage
:
268 case Function::ExternalLinkage
:
269 O
<< "\t.globl\t" << CurrentFnName
<< "\n";
271 case Function::WeakAnyLinkage
:
272 case Function::WeakODRLinkage
:
273 case Function::LinkOnceAnyLinkage
:
274 case Function::LinkOnceODRLinkage
:
275 if (Subtarget
->isTargetDarwin()) {
276 O
<< "\t.globl\t" << CurrentFnName
<< "\n";
277 O
<< "\t.weak_definition\t" << CurrentFnName
<< "\n";
279 O
<< TAI
->getWeakRefDirective() << CurrentFnName
<< "\n";
284 printVisibility(CurrentFnName
, F
->getVisibility());
286 if (AFI
->isThumbFunction()) {
287 EmitAlignment(MF
.getAlignment(), F
, AFI
->getAlign());
288 O
<< "\t.code\t16\n";
289 O
<< "\t.thumb_func";
290 if (Subtarget
->isTargetDarwin())
291 O
<< "\t" << CurrentFnName
;
295 EmitAlignment(MF
.getAlignment(), F
);
298 O
<< CurrentFnName
<< ":\n";
299 // Emit pre-function debug information.
300 DW
->BeginFunction(&MF
);
302 if (Subtarget
->isTargetDarwin()) {
303 // If the function is empty, then we need to emit *something*. Otherwise,
304 // the function's label might be associated with something that it wasn't
305 // meant to be associated with. We emit a noop in this situation.
306 MachineFunction::iterator I
= MF
.begin();
308 if (++I
== MF
.end() && MF
.front().empty())
312 // Print out code for the function.
313 for (MachineFunction::const_iterator I
= MF
.begin(), E
= MF
.end();
315 // Print a label for the basic block.
316 if (I
!= MF
.begin()) {
317 printBasicBlockLabel(I
, true, true, VerboseAsm
);
320 for (MachineBasicBlock::const_iterator II
= I
->begin(), E
= I
->end();
322 // Print the assembly for the instruction.
323 printMachineInstruction(II
);
327 if (TAI
->hasDotTypeDotSizeDirective())
328 O
<< "\t.size " << CurrentFnName
<< ", .-" << CurrentFnName
<< "\n";
330 // Emit post-function debug information.
331 DW
->EndFunction(&MF
);
338 void ARMAsmPrinter::printOperand(const MachineInstr
*MI
, int OpNum
,
339 const char *Modifier
) {
340 const MachineOperand
&MO
= MI
->getOperand(OpNum
);
341 switch (MO
.getType()) {
342 case MachineOperand::MO_Register
: {
343 unsigned Reg
= MO
.getReg();
344 if (TargetRegisterInfo::isPhysicalRegister(Reg
)) {
345 if (Modifier
&& strcmp(Modifier
, "dregpair") == 0) {
346 unsigned DRegLo
= TRI
->getSubReg(Reg
, 5); // arm_dsubreg_0
347 unsigned DRegHi
= TRI
->getSubReg(Reg
, 6); // arm_dsubreg_1
349 << TRI
->getAsmName(DRegLo
) << ',' << TRI
->getAsmName(DRegHi
)
352 O
<< TRI
->getAsmName(Reg
);
355 llvm_unreachable("not implemented");
358 case MachineOperand::MO_Immediate
: {
359 if (!Modifier
|| strcmp(Modifier
, "no_hash") != 0)
365 case MachineOperand::MO_MachineBasicBlock
:
366 printBasicBlockLabel(MO
.getMBB());
368 case MachineOperand::MO_GlobalAddress
: {
369 bool isCallOp
= Modifier
&& !strcmp(Modifier
, "call");
370 GlobalValue
*GV
= MO
.getGlobal();
372 bool isExt
= GV
->isDeclaration() || GV
->isWeakForLinker();
373 if (isExt
&& isCallOp
&& Subtarget
->isTargetDarwin() &&
374 TM
.getRelocationModel() != Reloc::Static
) {
375 FnStubInfo
&FnInfo
= FnStubs
[Mang
->getMangledName(GV
)];
376 FnInfo
.Init(GV
, Mang
);
379 Name
= Mang
->getMangledName(GV
);
384 printOffset(MO
.getOffset());
386 if (isCallOp
&& Subtarget
->isTargetELF() &&
387 TM
.getRelocationModel() == Reloc::PIC_
)
391 case MachineOperand::MO_ExternalSymbol
: {
392 bool isCallOp
= Modifier
&& !strcmp(Modifier
, "call");
394 if (isCallOp
&& Subtarget
->isTargetDarwin() &&
395 TM
.getRelocationModel() != Reloc::Static
) {
396 FnStubInfo
&FnInfo
= FnStubs
[Mang
->makeNameProper(MO
.getSymbolName())];
397 FnInfo
.Init(MO
.getSymbolName(), Mang
);
400 Name
= Mang
->makeNameProper(MO
.getSymbolName());
403 if (isCallOp
&& Subtarget
->isTargetELF() &&
404 TM
.getRelocationModel() == Reloc::PIC_
)
408 case MachineOperand::MO_ConstantPoolIndex
:
409 O
<< TAI
->getPrivateGlobalPrefix() << "CPI" << getFunctionNumber()
410 << '_' << MO
.getIndex();
412 case MachineOperand::MO_JumpTableIndex
:
413 O
<< TAI
->getPrivateGlobalPrefix() << "JTI" << getFunctionNumber()
414 << '_' << MO
.getIndex();
417 O
<< "<unknown operand type>"; abort (); break;
421 static void printSOImm(formatted_raw_ostream
&O
, int64_t V
, bool VerboseAsm
,
422 const TargetAsmInfo
*TAI
) {
423 // Break it up into two parts that make up a shifter immediate.
424 V
= ARM_AM::getSOImmVal(V
);
425 assert(V
!= -1 && "Not a valid so_imm value!");
427 unsigned Imm
= ARM_AM::getSOImmValImm(V
);
428 unsigned Rot
= ARM_AM::getSOImmValRot(V
);
430 // Print low-level immediate formation info, per
431 // A5.1.3: "Data-processing operands - Immediate".
433 O
<< "#" << Imm
<< ", " << Rot
;
434 // Pretty printed version.
436 O
<< ' ' << TAI
->getCommentString()
437 << ' ' << (int)ARM_AM::rotr32(Imm
, Rot
);
443 /// printSOImmOperand - SOImm is 4-bit rotate amount in bits 8-11 with 8-bit
444 /// immediate in bits 0-7.
445 void ARMAsmPrinter::printSOImmOperand(const MachineInstr
*MI
, int OpNum
) {
446 const MachineOperand
&MO
= MI
->getOperand(OpNum
);
447 assert(MO
.isImm() && "Not a valid so_imm value!");
448 printSOImm(O
, MO
.getImm(), VerboseAsm
, TAI
);
451 /// printSOImm2PartOperand - SOImm is broken into two pieces using a 'mov'
452 /// followed by an 'orr' to materialize.
453 void ARMAsmPrinter::printSOImm2PartOperand(const MachineInstr
*MI
, int OpNum
) {
454 const MachineOperand
&MO
= MI
->getOperand(OpNum
);
455 assert(MO
.isImm() && "Not a valid so_imm value!");
456 unsigned V1
= ARM_AM::getSOImmTwoPartFirst(MO
.getImm());
457 unsigned V2
= ARM_AM::getSOImmTwoPartSecond(MO
.getImm());
458 printSOImm(O
, V1
, VerboseAsm
, TAI
);
460 printPredicateOperand(MI
, 2);
466 printSOImm(O
, V2
, VerboseAsm
, TAI
);
469 // so_reg is a 4-operand unit corresponding to register forms of the A5.1
470 // "Addressing Mode 1 - Data-processing operands" forms. This includes:
472 // REG REG 0,SH_OPC - e.g. R5, ROR R3
473 // REG 0 IMM,SH_OPC - e.g. R5, LSL #3
474 void ARMAsmPrinter::printSORegOperand(const MachineInstr
*MI
, int Op
) {
475 const MachineOperand
&MO1
= MI
->getOperand(Op
);
476 const MachineOperand
&MO2
= MI
->getOperand(Op
+1);
477 const MachineOperand
&MO3
= MI
->getOperand(Op
+2);
479 assert(TargetRegisterInfo::isPhysicalRegister(MO1
.getReg()));
480 O
<< TRI
->getAsmName(MO1
.getReg());
482 // Print the shift opc.
484 << ARM_AM::getShiftOpcStr(ARM_AM::getSORegShOp(MO3
.getImm()))
488 assert(TargetRegisterInfo::isPhysicalRegister(MO2
.getReg()));
489 O
<< TRI
->getAsmName(MO2
.getReg());
490 assert(ARM_AM::getSORegOffset(MO3
.getImm()) == 0);
492 O
<< "#" << ARM_AM::getSORegOffset(MO3
.getImm());
496 void ARMAsmPrinter::printAddrMode2Operand(const MachineInstr
*MI
, int Op
) {
497 const MachineOperand
&MO1
= MI
->getOperand(Op
);
498 const MachineOperand
&MO2
= MI
->getOperand(Op
+1);
499 const MachineOperand
&MO3
= MI
->getOperand(Op
+2);
501 if (!MO1
.isReg()) { // FIXME: This is for CP entries, but isn't right.
502 printOperand(MI
, Op
);
506 O
<< "[" << TRI
->getAsmName(MO1
.getReg());
509 if (ARM_AM::getAM2Offset(MO3
.getImm())) // Don't print +0.
511 << (char)ARM_AM::getAM2Op(MO3
.getImm())
512 << ARM_AM::getAM2Offset(MO3
.getImm());
518 << (char)ARM_AM::getAM2Op(MO3
.getImm())
519 << TRI
->getAsmName(MO2
.getReg());
521 if (unsigned ShImm
= ARM_AM::getAM2Offset(MO3
.getImm()))
523 << ARM_AM::getShiftOpcStr(ARM_AM::getAM2ShiftOpc(MO3
.getImm()))
528 void ARMAsmPrinter::printAddrMode2OffsetOperand(const MachineInstr
*MI
, int Op
){
529 const MachineOperand
&MO1
= MI
->getOperand(Op
);
530 const MachineOperand
&MO2
= MI
->getOperand(Op
+1);
533 unsigned ImmOffs
= ARM_AM::getAM2Offset(MO2
.getImm());
534 assert(ImmOffs
&& "Malformed indexed load / store!");
536 << (char)ARM_AM::getAM2Op(MO2
.getImm())
541 O
<< (char)ARM_AM::getAM2Op(MO2
.getImm())
542 << TRI
->getAsmName(MO1
.getReg());
544 if (unsigned ShImm
= ARM_AM::getAM2Offset(MO2
.getImm()))
546 << ARM_AM::getShiftOpcStr(ARM_AM::getAM2ShiftOpc(MO2
.getImm()))
550 void ARMAsmPrinter::printAddrMode3Operand(const MachineInstr
*MI
, int Op
) {
551 const MachineOperand
&MO1
= MI
->getOperand(Op
);
552 const MachineOperand
&MO2
= MI
->getOperand(Op
+1);
553 const MachineOperand
&MO3
= MI
->getOperand(Op
+2);
555 assert(TargetRegisterInfo::isPhysicalRegister(MO1
.getReg()));
556 O
<< "[" << TRI
->getAsmName(MO1
.getReg());
560 << (char)ARM_AM::getAM3Op(MO3
.getImm())
561 << TRI
->getAsmName(MO2
.getReg())
566 if (unsigned ImmOffs
= ARM_AM::getAM3Offset(MO3
.getImm()))
568 << (char)ARM_AM::getAM3Op(MO3
.getImm())
573 void ARMAsmPrinter::printAddrMode3OffsetOperand(const MachineInstr
*MI
, int Op
){
574 const MachineOperand
&MO1
= MI
->getOperand(Op
);
575 const MachineOperand
&MO2
= MI
->getOperand(Op
+1);
578 O
<< (char)ARM_AM::getAM3Op(MO2
.getImm())
579 << TRI
->getAsmName(MO1
.getReg());
583 unsigned ImmOffs
= ARM_AM::getAM3Offset(MO2
.getImm());
584 assert(ImmOffs
&& "Malformed indexed load / store!");
586 << (char)ARM_AM::getAM3Op(MO2
.getImm())
590 void ARMAsmPrinter::printAddrMode4Operand(const MachineInstr
*MI
, int Op
,
591 const char *Modifier
) {
592 const MachineOperand
&MO1
= MI
->getOperand(Op
);
593 const MachineOperand
&MO2
= MI
->getOperand(Op
+1);
594 ARM_AM::AMSubMode Mode
= ARM_AM::getAM4SubMode(MO2
.getImm());
595 if (Modifier
&& strcmp(Modifier
, "submode") == 0) {
596 if (MO1
.getReg() == ARM::SP
) {
598 bool isLDM
= (MI
->getOpcode() == ARM::LDM
||
599 MI
->getOpcode() == ARM::LDM_RET
||
600 MI
->getOpcode() == ARM::t2LDM
||
601 MI
->getOpcode() == ARM::t2LDM_RET
);
602 O
<< ARM_AM::getAMSubModeAltStr(Mode
, isLDM
);
604 O
<< ARM_AM::getAMSubModeStr(Mode
);
606 printOperand(MI
, Op
);
607 if (ARM_AM::getAM4WBFlag(MO2
.getImm()))
612 void ARMAsmPrinter::printAddrMode5Operand(const MachineInstr
*MI
, int Op
,
613 const char *Modifier
) {
614 const MachineOperand
&MO1
= MI
->getOperand(Op
);
615 const MachineOperand
&MO2
= MI
->getOperand(Op
+1);
617 if (!MO1
.isReg()) { // FIXME: This is for CP entries, but isn't right.
618 printOperand(MI
, Op
);
622 assert(TargetRegisterInfo::isPhysicalRegister(MO1
.getReg()));
624 if (Modifier
&& strcmp(Modifier
, "submode") == 0) {
625 ARM_AM::AMSubMode Mode
= ARM_AM::getAM5SubMode(MO2
.getImm());
626 if (MO1
.getReg() == ARM::SP
) {
627 bool isFLDM
= (MI
->getOpcode() == ARM::FLDMD
||
628 MI
->getOpcode() == ARM::FLDMS
);
629 O
<< ARM_AM::getAMSubModeAltStr(Mode
, isFLDM
);
631 O
<< ARM_AM::getAMSubModeStr(Mode
);
633 } else if (Modifier
&& strcmp(Modifier
, "base") == 0) {
634 // Used for FSTM{D|S} and LSTM{D|S} operations.
635 O
<< TRI
->getAsmName(MO1
.getReg());
636 if (ARM_AM::getAM5WBFlag(MO2
.getImm()))
641 O
<< "[" << TRI
->getAsmName(MO1
.getReg());
643 if (unsigned ImmOffs
= ARM_AM::getAM5Offset(MO2
.getImm())) {
645 << (char)ARM_AM::getAM5Op(MO2
.getImm())
651 void ARMAsmPrinter::printAddrMode6Operand(const MachineInstr
*MI
, int Op
) {
652 const MachineOperand
&MO1
= MI
->getOperand(Op
);
653 const MachineOperand
&MO2
= MI
->getOperand(Op
+1);
654 const MachineOperand
&MO3
= MI
->getOperand(Op
+2);
656 // FIXME: No support yet for specifying alignment.
657 O
<< "[" << TRI
->getAsmName(MO1
.getReg()) << "]";
659 if (ARM_AM::getAM6WBFlag(MO3
.getImm())) {
660 if (MO2
.getReg() == 0)
663 O
<< ", " << TRI
->getAsmName(MO2
.getReg());
667 void ARMAsmPrinter::printAddrModePCOperand(const MachineInstr
*MI
, int Op
,
668 const char *Modifier
) {
669 if (Modifier
&& strcmp(Modifier
, "label") == 0) {
670 printPCLabel(MI
, Op
+1);
674 const MachineOperand
&MO1
= MI
->getOperand(Op
);
675 assert(TargetRegisterInfo::isPhysicalRegister(MO1
.getReg()));
676 O
<< "[pc, +" << TRI
->getAsmName(MO1
.getReg()) << "]";
680 ARMAsmPrinter::printBitfieldInvMaskImmOperand(const MachineInstr
*MI
, int Op
) {
681 const MachineOperand
&MO
= MI
->getOperand(Op
);
682 uint32_t v
= ~MO
.getImm();
683 int32_t lsb
= CountTrailingZeros_32(v
);
684 int32_t width
= (32 - CountLeadingZeros_32 (v
)) - lsb
;
685 assert(MO
.isImm() && "Not a valid bf_inv_mask_imm value!");
686 O
<< "#" << lsb
<< ", #" << width
;
689 //===--------------------------------------------------------------------===//
692 ARMAsmPrinter::printThumbITMask(const MachineInstr
*MI
, int Op
) {
693 // (3 - the number of trailing zeros) is the number of then / else.
694 unsigned Mask
= MI
->getOperand(Op
).getImm();
695 unsigned NumTZ
= CountTrailingZeros_32(Mask
);
696 assert(NumTZ
<= 3 && "Invalid IT mask!");
697 for (unsigned Pos
= 3, e
= NumTZ
; Pos
> e
; --Pos
) {
698 bool T
= (Mask
& (1 << Pos
)) != 0;
707 ARMAsmPrinter::printThumbAddrModeRROperand(const MachineInstr
*MI
, int Op
) {
708 const MachineOperand
&MO1
= MI
->getOperand(Op
);
709 const MachineOperand
&MO2
= MI
->getOperand(Op
+1);
710 O
<< "[" << TRI
->getAsmName(MO1
.getReg());
711 O
<< ", " << TRI
->getAsmName(MO2
.getReg()) << "]";
715 ARMAsmPrinter::printThumbAddrModeRI5Operand(const MachineInstr
*MI
, int Op
,
717 const MachineOperand
&MO1
= MI
->getOperand(Op
);
718 const MachineOperand
&MO2
= MI
->getOperand(Op
+1);
719 const MachineOperand
&MO3
= MI
->getOperand(Op
+2);
721 if (!MO1
.isReg()) { // FIXME: This is for CP entries, but isn't right.
722 printOperand(MI
, Op
);
726 O
<< "[" << TRI
->getAsmName(MO1
.getReg());
728 O
<< ", " << TRI
->getAsmName(MO3
.getReg());
729 else if (unsigned ImmOffs
= MO2
.getImm()) {
730 O
<< ", #" << ImmOffs
;
738 ARMAsmPrinter::printThumbAddrModeS1Operand(const MachineInstr
*MI
, int Op
) {
739 printThumbAddrModeRI5Operand(MI
, Op
, 1);
742 ARMAsmPrinter::printThumbAddrModeS2Operand(const MachineInstr
*MI
, int Op
) {
743 printThumbAddrModeRI5Operand(MI
, Op
, 2);
746 ARMAsmPrinter::printThumbAddrModeS4Operand(const MachineInstr
*MI
, int Op
) {
747 printThumbAddrModeRI5Operand(MI
, Op
, 4);
750 void ARMAsmPrinter::printThumbAddrModeSPOperand(const MachineInstr
*MI
,int Op
) {
751 const MachineOperand
&MO1
= MI
->getOperand(Op
);
752 const MachineOperand
&MO2
= MI
->getOperand(Op
+1);
753 O
<< "[" << TRI
->getAsmName(MO1
.getReg());
754 if (unsigned ImmOffs
= MO2
.getImm())
755 O
<< ", #" << ImmOffs
<< " * 4";
759 //===--------------------------------------------------------------------===//
761 // Constant shifts t2_so_reg is a 2-operand unit corresponding to the Thumb2
762 // register with shift forms.
764 // REG IMM, SH_OPC - e.g. R5, LSL #3
765 void ARMAsmPrinter::printT2SOOperand(const MachineInstr
*MI
, int OpNum
) {
766 const MachineOperand
&MO1
= MI
->getOperand(OpNum
);
767 const MachineOperand
&MO2
= MI
->getOperand(OpNum
+1);
769 unsigned Reg
= MO1
.getReg();
770 assert(TargetRegisterInfo::isPhysicalRegister(Reg
));
771 O
<< TRI
->getAsmName(Reg
);
773 // Print the shift opc.
775 << ARM_AM::getShiftOpcStr(ARM_AM::getSORegShOp(MO2
.getImm()))
778 assert(MO2
.isImm() && "Not a valid t2_so_reg value!");
779 O
<< "#" << ARM_AM::getSORegOffset(MO2
.getImm());
782 void ARMAsmPrinter::printT2AddrModeImm12Operand(const MachineInstr
*MI
,
784 const MachineOperand
&MO1
= MI
->getOperand(OpNum
);
785 const MachineOperand
&MO2
= MI
->getOperand(OpNum
+1);
787 O
<< "[" << TRI
->getAsmName(MO1
.getReg());
789 unsigned OffImm
= MO2
.getImm();
790 if (OffImm
) // Don't print +0.
791 O
<< ", #+" << OffImm
;
795 void ARMAsmPrinter::printT2AddrModeImm8Operand(const MachineInstr
*MI
,
797 const MachineOperand
&MO1
= MI
->getOperand(OpNum
);
798 const MachineOperand
&MO2
= MI
->getOperand(OpNum
+1);
800 O
<< "[" << TRI
->getAsmName(MO1
.getReg());
802 int32_t OffImm
= (int32_t)MO2
.getImm();
805 O
<< ", #-" << -OffImm
;
807 O
<< ", #+" << OffImm
;
811 void ARMAsmPrinter::printT2AddrModeImm8s4Operand(const MachineInstr
*MI
,
813 const MachineOperand
&MO1
= MI
->getOperand(OpNum
);
814 const MachineOperand
&MO2
= MI
->getOperand(OpNum
+1);
816 O
<< "[" << TRI
->getAsmName(MO1
.getReg());
818 int32_t OffImm
= (int32_t)MO2
.getImm() / 4;
821 O
<< ", #-" << -OffImm
<< " * 4";
823 O
<< ", #+" << OffImm
<< " * 4";
827 void ARMAsmPrinter::printT2AddrModeImm8OffsetOperand(const MachineInstr
*MI
,
829 const MachineOperand
&MO1
= MI
->getOperand(OpNum
);
830 int32_t OffImm
= (int32_t)MO1
.getImm();
833 O
<< "#-" << -OffImm
;
838 void ARMAsmPrinter::printT2AddrModeSoRegOperand(const MachineInstr
*MI
,
840 const MachineOperand
&MO1
= MI
->getOperand(OpNum
);
841 const MachineOperand
&MO2
= MI
->getOperand(OpNum
+1);
842 const MachineOperand
&MO3
= MI
->getOperand(OpNum
+2);
844 O
<< "[" << TRI
->getAsmName(MO1
.getReg());
847 O
<< ", +" << TRI
->getAsmName(MO2
.getReg());
849 unsigned ShAmt
= MO3
.getImm();
851 assert(ShAmt
<= 3 && "Not a valid Thumb2 addressing mode!");
852 O
<< ", lsl #" << ShAmt
;
859 //===--------------------------------------------------------------------===//
861 void ARMAsmPrinter::printPredicateOperand(const MachineInstr
*MI
, int OpNum
) {
862 ARMCC::CondCodes CC
= (ARMCC::CondCodes
)MI
->getOperand(OpNum
).getImm();
864 O
<< ARMCondCodeToString(CC
);
867 void ARMAsmPrinter::printSBitModifierOperand(const MachineInstr
*MI
, int OpNum
){
868 unsigned Reg
= MI
->getOperand(OpNum
).getReg();
870 assert(Reg
== ARM::CPSR
&& "Expect ARM CPSR register!");
875 void ARMAsmPrinter::printPCLabel(const MachineInstr
*MI
, int OpNum
) {
876 int Id
= (int)MI
->getOperand(OpNum
).getImm();
877 O
<< TAI
->getPrivateGlobalPrefix() << "PC" << Id
;
880 void ARMAsmPrinter::printRegisterList(const MachineInstr
*MI
, int OpNum
) {
882 for (unsigned i
= OpNum
, e
= MI
->getNumOperands(); i
!= e
; ++i
) {
884 if (i
!= e
-1) O
<< ", ";
889 void ARMAsmPrinter::printCPInstOperand(const MachineInstr
*MI
, int OpNum
,
890 const char *Modifier
) {
891 assert(Modifier
&& "This operand only works with a modifier!");
892 // There are two aspects to a CONSTANTPOOL_ENTRY operand, the label and the
894 if (!strcmp(Modifier
, "label")) {
895 unsigned ID
= MI
->getOperand(OpNum
).getImm();
896 O
<< TAI
->getPrivateGlobalPrefix() << "CPI" << getFunctionNumber()
897 << '_' << ID
<< ":\n";
899 assert(!strcmp(Modifier
, "cpentry") && "Unknown modifier for CPE");
900 unsigned CPI
= MI
->getOperand(OpNum
).getIndex();
902 const MachineConstantPoolEntry
&MCPE
= MCP
->getConstants()[CPI
];
904 if (MCPE
.isMachineConstantPoolEntry()) {
905 EmitMachineConstantPoolValue(MCPE
.Val
.MachineCPVal
);
907 EmitGlobalConstant(MCPE
.Val
.ConstVal
);
912 void ARMAsmPrinter::printJTBlockOperand(const MachineInstr
*MI
, int OpNum
) {
913 assert(!Subtarget
->isThumb2() && "Thumb2 should use double-jump jumptables!");
915 const MachineOperand
&MO1
= MI
->getOperand(OpNum
);
916 const MachineOperand
&MO2
= MI
->getOperand(OpNum
+1); // Unique Id
917 unsigned JTI
= MO1
.getIndex();
918 O
<< TAI
->getPrivateGlobalPrefix() << "JTI" << getFunctionNumber()
919 << '_' << JTI
<< '_' << MO2
.getImm() << ":\n";
921 const char *JTEntryDirective
= TAI
->getJumpTableDirective();
922 if (!JTEntryDirective
)
923 JTEntryDirective
= TAI
->getData32bitsDirective();
925 const MachineFunction
*MF
= MI
->getParent()->getParent();
926 const MachineJumpTableInfo
*MJTI
= MF
->getJumpTableInfo();
927 const std::vector
<MachineJumpTableEntry
> &JT
= MJTI
->getJumpTables();
928 const std::vector
<MachineBasicBlock
*> &JTBBs
= JT
[JTI
].MBBs
;
929 bool UseSet
= TAI
->getSetDirective() && TM
.getRelocationModel() == Reloc::PIC_
;
930 SmallPtrSet
<MachineBasicBlock
*, 8> JTSets
;
931 for (unsigned i
= 0, e
= JTBBs
.size(); i
!= e
; ++i
) {
932 MachineBasicBlock
*MBB
= JTBBs
[i
];
933 bool isNew
= JTSets
.insert(MBB
);
936 printPICJumpTableSetLabel(JTI
, MO2
.getImm(), MBB
);
938 O
<< JTEntryDirective
<< ' ';
940 O
<< TAI
->getPrivateGlobalPrefix() << getFunctionNumber()
941 << '_' << JTI
<< '_' << MO2
.getImm()
942 << "_set_" << MBB
->getNumber();
943 else if (TM
.getRelocationModel() == Reloc::PIC_
) {
944 printBasicBlockLabel(MBB
, false, false, false);
945 // If the arch uses custom Jump Table directives, don't calc relative to JT
946 if (!TAI
->getJumpTableDirective())
947 O
<< '-' << TAI
->getPrivateGlobalPrefix() << "JTI"
948 << getFunctionNumber() << '_' << JTI
<< '_' << MO2
.getImm();
950 printBasicBlockLabel(MBB
, false, false, false);
957 void ARMAsmPrinter::printJT2BlockOperand(const MachineInstr
*MI
, int OpNum
) {
958 const MachineOperand
&MO1
= MI
->getOperand(OpNum
);
959 const MachineOperand
&MO2
= MI
->getOperand(OpNum
+1); // Unique Id
960 unsigned JTI
= MO1
.getIndex();
961 O
<< TAI
->getPrivateGlobalPrefix() << "JTI" << getFunctionNumber()
962 << '_' << JTI
<< '_' << MO2
.getImm() << ":\n";
964 const MachineFunction
*MF
= MI
->getParent()->getParent();
965 const MachineJumpTableInfo
*MJTI
= MF
->getJumpTableInfo();
966 const std::vector
<MachineJumpTableEntry
> &JT
= MJTI
->getJumpTables();
967 const std::vector
<MachineBasicBlock
*> &JTBBs
= JT
[JTI
].MBBs
;
968 bool ByteOffset
= false, HalfWordOffset
= false;
969 if (MI
->getOpcode() == ARM::t2TBB
)
971 else if (MI
->getOpcode() == ARM::t2TBH
)
972 HalfWordOffset
= true;
974 for (unsigned i
= 0, e
= JTBBs
.size(); i
!= e
; ++i
) {
975 MachineBasicBlock
*MBB
= JTBBs
[i
];
977 O
<< TAI
->getData8bitsDirective();
978 else if (HalfWordOffset
)
979 O
<< TAI
->getData16bitsDirective();
980 if (ByteOffset
|| HalfWordOffset
) {
982 printBasicBlockLabel(MBB
, false, false, false);
983 O
<< "-" << TAI
->getPrivateGlobalPrefix() << "JTI" << getFunctionNumber()
984 << '_' << JTI
<< '_' << MO2
.getImm() << ")/2";
987 printBasicBlockLabel(MBB
, false, false, false);
993 // Make sure the instruction that follows TBB is 2-byte aligned.
994 // FIXME: Constant island pass should insert an "ALIGN" instruction instead.
995 if (ByteOffset
&& (JTBBs
.size() & 1)) {
1001 void ARMAsmPrinter::printTBAddrMode(const MachineInstr
*MI
, int OpNum
) {
1002 O
<< "[pc, " << TRI
->getAsmName(MI
->getOperand(OpNum
).getReg());
1003 if (MI
->getOpcode() == ARM::t2TBH
)
1009 bool ARMAsmPrinter::PrintAsmOperand(const MachineInstr
*MI
, unsigned OpNum
,
1010 unsigned AsmVariant
, const char *ExtraCode
){
1011 // Does this asm operand have a single letter operand modifier?
1012 if (ExtraCode
&& ExtraCode
[0]) {
1013 if (ExtraCode
[1] != 0) return true; // Unknown modifier.
1015 switch (ExtraCode
[0]) {
1016 default: return true; // Unknown modifier.
1017 case 'a': // Print as a memory address.
1018 if (MI
->getOperand(OpNum
).isReg()) {
1019 O
<< "[" << TRI
->getAsmName(MI
->getOperand(OpNum
).getReg()) << "]";
1023 case 'c': // Don't print "#" before an immediate operand.
1024 printOperand(MI
, OpNum
, "no_hash");
1026 case 'P': // Print a VFP double precision register.
1027 printOperand(MI
, OpNum
);
1030 if (TM
.getTargetData()->isLittleEndian())
1034 if (TM
.getTargetData()->isBigEndian())
1037 case 'H': // Write second word of DI / DF reference.
1038 // Verify that this operand has two consecutive registers.
1039 if (!MI
->getOperand(OpNum
).isReg() ||
1040 OpNum
+1 == MI
->getNumOperands() ||
1041 !MI
->getOperand(OpNum
+1).isReg())
1043 ++OpNum
; // Return the high-part.
1047 printOperand(MI
, OpNum
);
1051 bool ARMAsmPrinter::PrintAsmMemoryOperand(const MachineInstr
*MI
,
1052 unsigned OpNum
, unsigned AsmVariant
,
1053 const char *ExtraCode
) {
1054 if (ExtraCode
&& ExtraCode
[0])
1055 return true; // Unknown modifier.
1056 printAddrMode2Operand(MI
, OpNum
);
1060 void ARMAsmPrinter::printMachineInstruction(const MachineInstr
*MI
) {
1063 int Opc
= MI
->getOpcode();
1065 case ARM::CONSTPOOL_ENTRY
:
1066 if (!InCPMode
&& AFI
->isThumbFunction()) {
1072 if (InCPMode
&& AFI
->isThumbFunction())
1076 // Call the autogenerated instruction printer routines.
1077 printInstruction(MI
);
1080 bool ARMAsmPrinter::doInitialization(Module
&M
) {
1082 bool Result
= AsmPrinter::doInitialization(M
);
1083 DW
= getAnalysisIfAvailable
<DwarfWriter
>();
1085 // Use unified assembler syntax mode for Thumb.
1086 if (Subtarget
->isThumb())
1087 O
<< "\t.syntax unified\n";
1089 // Emit ARM Build Attributes
1090 if (Subtarget
->isTargetELF()) {
1092 std::string CPUString
= Subtarget
->getCPUString();
1093 if (CPUString
!= "generic")
1094 O
<< "\t.cpu " << CPUString
<< '\n';
1096 // FIXME: Emit FPU type
1097 if (Subtarget
->hasVFP2())
1098 O
<< "\t.eabi_attribute " << ARMBuildAttrs::VFP_arch
<< ", 2\n";
1100 // Signal various FP modes.
1102 O
<< "\t.eabi_attribute " << ARMBuildAttrs::ABI_FP_denormal
<< ", 1\n"
1103 << "\t.eabi_attribute " << ARMBuildAttrs::ABI_FP_exceptions
<< ", 1\n";
1105 if (FiniteOnlyFPMath())
1106 O
<< "\t.eabi_attribute " << ARMBuildAttrs::ABI_FP_number_model
<< ", 1\n";
1108 O
<< "\t.eabi_attribute " << ARMBuildAttrs::ABI_FP_number_model
<< ", 3\n";
1110 // 8-bytes alignment stuff.
1111 O
<< "\t.eabi_attribute " << ARMBuildAttrs::ABI_align8_needed
<< ", 1\n"
1112 << "\t.eabi_attribute " << ARMBuildAttrs::ABI_align8_preserved
<< ", 1\n";
1114 // FIXME: Should we signal R9 usage?
1120 /// PrintUnmangledNameSafely - Print out the printable characters in the name.
1121 /// Don't print things like \\n or \\0.
1122 static void PrintUnmangledNameSafely(const Value
*V
,
1123 formatted_raw_ostream
&OS
) {
1124 for (StringRef::iterator it
= V
->getName().begin(),
1125 ie
= V
->getName().end(); it
!= ie
; ++it
)
1130 void ARMAsmPrinter::PrintGlobalVariable(const GlobalVariable
* GVar
) {
1131 const TargetData
*TD
= TM
.getTargetData();
1133 if (!GVar
->hasInitializer()) // External global require no code
1136 // Check to see if this is a special global used by LLVM, if so, emit it.
1138 if (EmitSpecialLLVMGlobal(GVar
)) {
1139 if (Subtarget
->isTargetDarwin() &&
1140 TM
.getRelocationModel() == Reloc::Static
) {
1141 if (GVar
->getName() == "llvm.global_ctors")
1142 O
<< ".reference .constructors_used\n";
1143 else if (GVar
->getName() == "llvm.global_dtors")
1144 O
<< ".reference .destructors_used\n";
1149 std::string name
= Mang
->getMangledName(GVar
);
1150 Constant
*C
= GVar
->getInitializer();
1151 if (isa
<MDNode
>(C
) || isa
<MDString
>(C
))
1153 const Type
*Type
= C
->getType();
1154 unsigned Size
= TD
->getTypeAllocSize(Type
);
1155 unsigned Align
= TD
->getPreferredAlignmentLog(GVar
);
1156 bool isDarwin
= Subtarget
->isTargetDarwin();
1158 printVisibility(name
, GVar
->getVisibility());
1160 if (Subtarget
->isTargetELF())
1161 O
<< "\t.type " << name
<< ",%object\n";
1163 const MCSection
*TheSection
=
1164 getObjFileLowering().SectionForGlobal(GVar
, Mang
, TM
);
1165 SwitchToSection(TheSection
);
1167 // FIXME: get this stuff from section kind flags.
1168 if (C
->isNullValue() && !GVar
->hasSection() && !GVar
->isThreadLocal() &&
1169 // Don't put things that should go in the cstring section into "comm".
1170 !TheSection
->getKind().isMergeableCString()) {
1171 if (GVar
->hasExternalLinkage()) {
1172 if (const char *Directive
= TAI
->getZeroFillDirective()) {
1173 O
<< "\t.globl\t" << name
<< "\n";
1174 O
<< Directive
<< "__DATA, __common, " << name
<< ", "
1175 << Size
<< ", " << Align
<< "\n";
1180 if (GVar
->hasLocalLinkage() || GVar
->isWeakForLinker()) {
1181 if (Size
== 0) Size
= 1; // .comm Foo, 0 is undefined, avoid it.
1184 if (GVar
->hasLocalLinkage()) {
1185 O
<< TAI
->getLCOMMDirective() << name
<< "," << Size
1187 } else if (GVar
->hasCommonLinkage()) {
1188 O
<< TAI
->getCOMMDirective() << name
<< "," << Size
1191 SwitchToSection(getObjFileLowering().SectionForGlobal(GVar
, Mang
,TM
));
1192 O
<< "\t.globl " << name
<< '\n'
1193 << TAI
->getWeakDefDirective() << name
<< '\n';
1194 EmitAlignment(Align
, GVar
);
1197 O
<< "\t\t\t\t" << TAI
->getCommentString() << ' ';
1198 PrintUnmangledNameSafely(GVar
, O
);
1201 EmitGlobalConstant(C
);
1204 } else if (TAI
->getLCOMMDirective() != NULL
) {
1205 if (GVar
->hasLocalLinkage()) {
1206 O
<< TAI
->getLCOMMDirective() << name
<< "," << Size
;
1208 O
<< TAI
->getCOMMDirective() << name
<< "," << Size
;
1209 if (TAI
->getCOMMDirectiveTakesAlignment())
1210 O
<< ',' << (TAI
->getAlignmentIsInBytes() ? (1 << Align
) : Align
);
1213 if (GVar
->hasLocalLinkage())
1214 O
<< "\t.local\t" << name
<< "\n";
1215 O
<< TAI
->getCOMMDirective() << name
<< "," << Size
;
1216 if (TAI
->getCOMMDirectiveTakesAlignment())
1217 O
<< "," << (TAI
->getAlignmentIsInBytes() ? (1 << Align
) : Align
);
1220 O
<< "\t\t" << TAI
->getCommentString() << " ";
1221 PrintUnmangledNameSafely(GVar
, O
);
1228 switch (GVar
->getLinkage()) {
1229 case GlobalValue::CommonLinkage
:
1230 case GlobalValue::LinkOnceAnyLinkage
:
1231 case GlobalValue::LinkOnceODRLinkage
:
1232 case GlobalValue::WeakAnyLinkage
:
1233 case GlobalValue::WeakODRLinkage
:
1235 O
<< "\t.globl " << name
<< "\n"
1236 << "\t.weak_definition " << name
<< "\n";
1238 O
<< "\t.weak " << name
<< "\n";
1241 case GlobalValue::AppendingLinkage
:
1242 // FIXME: appending linkage variables should go into a section of
1243 // their name or something. For now, just emit them as external.
1244 case GlobalValue::ExternalLinkage
:
1245 O
<< "\t.globl " << name
<< "\n";
1247 case GlobalValue::PrivateLinkage
:
1248 case GlobalValue::LinkerPrivateLinkage
:
1249 case GlobalValue::InternalLinkage
:
1252 llvm_unreachable("Unknown linkage type!");
1255 EmitAlignment(Align
, GVar
);
1258 O
<< "\t\t\t\t" << TAI
->getCommentString() << " ";
1259 PrintUnmangledNameSafely(GVar
, O
);
1262 if (TAI
->hasDotTypeDotSizeDirective())
1263 O
<< "\t.size " << name
<< ", " << Size
<< "\n";
1265 EmitGlobalConstant(C
);
1270 bool ARMAsmPrinter::doFinalization(Module
&M
) {
1271 if (Subtarget
->isTargetDarwin()) {
1272 // All darwin targets use mach-o.
1273 TargetLoweringObjectFileMachO
&TLOFMacho
=
1274 static_cast<TargetLoweringObjectFileMachO
&>(getObjFileLowering());
1278 if (!FnStubs
.empty()) {
1279 const MCSection
*StubSection
;
1280 if (TM
.getRelocationModel() == Reloc::PIC_
)
1281 StubSection
= TLOFMacho
.getMachOSection(".section __TEXT,__picsymbolstu"
1282 "b4,symbol_stubs,none,16", true,
1283 SectionKind::getText());
1285 StubSection
= TLOFMacho
.getMachOSection(".section __TEXT,__symbol_stub4"
1286 ",symbol_stubs,none,12", true,
1287 SectionKind::getText());
1289 const MCSection
*LazySymbolPointerSection
1290 = TLOFMacho
.getMachOSection(".lazy_symbol_pointer", true,
1291 SectionKind::getMetadata());
1293 // Output stubs for dynamically-linked functions
1294 for (StringMap
<FnStubInfo
>::iterator I
= FnStubs
.begin(),
1295 E
= FnStubs
.end(); I
!= E
; ++I
) {
1296 const FnStubInfo
&Info
= I
->second
;
1298 SwitchToSection(StubSection
);
1300 O
<< "\t.code\t32\n";
1302 O
<< Info
.Stub
<< ":\n";
1303 O
<< "\t.indirect_symbol " << I
->getKeyData() << '\n';
1304 O
<< "\tldr ip, " << Info
.SLP
<< '\n';
1305 if (TM
.getRelocationModel() == Reloc::PIC_
) {
1306 O
<< Info
.SCV
<< ":\n";
1307 O
<< "\tadd ip, pc, ip\n";
1309 O
<< "\tldr pc, [ip, #0]\n";
1310 O
<< Info
.SLP
<< ":\n";
1311 O
<< "\t.long\t" << Info
.LazyPtr
;
1312 if (TM
.getRelocationModel() == Reloc::PIC_
)
1313 O
<< "-(" << Info
.SCV
<< "+8)";
1316 SwitchToSection(LazySymbolPointerSection
);
1317 O
<< Info
.LazyPtr
<< ":\n";
1318 O
<< "\t.indirect_symbol " << I
->getKeyData() << "\n";
1319 O
<< "\t.long\tdyld_stub_binding_helper\n";
1324 // Output non-lazy-pointers for external and common global variables.
1325 if (!GVNonLazyPtrs
.empty()) {
1326 SwitchToSection(TLOFMacho
.getMachOSection(".non_lazy_symbol_pointer",
1328 SectionKind::getMetadata()));
1329 for (StringMap
<std::string
>::iterator I
= GVNonLazyPtrs
.begin(),
1330 E
= GVNonLazyPtrs
.end(); I
!= E
; ++I
) {
1331 O
<< I
->second
<< ":\n";
1332 O
<< "\t.indirect_symbol " << I
->getKeyData() << "\n";
1333 O
<< "\t.long\t0\n";
1337 if (!HiddenGVNonLazyPtrs
.empty()) {
1338 SwitchToSection(getObjFileLowering().getDataSection());
1339 for (StringMap
<std::string
>::iterator I
= HiddenGVNonLazyPtrs
.begin(),
1340 E
= HiddenGVNonLazyPtrs
.end(); I
!= E
; ++I
) {
1342 O
<< I
->second
<< ":\n";
1343 O
<< "\t.long " << I
->getKeyData() << "\n";
1348 // Funny Darwin hack: This flag tells the linker that no global symbols
1349 // contain code that falls through to other global symbols (e.g. the obvious
1350 // implementation of multiple entry points). If this doesn't occur, the
1351 // linker can safely perform dead code stripping. Since LLVM never
1352 // generates code that does this, it is always safe to set.
1353 O
<< "\t.subsections_via_symbols\n";
1356 return AsmPrinter::doFinalization(M
);
1359 // Force static initialization.
1360 extern "C" void LLVMInitializeARMAsmPrinter() {
1361 RegisterAsmPrinter
<ARMAsmPrinter
> X(TheARMTarget
);
1362 RegisterAsmPrinter
<ARMAsmPrinter
> Y(TheThumbTarget
);