1 //===-- ARMAsmPrinter.cpp - ARM LLVM assembly writer ----------------------===//
3 // The LLVM Compiler Infrastructure
5 // This file was developed by the "Instituto Nokia de Tecnologia" and
6 // is distributed under the University of Illinois Open Source
7 // License. See LICENSE.TXT for details.
9 //===----------------------------------------------------------------------===//
11 // This file contains a printer that converts from our internal representation
12 // of machine-dependent LLVM code to GAS-format ARM assembly language.
14 //===----------------------------------------------------------------------===//
16 #define DEBUG_TYPE "asm-printer"
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/CodeGen/AsmPrinter.h"
25 #include "llvm/CodeGen/DwarfWriter.h"
26 #include "llvm/CodeGen/MachineModuleInfo.h"
27 #include "llvm/CodeGen/MachineFunctionPass.h"
28 #include "llvm/CodeGen/MachineJumpTableInfo.h"
29 #include "llvm/Target/TargetAsmInfo.h"
30 #include "llvm/Target/TargetData.h"
31 #include "llvm/Target/TargetMachine.h"
32 #include "llvm/Target/TargetOptions.h"
33 #include "llvm/ADT/Statistic.h"
34 #include "llvm/ADT/StringExtras.h"
35 #include "llvm/Support/Compiler.h"
36 #include "llvm/Support/Mangler.h"
37 #include "llvm/Support/MathExtras.h"
41 STATISTIC(EmittedInsts
, "Number of machine instrs printed");
44 struct VISIBILITY_HIDDEN ARMAsmPrinter
: public AsmPrinter
{
45 ARMAsmPrinter(std::ostream
&O
, TargetMachine
&TM
, const TargetAsmInfo
*T
)
46 : AsmPrinter(O
, TM
, T
), DW(O
, this, T
), AFI(NULL
), InCPMode(false) {
47 Subtarget
= &TM
.getSubtarget
<ARMSubtarget
>();
52 /// Subtarget - Keep a pointer to the ARMSubtarget around so that we can
53 /// make the right decision when printing asm code for different targets.
54 const ARMSubtarget
*Subtarget
;
56 /// AFI - Keep a pointer to ARMFunctionInfo for the current
60 /// We name each basic block in a Function with a unique number, so
61 /// that we can consistently refer to them later. This is cleared
62 /// at the beginning of each call to runOnMachineFunction().
64 typedef std::map
<const Value
*, unsigned> ValueMapTy
;
65 ValueMapTy NumberForBB
;
67 /// Keeps the set of GlobalValues that require non-lazy-pointers for
69 std::set
<std::string
> GVNonLazyPtrs
;
71 /// Keeps the set of external function GlobalAddresses that the asm
72 /// printer should generate stubs for.
73 std::set
<std::string
> FnStubs
;
75 /// True if asm printer is printing a series of CONSTPOOL_ENTRY.
78 virtual const char *getPassName() const {
79 return "ARM Assembly Printer";
82 void printOperand(const MachineInstr
*MI
, int opNum
,
83 const char *Modifier
= 0);
84 void printSOImmOperand(const MachineInstr
*MI
, int opNum
);
85 void printSOImm2PartOperand(const MachineInstr
*MI
, int opNum
);
86 void printSORegOperand(const MachineInstr
*MI
, int opNum
);
87 void printAddrMode2Operand(const MachineInstr
*MI
, int OpNo
);
88 void printAddrMode2OffsetOperand(const MachineInstr
*MI
, int OpNo
);
89 void printAddrMode3Operand(const MachineInstr
*MI
, int OpNo
);
90 void printAddrMode3OffsetOperand(const MachineInstr
*MI
, int OpNo
);
91 void printAddrMode4Operand(const MachineInstr
*MI
, int OpNo
,
92 const char *Modifier
= 0);
93 void printAddrMode5Operand(const MachineInstr
*MI
, int OpNo
,
94 const char *Modifier
= 0);
95 void printAddrModePCOperand(const MachineInstr
*MI
, int OpNo
,
96 const char *Modifier
= 0);
97 void printThumbAddrModeRROperand(const MachineInstr
*MI
, int OpNo
);
98 void printThumbAddrModeRI5Operand(const MachineInstr
*MI
, int OpNo
,
100 void printThumbAddrModeS1Operand(const MachineInstr
*MI
, int OpNo
);
101 void printThumbAddrModeS2Operand(const MachineInstr
*MI
, int OpNo
);
102 void printThumbAddrModeS4Operand(const MachineInstr
*MI
, int OpNo
);
103 void printThumbAddrModeSPOperand(const MachineInstr
*MI
, int OpNo
);
104 void printPredicateOperand(const MachineInstr
*MI
, int opNum
);
105 void printSBitModifierOperand(const MachineInstr
*MI
, int opNum
);
106 void printPCLabel(const MachineInstr
*MI
, int opNum
);
107 void printRegisterList(const MachineInstr
*MI
, int opNum
);
108 void printCPInstOperand(const MachineInstr
*MI
, int opNum
,
109 const char *Modifier
);
110 void printJTBlockOperand(const MachineInstr
*MI
, int opNum
);
112 virtual bool PrintAsmOperand(const MachineInstr
*MI
, unsigned OpNo
,
113 unsigned AsmVariant
, const char *ExtraCode
);
115 bool printInstruction(const MachineInstr
*MI
); // autogenerated.
116 void printMachineInstruction(const MachineInstr
*MI
);
117 bool runOnMachineFunction(MachineFunction
&F
);
118 bool doInitialization(Module
&M
);
119 bool doFinalization(Module
&M
);
121 virtual void EmitMachineConstantPoolValue(MachineConstantPoolValue
*MCPV
) {
122 printDataDirective(MCPV
->getType());
124 ARMConstantPoolValue
*ACPV
= (ARMConstantPoolValue
*)MCPV
;
125 GlobalValue
*GV
= ACPV
->getGV();
126 std::string Name
= GV
? Mang
->getValueName(GV
) : TAI
->getGlobalPrefix();
128 Name
+= ACPV
->getSymbol();
129 if (ACPV
->isNonLazyPointer()) {
130 GVNonLazyPtrs
.insert(Name
);
131 O
<< TAI
->getPrivateGlobalPrefix() << Name
<< "$non_lazy_ptr";
132 } else if (ACPV
->isStub()) {
133 FnStubs
.insert(Name
);
134 O
<< TAI
->getPrivateGlobalPrefix() << Name
<< "$stub";
137 if (ACPV
->hasModifier()) O
<< "(" << ACPV
->getModifier() << ")";
138 if (ACPV
->getPCAdjustment() != 0) {
139 O
<< "-(" << TAI
->getPrivateGlobalPrefix() << "PC"
140 << utostr(ACPV
->getLabelId())
141 << "+" << (unsigned)ACPV
->getPCAdjustment();
142 if (ACPV
->mustAddCurrentAddress())
148 // If the constant pool value is a extern weak symbol, remember to emit
149 // the weak reference.
150 if (GV
&& GV
->hasExternalWeakLinkage())
151 ExtWeakSymbols
.insert(GV
);
154 void getAnalysisUsage(AnalysisUsage
&AU
) const {
155 AU
.setPreservesAll();
156 AU
.addRequired
<MachineModuleInfo
>();
159 } // end of anonymous namespace
161 #include "ARMGenAsmWriter.inc"
163 /// createARMCodePrinterPass - Returns a pass that prints the ARM
164 /// assembly code for a MachineFunction to the given output stream,
165 /// using the given target machine description. This should work
166 /// regardless of whether the function is in SSA form.
168 FunctionPass
*llvm::createARMCodePrinterPass(std::ostream
&o
,
169 ARMTargetMachine
&tm
) {
170 return new ARMAsmPrinter(o
, tm
, tm
.getTargetAsmInfo());
173 /// runOnMachineFunction - This uses the printInstruction()
174 /// method to print assembly for each instruction.
176 bool ARMAsmPrinter::runOnMachineFunction(MachineFunction
&MF
) {
177 AFI
= MF
.getInfo
<ARMFunctionInfo
>();
179 DW
.SetModuleInfo(&getAnalysis
<MachineModuleInfo
>());
181 SetupMachineFunction(MF
);
184 // NOTE: we don't print out constant pools here, they are handled as
188 // Print out labels for the function.
189 const Function
*F
= MF
.getFunction();
190 switch (F
->getLinkage()) {
191 default: assert(0 && "Unknown linkage type!");
192 case Function::InternalLinkage
:
193 SwitchToTextSection("\t.text", F
);
195 case Function::ExternalLinkage
:
196 SwitchToTextSection("\t.text", F
);
197 O
<< "\t.globl\t" << CurrentFnName
<< "\n";
199 case Function::WeakLinkage
:
200 case Function::LinkOnceLinkage
:
201 if (Subtarget
->isTargetDarwin()) {
203 ".section __TEXT,__textcoal_nt,coalesced,pure_instructions", F
);
204 O
<< "\t.globl\t" << CurrentFnName
<< "\n";
205 O
<< "\t.weak_definition\t" << CurrentFnName
<< "\n";
207 O
<< TAI
->getWeakRefDirective() << CurrentFnName
<< "\n";
212 const char *VisibilityDirective
= NULL
;
213 if (F
->hasHiddenVisibility())
214 VisibilityDirective
= TAI
->getHiddenDirective();
215 else if (F
->hasProtectedVisibility())
216 VisibilityDirective
= TAI
->getProtectedDirective();
218 if (VisibilityDirective
)
219 O
<< VisibilityDirective
<< CurrentFnName
<< "\n";
221 if (AFI
->isThumbFunction()) {
222 EmitAlignment(1, F
, AFI
->getAlign());
223 O
<< "\t.code\t16\n";
224 O
<< "\t.thumb_func";
225 if (Subtarget
->isTargetDarwin())
226 O
<< "\t" << CurrentFnName
;
232 O
<< CurrentFnName
<< ":\n";
233 // Emit pre-function debug information.
234 DW
.BeginFunction(&MF
);
236 // Print out code for the function.
237 for (MachineFunction::const_iterator I
= MF
.begin(), E
= MF
.end();
239 // Print a label for the basic block.
240 if (I
!= MF
.begin()) {
241 printBasicBlockLabel(I
, true);
244 for (MachineBasicBlock::const_iterator II
= I
->begin(), E
= I
->end();
246 // Print the assembly for the instruction.
247 printMachineInstruction(II
);
251 if (TAI
->hasDotTypeDotSizeDirective())
252 O
<< "\t.size " << CurrentFnName
<< ", .-" << CurrentFnName
<< "\n";
254 // Emit post-function debug information.
260 void ARMAsmPrinter::printOperand(const MachineInstr
*MI
, int opNum
,
261 const char *Modifier
) {
262 const MachineOperand
&MO
= MI
->getOperand(opNum
);
263 switch (MO
.getType()) {
264 case MachineOperand::MO_Register
:
265 if (MRegisterInfo::isPhysicalRegister(MO
.getReg()))
266 O
<< TM
.getRegisterInfo()->get(MO
.getReg()).Name
;
268 assert(0 && "not implemented");
270 case MachineOperand::MO_Immediate
: {
271 if (!Modifier
|| strcmp(Modifier
, "no_hash") != 0)
274 O
<< (int)MO
.getImmedValue();
277 case MachineOperand::MO_MachineBasicBlock
:
278 printBasicBlockLabel(MO
.getMachineBasicBlock());
280 case MachineOperand::MO_GlobalAddress
: {
281 bool isCallOp
= Modifier
&& !strcmp(Modifier
, "call");
282 GlobalValue
*GV
= MO
.getGlobal();
283 std::string Name
= Mang
->getValueName(GV
);
284 bool isExt
= (GV
->isDeclaration() || GV
->hasWeakLinkage() ||
285 GV
->hasLinkOnceLinkage());
286 if (isExt
&& isCallOp
&& Subtarget
->isTargetDarwin() &&
287 TM
.getRelocationModel() != Reloc::Static
) {
288 O
<< TAI
->getPrivateGlobalPrefix() << Name
<< "$stub";
289 FnStubs
.insert(Name
);
293 if (MO
.getOffset() > 0)
294 O
<< '+' << MO
.getOffset();
295 else if (MO
.getOffset() < 0)
298 if (isCallOp
&& Subtarget
->isTargetELF() &&
299 TM
.getRelocationModel() == Reloc::PIC_
)
301 if (GV
->hasExternalWeakLinkage())
302 ExtWeakSymbols
.insert(GV
);
305 case MachineOperand::MO_ExternalSymbol
: {
306 bool isCallOp
= Modifier
&& !strcmp(Modifier
, "call");
307 std::string
Name(TAI
->getGlobalPrefix());
308 Name
+= MO
.getSymbolName();
309 if (isCallOp
&& Subtarget
->isTargetDarwin() &&
310 TM
.getRelocationModel() != Reloc::Static
) {
311 O
<< TAI
->getPrivateGlobalPrefix() << Name
<< "$stub";
312 FnStubs
.insert(Name
);
315 if (isCallOp
&& Subtarget
->isTargetELF() &&
316 TM
.getRelocationModel() == Reloc::PIC_
)
320 case MachineOperand::MO_ConstantPoolIndex
:
321 O
<< TAI
->getPrivateGlobalPrefix() << "CPI" << getFunctionNumber()
322 << '_' << MO
.getConstantPoolIndex();
324 case MachineOperand::MO_JumpTableIndex
:
325 O
<< TAI
->getPrivateGlobalPrefix() << "JTI" << getFunctionNumber()
326 << '_' << MO
.getJumpTableIndex();
329 O
<< "<unknown operand type>"; abort (); break;
333 static void printSOImm(std::ostream
&O
, int64_t V
, const TargetAsmInfo
*TAI
) {
334 assert(V
< (1 << 12) && "Not a valid so_imm value!");
335 unsigned Imm
= ARM_AM::getSOImmValImm(V
);
336 unsigned Rot
= ARM_AM::getSOImmValRot(V
);
338 // Print low-level immediate formation info, per
339 // A5.1.3: "Data-processing operands - Immediate".
341 O
<< "#" << Imm
<< ", " << Rot
;
342 // Pretty printed version.
343 O
<< ' ' << TAI
->getCommentString() << ' ' << (int)ARM_AM::rotr32(Imm
, Rot
);
349 /// printSOImmOperand - SOImm is 4-bit rotate amount in bits 8-11 with 8-bit
350 /// immediate in bits 0-7.
351 void ARMAsmPrinter::printSOImmOperand(const MachineInstr
*MI
, int OpNum
) {
352 const MachineOperand
&MO
= MI
->getOperand(OpNum
);
353 assert(MO
.isImmediate() && "Not a valid so_imm value!");
354 printSOImm(O
, MO
.getImmedValue(), TAI
);
357 /// printSOImm2PartOperand - SOImm is broken into two pieces using a mov
358 /// followed by a or to materialize.
359 void ARMAsmPrinter::printSOImm2PartOperand(const MachineInstr
*MI
, int OpNum
) {
360 const MachineOperand
&MO
= MI
->getOperand(OpNum
);
361 assert(MO
.isImmediate() && "Not a valid so_imm value!");
362 unsigned V1
= ARM_AM::getSOImmTwoPartFirst(MO
.getImmedValue());
363 unsigned V2
= ARM_AM::getSOImmTwoPartSecond(MO
.getImmedValue());
364 printSOImm(O
, ARM_AM::getSOImmVal(V1
), TAI
);
366 printPredicateOperand(MI
, 2);
372 printSOImm(O
, ARM_AM::getSOImmVal(V2
), TAI
);
375 // so_reg is a 4-operand unit corresponding to register forms of the A5.1
376 // "Addressing Mode 1 - Data-processing operands" forms. This includes:
378 // REG REG 0,SH_OPC - e.g. R5, ROR R3
379 // REG 0 IMM,SH_OPC - e.g. R5, LSL #3
380 void ARMAsmPrinter::printSORegOperand(const MachineInstr
*MI
, int Op
) {
381 const MachineOperand
&MO1
= MI
->getOperand(Op
);
382 const MachineOperand
&MO2
= MI
->getOperand(Op
+1);
383 const MachineOperand
&MO3
= MI
->getOperand(Op
+2);
385 assert(MRegisterInfo::isPhysicalRegister(MO1
.getReg()));
386 O
<< TM
.getRegisterInfo()->get(MO1
.getReg()).Name
;
388 // Print the shift opc.
390 << ARM_AM::getShiftOpcStr(ARM_AM::getSORegShOp(MO3
.getImmedValue()))
394 assert(MRegisterInfo::isPhysicalRegister(MO2
.getReg()));
395 O
<< TM
.getRegisterInfo()->get(MO2
.getReg()).Name
;
396 assert(ARM_AM::getSORegOffset(MO3
.getImm()) == 0);
398 O
<< "#" << ARM_AM::getSORegOffset(MO3
.getImm());
402 void ARMAsmPrinter::printAddrMode2Operand(const MachineInstr
*MI
, int Op
) {
403 const MachineOperand
&MO1
= MI
->getOperand(Op
);
404 const MachineOperand
&MO2
= MI
->getOperand(Op
+1);
405 const MachineOperand
&MO3
= MI
->getOperand(Op
+2);
407 if (!MO1
.isRegister()) { // FIXME: This is for CP entries, but isn't right.
408 printOperand(MI
, Op
);
412 O
<< "[" << TM
.getRegisterInfo()->get(MO1
.getReg()).Name
;
415 if (ARM_AM::getAM2Offset(MO3
.getImm())) // Don't print +0.
417 << (char)ARM_AM::getAM2Op(MO3
.getImm())
418 << ARM_AM::getAM2Offset(MO3
.getImm());
424 << (char)ARM_AM::getAM2Op(MO3
.getImm())
425 << TM
.getRegisterInfo()->get(MO2
.getReg()).Name
;
427 if (unsigned ShImm
= ARM_AM::getAM2Offset(MO3
.getImm()))
429 << ARM_AM::getShiftOpcStr(ARM_AM::getAM2ShiftOpc(MO3
.getImmedValue()))
434 void ARMAsmPrinter::printAddrMode2OffsetOperand(const MachineInstr
*MI
, int Op
){
435 const MachineOperand
&MO1
= MI
->getOperand(Op
);
436 const MachineOperand
&MO2
= MI
->getOperand(Op
+1);
439 unsigned ImmOffs
= ARM_AM::getAM2Offset(MO2
.getImm());
440 assert(ImmOffs
&& "Malformed indexed load / store!");
442 << (char)ARM_AM::getAM2Op(MO2
.getImm())
447 O
<< (char)ARM_AM::getAM2Op(MO2
.getImm())
448 << TM
.getRegisterInfo()->get(MO1
.getReg()).Name
;
450 if (unsigned ShImm
= ARM_AM::getAM2Offset(MO2
.getImm()))
452 << ARM_AM::getShiftOpcStr(ARM_AM::getAM2ShiftOpc(MO2
.getImmedValue()))
456 void ARMAsmPrinter::printAddrMode3Operand(const MachineInstr
*MI
, int Op
) {
457 const MachineOperand
&MO1
= MI
->getOperand(Op
);
458 const MachineOperand
&MO2
= MI
->getOperand(Op
+1);
459 const MachineOperand
&MO3
= MI
->getOperand(Op
+2);
461 assert(MRegisterInfo::isPhysicalRegister(MO1
.getReg()));
462 O
<< "[" << TM
.getRegisterInfo()->get(MO1
.getReg()).Name
;
466 << (char)ARM_AM::getAM3Op(MO3
.getImm())
467 << TM
.getRegisterInfo()->get(MO2
.getReg()).Name
472 if (unsigned ImmOffs
= ARM_AM::getAM3Offset(MO3
.getImm()))
474 << (char)ARM_AM::getAM3Op(MO3
.getImm())
479 void ARMAsmPrinter::printAddrMode3OffsetOperand(const MachineInstr
*MI
, int Op
){
480 const MachineOperand
&MO1
= MI
->getOperand(Op
);
481 const MachineOperand
&MO2
= MI
->getOperand(Op
+1);
484 O
<< (char)ARM_AM::getAM3Op(MO2
.getImm())
485 << TM
.getRegisterInfo()->get(MO1
.getReg()).Name
;
489 unsigned ImmOffs
= ARM_AM::getAM3Offset(MO2
.getImm());
490 assert(ImmOffs
&& "Malformed indexed load / store!");
492 << (char)ARM_AM::getAM3Op(MO2
.getImm())
496 void ARMAsmPrinter::printAddrMode4Operand(const MachineInstr
*MI
, int Op
,
497 const char *Modifier
) {
498 const MachineOperand
&MO1
= MI
->getOperand(Op
);
499 const MachineOperand
&MO2
= MI
->getOperand(Op
+1);
500 ARM_AM::AMSubMode Mode
= ARM_AM::getAM4SubMode(MO2
.getImm());
501 if (Modifier
&& strcmp(Modifier
, "submode") == 0) {
502 if (MO1
.getReg() == ARM::SP
) {
503 bool isLDM
= (MI
->getOpcode() == ARM::LDM
||
504 MI
->getOpcode() == ARM::LDM_RET
);
505 O
<< ARM_AM::getAMSubModeAltStr(Mode
, isLDM
);
507 O
<< ARM_AM::getAMSubModeStr(Mode
);
509 printOperand(MI
, Op
);
510 if (ARM_AM::getAM4WBFlag(MO2
.getImm()))
515 void ARMAsmPrinter::printAddrMode5Operand(const MachineInstr
*MI
, int Op
,
516 const char *Modifier
) {
517 const MachineOperand
&MO1
= MI
->getOperand(Op
);
518 const MachineOperand
&MO2
= MI
->getOperand(Op
+1);
520 if (!MO1
.isRegister()) { // FIXME: This is for CP entries, but isn't right.
521 printOperand(MI
, Op
);
525 assert(MRegisterInfo::isPhysicalRegister(MO1
.getReg()));
527 if (Modifier
&& strcmp(Modifier
, "submode") == 0) {
528 ARM_AM::AMSubMode Mode
= ARM_AM::getAM5SubMode(MO2
.getImm());
529 if (MO1
.getReg() == ARM::SP
) {
530 bool isFLDM
= (MI
->getOpcode() == ARM::FLDMD
||
531 MI
->getOpcode() == ARM::FLDMS
);
532 O
<< ARM_AM::getAMSubModeAltStr(Mode
, isFLDM
);
534 O
<< ARM_AM::getAMSubModeStr(Mode
);
536 } else if (Modifier
&& strcmp(Modifier
, "base") == 0) {
537 // Used for FSTM{D|S} and LSTM{D|S} operations.
538 O
<< TM
.getRegisterInfo()->get(MO1
.getReg()).Name
;
539 if (ARM_AM::getAM5WBFlag(MO2
.getImm()))
544 O
<< "[" << TM
.getRegisterInfo()->get(MO1
.getReg()).Name
;
546 if (unsigned ImmOffs
= ARM_AM::getAM5Offset(MO2
.getImm())) {
548 << (char)ARM_AM::getAM5Op(MO2
.getImm())
554 void ARMAsmPrinter::printAddrModePCOperand(const MachineInstr
*MI
, int Op
,
555 const char *Modifier
) {
556 if (Modifier
&& strcmp(Modifier
, "label") == 0) {
557 printPCLabel(MI
, Op
+1);
561 const MachineOperand
&MO1
= MI
->getOperand(Op
);
562 assert(MRegisterInfo::isPhysicalRegister(MO1
.getReg()));
563 O
<< "[pc, +" << TM
.getRegisterInfo()->get(MO1
.getReg()).Name
<< "]";
567 ARMAsmPrinter::printThumbAddrModeRROperand(const MachineInstr
*MI
, int Op
) {
568 const MachineOperand
&MO1
= MI
->getOperand(Op
);
569 const MachineOperand
&MO2
= MI
->getOperand(Op
+1);
570 O
<< "[" << TM
.getRegisterInfo()->get(MO1
.getReg()).Name
;
571 O
<< ", " << TM
.getRegisterInfo()->get(MO2
.getReg()).Name
<< "]";
575 ARMAsmPrinter::printThumbAddrModeRI5Operand(const MachineInstr
*MI
, int Op
,
577 const MachineOperand
&MO1
= MI
->getOperand(Op
);
578 const MachineOperand
&MO2
= MI
->getOperand(Op
+1);
579 const MachineOperand
&MO3
= MI
->getOperand(Op
+2);
581 if (!MO1
.isRegister()) { // FIXME: This is for CP entries, but isn't right.
582 printOperand(MI
, Op
);
586 O
<< "[" << TM
.getRegisterInfo()->get(MO1
.getReg()).Name
;
588 O
<< ", " << TM
.getRegisterInfo()->get(MO3
.getReg()).Name
;
589 else if (unsigned ImmOffs
= MO2
.getImm()) {
590 O
<< ", #" << ImmOffs
;
598 ARMAsmPrinter::printThumbAddrModeS1Operand(const MachineInstr
*MI
, int Op
) {
599 printThumbAddrModeRI5Operand(MI
, Op
, 1);
602 ARMAsmPrinter::printThumbAddrModeS2Operand(const MachineInstr
*MI
, int Op
) {
603 printThumbAddrModeRI5Operand(MI
, Op
, 2);
606 ARMAsmPrinter::printThumbAddrModeS4Operand(const MachineInstr
*MI
, int Op
) {
607 printThumbAddrModeRI5Operand(MI
, Op
, 4);
610 void ARMAsmPrinter::printThumbAddrModeSPOperand(const MachineInstr
*MI
,int Op
) {
611 const MachineOperand
&MO1
= MI
->getOperand(Op
);
612 const MachineOperand
&MO2
= MI
->getOperand(Op
+1);
613 O
<< "[" << TM
.getRegisterInfo()->get(MO1
.getReg()).Name
;
614 if (unsigned ImmOffs
= MO2
.getImm())
615 O
<< ", #" << ImmOffs
<< " * 4";
619 void ARMAsmPrinter::printPredicateOperand(const MachineInstr
*MI
, int opNum
) {
620 ARMCC::CondCodes CC
= (ARMCC::CondCodes
)MI
->getOperand(opNum
).getImmedValue();
622 O
<< ARMCondCodeToString(CC
);
625 void ARMAsmPrinter::printSBitModifierOperand(const MachineInstr
*MI
, int opNum
){
626 unsigned Reg
= MI
->getOperand(opNum
).getReg();
628 assert(Reg
== ARM::CPSR
&& "Expect ARM CPSR register!");
633 void ARMAsmPrinter::printPCLabel(const MachineInstr
*MI
, int opNum
) {
634 int Id
= (int)MI
->getOperand(opNum
).getImmedValue();
635 O
<< TAI
->getPrivateGlobalPrefix() << "PC" << Id
;
638 void ARMAsmPrinter::printRegisterList(const MachineInstr
*MI
, int opNum
) {
640 for (unsigned i
= opNum
, e
= MI
->getNumOperands(); i
!= e
; ++i
) {
642 if (i
!= e
-1) O
<< ", ";
647 void ARMAsmPrinter::printCPInstOperand(const MachineInstr
*MI
, int OpNo
,
648 const char *Modifier
) {
649 assert(Modifier
&& "This operand only works with a modifier!");
650 // There are two aspects to a CONSTANTPOOL_ENTRY operand, the label and the
652 if (!strcmp(Modifier
, "label")) {
653 unsigned ID
= MI
->getOperand(OpNo
).getImm();
654 O
<< TAI
->getPrivateGlobalPrefix() << "CPI" << getFunctionNumber()
655 << '_' << ID
<< ":\n";
657 assert(!strcmp(Modifier
, "cpentry") && "Unknown modifier for CPE");
658 unsigned CPI
= MI
->getOperand(OpNo
).getConstantPoolIndex();
660 const MachineConstantPoolEntry
&MCPE
= // Chasing pointers is fun?
661 MI
->getParent()->getParent()->getConstantPool()->getConstants()[CPI
];
663 if (MCPE
.isMachineConstantPoolEntry())
664 EmitMachineConstantPoolValue(MCPE
.Val
.MachineCPVal
);
666 EmitGlobalConstant(MCPE
.Val
.ConstVal
);
667 // remember to emit the weak reference
668 if (const GlobalValue
*GV
= dyn_cast
<GlobalValue
>(MCPE
.Val
.ConstVal
))
669 if (GV
->hasExternalWeakLinkage())
670 ExtWeakSymbols
.insert(GV
);
675 void ARMAsmPrinter::printJTBlockOperand(const MachineInstr
*MI
, int OpNo
) {
676 const MachineOperand
&MO1
= MI
->getOperand(OpNo
);
677 const MachineOperand
&MO2
= MI
->getOperand(OpNo
+1); // Unique Id
678 unsigned JTI
= MO1
.getJumpTableIndex();
679 O
<< TAI
->getPrivateGlobalPrefix() << "JTI" << getFunctionNumber()
680 << '_' << JTI
<< '_' << MO2
.getImmedValue() << ":\n";
682 const char *JTEntryDirective
= TAI
->getJumpTableDirective();
683 if (!JTEntryDirective
)
684 JTEntryDirective
= TAI
->getData32bitsDirective();
686 const MachineFunction
*MF
= MI
->getParent()->getParent();
687 MachineJumpTableInfo
*MJTI
= MF
->getJumpTableInfo();
688 const std::vector
<MachineJumpTableEntry
> &JT
= MJTI
->getJumpTables();
689 const std::vector
<MachineBasicBlock
*> &JTBBs
= JT
[JTI
].MBBs
;
690 bool UseSet
= TAI
->getSetDirective() && TM
.getRelocationModel() == Reloc::PIC_
;
691 std::set
<MachineBasicBlock
*> JTSets
;
692 for (unsigned i
= 0, e
= JTBBs
.size(); i
!= e
; ++i
) {
693 MachineBasicBlock
*MBB
= JTBBs
[i
];
694 if (UseSet
&& JTSets
.insert(MBB
).second
)
695 printSetLabel(JTI
, MO2
.getImmedValue(), MBB
);
697 O
<< JTEntryDirective
<< ' ';
699 O
<< TAI
->getPrivateGlobalPrefix() << getFunctionNumber()
700 << '_' << JTI
<< '_' << MO2
.getImmedValue()
701 << "_set_" << MBB
->getNumber();
702 else if (TM
.getRelocationModel() == Reloc::PIC_
) {
703 printBasicBlockLabel(MBB
, false, false);
704 // If the arch uses custom Jump Table directives, don't calc relative to JT
705 if (!TAI
->getJumpTableDirective())
706 O
<< '-' << TAI
->getPrivateGlobalPrefix() << "JTI"
707 << getFunctionNumber() << '_' << JTI
<< '_' << MO2
.getImmedValue();
709 printBasicBlockLabel(MBB
, false, false);
716 bool ARMAsmPrinter::PrintAsmOperand(const MachineInstr
*MI
, unsigned OpNo
,
717 unsigned AsmVariant
, const char *ExtraCode
){
718 // Does this asm operand have a single letter operand modifier?
719 if (ExtraCode
&& ExtraCode
[0]) {
720 if (ExtraCode
[1] != 0) return true; // Unknown modifier.
722 switch (ExtraCode
[0]) {
723 default: return true; // Unknown modifier.
724 case 'c': // Don't print "$" before a global var name or constant.
725 case 'P': // Print a VFP double precision register.
726 printOperand(MI
, OpNo
);
729 if (TM
.getTargetData()->isLittleEndian())
733 if (TM
.getTargetData()->isBigEndian())
736 case 'H': // Write second word of DI / DF reference.
737 // Verify that this operand has two consecutive registers.
738 if (!MI
->getOperand(OpNo
).isRegister() ||
739 OpNo
+1 == MI
->getNumOperands() ||
740 !MI
->getOperand(OpNo
+1).isRegister())
742 ++OpNo
; // Return the high-part.
746 printOperand(MI
, OpNo
);
750 void ARMAsmPrinter::printMachineInstruction(const MachineInstr
*MI
) {
753 int Opc
= MI
->getOpcode();
755 case ARM::CONSTPOOL_ENTRY
:
756 if (!InCPMode
&& AFI
->isThumbFunction()) {
762 if (InCPMode
&& AFI
->isThumbFunction())
784 // Call the autogenerated instruction printer routines.
785 printInstruction(MI
);
788 bool ARMAsmPrinter::doInitialization(Module
&M
) {
789 // Emit initial debug information.
792 bool Result
= AsmPrinter::doInitialization(M
);
794 // Darwin wants symbols to be quoted if they have complex names.
795 if (Subtarget
->isTargetDarwin())
796 Mang
->setUseQuotes(true);
801 bool ARMAsmPrinter::doFinalization(Module
&M
) {
802 const TargetData
*TD
= TM
.getTargetData();
804 for (Module::const_global_iterator I
= M
.global_begin(), E
= M
.global_end();
806 if (!I
->hasInitializer()) // External global require no code
809 if (EmitSpecialLLVMGlobal(I
)) {
810 if (Subtarget
->isTargetDarwin() &&
811 TM
.getRelocationModel() == Reloc::Static
) {
812 if (I
->getName() == "llvm.global_ctors")
813 O
<< ".reference .constructors_used\n";
814 else if (I
->getName() == "llvm.global_dtors")
815 O
<< ".reference .destructors_used\n";
820 std::string name
= Mang
->getValueName(I
);
821 Constant
*C
= I
->getInitializer();
822 const Type
*Type
= C
->getType();
823 unsigned Size
= TD
->getTypeSize(Type
);
824 unsigned Align
= TD
->getPreferredAlignmentLog(I
);
826 const char *VisibilityDirective
= NULL
;
827 if (I
->hasHiddenVisibility())
828 VisibilityDirective
= TAI
->getHiddenDirective();
829 else if (I
->hasProtectedVisibility())
830 VisibilityDirective
= TAI
->getProtectedDirective();
832 if (VisibilityDirective
)
833 O
<< VisibilityDirective
<< name
<< "\n";
835 if (Subtarget
->isTargetELF())
836 O
<< "\t.type " << name
<< ",%object\n";
838 if (C
->isNullValue() && !I
->hasSection()) {
839 if (I
->hasExternalLinkage()) {
840 if (const char *Directive
= TAI
->getZeroFillDirective()) {
841 O
<< "\t.globl\t" << name
<< "\n";
842 O
<< Directive
<< "__DATA__, __common, " << name
<< ", "
843 << Size
<< ", " << Align
<< "\n";
848 if (I
->hasInternalLinkage() || I
->hasWeakLinkage() ||
849 I
->hasLinkOnceLinkage()) {
850 if (Size
== 0) Size
= 1; // .comm Foo, 0 is undefined, avoid it.
851 if (!NoZerosInBSS
&& TAI
->getBSSSection())
852 SwitchToDataSection(TAI
->getBSSSection(), I
);
854 SwitchToDataSection(TAI
->getDataSection(), I
);
855 if (TAI
->getLCOMMDirective() != NULL
) {
856 if (I
->hasInternalLinkage()) {
857 O
<< TAI
->getLCOMMDirective() << name
<< "," << Size
;
858 if (Subtarget
->isTargetDarwin())
861 O
<< TAI
->getCOMMDirective() << name
<< "," << Size
;
863 if (I
->hasInternalLinkage())
864 O
<< "\t.local\t" << name
<< "\n";
865 O
<< TAI
->getCOMMDirective() << name
<< "," << Size
;
866 if (TAI
->getCOMMDirectiveTakesAlignment())
867 O
<< "," << (TAI
->getAlignmentIsInBytes() ? (1 << Align
) : Align
);
869 O
<< "\t\t" << TAI
->getCommentString() << " " << I
->getName() << "\n";
874 switch (I
->getLinkage()) {
875 case GlobalValue::LinkOnceLinkage
:
876 case GlobalValue::WeakLinkage
:
877 if (Subtarget
->isTargetDarwin()) {
878 O
<< "\t.globl " << name
<< "\n"
879 << "\t.weak_definition " << name
<< "\n";
880 SwitchToDataSection("\t.section __DATA,__const_coal,coalesced", I
);
882 std::string
SectionName("\t.section\t.llvm.linkonce.d." +
884 ",\"aw\",%progbits");
885 SwitchToDataSection(SectionName
.c_str(), I
);
886 O
<< "\t.weak " << name
<< "\n";
889 case GlobalValue::AppendingLinkage
:
890 // FIXME: appending linkage variables should go into a section of
891 // their name or something. For now, just emit them as external.
892 case GlobalValue::ExternalLinkage
:
893 O
<< "\t.globl " << name
<< "\n";
895 case GlobalValue::InternalLinkage
: {
896 if (I
->isConstant()) {
897 const ConstantArray
*CVA
= dyn_cast
<ConstantArray
>(C
);
898 if (TAI
->getCStringSection() && CVA
&& CVA
->isCString()) {
899 SwitchToDataSection(TAI
->getCStringSection(), I
);
903 // FIXME: special handling for ".ctors" & ".dtors" sections
904 if (I
->hasSection() &&
905 (I
->getSection() == ".ctors" ||
906 I
->getSection() == ".dtors")) {
907 assert(!Subtarget
->isTargetDarwin());
908 std::string SectionName
= ".section " + I
->getSection();
909 SectionName
+= ",\"aw\",%progbits";
910 SwitchToDataSection(SectionName
.c_str());
912 if (C
->isNullValue() && !NoZerosInBSS
&& TAI
->getBSSSection())
913 SwitchToDataSection(I
->isThreadLocal() ? TAI
->getTLSBSSSection() :
914 TAI
->getBSSSection(), I
);
915 else if (!I
->isConstant())
916 SwitchToDataSection(I
->isThreadLocal() ? TAI
->getTLSDataSection() :
917 TAI
->getDataSection(), I
);
918 else if (I
->isThreadLocal())
919 SwitchToDataSection(TAI
->getTLSDataSection());
922 bool HasReloc
= C
->ContainsRelocations();
924 Subtarget
->isTargetDarwin() &&
925 TM
.getRelocationModel() != Reloc::Static
)
926 SwitchToDataSection("\t.const_data\n");
927 else if (!HasReloc
&& Size
== 4 &&
928 TAI
->getFourByteConstantSection())
929 SwitchToDataSection(TAI
->getFourByteConstantSection(), I
);
930 else if (!HasReloc
&& Size
== 8 &&
931 TAI
->getEightByteConstantSection())
932 SwitchToDataSection(TAI
->getEightByteConstantSection(), I
);
933 else if (!HasReloc
&& Size
== 16 &&
934 TAI
->getSixteenByteConstantSection())
935 SwitchToDataSection(TAI
->getSixteenByteConstantSection(), I
);
936 else if (TAI
->getReadOnlySection())
937 SwitchToDataSection(TAI
->getReadOnlySection(), I
);
939 SwitchToDataSection(TAI
->getDataSection(), I
);
946 assert(0 && "Unknown linkage type!");
950 EmitAlignment(Align
, I
);
951 O
<< name
<< ":\t\t\t\t" << TAI
->getCommentString() << " " << I
->getName()
953 if (TAI
->hasDotTypeDotSizeDirective())
954 O
<< "\t.size " << name
<< ", " << Size
<< "\n";
955 // If the initializer is a extern weak symbol, remember to emit the weak
957 if (const GlobalValue
*GV
= dyn_cast
<GlobalValue
>(C
))
958 if (GV
->hasExternalWeakLinkage())
959 ExtWeakSymbols
.insert(GV
);
961 EmitGlobalConstant(C
);
965 if (Subtarget
->isTargetDarwin()) {
966 SwitchToDataSection("");
968 // Output stubs for dynamically-linked functions
970 for (std::set
<std::string
>::iterator i
= FnStubs
.begin(), e
= FnStubs
.end();
972 if (TM
.getRelocationModel() == Reloc::PIC_
)
973 SwitchToTextSection(".section __TEXT,__picsymbolstub4,symbol_stubs,"
976 SwitchToTextSection(".section __TEXT,__symbol_stub4,symbol_stubs,"
980 O
<< "\t.code\t32\n";
982 O
<< "L" << *i
<< "$stub:\n";
983 O
<< "\t.indirect_symbol " << *i
<< "\n";
984 O
<< "\tldr ip, L" << *i
<< "$slp\n";
985 if (TM
.getRelocationModel() == Reloc::PIC_
) {
986 O
<< "L" << *i
<< "$scv:\n";
987 O
<< "\tadd ip, pc, ip\n";
989 O
<< "\tldr pc, [ip, #0]\n";
990 O
<< "L" << *i
<< "$slp:\n";
991 if (TM
.getRelocationModel() == Reloc::PIC_
)
992 O
<< "\t.long\tL" << *i
<< "$lazy_ptr-(L" << *i
<< "$scv+8)\n";
994 O
<< "\t.long\tL" << *i
<< "$lazy_ptr\n";
995 SwitchToDataSection(".lazy_symbol_pointer", 0);
996 O
<< "L" << *i
<< "$lazy_ptr:\n";
997 O
<< "\t.indirect_symbol " << *i
<< "\n";
998 O
<< "\t.long\tdyld_stub_binding_helper\n";
1002 // Output non-lazy-pointers for external and common global variables.
1003 if (GVNonLazyPtrs
.begin() != GVNonLazyPtrs
.end())
1004 SwitchToDataSection(".non_lazy_symbol_pointer", 0);
1005 for (std::set
<std::string
>::iterator i
= GVNonLazyPtrs
.begin(),
1006 e
= GVNonLazyPtrs
.end(); i
!= e
; ++i
) {
1007 O
<< "L" << *i
<< "$non_lazy_ptr:\n";
1008 O
<< "\t.indirect_symbol " << *i
<< "\n";
1009 O
<< "\t.long\t0\n";
1012 // Emit initial debug information.
1015 // Funny Darwin hack: This flag tells the linker that no global symbols
1016 // contain code that falls through to other global symbols (e.g. the obvious
1017 // implementation of multiple entry points). If this doesn't occur, the
1018 // linker can safely perform dead code stripping. Since LLVM never
1019 // generates code that does this, it is always safe to set.
1020 O
<< "\t.subsections_via_symbols\n";
1022 // Emit final debug information for ELF.
1026 return AsmPrinter::doFinalization(M
);