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 printPCLabel(const MachineInstr
*MI
, int opNum
);
106 void printRegisterList(const MachineInstr
*MI
, int opNum
);
107 void printCPInstOperand(const MachineInstr
*MI
, int opNum
,
108 const char *Modifier
);
109 void printJTBlockOperand(const MachineInstr
*MI
, int opNum
);
111 virtual bool PrintAsmOperand(const MachineInstr
*MI
, unsigned OpNo
,
112 unsigned AsmVariant
, const char *ExtraCode
);
114 bool printInstruction(const MachineInstr
*MI
); // autogenerated.
115 void printMachineInstruction(const MachineInstr
*MI
);
116 bool runOnMachineFunction(MachineFunction
&F
);
117 bool doInitialization(Module
&M
);
118 bool doFinalization(Module
&M
);
120 virtual void EmitMachineConstantPoolValue(MachineConstantPoolValue
*MCPV
) {
121 printDataDirective(MCPV
->getType());
123 ARMConstantPoolValue
*ACPV
= (ARMConstantPoolValue
*)MCPV
;
124 GlobalValue
*GV
= ACPV
->getGV();
125 std::string Name
= GV
? Mang
->getValueName(GV
) : TAI
->getGlobalPrefix();
127 Name
+= ACPV
->getSymbol();
128 if (ACPV
->isNonLazyPointer()) {
129 GVNonLazyPtrs
.insert(Name
);
130 O
<< TAI
->getPrivateGlobalPrefix() << Name
<< "$non_lazy_ptr";
131 } else if (ACPV
->isStub()) {
132 FnStubs
.insert(Name
);
133 O
<< TAI
->getPrivateGlobalPrefix() << Name
<< "$stub";
136 if (ACPV
->hasModifier()) O
<< "(" << ACPV
->getModifier() << ")";
137 if (ACPV
->getPCAdjustment() != 0) {
138 O
<< "-(" << TAI
->getPrivateGlobalPrefix() << "PC"
139 << utostr(ACPV
->getLabelId())
140 << "+" << (unsigned)ACPV
->getPCAdjustment();
141 if (ACPV
->mustAddCurrentAddress())
147 // If the constant pool value is a extern weak symbol, remember to emit
148 // the weak reference.
149 if (GV
&& GV
->hasExternalWeakLinkage())
150 ExtWeakSymbols
.insert(GV
);
153 void getAnalysisUsage(AnalysisUsage
&AU
) const {
154 AU
.setPreservesAll();
155 AU
.addRequired
<MachineModuleInfo
>();
158 } // end of anonymous namespace
160 #include "ARMGenAsmWriter.inc"
162 /// createARMCodePrinterPass - Returns a pass that prints the ARM
163 /// assembly code for a MachineFunction to the given output stream,
164 /// using the given target machine description. This should work
165 /// regardless of whether the function is in SSA form.
167 FunctionPass
*llvm::createARMCodePrinterPass(std::ostream
&o
,
168 ARMTargetMachine
&tm
) {
169 return new ARMAsmPrinter(o
, tm
, tm
.getTargetAsmInfo());
172 /// runOnMachineFunction - This uses the printInstruction()
173 /// method to print assembly for each instruction.
175 bool ARMAsmPrinter::runOnMachineFunction(MachineFunction
&MF
) {
176 AFI
= MF
.getInfo
<ARMFunctionInfo
>();
178 DW
.SetModuleInfo(&getAnalysis
<MachineModuleInfo
>());
180 SetupMachineFunction(MF
);
183 // NOTE: we don't print out constant pools here, they are handled as
187 // Print out labels for the function.
188 const Function
*F
= MF
.getFunction();
189 switch (F
->getLinkage()) {
190 default: assert(0 && "Unknown linkage type!");
191 case Function::InternalLinkage
:
192 SwitchToTextSection("\t.text", F
);
194 case Function::ExternalLinkage
:
195 SwitchToTextSection("\t.text", F
);
196 O
<< "\t.globl\t" << CurrentFnName
<< "\n";
198 case Function::WeakLinkage
:
199 case Function::LinkOnceLinkage
:
200 if (Subtarget
->isTargetDarwin()) {
202 ".section __TEXT,__textcoal_nt,coalesced,pure_instructions", F
);
203 O
<< "\t.globl\t" << CurrentFnName
<< "\n";
204 O
<< "\t.weak_definition\t" << CurrentFnName
<< "\n";
206 O
<< TAI
->getWeakRefDirective() << CurrentFnName
<< "\n";
211 const char *VisibilityDirective
= NULL
;
212 if (F
->hasHiddenVisibility())
213 VisibilityDirective
= TAI
->getHiddenDirective();
214 else if (F
->hasProtectedVisibility())
215 VisibilityDirective
= TAI
->getProtectedDirective();
217 if (VisibilityDirective
)
218 O
<< VisibilityDirective
<< CurrentFnName
<< "\n";
220 if (AFI
->isThumbFunction()) {
221 EmitAlignment(1, F
, AFI
->getAlign());
222 O
<< "\t.code\t16\n";
223 O
<< "\t.thumb_func";
224 if (Subtarget
->isTargetDarwin())
225 O
<< "\t" << CurrentFnName
;
231 O
<< CurrentFnName
<< ":\n";
232 // Emit pre-function debug information.
233 DW
.BeginFunction(&MF
);
235 // Print out code for the function.
236 for (MachineFunction::const_iterator I
= MF
.begin(), E
= MF
.end();
238 // Print a label for the basic block.
239 if (I
!= MF
.begin()) {
240 printBasicBlockLabel(I
, true);
243 for (MachineBasicBlock::const_iterator II
= I
->begin(), E
= I
->end();
245 // Print the assembly for the instruction.
246 printMachineInstruction(II
);
250 if (TAI
->hasDotTypeDotSizeDirective())
251 O
<< "\t.size " << CurrentFnName
<< ", .-" << CurrentFnName
<< "\n";
253 // Emit post-function debug information.
259 void ARMAsmPrinter::printOperand(const MachineInstr
*MI
, int opNum
,
260 const char *Modifier
) {
261 const MachineOperand
&MO
= MI
->getOperand(opNum
);
262 switch (MO
.getType()) {
263 case MachineOperand::MO_Register
:
264 if (MRegisterInfo::isPhysicalRegister(MO
.getReg()))
265 O
<< TM
.getRegisterInfo()->get(MO
.getReg()).Name
;
267 assert(0 && "not implemented");
269 case MachineOperand::MO_Immediate
: {
270 if (!Modifier
|| strcmp(Modifier
, "no_hash") != 0)
273 O
<< (int)MO
.getImmedValue();
276 case MachineOperand::MO_MachineBasicBlock
:
277 printBasicBlockLabel(MO
.getMachineBasicBlock());
279 case MachineOperand::MO_GlobalAddress
: {
280 bool isCallOp
= Modifier
&& !strcmp(Modifier
, "call");
281 GlobalValue
*GV
= MO
.getGlobal();
282 std::string Name
= Mang
->getValueName(GV
);
283 bool isExt
= (GV
->isDeclaration() || GV
->hasWeakLinkage() ||
284 GV
->hasLinkOnceLinkage());
285 if (isExt
&& isCallOp
&& Subtarget
->isTargetDarwin() &&
286 TM
.getRelocationModel() != Reloc::Static
) {
287 O
<< TAI
->getPrivateGlobalPrefix() << Name
<< "$stub";
288 FnStubs
.insert(Name
);
292 if (MO
.getOffset() > 0)
293 O
<< '+' << MO
.getOffset();
294 else if (MO
.getOffset() < 0)
297 if (isCallOp
&& Subtarget
->isTargetELF() &&
298 TM
.getRelocationModel() == Reloc::PIC_
)
300 if (GV
->hasExternalWeakLinkage())
301 ExtWeakSymbols
.insert(GV
);
304 case MachineOperand::MO_ExternalSymbol
: {
305 bool isCallOp
= Modifier
&& !strcmp(Modifier
, "call");
306 std::string
Name(TAI
->getGlobalPrefix());
307 Name
+= MO
.getSymbolName();
308 if (isCallOp
&& Subtarget
->isTargetDarwin() &&
309 TM
.getRelocationModel() != Reloc::Static
) {
310 O
<< TAI
->getPrivateGlobalPrefix() << Name
<< "$stub";
311 FnStubs
.insert(Name
);
314 if (isCallOp
&& Subtarget
->isTargetELF() &&
315 TM
.getRelocationModel() == Reloc::PIC_
)
319 case MachineOperand::MO_ConstantPoolIndex
:
320 O
<< TAI
->getPrivateGlobalPrefix() << "CPI" << getFunctionNumber()
321 << '_' << MO
.getConstantPoolIndex();
323 case MachineOperand::MO_JumpTableIndex
:
324 O
<< TAI
->getPrivateGlobalPrefix() << "JTI" << getFunctionNumber()
325 << '_' << MO
.getJumpTableIndex();
328 O
<< "<unknown operand type>"; abort (); break;
332 static void printSOImm(std::ostream
&O
, int64_t V
, const TargetAsmInfo
*TAI
) {
333 assert(V
< (1 << 12) && "Not a valid so_imm value!");
334 unsigned Imm
= ARM_AM::getSOImmValImm(V
);
335 unsigned Rot
= ARM_AM::getSOImmValRot(V
);
337 // Print low-level immediate formation info, per
338 // A5.1.3: "Data-processing operands - Immediate".
340 O
<< "#" << Imm
<< ", " << Rot
;
341 // Pretty printed version.
342 O
<< ' ' << TAI
->getCommentString() << ' ' << (int)ARM_AM::rotr32(Imm
, Rot
);
348 /// printSOImmOperand - SOImm is 4-bit rotate amount in bits 8-11 with 8-bit
349 /// immediate in bits 0-7.
350 void ARMAsmPrinter::printSOImmOperand(const MachineInstr
*MI
, int OpNum
) {
351 const MachineOperand
&MO
= MI
->getOperand(OpNum
);
352 assert(MO
.isImmediate() && "Not a valid so_imm value!");
353 printSOImm(O
, MO
.getImmedValue(), TAI
);
356 /// printSOImm2PartOperand - SOImm is broken into two pieces using a mov
357 /// followed by a or to materialize.
358 void ARMAsmPrinter::printSOImm2PartOperand(const MachineInstr
*MI
, int OpNum
) {
359 const MachineOperand
&MO
= MI
->getOperand(OpNum
);
360 assert(MO
.isImmediate() && "Not a valid so_imm value!");
361 unsigned V1
= ARM_AM::getSOImmTwoPartFirst(MO
.getImmedValue());
362 unsigned V2
= ARM_AM::getSOImmTwoPartSecond(MO
.getImmedValue());
363 printSOImm(O
, ARM_AM::getSOImmVal(V1
), TAI
);
365 printPredicateOperand(MI
, 2);
371 printSOImm(O
, ARM_AM::getSOImmVal(V2
), TAI
);
374 // so_reg is a 4-operand unit corresponding to register forms of the A5.1
375 // "Addressing Mode 1 - Data-processing operands" forms. This includes:
377 // REG REG 0,SH_OPC - e.g. R5, ROR R3
378 // REG 0 IMM,SH_OPC - e.g. R5, LSL #3
379 void ARMAsmPrinter::printSORegOperand(const MachineInstr
*MI
, int Op
) {
380 const MachineOperand
&MO1
= MI
->getOperand(Op
);
381 const MachineOperand
&MO2
= MI
->getOperand(Op
+1);
382 const MachineOperand
&MO3
= MI
->getOperand(Op
+2);
384 assert(MRegisterInfo::isPhysicalRegister(MO1
.getReg()));
385 O
<< TM
.getRegisterInfo()->get(MO1
.getReg()).Name
;
387 // Print the shift opc.
389 << ARM_AM::getShiftOpcStr(ARM_AM::getSORegShOp(MO3
.getImmedValue()))
393 assert(MRegisterInfo::isPhysicalRegister(MO2
.getReg()));
394 O
<< TM
.getRegisterInfo()->get(MO2
.getReg()).Name
;
395 assert(ARM_AM::getSORegOffset(MO3
.getImm()) == 0);
397 O
<< "#" << ARM_AM::getSORegOffset(MO3
.getImm());
401 void ARMAsmPrinter::printAddrMode2Operand(const MachineInstr
*MI
, int Op
) {
402 const MachineOperand
&MO1
= MI
->getOperand(Op
);
403 const MachineOperand
&MO2
= MI
->getOperand(Op
+1);
404 const MachineOperand
&MO3
= MI
->getOperand(Op
+2);
406 if (!MO1
.isRegister()) { // FIXME: This is for CP entries, but isn't right.
407 printOperand(MI
, Op
);
411 O
<< "[" << TM
.getRegisterInfo()->get(MO1
.getReg()).Name
;
414 if (ARM_AM::getAM2Offset(MO3
.getImm())) // Don't print +0.
416 << (char)ARM_AM::getAM2Op(MO3
.getImm())
417 << ARM_AM::getAM2Offset(MO3
.getImm());
423 << (char)ARM_AM::getAM2Op(MO3
.getImm())
424 << TM
.getRegisterInfo()->get(MO2
.getReg()).Name
;
426 if (unsigned ShImm
= ARM_AM::getAM2Offset(MO3
.getImm()))
428 << ARM_AM::getShiftOpcStr(ARM_AM::getAM2ShiftOpc(MO3
.getImmedValue()))
433 void ARMAsmPrinter::printAddrMode2OffsetOperand(const MachineInstr
*MI
, int Op
){
434 const MachineOperand
&MO1
= MI
->getOperand(Op
);
435 const MachineOperand
&MO2
= MI
->getOperand(Op
+1);
438 unsigned ImmOffs
= ARM_AM::getAM2Offset(MO2
.getImm());
439 assert(ImmOffs
&& "Malformed indexed load / store!");
441 << (char)ARM_AM::getAM2Op(MO2
.getImm())
446 O
<< (char)ARM_AM::getAM2Op(MO2
.getImm())
447 << TM
.getRegisterInfo()->get(MO1
.getReg()).Name
;
449 if (unsigned ShImm
= ARM_AM::getAM2Offset(MO2
.getImm()))
451 << ARM_AM::getShiftOpcStr(ARM_AM::getAM2ShiftOpc(MO2
.getImmedValue()))
455 void ARMAsmPrinter::printAddrMode3Operand(const MachineInstr
*MI
, int Op
) {
456 const MachineOperand
&MO1
= MI
->getOperand(Op
);
457 const MachineOperand
&MO2
= MI
->getOperand(Op
+1);
458 const MachineOperand
&MO3
= MI
->getOperand(Op
+2);
460 assert(MRegisterInfo::isPhysicalRegister(MO1
.getReg()));
461 O
<< "[" << TM
.getRegisterInfo()->get(MO1
.getReg()).Name
;
465 << (char)ARM_AM::getAM3Op(MO3
.getImm())
466 << TM
.getRegisterInfo()->get(MO2
.getReg()).Name
471 if (unsigned ImmOffs
= ARM_AM::getAM3Offset(MO3
.getImm()))
473 << (char)ARM_AM::getAM3Op(MO3
.getImm())
478 void ARMAsmPrinter::printAddrMode3OffsetOperand(const MachineInstr
*MI
, int Op
){
479 const MachineOperand
&MO1
= MI
->getOperand(Op
);
480 const MachineOperand
&MO2
= MI
->getOperand(Op
+1);
483 O
<< (char)ARM_AM::getAM3Op(MO2
.getImm())
484 << TM
.getRegisterInfo()->get(MO1
.getReg()).Name
;
488 unsigned ImmOffs
= ARM_AM::getAM3Offset(MO2
.getImm());
489 assert(ImmOffs
&& "Malformed indexed load / store!");
491 << (char)ARM_AM::getAM3Op(MO2
.getImm())
495 void ARMAsmPrinter::printAddrMode4Operand(const MachineInstr
*MI
, int Op
,
496 const char *Modifier
) {
497 const MachineOperand
&MO1
= MI
->getOperand(Op
);
498 const MachineOperand
&MO2
= MI
->getOperand(Op
+1);
499 ARM_AM::AMSubMode Mode
= ARM_AM::getAM4SubMode(MO2
.getImm());
500 if (Modifier
&& strcmp(Modifier
, "submode") == 0) {
501 if (MO1
.getReg() == ARM::SP
) {
502 bool isLDM
= (MI
->getOpcode() == ARM::LDM
||
503 MI
->getOpcode() == ARM::LDM_RET
);
504 O
<< ARM_AM::getAMSubModeAltStr(Mode
, isLDM
);
506 O
<< ARM_AM::getAMSubModeStr(Mode
);
508 printOperand(MI
, Op
);
509 if (ARM_AM::getAM4WBFlag(MO2
.getImm()))
514 void ARMAsmPrinter::printAddrMode5Operand(const MachineInstr
*MI
, int Op
,
515 const char *Modifier
) {
516 const MachineOperand
&MO1
= MI
->getOperand(Op
);
517 const MachineOperand
&MO2
= MI
->getOperand(Op
+1);
519 if (!MO1
.isRegister()) { // FIXME: This is for CP entries, but isn't right.
520 printOperand(MI
, Op
);
524 assert(MRegisterInfo::isPhysicalRegister(MO1
.getReg()));
526 if (Modifier
&& strcmp(Modifier
, "submode") == 0) {
527 ARM_AM::AMSubMode Mode
= ARM_AM::getAM5SubMode(MO2
.getImm());
528 if (MO1
.getReg() == ARM::SP
) {
529 bool isFLDM
= (MI
->getOpcode() == ARM::FLDMD
||
530 MI
->getOpcode() == ARM::FLDMS
);
531 O
<< ARM_AM::getAMSubModeAltStr(Mode
, isFLDM
);
533 O
<< ARM_AM::getAMSubModeStr(Mode
);
535 } else if (Modifier
&& strcmp(Modifier
, "base") == 0) {
536 // Used for FSTM{D|S} and LSTM{D|S} operations.
537 O
<< TM
.getRegisterInfo()->get(MO1
.getReg()).Name
;
538 if (ARM_AM::getAM5WBFlag(MO2
.getImm()))
543 O
<< "[" << TM
.getRegisterInfo()->get(MO1
.getReg()).Name
;
545 if (unsigned ImmOffs
= ARM_AM::getAM5Offset(MO2
.getImm())) {
547 << (char)ARM_AM::getAM5Op(MO2
.getImm())
553 void ARMAsmPrinter::printAddrModePCOperand(const MachineInstr
*MI
, int Op
,
554 const char *Modifier
) {
555 if (Modifier
&& strcmp(Modifier
, "label") == 0) {
556 printPCLabel(MI
, Op
+1);
560 const MachineOperand
&MO1
= MI
->getOperand(Op
);
561 assert(MRegisterInfo::isPhysicalRegister(MO1
.getReg()));
562 O
<< "[pc, +" << TM
.getRegisterInfo()->get(MO1
.getReg()).Name
<< "]";
566 ARMAsmPrinter::printThumbAddrModeRROperand(const MachineInstr
*MI
, int Op
) {
567 const MachineOperand
&MO1
= MI
->getOperand(Op
);
568 const MachineOperand
&MO2
= MI
->getOperand(Op
+1);
569 O
<< "[" << TM
.getRegisterInfo()->get(MO1
.getReg()).Name
;
570 O
<< ", " << TM
.getRegisterInfo()->get(MO2
.getReg()).Name
<< "]";
574 ARMAsmPrinter::printThumbAddrModeRI5Operand(const MachineInstr
*MI
, int Op
,
576 const MachineOperand
&MO1
= MI
->getOperand(Op
);
577 const MachineOperand
&MO2
= MI
->getOperand(Op
+1);
578 const MachineOperand
&MO3
= MI
->getOperand(Op
+2);
580 if (!MO1
.isRegister()) { // FIXME: This is for CP entries, but isn't right.
581 printOperand(MI
, Op
);
585 O
<< "[" << TM
.getRegisterInfo()->get(MO1
.getReg()).Name
;
587 O
<< ", " << TM
.getRegisterInfo()->get(MO3
.getReg()).Name
;
588 else if (unsigned ImmOffs
= MO2
.getImm()) {
589 O
<< ", #" << ImmOffs
;
597 ARMAsmPrinter::printThumbAddrModeS1Operand(const MachineInstr
*MI
, int Op
) {
598 printThumbAddrModeRI5Operand(MI
, Op
, 1);
601 ARMAsmPrinter::printThumbAddrModeS2Operand(const MachineInstr
*MI
, int Op
) {
602 printThumbAddrModeRI5Operand(MI
, Op
, 2);
605 ARMAsmPrinter::printThumbAddrModeS4Operand(const MachineInstr
*MI
, int Op
) {
606 printThumbAddrModeRI5Operand(MI
, Op
, 4);
609 void ARMAsmPrinter::printThumbAddrModeSPOperand(const MachineInstr
*MI
,int Op
) {
610 const MachineOperand
&MO1
= MI
->getOperand(Op
);
611 const MachineOperand
&MO2
= MI
->getOperand(Op
+1);
612 O
<< "[" << TM
.getRegisterInfo()->get(MO1
.getReg()).Name
;
613 if (unsigned ImmOffs
= MO2
.getImm())
614 O
<< ", #" << ImmOffs
<< " * 4";
618 void ARMAsmPrinter::printPredicateOperand(const MachineInstr
*MI
, int opNum
) {
619 ARMCC::CondCodes CC
= (ARMCC::CondCodes
)MI
->getOperand(opNum
).getImmedValue();
621 O
<< ARMCondCodeToString(CC
);
624 void ARMAsmPrinter::printPCLabel(const MachineInstr
*MI
, int opNum
) {
625 int Id
= (int)MI
->getOperand(opNum
).getImmedValue();
626 O
<< TAI
->getPrivateGlobalPrefix() << "PC" << Id
;
629 void ARMAsmPrinter::printRegisterList(const MachineInstr
*MI
, int opNum
) {
631 for (unsigned i
= opNum
, e
= MI
->getNumOperands(); i
!= e
; ++i
) {
633 if (i
!= e
-1) O
<< ", ";
638 void ARMAsmPrinter::printCPInstOperand(const MachineInstr
*MI
, int OpNo
,
639 const char *Modifier
) {
640 assert(Modifier
&& "This operand only works with a modifier!");
641 // There are two aspects to a CONSTANTPOOL_ENTRY operand, the label and the
643 if (!strcmp(Modifier
, "label")) {
644 unsigned ID
= MI
->getOperand(OpNo
).getImm();
645 O
<< TAI
->getPrivateGlobalPrefix() << "CPI" << getFunctionNumber()
646 << '_' << ID
<< ":\n";
648 assert(!strcmp(Modifier
, "cpentry") && "Unknown modifier for CPE");
649 unsigned CPI
= MI
->getOperand(OpNo
).getConstantPoolIndex();
651 const MachineConstantPoolEntry
&MCPE
= // Chasing pointers is fun?
652 MI
->getParent()->getParent()->getConstantPool()->getConstants()[CPI
];
654 if (MCPE
.isMachineConstantPoolEntry())
655 EmitMachineConstantPoolValue(MCPE
.Val
.MachineCPVal
);
657 EmitGlobalConstant(MCPE
.Val
.ConstVal
);
658 // remember to emit the weak reference
659 if (const GlobalValue
*GV
= dyn_cast
<GlobalValue
>(MCPE
.Val
.ConstVal
))
660 if (GV
->hasExternalWeakLinkage())
661 ExtWeakSymbols
.insert(GV
);
666 void ARMAsmPrinter::printJTBlockOperand(const MachineInstr
*MI
, int OpNo
) {
667 const MachineOperand
&MO1
= MI
->getOperand(OpNo
);
668 const MachineOperand
&MO2
= MI
->getOperand(OpNo
+1); // Unique Id
669 unsigned JTI
= MO1
.getJumpTableIndex();
670 O
<< TAI
->getPrivateGlobalPrefix() << "JTI" << getFunctionNumber()
671 << '_' << JTI
<< '_' << MO2
.getImmedValue() << ":\n";
673 const char *JTEntryDirective
= TAI
->getJumpTableDirective();
674 if (!JTEntryDirective
)
675 JTEntryDirective
= TAI
->getData32bitsDirective();
677 const MachineFunction
*MF
= MI
->getParent()->getParent();
678 MachineJumpTableInfo
*MJTI
= MF
->getJumpTableInfo();
679 const std::vector
<MachineJumpTableEntry
> &JT
= MJTI
->getJumpTables();
680 const std::vector
<MachineBasicBlock
*> &JTBBs
= JT
[JTI
].MBBs
;
681 bool UseSet
= TAI
->getSetDirective() && TM
.getRelocationModel() == Reloc::PIC_
;
682 std::set
<MachineBasicBlock
*> JTSets
;
683 for (unsigned i
= 0, e
= JTBBs
.size(); i
!= e
; ++i
) {
684 MachineBasicBlock
*MBB
= JTBBs
[i
];
685 if (UseSet
&& JTSets
.insert(MBB
).second
)
686 printSetLabel(JTI
, MO2
.getImmedValue(), MBB
);
688 O
<< JTEntryDirective
<< ' ';
690 O
<< TAI
->getPrivateGlobalPrefix() << getFunctionNumber()
691 << '_' << JTI
<< '_' << MO2
.getImmedValue()
692 << "_set_" << MBB
->getNumber();
693 else if (TM
.getRelocationModel() == Reloc::PIC_
) {
694 printBasicBlockLabel(MBB
, false, false);
695 // If the arch uses custom Jump Table directives, don't calc relative to JT
696 if (!TAI
->getJumpTableDirective())
697 O
<< '-' << TAI
->getPrivateGlobalPrefix() << "JTI"
698 << getFunctionNumber() << '_' << JTI
<< '_' << MO2
.getImmedValue();
700 printBasicBlockLabel(MBB
, false, false);
707 bool ARMAsmPrinter::PrintAsmOperand(const MachineInstr
*MI
, unsigned OpNo
,
708 unsigned AsmVariant
, const char *ExtraCode
){
709 // Does this asm operand have a single letter operand modifier?
710 if (ExtraCode
&& ExtraCode
[0]) {
711 if (ExtraCode
[1] != 0) return true; // Unknown modifier.
713 switch (ExtraCode
[0]) {
714 default: return true; // Unknown modifier.
715 case 'c': // Don't print "$" before a global var name or constant.
716 case 'P': // Print a VFP double precision register.
717 printOperand(MI
, OpNo
);
720 if (TM
.getTargetData()->isLittleEndian())
724 if (TM
.getTargetData()->isBigEndian())
727 case 'H': // Write second word of DI / DF reference.
728 // Verify that this operand has two consecutive registers.
729 if (!MI
->getOperand(OpNo
).isRegister() ||
730 OpNo
+1 == MI
->getNumOperands() ||
731 !MI
->getOperand(OpNo
+1).isRegister())
733 ++OpNo
; // Return the high-part.
737 printOperand(MI
, OpNo
);
741 void ARMAsmPrinter::printMachineInstruction(const MachineInstr
*MI
) {
744 int Opc
= MI
->getOpcode();
746 case ARM::CONSTPOOL_ENTRY
:
747 if (!InCPMode
&& AFI
->isThumbFunction()) {
753 if (InCPMode
&& AFI
->isThumbFunction())
775 // Call the autogenerated instruction printer routines.
776 printInstruction(MI
);
779 bool ARMAsmPrinter::doInitialization(Module
&M
) {
780 // Emit initial debug information.
783 return AsmPrinter::doInitialization(M
);
786 bool ARMAsmPrinter::doFinalization(Module
&M
) {
787 const TargetData
*TD
= TM
.getTargetData();
789 for (Module::const_global_iterator I
= M
.global_begin(), E
= M
.global_end();
791 if (!I
->hasInitializer()) // External global require no code
794 if (EmitSpecialLLVMGlobal(I
)) {
795 if (Subtarget
->isTargetDarwin() &&
796 TM
.getRelocationModel() == Reloc::Static
) {
797 if (I
->getName() == "llvm.global_ctors")
798 O
<< ".reference .constructors_used\n";
799 else if (I
->getName() == "llvm.global_dtors")
800 O
<< ".reference .destructors_used\n";
805 std::string name
= Mang
->getValueName(I
);
806 Constant
*C
= I
->getInitializer();
807 const Type
*Type
= C
->getType();
808 unsigned Size
= TD
->getTypeSize(Type
);
809 unsigned Align
= TD
->getPreferredAlignmentLog(I
);
811 const char *VisibilityDirective
= NULL
;
812 if (I
->hasHiddenVisibility())
813 VisibilityDirective
= TAI
->getHiddenDirective();
814 else if (I
->hasProtectedVisibility())
815 VisibilityDirective
= TAI
->getProtectedDirective();
817 if (VisibilityDirective
)
818 O
<< VisibilityDirective
<< name
<< "\n";
820 if (Subtarget
->isTargetELF())
821 O
<< "\t.type " << name
<< ",%object\n";
823 if (C
->isNullValue()) {
824 if (I
->hasExternalLinkage()) {
825 if (const char *Directive
= TAI
->getZeroFillDirective()) {
826 O
<< "\t.globl\t" << name
<< "\n";
827 O
<< Directive
<< "__DATA__, __common, " << name
<< ", "
828 << Size
<< ", " << Align
<< "\n";
833 if (!I
->hasSection() &&
834 (I
->hasInternalLinkage() || I
->hasWeakLinkage() ||
835 I
->hasLinkOnceLinkage())) {
836 if (Size
== 0) Size
= 1; // .comm Foo, 0 is undefined, avoid it.
837 if (!NoZerosInBSS
&& TAI
->getBSSSection())
838 SwitchToDataSection(TAI
->getBSSSection(), I
);
840 SwitchToDataSection(TAI
->getDataSection(), I
);
841 if (TAI
->getLCOMMDirective() != NULL
) {
842 if (I
->hasInternalLinkage()) {
843 O
<< TAI
->getLCOMMDirective() << name
<< "," << Size
;
844 if (Subtarget
->isTargetDarwin())
847 O
<< TAI
->getCOMMDirective() << name
<< "," << Size
;
849 if (I
->hasInternalLinkage())
850 O
<< "\t.local\t" << name
<< "\n";
851 O
<< TAI
->getCOMMDirective() << name
<< "," << Size
;
852 if (TAI
->getCOMMDirectiveTakesAlignment())
853 O
<< "," << (TAI
->getAlignmentIsInBytes() ? (1 << Align
) : Align
);
855 O
<< "\t\t" << TAI
->getCommentString() << " " << I
->getName() << "\n";
860 switch (I
->getLinkage()) {
861 case GlobalValue::LinkOnceLinkage
:
862 case GlobalValue::WeakLinkage
:
863 if (Subtarget
->isTargetDarwin()) {
864 O
<< "\t.globl " << name
<< "\n"
865 << "\t.weak_definition " << name
<< "\n";
866 SwitchToDataSection("\t.section __DATA,__const_coal,coalesced", I
);
868 std::string
SectionName("\t.section\t.llvm.linkonce.d." +
870 ",\"aw\",%progbits");
871 SwitchToDataSection(SectionName
.c_str(), I
);
872 O
<< "\t.weak " << name
<< "\n";
875 case GlobalValue::AppendingLinkage
:
876 // FIXME: appending linkage variables should go into a section of
877 // their name or something. For now, just emit them as external.
878 case GlobalValue::ExternalLinkage
:
879 O
<< "\t.globl " << name
<< "\n";
881 case GlobalValue::InternalLinkage
: {
882 if (I
->isConstant()) {
883 const ConstantArray
*CVA
= dyn_cast
<ConstantArray
>(C
);
884 if (TAI
->getCStringSection() && CVA
&& CVA
->isCString()) {
885 SwitchToDataSection(TAI
->getCStringSection(), I
);
889 // FIXME: special handling for ".ctors" & ".dtors" sections
890 if (I
->hasSection() &&
891 (I
->getSection() == ".ctors" ||
892 I
->getSection() == ".dtors")) {
893 assert(!Subtarget
->isTargetDarwin());
894 std::string SectionName
= ".section " + I
->getSection();
895 SectionName
+= ",\"aw\",%progbits";
896 SwitchToDataSection(SectionName
.c_str());
898 if (C
->isNullValue() && !NoZerosInBSS
&& TAI
->getBSSSection())
899 SwitchToDataSection(I
->isThreadLocal() ? TAI
->getTLSBSSSection() :
900 TAI
->getBSSSection(), I
);
901 else if (!I
->isConstant())
902 SwitchToDataSection(I
->isThreadLocal() ? TAI
->getTLSDataSection() :
903 TAI
->getDataSection(), I
);
904 else if (I
->isThreadLocal())
905 SwitchToDataSection(TAI
->getTLSDataSection());
908 bool HasReloc
= C
->ContainsRelocations();
910 Subtarget
->isTargetDarwin() &&
911 TM
.getRelocationModel() != Reloc::Static
)
912 SwitchToDataSection("\t.const_data\n");
913 else if (!HasReloc
&& Size
== 4 &&
914 TAI
->getFourByteConstantSection())
915 SwitchToDataSection(TAI
->getFourByteConstantSection(), I
);
916 else if (!HasReloc
&& Size
== 8 &&
917 TAI
->getEightByteConstantSection())
918 SwitchToDataSection(TAI
->getEightByteConstantSection(), I
);
919 else if (!HasReloc
&& Size
== 16 &&
920 TAI
->getSixteenByteConstantSection())
921 SwitchToDataSection(TAI
->getSixteenByteConstantSection(), I
);
922 else if (TAI
->getReadOnlySection())
923 SwitchToDataSection(TAI
->getReadOnlySection(), I
);
925 SwitchToDataSection(TAI
->getDataSection(), I
);
932 assert(0 && "Unknown linkage type!");
936 EmitAlignment(Align
, I
);
937 O
<< name
<< ":\t\t\t\t" << TAI
->getCommentString() << " " << I
->getName()
939 if (TAI
->hasDotTypeDotSizeDirective())
940 O
<< "\t.size " << name
<< ", " << Size
<< "\n";
941 // If the initializer is a extern weak symbol, remember to emit the weak
943 if (const GlobalValue
*GV
= dyn_cast
<GlobalValue
>(C
))
944 if (GV
->hasExternalWeakLinkage())
945 ExtWeakSymbols
.insert(GV
);
947 EmitGlobalConstant(C
);
951 if (Subtarget
->isTargetDarwin()) {
952 SwitchToDataSection("");
954 // Output stubs for dynamically-linked functions
956 for (std::set
<std::string
>::iterator i
= FnStubs
.begin(), e
= FnStubs
.end();
958 if (TM
.getRelocationModel() == Reloc::PIC_
)
959 SwitchToTextSection(".section __TEXT,__picsymbolstub4,symbol_stubs,"
962 SwitchToTextSection(".section __TEXT,__symbol_stub4,symbol_stubs,"
966 O
<< "\t.code\t32\n";
968 O
<< "L" << *i
<< "$stub:\n";
969 O
<< "\t.indirect_symbol " << *i
<< "\n";
970 O
<< "\tldr ip, L" << *i
<< "$slp\n";
971 if (TM
.getRelocationModel() == Reloc::PIC_
) {
972 O
<< "L" << *i
<< "$scv:\n";
973 O
<< "\tadd ip, pc, ip\n";
975 O
<< "\tldr pc, [ip, #0]\n";
976 O
<< "L" << *i
<< "$slp:\n";
977 if (TM
.getRelocationModel() == Reloc::PIC_
)
978 O
<< "\t.long\tL" << *i
<< "$lazy_ptr-(L" << *i
<< "$scv+8)\n";
980 O
<< "\t.long\tL" << *i
<< "$lazy_ptr\n";
981 SwitchToDataSection(".lazy_symbol_pointer", 0);
982 O
<< "L" << *i
<< "$lazy_ptr:\n";
983 O
<< "\t.indirect_symbol " << *i
<< "\n";
984 O
<< "\t.long\tdyld_stub_binding_helper\n";
988 // Output non-lazy-pointers for external and common global variables.
989 if (GVNonLazyPtrs
.begin() != GVNonLazyPtrs
.end())
990 SwitchToDataSection(".non_lazy_symbol_pointer", 0);
991 for (std::set
<std::string
>::iterator i
= GVNonLazyPtrs
.begin(),
992 e
= GVNonLazyPtrs
.end(); i
!= e
; ++i
) {
993 O
<< "L" << *i
<< "$non_lazy_ptr:\n";
994 O
<< "\t.indirect_symbol " << *i
<< "\n";
998 // Emit initial debug information.
1001 // Funny Darwin hack: This flag tells the linker that no global symbols
1002 // contain code that falls through to other global symbols (e.g. the obvious
1003 // implementation of multiple entry points). If this doesn't occur, the
1004 // linker can safely perform dead code stripping. Since LLVM never
1005 // generates code that does this, it is always safe to set.
1006 O
<< "\t.subsections_via_symbols\n";
1008 // Emit final debug information for ELF.
1012 AsmPrinter::doFinalization(M
);
1013 return false; // success