1 // The LLVM Compiler Infrastructure
3 // This file is distributed under the University of Illinois Open Source
4 // License. See LICENSE.TXT for details.
6 //===----------------------------------------------------------------------===//
8 // This file contains a printer that converts from our internal representation
9 // of machine-dependent LLVM code to GAS-format ARM assembly language.
11 //===----------------------------------------------------------------------===//
13 #define DEBUG_TYPE "asm-printer"
15 #include "ARMBuildAttrs.h"
16 #include "ARMTargetMachine.h"
17 #include "ARMAddressingModes.h"
18 #include "ARMConstantPoolValue.h"
19 #include "ARMMachineFunctionInfo.h"
20 #include "llvm/Constants.h"
21 #include "llvm/Module.h"
22 #include "llvm/Assembly/Writer.h"
23 #include "llvm/CodeGen/AsmPrinter.h"
24 #include "llvm/CodeGen/DwarfWriter.h"
25 #include "llvm/CodeGen/MachineModuleInfo.h"
26 #include "llvm/CodeGen/MachineFunctionPass.h"
27 #include "llvm/CodeGen/MachineJumpTableInfo.h"
28 #include "llvm/MC/MCSectionMachO.h"
29 #include "llvm/MC/MCStreamer.h"
30 #include "llvm/MC/MCAsmInfo.h"
31 #include "llvm/MC/MCSymbol.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/SmallString.h"
39 #include "llvm/ADT/Statistic.h"
40 #include "llvm/ADT/StringSet.h"
41 #include "llvm/Support/Compiler.h"
42 #include "llvm/Support/ErrorHandling.h"
43 #include "llvm/Support/Mangler.h"
44 #include "llvm/Support/MathExtras.h"
45 #include "llvm/Support/FormattedStream.h"
49 STATISTIC(EmittedInsts
, "Number of machine instrs printed");
52 class VISIBILITY_HIDDEN ARMAsmPrinter
: public AsmPrinter
{
55 /// Subtarget - Keep a pointer to the ARMSubtarget around so that we can
56 /// make the right decision when printing asm code for different targets.
57 const ARMSubtarget
*Subtarget
;
59 /// AFI - Keep a pointer to ARMFunctionInfo for the current
63 /// MCP - Keep a pointer to constantpool entries of the current
65 const MachineConstantPool
*MCP
;
67 /// We name each basic block in a Function with a unique number, so
68 /// that we can consistently refer to them later. This is cleared
69 /// at the beginning of each call to runOnMachineFunction().
71 typedef std::map
<const Value
*, unsigned> ValueMapTy
;
72 ValueMapTy NumberForBB
;
74 /// GVNonLazyPtrs - Keeps the set of GlobalValues that require
75 /// non-lazy-pointers for indirect access.
76 StringMap
<std::string
> GVNonLazyPtrs
;
78 /// HiddenGVNonLazyPtrs - Keeps the set of GlobalValues with hidden
79 /// visibility that require non-lazy-pointers for indirect access.
80 StringMap
<std::string
> HiddenGVNonLazyPtrs
;
82 /// True if asm printer is printing a series of CONSTPOOL_ENTRY.
85 explicit ARMAsmPrinter(formatted_raw_ostream
&O
, TargetMachine
&TM
,
86 const MCAsmInfo
*T
, bool V
)
87 : AsmPrinter(O
, TM
, T
, V
), DW(0), AFI(NULL
), MCP(NULL
),
89 Subtarget
= &TM
.getSubtarget
<ARMSubtarget
>();
92 virtual const char *getPassName() const {
93 return "ARM Assembly Printer";
96 void printOperand(const MachineInstr
*MI
, int OpNum
,
97 const char *Modifier
= 0);
98 void printSOImmOperand(const MachineInstr
*MI
, int OpNum
);
99 void printSOImm2PartOperand(const MachineInstr
*MI
, int OpNum
);
100 void printSORegOperand(const MachineInstr
*MI
, int OpNum
);
101 void printAddrMode2Operand(const MachineInstr
*MI
, int OpNum
);
102 void printAddrMode2OffsetOperand(const MachineInstr
*MI
, int OpNum
);
103 void printAddrMode3Operand(const MachineInstr
*MI
, int OpNum
);
104 void printAddrMode3OffsetOperand(const MachineInstr
*MI
, int OpNum
);
105 void printAddrMode4Operand(const MachineInstr
*MI
, int OpNum
,
106 const char *Modifier
= 0);
107 void printAddrMode5Operand(const MachineInstr
*MI
, int OpNum
,
108 const char *Modifier
= 0);
109 void printAddrMode6Operand(const MachineInstr
*MI
, int OpNum
);
110 void printAddrModePCOperand(const MachineInstr
*MI
, int OpNum
,
111 const char *Modifier
= 0);
112 void printBitfieldInvMaskImmOperand (const MachineInstr
*MI
, int OpNum
);
114 void printThumbITMask(const MachineInstr
*MI
, int OpNum
);
115 void printThumbAddrModeRROperand(const MachineInstr
*MI
, int OpNum
);
116 void printThumbAddrModeRI5Operand(const MachineInstr
*MI
, int OpNum
,
118 void printThumbAddrModeS1Operand(const MachineInstr
*MI
, int OpNum
);
119 void printThumbAddrModeS2Operand(const MachineInstr
*MI
, int OpNum
);
120 void printThumbAddrModeS4Operand(const MachineInstr
*MI
, int OpNum
);
121 void printThumbAddrModeSPOperand(const MachineInstr
*MI
, int OpNum
);
123 void printT2SOOperand(const MachineInstr
*MI
, int OpNum
);
124 void printT2AddrModeImm12Operand(const MachineInstr
*MI
, int OpNum
);
125 void printT2AddrModeImm8Operand(const MachineInstr
*MI
, int OpNum
);
126 void printT2AddrModeImm8s4Operand(const MachineInstr
*MI
, int OpNum
);
127 void printT2AddrModeImm8OffsetOperand(const MachineInstr
*MI
, int OpNum
);
128 void printT2AddrModeSoRegOperand(const MachineInstr
*MI
, int OpNum
);
130 void printPredicateOperand(const MachineInstr
*MI
, int OpNum
);
131 void printSBitModifierOperand(const MachineInstr
*MI
, int OpNum
);
132 void printPCLabel(const MachineInstr
*MI
, int OpNum
);
133 void printRegisterList(const MachineInstr
*MI
, int OpNum
);
134 void printCPInstOperand(const MachineInstr
*MI
, int OpNum
,
135 const char *Modifier
);
136 void printJTBlockOperand(const MachineInstr
*MI
, int OpNum
);
137 void printJT2BlockOperand(const MachineInstr
*MI
, int OpNum
);
138 void printTBAddrMode(const MachineInstr
*MI
, int OpNum
);
139 void printNoHashImmediate(const MachineInstr
*MI
, int OpNum
);
141 virtual bool PrintAsmOperand(const MachineInstr
*MI
, unsigned OpNum
,
142 unsigned AsmVariant
, const char *ExtraCode
);
143 virtual bool PrintAsmMemoryOperand(const MachineInstr
*MI
, unsigned OpNum
,
145 const char *ExtraCode
);
147 void PrintGlobalVariable(const GlobalVariable
* GVar
);
148 void printInstruction(const MachineInstr
*MI
); // autogenerated.
149 static const char *getRegisterName(unsigned RegNo
);
151 void printMachineInstruction(const MachineInstr
*MI
);
152 bool runOnMachineFunction(MachineFunction
&F
);
153 bool doInitialization(Module
&M
);
154 bool doFinalization(Module
&M
);
156 /// EmitMachineConstantPoolValue - Print a machine constantpool value to
158 virtual void EmitMachineConstantPoolValue(MachineConstantPoolValue
*MCPV
) {
159 printDataDirective(MCPV
->getType());
161 ARMConstantPoolValue
*ACPV
= static_cast<ARMConstantPoolValue
*>(MCPV
);
162 GlobalValue
*GV
= ACPV
->getGV();
165 if (ACPV
->isLSDA()) {
166 SmallString
<16> LSDAName
;
167 raw_svector_ostream(LSDAName
) << MAI
->getPrivateGlobalPrefix() <<
168 "_LSDA_" << getFunctionNumber();
169 Name
= LSDAName
.str();
171 bool isIndirect
= Subtarget
->isTargetDarwin() &&
172 Subtarget
->GVIsIndirectSymbol(GV
, TM
.getRelocationModel());
174 Name
= Mang
->getMangledName(GV
);
176 // FIXME: Remove this when Darwin transition to @GOT like syntax.
177 std::string SymName
= Mang
->getMangledName(GV
);
178 Name
= Mang
->getMangledName(GV
, "$non_lazy_ptr", true);
179 if (GV
->hasHiddenVisibility())
180 HiddenGVNonLazyPtrs
[SymName
] = Name
;
182 GVNonLazyPtrs
[SymName
] = Name
;
185 Name
= Mang
->makeNameProper(ACPV
->getSymbol());
188 if (ACPV
->hasModifier()) O
<< "(" << ACPV
->getModifier() << ")";
189 if (ACPV
->getPCAdjustment() != 0) {
190 O
<< "-(" << MAI
->getPrivateGlobalPrefix() << "PC"
191 << ACPV
->getLabelId()
192 << "+" << (unsigned)ACPV
->getPCAdjustment();
193 if (ACPV
->mustAddCurrentAddress())
200 void getAnalysisUsage(AnalysisUsage
&AU
) const {
201 AsmPrinter::getAnalysisUsage(AU
);
202 AU
.setPreservesAll();
203 AU
.addRequired
<MachineModuleInfo
>();
204 AU
.addRequired
<DwarfWriter
>();
207 } // end of anonymous namespace
209 #include "ARMGenAsmWriter.inc"
211 /// runOnMachineFunction - This uses the printInstruction()
212 /// method to print assembly for each instruction.
214 bool ARMAsmPrinter::runOnMachineFunction(MachineFunction
&MF
) {
217 AFI
= MF
.getInfo
<ARMFunctionInfo
>();
218 MCP
= MF
.getConstantPool();
220 SetupMachineFunction(MF
);
223 // NOTE: we don't print out constant pools here, they are handled as
228 // Print out labels for the function.
229 const Function
*F
= MF
.getFunction();
230 OutStreamer
.SwitchSection(getObjFileLowering().SectionForGlobal(F
, Mang
, TM
));
232 switch (F
->getLinkage()) {
233 default: llvm_unreachable("Unknown linkage type!");
234 case Function::PrivateLinkage
:
235 case Function::InternalLinkage
:
237 case Function::ExternalLinkage
:
238 O
<< "\t.globl\t" << CurrentFnName
<< "\n";
240 case Function::LinkerPrivateLinkage
:
241 case Function::WeakAnyLinkage
:
242 case Function::WeakODRLinkage
:
243 case Function::LinkOnceAnyLinkage
:
244 case Function::LinkOnceODRLinkage
:
245 if (Subtarget
->isTargetDarwin()) {
246 O
<< "\t.globl\t" << CurrentFnName
<< "\n";
247 O
<< "\t.weak_definition\t" << CurrentFnName
<< "\n";
249 O
<< MAI
->getWeakRefDirective() << CurrentFnName
<< "\n";
254 printVisibility(CurrentFnName
, F
->getVisibility());
256 if (AFI
->isThumbFunction()) {
257 EmitAlignment(MF
.getAlignment(), F
, AFI
->getAlign());
258 O
<< "\t.code\t16\n";
259 O
<< "\t.thumb_func";
260 if (Subtarget
->isTargetDarwin())
261 O
<< "\t" << CurrentFnName
;
265 EmitAlignment(MF
.getAlignment(), F
);
268 O
<< CurrentFnName
<< ":\n";
269 // Emit pre-function debug information.
270 DW
->BeginFunction(&MF
);
272 if (Subtarget
->isTargetDarwin()) {
273 // If the function is empty, then we need to emit *something*. Otherwise,
274 // the function's label might be associated with something that it wasn't
275 // meant to be associated with. We emit a noop in this situation.
276 MachineFunction::iterator I
= MF
.begin();
278 if (++I
== MF
.end() && MF
.front().empty())
282 // Print out code for the function.
283 for (MachineFunction::const_iterator I
= MF
.begin(), E
= MF
.end();
285 // Print a label for the basic block.
286 if (I
!= MF
.begin()) {
287 EmitBasicBlockStart(I
);
290 for (MachineBasicBlock::const_iterator II
= I
->begin(), E
= I
->end();
292 // Print the assembly for the instruction.
293 printMachineInstruction(II
);
297 if (MAI
->hasDotTypeDotSizeDirective())
298 O
<< "\t.size " << CurrentFnName
<< ", .-" << CurrentFnName
<< "\n";
300 // Emit post-function debug information.
301 DW
->EndFunction(&MF
);
306 void ARMAsmPrinter::printOperand(const MachineInstr
*MI
, int OpNum
,
307 const char *Modifier
) {
308 const MachineOperand
&MO
= MI
->getOperand(OpNum
);
309 switch (MO
.getType()) {
310 case MachineOperand::MO_Register
: {
311 unsigned Reg
= MO
.getReg();
312 if (TargetRegisterInfo::isPhysicalRegister(Reg
)) {
313 if (Modifier
&& strcmp(Modifier
, "dregpair") == 0) {
314 unsigned DRegLo
= TRI
->getSubReg(Reg
, 5); // arm_dsubreg_0
315 unsigned DRegHi
= TRI
->getSubReg(Reg
, 6); // arm_dsubreg_1
317 << getRegisterName(DRegLo
) << ',' << getRegisterName(DRegHi
)
319 } else if (Modifier
&& strcmp(Modifier
, "lane") == 0) {
320 unsigned RegNum
= ARMRegisterInfo::getRegisterNumbering(Reg
);
321 unsigned DReg
= TRI
->getMatchingSuperReg(Reg
, RegNum
& 1 ? 2 : 1,
322 &ARM::DPR_VFP2RegClass
);
323 O
<< getRegisterName(DReg
) << '[' << (RegNum
& 1) << ']';
325 O
<< getRegisterName(Reg
);
328 llvm_unreachable("not implemented");
331 case MachineOperand::MO_Immediate
: {
332 O
<< '#' << MO
.getImm();
335 case MachineOperand::MO_MachineBasicBlock
:
336 GetMBBSymbol(MO
.getMBB()->getNumber())->print(O
, MAI
);
338 case MachineOperand::MO_GlobalAddress
: {
339 bool isCallOp
= Modifier
&& !strcmp(Modifier
, "call");
340 GlobalValue
*GV
= MO
.getGlobal();
341 O
<< Mang
->getMangledName(GV
);
343 printOffset(MO
.getOffset());
345 if (isCallOp
&& Subtarget
->isTargetELF() &&
346 TM
.getRelocationModel() == Reloc::PIC_
)
350 case MachineOperand::MO_ExternalSymbol
: {
351 bool isCallOp
= Modifier
&& !strcmp(Modifier
, "call");
352 std::string Name
= Mang
->makeNameProper(MO
.getSymbolName());
355 if (isCallOp
&& Subtarget
->isTargetELF() &&
356 TM
.getRelocationModel() == Reloc::PIC_
)
360 case MachineOperand::MO_ConstantPoolIndex
:
361 O
<< MAI
->getPrivateGlobalPrefix() << "CPI" << getFunctionNumber()
362 << '_' << MO
.getIndex();
364 case MachineOperand::MO_JumpTableIndex
:
365 O
<< MAI
->getPrivateGlobalPrefix() << "JTI" << getFunctionNumber()
366 << '_' << MO
.getIndex();
369 O
<< "<unknown operand type>"; abort (); break;
373 static void printSOImm(formatted_raw_ostream
&O
, int64_t V
, bool VerboseAsm
,
374 const MCAsmInfo
*MAI
) {
375 // Break it up into two parts that make up a shifter immediate.
376 V
= ARM_AM::getSOImmVal(V
);
377 assert(V
!= -1 && "Not a valid so_imm value!");
379 unsigned Imm
= ARM_AM::getSOImmValImm(V
);
380 unsigned Rot
= ARM_AM::getSOImmValRot(V
);
382 // Print low-level immediate formation info, per
383 // A5.1.3: "Data-processing operands - Immediate".
385 O
<< "#" << Imm
<< ", " << Rot
;
386 // Pretty printed version.
388 O
<< ' ' << MAI
->getCommentString()
389 << ' ' << (int)ARM_AM::rotr32(Imm
, Rot
);
395 /// printSOImmOperand - SOImm is 4-bit rotate amount in bits 8-11 with 8-bit
396 /// immediate in bits 0-7.
397 void ARMAsmPrinter::printSOImmOperand(const MachineInstr
*MI
, int OpNum
) {
398 const MachineOperand
&MO
= MI
->getOperand(OpNum
);
399 assert(MO
.isImm() && "Not a valid so_imm value!");
400 printSOImm(O
, MO
.getImm(), VerboseAsm
, MAI
);
403 /// printSOImm2PartOperand - SOImm is broken into two pieces using a 'mov'
404 /// followed by an 'orr' to materialize.
405 void ARMAsmPrinter::printSOImm2PartOperand(const MachineInstr
*MI
, int OpNum
) {
406 const MachineOperand
&MO
= MI
->getOperand(OpNum
);
407 assert(MO
.isImm() && "Not a valid so_imm value!");
408 unsigned V1
= ARM_AM::getSOImmTwoPartFirst(MO
.getImm());
409 unsigned V2
= ARM_AM::getSOImmTwoPartSecond(MO
.getImm());
410 printSOImm(O
, V1
, VerboseAsm
, MAI
);
412 printPredicateOperand(MI
, 2);
418 printSOImm(O
, V2
, VerboseAsm
, MAI
);
421 // so_reg is a 4-operand unit corresponding to register forms of the A5.1
422 // "Addressing Mode 1 - Data-processing operands" forms. This includes:
424 // REG REG 0,SH_OPC - e.g. R5, ROR R3
425 // REG 0 IMM,SH_OPC - e.g. R5, LSL #3
426 void ARMAsmPrinter::printSORegOperand(const MachineInstr
*MI
, int Op
) {
427 const MachineOperand
&MO1
= MI
->getOperand(Op
);
428 const MachineOperand
&MO2
= MI
->getOperand(Op
+1);
429 const MachineOperand
&MO3
= MI
->getOperand(Op
+2);
431 O
<< getRegisterName(MO1
.getReg());
433 // Print the shift opc.
435 << ARM_AM::getShiftOpcStr(ARM_AM::getSORegShOp(MO3
.getImm()))
439 O
<< getRegisterName(MO2
.getReg());
440 assert(ARM_AM::getSORegOffset(MO3
.getImm()) == 0);
442 O
<< "#" << ARM_AM::getSORegOffset(MO3
.getImm());
446 void ARMAsmPrinter::printAddrMode2Operand(const MachineInstr
*MI
, int Op
) {
447 const MachineOperand
&MO1
= MI
->getOperand(Op
);
448 const MachineOperand
&MO2
= MI
->getOperand(Op
+1);
449 const MachineOperand
&MO3
= MI
->getOperand(Op
+2);
451 if (!MO1
.isReg()) { // FIXME: This is for CP entries, but isn't right.
452 printOperand(MI
, Op
);
456 O
<< "[" << getRegisterName(MO1
.getReg());
459 if (ARM_AM::getAM2Offset(MO3
.getImm())) // Don't print +0.
461 << (char)ARM_AM::getAM2Op(MO3
.getImm())
462 << ARM_AM::getAM2Offset(MO3
.getImm());
468 << (char)ARM_AM::getAM2Op(MO3
.getImm())
469 << getRegisterName(MO2
.getReg());
471 if (unsigned ShImm
= ARM_AM::getAM2Offset(MO3
.getImm()))
473 << ARM_AM::getShiftOpcStr(ARM_AM::getAM2ShiftOpc(MO3
.getImm()))
478 void ARMAsmPrinter::printAddrMode2OffsetOperand(const MachineInstr
*MI
, int Op
){
479 const MachineOperand
&MO1
= MI
->getOperand(Op
);
480 const MachineOperand
&MO2
= MI
->getOperand(Op
+1);
483 unsigned ImmOffs
= ARM_AM::getAM2Offset(MO2
.getImm());
484 assert(ImmOffs
&& "Malformed indexed load / store!");
486 << (char)ARM_AM::getAM2Op(MO2
.getImm())
491 O
<< (char)ARM_AM::getAM2Op(MO2
.getImm())
492 << getRegisterName(MO1
.getReg());
494 if (unsigned ShImm
= ARM_AM::getAM2Offset(MO2
.getImm()))
496 << ARM_AM::getShiftOpcStr(ARM_AM::getAM2ShiftOpc(MO2
.getImm()))
500 void ARMAsmPrinter::printAddrMode3Operand(const MachineInstr
*MI
, int Op
) {
501 const MachineOperand
&MO1
= MI
->getOperand(Op
);
502 const MachineOperand
&MO2
= MI
->getOperand(Op
+1);
503 const MachineOperand
&MO3
= MI
->getOperand(Op
+2);
505 assert(TargetRegisterInfo::isPhysicalRegister(MO1
.getReg()));
506 O
<< "[" << getRegisterName(MO1
.getReg());
510 << (char)ARM_AM::getAM3Op(MO3
.getImm())
511 << getRegisterName(MO2
.getReg())
516 if (unsigned ImmOffs
= ARM_AM::getAM3Offset(MO3
.getImm()))
518 << (char)ARM_AM::getAM3Op(MO3
.getImm())
523 void ARMAsmPrinter::printAddrMode3OffsetOperand(const MachineInstr
*MI
, int Op
){
524 const MachineOperand
&MO1
= MI
->getOperand(Op
);
525 const MachineOperand
&MO2
= MI
->getOperand(Op
+1);
528 O
<< (char)ARM_AM::getAM3Op(MO2
.getImm())
529 << getRegisterName(MO1
.getReg());
533 unsigned ImmOffs
= ARM_AM::getAM3Offset(MO2
.getImm());
534 assert(ImmOffs
&& "Malformed indexed load / store!");
536 << (char)ARM_AM::getAM3Op(MO2
.getImm())
540 void ARMAsmPrinter::printAddrMode4Operand(const MachineInstr
*MI
, int Op
,
541 const char *Modifier
) {
542 const MachineOperand
&MO1
= MI
->getOperand(Op
);
543 const MachineOperand
&MO2
= MI
->getOperand(Op
+1);
544 ARM_AM::AMSubMode Mode
= ARM_AM::getAM4SubMode(MO2
.getImm());
545 if (Modifier
&& strcmp(Modifier
, "submode") == 0) {
546 if (MO1
.getReg() == ARM::SP
) {
548 bool isLDM
= (MI
->getOpcode() == ARM::LDM
||
549 MI
->getOpcode() == ARM::LDM_RET
||
550 MI
->getOpcode() == ARM::t2LDM
||
551 MI
->getOpcode() == ARM::t2LDM_RET
);
552 O
<< ARM_AM::getAMSubModeAltStr(Mode
, isLDM
);
554 O
<< ARM_AM::getAMSubModeStr(Mode
);
555 } else if (Modifier
&& strcmp(Modifier
, "wide") == 0) {
556 ARM_AM::AMSubMode Mode
= ARM_AM::getAM4SubMode(MO2
.getImm());
557 if (Mode
== ARM_AM::ia
)
560 printOperand(MI
, Op
);
561 if (ARM_AM::getAM4WBFlag(MO2
.getImm()))
566 void ARMAsmPrinter::printAddrMode5Operand(const MachineInstr
*MI
, int Op
,
567 const char *Modifier
) {
568 const MachineOperand
&MO1
= MI
->getOperand(Op
);
569 const MachineOperand
&MO2
= MI
->getOperand(Op
+1);
571 if (!MO1
.isReg()) { // FIXME: This is for CP entries, but isn't right.
572 printOperand(MI
, Op
);
576 assert(TargetRegisterInfo::isPhysicalRegister(MO1
.getReg()));
578 if (Modifier
&& strcmp(Modifier
, "submode") == 0) {
579 ARM_AM::AMSubMode Mode
= ARM_AM::getAM5SubMode(MO2
.getImm());
580 if (MO1
.getReg() == ARM::SP
) {
581 bool isFLDM
= (MI
->getOpcode() == ARM::FLDMD
||
582 MI
->getOpcode() == ARM::FLDMS
);
583 O
<< ARM_AM::getAMSubModeAltStr(Mode
, isFLDM
);
585 O
<< ARM_AM::getAMSubModeStr(Mode
);
587 } else if (Modifier
&& strcmp(Modifier
, "base") == 0) {
588 // Used for FSTM{D|S} and LSTM{D|S} operations.
589 O
<< getRegisterName(MO1
.getReg());
590 if (ARM_AM::getAM5WBFlag(MO2
.getImm()))
595 O
<< "[" << getRegisterName(MO1
.getReg());
597 if (unsigned ImmOffs
= ARM_AM::getAM5Offset(MO2
.getImm())) {
599 << (char)ARM_AM::getAM5Op(MO2
.getImm())
605 void ARMAsmPrinter::printAddrMode6Operand(const MachineInstr
*MI
, int Op
) {
606 const MachineOperand
&MO1
= MI
->getOperand(Op
);
607 const MachineOperand
&MO2
= MI
->getOperand(Op
+1);
608 const MachineOperand
&MO3
= MI
->getOperand(Op
+2);
610 // FIXME: No support yet for specifying alignment.
611 O
<< "[" << getRegisterName(MO1
.getReg()) << "]";
613 if (ARM_AM::getAM6WBFlag(MO3
.getImm())) {
614 if (MO2
.getReg() == 0)
617 O
<< ", " << getRegisterName(MO2
.getReg());
621 void ARMAsmPrinter::printAddrModePCOperand(const MachineInstr
*MI
, int Op
,
622 const char *Modifier
) {
623 if (Modifier
&& strcmp(Modifier
, "label") == 0) {
624 printPCLabel(MI
, Op
+1);
628 const MachineOperand
&MO1
= MI
->getOperand(Op
);
629 assert(TargetRegisterInfo::isPhysicalRegister(MO1
.getReg()));
630 O
<< "[pc, +" << getRegisterName(MO1
.getReg()) << "]";
634 ARMAsmPrinter::printBitfieldInvMaskImmOperand(const MachineInstr
*MI
, int Op
) {
635 const MachineOperand
&MO
= MI
->getOperand(Op
);
636 uint32_t v
= ~MO
.getImm();
637 int32_t lsb
= CountTrailingZeros_32(v
);
638 int32_t width
= (32 - CountLeadingZeros_32 (v
)) - lsb
;
639 assert(MO
.isImm() && "Not a valid bf_inv_mask_imm value!");
640 O
<< "#" << lsb
<< ", #" << width
;
643 //===--------------------------------------------------------------------===//
646 ARMAsmPrinter::printThumbITMask(const MachineInstr
*MI
, int Op
) {
647 // (3 - the number of trailing zeros) is the number of then / else.
648 unsigned Mask
= MI
->getOperand(Op
).getImm();
649 unsigned NumTZ
= CountTrailingZeros_32(Mask
);
650 assert(NumTZ
<= 3 && "Invalid IT mask!");
651 for (unsigned Pos
= 3, e
= NumTZ
; Pos
> e
; --Pos
) {
652 bool T
= (Mask
& (1 << Pos
)) == 0;
661 ARMAsmPrinter::printThumbAddrModeRROperand(const MachineInstr
*MI
, int Op
) {
662 const MachineOperand
&MO1
= MI
->getOperand(Op
);
663 const MachineOperand
&MO2
= MI
->getOperand(Op
+1);
664 O
<< "[" << getRegisterName(MO1
.getReg());
665 O
<< ", " << getRegisterName(MO2
.getReg()) << "]";
669 ARMAsmPrinter::printThumbAddrModeRI5Operand(const MachineInstr
*MI
, int Op
,
671 const MachineOperand
&MO1
= MI
->getOperand(Op
);
672 const MachineOperand
&MO2
= MI
->getOperand(Op
+1);
673 const MachineOperand
&MO3
= MI
->getOperand(Op
+2);
675 if (!MO1
.isReg()) { // FIXME: This is for CP entries, but isn't right.
676 printOperand(MI
, Op
);
680 O
<< "[" << getRegisterName(MO1
.getReg());
682 O
<< ", " << getRegisterName(MO3
.getReg());
683 else if (unsigned ImmOffs
= MO2
.getImm()) {
684 O
<< ", #" << ImmOffs
;
692 ARMAsmPrinter::printThumbAddrModeS1Operand(const MachineInstr
*MI
, int Op
) {
693 printThumbAddrModeRI5Operand(MI
, Op
, 1);
696 ARMAsmPrinter::printThumbAddrModeS2Operand(const MachineInstr
*MI
, int Op
) {
697 printThumbAddrModeRI5Operand(MI
, Op
, 2);
700 ARMAsmPrinter::printThumbAddrModeS4Operand(const MachineInstr
*MI
, int Op
) {
701 printThumbAddrModeRI5Operand(MI
, Op
, 4);
704 void ARMAsmPrinter::printThumbAddrModeSPOperand(const MachineInstr
*MI
,int Op
) {
705 const MachineOperand
&MO1
= MI
->getOperand(Op
);
706 const MachineOperand
&MO2
= MI
->getOperand(Op
+1);
707 O
<< "[" << getRegisterName(MO1
.getReg());
708 if (unsigned ImmOffs
= MO2
.getImm())
709 O
<< ", #" << ImmOffs
<< " * 4";
713 //===--------------------------------------------------------------------===//
715 // Constant shifts t2_so_reg is a 2-operand unit corresponding to the Thumb2
716 // register with shift forms.
718 // REG IMM, SH_OPC - e.g. R5, LSL #3
719 void ARMAsmPrinter::printT2SOOperand(const MachineInstr
*MI
, int OpNum
) {
720 const MachineOperand
&MO1
= MI
->getOperand(OpNum
);
721 const MachineOperand
&MO2
= MI
->getOperand(OpNum
+1);
723 unsigned Reg
= MO1
.getReg();
724 assert(TargetRegisterInfo::isPhysicalRegister(Reg
));
725 O
<< getRegisterName(Reg
);
727 // Print the shift opc.
729 << ARM_AM::getShiftOpcStr(ARM_AM::getSORegShOp(MO2
.getImm()))
732 assert(MO2
.isImm() && "Not a valid t2_so_reg value!");
733 O
<< "#" << ARM_AM::getSORegOffset(MO2
.getImm());
736 void ARMAsmPrinter::printT2AddrModeImm12Operand(const MachineInstr
*MI
,
738 const MachineOperand
&MO1
= MI
->getOperand(OpNum
);
739 const MachineOperand
&MO2
= MI
->getOperand(OpNum
+1);
741 O
<< "[" << getRegisterName(MO1
.getReg());
743 unsigned OffImm
= MO2
.getImm();
744 if (OffImm
) // Don't print +0.
745 O
<< ", #+" << OffImm
;
749 void ARMAsmPrinter::printT2AddrModeImm8Operand(const MachineInstr
*MI
,
751 const MachineOperand
&MO1
= MI
->getOperand(OpNum
);
752 const MachineOperand
&MO2
= MI
->getOperand(OpNum
+1);
754 O
<< "[" << getRegisterName(MO1
.getReg());
756 int32_t OffImm
= (int32_t)MO2
.getImm();
759 O
<< ", #-" << -OffImm
;
761 O
<< ", #+" << OffImm
;
765 void ARMAsmPrinter::printT2AddrModeImm8s4Operand(const MachineInstr
*MI
,
767 const MachineOperand
&MO1
= MI
->getOperand(OpNum
);
768 const MachineOperand
&MO2
= MI
->getOperand(OpNum
+1);
770 O
<< "[" << getRegisterName(MO1
.getReg());
772 int32_t OffImm
= (int32_t)MO2
.getImm() / 4;
775 O
<< ", #-" << -OffImm
<< " * 4";
777 O
<< ", #+" << OffImm
<< " * 4";
781 void ARMAsmPrinter::printT2AddrModeImm8OffsetOperand(const MachineInstr
*MI
,
783 const MachineOperand
&MO1
= MI
->getOperand(OpNum
);
784 int32_t OffImm
= (int32_t)MO1
.getImm();
787 O
<< "#-" << -OffImm
;
792 void ARMAsmPrinter::printT2AddrModeSoRegOperand(const MachineInstr
*MI
,
794 const MachineOperand
&MO1
= MI
->getOperand(OpNum
);
795 const MachineOperand
&MO2
= MI
->getOperand(OpNum
+1);
796 const MachineOperand
&MO3
= MI
->getOperand(OpNum
+2);
798 O
<< "[" << getRegisterName(MO1
.getReg());
800 assert(MO2
.getReg() && "Invalid so_reg load / store address!");
801 O
<< ", " << getRegisterName(MO2
.getReg());
803 unsigned ShAmt
= MO3
.getImm();
805 assert(ShAmt
<= 3 && "Not a valid Thumb2 addressing mode!");
806 O
<< ", lsl #" << ShAmt
;
812 //===--------------------------------------------------------------------===//
814 void ARMAsmPrinter::printPredicateOperand(const MachineInstr
*MI
, int OpNum
) {
815 ARMCC::CondCodes CC
= (ARMCC::CondCodes
)MI
->getOperand(OpNum
).getImm();
817 O
<< ARMCondCodeToString(CC
);
820 void ARMAsmPrinter::printSBitModifierOperand(const MachineInstr
*MI
, int OpNum
){
821 unsigned Reg
= MI
->getOperand(OpNum
).getReg();
823 assert(Reg
== ARM::CPSR
&& "Expect ARM CPSR register!");
828 void ARMAsmPrinter::printPCLabel(const MachineInstr
*MI
, int OpNum
) {
829 int Id
= (int)MI
->getOperand(OpNum
).getImm();
830 O
<< MAI
->getPrivateGlobalPrefix() << "PC" << Id
;
833 void ARMAsmPrinter::printRegisterList(const MachineInstr
*MI
, int OpNum
) {
835 for (unsigned i
= OpNum
, e
= MI
->getNumOperands(); i
!= e
; ++i
) {
836 if (MI
->getOperand(i
).isImplicit())
838 if ((int)i
!= OpNum
) O
<< ", ";
844 void ARMAsmPrinter::printCPInstOperand(const MachineInstr
*MI
, int OpNum
,
845 const char *Modifier
) {
846 assert(Modifier
&& "This operand only works with a modifier!");
847 // There are two aspects to a CONSTANTPOOL_ENTRY operand, the label and the
849 if (!strcmp(Modifier
, "label")) {
850 unsigned ID
= MI
->getOperand(OpNum
).getImm();
851 O
<< MAI
->getPrivateGlobalPrefix() << "CPI" << getFunctionNumber()
852 << '_' << ID
<< ":\n";
854 assert(!strcmp(Modifier
, "cpentry") && "Unknown modifier for CPE");
855 unsigned CPI
= MI
->getOperand(OpNum
).getIndex();
857 const MachineConstantPoolEntry
&MCPE
= MCP
->getConstants()[CPI
];
859 if (MCPE
.isMachineConstantPoolEntry()) {
860 EmitMachineConstantPoolValue(MCPE
.Val
.MachineCPVal
);
862 EmitGlobalConstant(MCPE
.Val
.ConstVal
);
867 void ARMAsmPrinter::printJTBlockOperand(const MachineInstr
*MI
, int OpNum
) {
868 assert(!Subtarget
->isThumb2() && "Thumb2 should use double-jump jumptables!");
870 const MachineOperand
&MO1
= MI
->getOperand(OpNum
);
871 const MachineOperand
&MO2
= MI
->getOperand(OpNum
+1); // Unique Id
872 unsigned JTI
= MO1
.getIndex();
873 O
<< MAI
->getPrivateGlobalPrefix() << "JTI" << getFunctionNumber()
874 << '_' << JTI
<< '_' << MO2
.getImm() << ":\n";
876 const char *JTEntryDirective
= MAI
->getData32bitsDirective();
878 const MachineFunction
*MF
= MI
->getParent()->getParent();
879 const MachineJumpTableInfo
*MJTI
= MF
->getJumpTableInfo();
880 const std::vector
<MachineJumpTableEntry
> &JT
= MJTI
->getJumpTables();
881 const std::vector
<MachineBasicBlock
*> &JTBBs
= JT
[JTI
].MBBs
;
882 bool UseSet
= MAI
->getSetDirective() && TM
.getRelocationModel() == Reloc::PIC_
;
883 SmallPtrSet
<MachineBasicBlock
*, 8> JTSets
;
884 for (unsigned i
= 0, e
= JTBBs
.size(); i
!= e
; ++i
) {
885 MachineBasicBlock
*MBB
= JTBBs
[i
];
886 bool isNew
= JTSets
.insert(MBB
);
889 printPICJumpTableSetLabel(JTI
, MO2
.getImm(), MBB
);
891 O
<< JTEntryDirective
<< ' ';
893 O
<< MAI
->getPrivateGlobalPrefix() << getFunctionNumber()
894 << '_' << JTI
<< '_' << MO2
.getImm()
895 << "_set_" << MBB
->getNumber();
896 else if (TM
.getRelocationModel() == Reloc::PIC_
) {
897 GetMBBSymbol(MBB
->getNumber())->print(O
, MAI
);
898 O
<< '-' << MAI
->getPrivateGlobalPrefix() << "JTI"
899 << getFunctionNumber() << '_' << JTI
<< '_' << MO2
.getImm();
901 GetMBBSymbol(MBB
->getNumber())->print(O
, MAI
);
908 void ARMAsmPrinter::printJT2BlockOperand(const MachineInstr
*MI
, int OpNum
) {
909 const MachineOperand
&MO1
= MI
->getOperand(OpNum
);
910 const MachineOperand
&MO2
= MI
->getOperand(OpNum
+1); // Unique Id
911 unsigned JTI
= MO1
.getIndex();
912 O
<< MAI
->getPrivateGlobalPrefix() << "JTI" << getFunctionNumber()
913 << '_' << JTI
<< '_' << MO2
.getImm() << ":\n";
915 const MachineFunction
*MF
= MI
->getParent()->getParent();
916 const MachineJumpTableInfo
*MJTI
= MF
->getJumpTableInfo();
917 const std::vector
<MachineJumpTableEntry
> &JT
= MJTI
->getJumpTables();
918 const std::vector
<MachineBasicBlock
*> &JTBBs
= JT
[JTI
].MBBs
;
919 bool ByteOffset
= false, HalfWordOffset
= false;
920 if (MI
->getOpcode() == ARM::t2TBB
)
922 else if (MI
->getOpcode() == ARM::t2TBH
)
923 HalfWordOffset
= true;
925 for (unsigned i
= 0, e
= JTBBs
.size(); i
!= e
; ++i
) {
926 MachineBasicBlock
*MBB
= JTBBs
[i
];
928 O
<< MAI
->getData8bitsDirective();
929 else if (HalfWordOffset
)
930 O
<< MAI
->getData16bitsDirective();
931 if (ByteOffset
|| HalfWordOffset
) {
933 GetMBBSymbol(MBB
->getNumber())->print(O
, MAI
);
934 O
<< "-" << MAI
->getPrivateGlobalPrefix() << "JTI" << getFunctionNumber()
935 << '_' << JTI
<< '_' << MO2
.getImm() << ")/2";
938 GetMBBSymbol(MBB
->getNumber())->print(O
, MAI
);
944 // Make sure the instruction that follows TBB is 2-byte aligned.
945 // FIXME: Constant island pass should insert an "ALIGN" instruction instead.
946 if (ByteOffset
&& (JTBBs
.size() & 1)) {
952 void ARMAsmPrinter::printTBAddrMode(const MachineInstr
*MI
, int OpNum
) {
953 O
<< "[pc, " << getRegisterName(MI
->getOperand(OpNum
).getReg());
954 if (MI
->getOpcode() == ARM::t2TBH
)
959 void ARMAsmPrinter::printNoHashImmediate(const MachineInstr
*MI
, int OpNum
) {
960 O
<< MI
->getOperand(OpNum
).getImm();
963 bool ARMAsmPrinter::PrintAsmOperand(const MachineInstr
*MI
, unsigned OpNum
,
964 unsigned AsmVariant
, const char *ExtraCode
){
965 // Does this asm operand have a single letter operand modifier?
966 if (ExtraCode
&& ExtraCode
[0]) {
967 if (ExtraCode
[1] != 0) return true; // Unknown modifier.
969 switch (ExtraCode
[0]) {
970 default: return true; // Unknown modifier.
971 case 'a': // Print as a memory address.
972 if (MI
->getOperand(OpNum
).isReg()) {
973 O
<< "[" << getRegisterName(MI
->getOperand(OpNum
).getReg()) << "]";
977 case 'c': // Don't print "#" before an immediate operand.
978 if (!MI
->getOperand(OpNum
).isImm())
980 printNoHashImmediate(MI
, OpNum
);
982 case 'P': // Print a VFP double precision register.
983 printOperand(MI
, OpNum
);
986 if (TM
.getTargetData()->isLittleEndian())
990 if (TM
.getTargetData()->isBigEndian())
993 case 'H': // Write second word of DI / DF reference.
994 // Verify that this operand has two consecutive registers.
995 if (!MI
->getOperand(OpNum
).isReg() ||
996 OpNum
+1 == MI
->getNumOperands() ||
997 !MI
->getOperand(OpNum
+1).isReg())
999 ++OpNum
; // Return the high-part.
1003 printOperand(MI
, OpNum
);
1007 bool ARMAsmPrinter::PrintAsmMemoryOperand(const MachineInstr
*MI
,
1008 unsigned OpNum
, unsigned AsmVariant
,
1009 const char *ExtraCode
) {
1010 if (ExtraCode
&& ExtraCode
[0])
1011 return true; // Unknown modifier.
1012 printAddrMode2Operand(MI
, OpNum
);
1016 void ARMAsmPrinter::printMachineInstruction(const MachineInstr
*MI
) {
1019 int Opc
= MI
->getOpcode();
1021 case ARM::CONSTPOOL_ENTRY
:
1022 if (!InCPMode
&& AFI
->isThumbFunction()) {
1028 if (InCPMode
&& AFI
->isThumbFunction())
1032 // Call the autogenerated instruction printer routines.
1033 processDebugLoc(MI
->getDebugLoc());
1034 printInstruction(MI
);
1035 if (VerboseAsm
&& !MI
->getDebugLoc().isUnknown())
1040 bool ARMAsmPrinter::doInitialization(Module
&M
) {
1042 bool Result
= AsmPrinter::doInitialization(M
);
1043 DW
= getAnalysisIfAvailable
<DwarfWriter
>();
1045 // Use unified assembler syntax mode for Thumb.
1046 if (Subtarget
->isThumb())
1047 O
<< "\t.syntax unified\n";
1049 // Emit ARM Build Attributes
1050 if (Subtarget
->isTargetELF()) {
1052 std::string CPUString
= Subtarget
->getCPUString();
1053 if (CPUString
!= "generic")
1054 O
<< "\t.cpu " << CPUString
<< '\n';
1056 // FIXME: Emit FPU type
1057 if (Subtarget
->hasVFP2())
1058 O
<< "\t.eabi_attribute " << ARMBuildAttrs::VFP_arch
<< ", 2\n";
1060 // Signal various FP modes.
1062 O
<< "\t.eabi_attribute " << ARMBuildAttrs::ABI_FP_denormal
<< ", 1\n"
1063 << "\t.eabi_attribute " << ARMBuildAttrs::ABI_FP_exceptions
<< ", 1\n";
1065 if (FiniteOnlyFPMath())
1066 O
<< "\t.eabi_attribute " << ARMBuildAttrs::ABI_FP_number_model
<< ", 1\n";
1068 O
<< "\t.eabi_attribute " << ARMBuildAttrs::ABI_FP_number_model
<< ", 3\n";
1070 // 8-bytes alignment stuff.
1071 O
<< "\t.eabi_attribute " << ARMBuildAttrs::ABI_align8_needed
<< ", 1\n"
1072 << "\t.eabi_attribute " << ARMBuildAttrs::ABI_align8_preserved
<< ", 1\n";
1074 // Hard float. Use both S and D registers and conform to AAPCS-VFP.
1075 if (Subtarget
->isAAPCS_ABI() && FloatABIType
== FloatABI::Hard
)
1076 O
<< "\t.eabi_attribute " << ARMBuildAttrs::ABI_HardFP_use
<< ", 3\n"
1077 << "\t.eabi_attribute " << ARMBuildAttrs::ABI_VFP_args
<< ", 1\n";
1079 // FIXME: Should we signal R9 usage?
1085 void ARMAsmPrinter::PrintGlobalVariable(const GlobalVariable
* GVar
) {
1086 const TargetData
*TD
= TM
.getTargetData();
1088 if (!GVar
->hasInitializer()) // External global require no code
1091 // Check to see if this is a special global used by LLVM, if so, emit it.
1093 if (EmitSpecialLLVMGlobal(GVar
)) {
1094 if (Subtarget
->isTargetDarwin() &&
1095 TM
.getRelocationModel() == Reloc::Static
) {
1096 if (GVar
->getName() == "llvm.global_ctors")
1097 O
<< ".reference .constructors_used\n";
1098 else if (GVar
->getName() == "llvm.global_dtors")
1099 O
<< ".reference .destructors_used\n";
1104 std::string name
= Mang
->getMangledName(GVar
);
1105 Constant
*C
= GVar
->getInitializer();
1106 const Type
*Type
= C
->getType();
1107 unsigned Size
= TD
->getTypeAllocSize(Type
);
1108 unsigned Align
= TD
->getPreferredAlignmentLog(GVar
);
1109 bool isDarwin
= Subtarget
->isTargetDarwin();
1111 printVisibility(name
, GVar
->getVisibility());
1113 if (Subtarget
->isTargetELF())
1114 O
<< "\t.type " << name
<< ",%object\n";
1116 const MCSection
*TheSection
=
1117 getObjFileLowering().SectionForGlobal(GVar
, Mang
, TM
);
1118 OutStreamer
.SwitchSection(TheSection
);
1120 // FIXME: get this stuff from section kind flags.
1121 if (C
->isNullValue() && !GVar
->hasSection() && !GVar
->isThreadLocal() &&
1122 // Don't put things that should go in the cstring section into "comm".
1123 !TheSection
->getKind().isMergeableCString()) {
1124 if (GVar
->hasExternalLinkage()) {
1125 if (const char *Directive
= MAI
->getZeroFillDirective()) {
1126 O
<< "\t.globl\t" << name
<< "\n";
1127 O
<< Directive
<< "__DATA, __common, " << name
<< ", "
1128 << Size
<< ", " << Align
<< "\n";
1133 if (GVar
->hasLocalLinkage() || GVar
->isWeakForLinker()) {
1134 if (Size
== 0) Size
= 1; // .comm Foo, 0 is undefined, avoid it.
1137 if (GVar
->hasLocalLinkage()) {
1138 O
<< MAI
->getLCOMMDirective() << name
<< "," << Size
1140 } else if (GVar
->hasCommonLinkage()) {
1141 O
<< MAI
->getCOMMDirective() << name
<< "," << Size
1144 OutStreamer
.SwitchSection(TheSection
);
1145 O
<< "\t.globl " << name
<< '\n'
1146 << MAI
->getWeakDefDirective() << name
<< '\n';
1147 EmitAlignment(Align
, GVar
);
1150 O
<< "\t\t\t\t" << MAI
->getCommentString() << ' ';
1151 WriteAsOperand(O
, GVar
, /*PrintType=*/false, GVar
->getParent());
1154 EmitGlobalConstant(C
);
1157 } else if (MAI
->getLCOMMDirective() != NULL
) {
1158 if (GVar
->hasLocalLinkage()) {
1159 O
<< MAI
->getLCOMMDirective() << name
<< "," << Size
;
1161 O
<< MAI
->getCOMMDirective() << name
<< "," << Size
;
1162 if (MAI
->getCOMMDirectiveTakesAlignment())
1163 O
<< ',' << (MAI
->getAlignmentIsInBytes() ? (1 << Align
) : Align
);
1166 if (GVar
->hasLocalLinkage())
1167 O
<< "\t.local\t" << name
<< "\n";
1168 O
<< MAI
->getCOMMDirective() << name
<< "," << Size
;
1169 if (MAI
->getCOMMDirectiveTakesAlignment())
1170 O
<< "," << (MAI
->getAlignmentIsInBytes() ? (1 << Align
) : Align
);
1173 O
<< "\t\t" << MAI
->getCommentString() << " ";
1174 WriteAsOperand(O
, GVar
, /*PrintType=*/false, GVar
->getParent());
1181 switch (GVar
->getLinkage()) {
1182 case GlobalValue::CommonLinkage
:
1183 case GlobalValue::LinkOnceAnyLinkage
:
1184 case GlobalValue::LinkOnceODRLinkage
:
1185 case GlobalValue::WeakAnyLinkage
:
1186 case GlobalValue::WeakODRLinkage
:
1187 case GlobalValue::LinkerPrivateLinkage
:
1189 O
<< "\t.globl " << name
<< "\n"
1190 << "\t.weak_definition " << name
<< "\n";
1192 O
<< "\t.weak " << name
<< "\n";
1195 case GlobalValue::AppendingLinkage
:
1196 // FIXME: appending linkage variables should go into a section of
1197 // their name or something. For now, just emit them as external.
1198 case GlobalValue::ExternalLinkage
:
1199 O
<< "\t.globl " << name
<< "\n";
1201 case GlobalValue::PrivateLinkage
:
1202 case GlobalValue::InternalLinkage
:
1205 llvm_unreachable("Unknown linkage type!");
1208 EmitAlignment(Align
, GVar
);
1211 O
<< "\t\t\t\t" << MAI
->getCommentString() << " ";
1212 WriteAsOperand(O
, GVar
, /*PrintType=*/false, GVar
->getParent());
1215 if (MAI
->hasDotTypeDotSizeDirective())
1216 O
<< "\t.size " << name
<< ", " << Size
<< "\n";
1218 EmitGlobalConstant(C
);
1223 bool ARMAsmPrinter::doFinalization(Module
&M
) {
1224 if (Subtarget
->isTargetDarwin()) {
1225 // All darwin targets use mach-o.
1226 TargetLoweringObjectFileMachO
&TLOFMacho
=
1227 static_cast<TargetLoweringObjectFileMachO
&>(getObjFileLowering());
1231 // Output non-lazy-pointers for external and common global variables.
1232 if (!GVNonLazyPtrs
.empty()) {
1233 // Switch with ".non_lazy_symbol_pointer" directive.
1234 OutStreamer
.SwitchSection(TLOFMacho
.getNonLazySymbolPointerSection());
1236 for (StringMap
<std::string
>::iterator I
= GVNonLazyPtrs
.begin(),
1237 E
= GVNonLazyPtrs
.end(); I
!= E
; ++I
) {
1238 O
<< I
->second
<< ":\n";
1239 O
<< "\t.indirect_symbol " << I
->getKeyData() << "\n";
1240 O
<< "\t.long\t0\n";
1244 if (!HiddenGVNonLazyPtrs
.empty()) {
1245 OutStreamer
.SwitchSection(getObjFileLowering().getDataSection());
1247 for (StringMap
<std::string
>::iterator I
= HiddenGVNonLazyPtrs
.begin(),
1248 E
= HiddenGVNonLazyPtrs
.end(); I
!= E
; ++I
) {
1249 O
<< I
->second
<< ":\n";
1250 O
<< "\t.long " << I
->getKeyData() << "\n";
1254 // Funny Darwin hack: This flag tells the linker that no global symbols
1255 // contain code that falls through to other global symbols (e.g. the obvious
1256 // implementation of multiple entry points). If this doesn't occur, the
1257 // linker can safely perform dead code stripping. Since LLVM never
1258 // generates code that does this, it is always safe to set.
1259 O
<< "\t.subsections_via_symbols\n";
1262 return AsmPrinter::doFinalization(M
);
1265 // Force static initialization.
1266 extern "C" void LLVMInitializeARMAsmPrinter() {
1267 RegisterAsmPrinter
<ARMAsmPrinter
> X(TheARMTarget
);
1268 RegisterAsmPrinter
<ARMAsmPrinter
> Y(TheThumbTarget
);