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/MachineModuleInfoImpls.h"
26 #include "llvm/CodeGen/MachineFunctionPass.h"
27 #include "llvm/CodeGen/MachineJumpTableInfo.h"
28 #include "llvm/MC/MCAsmInfo.h"
29 #include "llvm/MC/MCContext.h"
30 #include "llvm/MC/MCSectionMachO.h"
31 #include "llvm/MC/MCStreamer.h"
32 #include "llvm/MC/MCSymbol.h"
33 #include "llvm/Target/TargetData.h"
34 #include "llvm/Target/TargetLoweringObjectFile.h"
35 #include "llvm/Target/TargetMachine.h"
36 #include "llvm/Target/TargetOptions.h"
37 #include "llvm/Target/TargetRegistry.h"
38 #include "llvm/ADT/SmallPtrSet.h"
39 #include "llvm/ADT/SmallString.h"
40 #include "llvm/ADT/Statistic.h"
41 #include "llvm/ADT/StringSet.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 ARMAsmPrinter : public AsmPrinter {
54 /// Subtarget - Keep a pointer to the ARMSubtarget around so that we can
55 /// make the right decision when printing asm code for different targets.
56 const ARMSubtarget *Subtarget;
58 /// AFI - Keep a pointer to ARMFunctionInfo for the current
62 /// MCP - Keep a pointer to constantpool entries of the current
64 const MachineConstantPool *MCP;
67 explicit ARMAsmPrinter(formatted_raw_ostream &O, TargetMachine &TM,
68 const MCAsmInfo *T, bool V)
69 : AsmPrinter(O, TM, T, V), AFI(NULL), MCP(NULL) {
70 Subtarget = &TM.getSubtarget<ARMSubtarget>();
73 virtual const char *getPassName() const {
74 return "ARM Assembly Printer";
77 void printOperand(const MachineInstr *MI, int OpNum,
78 const char *Modifier = 0);
79 void printSOImmOperand(const MachineInstr *MI, int OpNum);
80 void printSOImm2PartOperand(const MachineInstr *MI, int OpNum);
81 void printSORegOperand(const MachineInstr *MI, int OpNum);
82 void printAddrMode2Operand(const MachineInstr *MI, int OpNum);
83 void printAddrMode2OffsetOperand(const MachineInstr *MI, int OpNum);
84 void printAddrMode3Operand(const MachineInstr *MI, int OpNum);
85 void printAddrMode3OffsetOperand(const MachineInstr *MI, int OpNum);
86 void printAddrMode4Operand(const MachineInstr *MI, int OpNum,
87 const char *Modifier = 0);
88 void printAddrMode5Operand(const MachineInstr *MI, int OpNum,
89 const char *Modifier = 0);
90 void printAddrMode6Operand(const MachineInstr *MI, int OpNum);
91 void printAddrModePCOperand(const MachineInstr *MI, int OpNum,
92 const char *Modifier = 0);
93 void printBitfieldInvMaskImmOperand (const MachineInstr *MI, int OpNum);
95 void printThumbITMask(const MachineInstr *MI, int OpNum);
96 void printThumbAddrModeRROperand(const MachineInstr *MI, int OpNum);
97 void printThumbAddrModeRI5Operand(const MachineInstr *MI, int OpNum,
99 void printThumbAddrModeS1Operand(const MachineInstr *MI, int OpNum);
100 void printThumbAddrModeS2Operand(const MachineInstr *MI, int OpNum);
101 void printThumbAddrModeS4Operand(const MachineInstr *MI, int OpNum);
102 void printThumbAddrModeSPOperand(const MachineInstr *MI, int OpNum);
104 void printT2SOOperand(const MachineInstr *MI, int OpNum);
105 void printT2AddrModeImm12Operand(const MachineInstr *MI, int OpNum);
106 void printT2AddrModeImm8Operand(const MachineInstr *MI, int OpNum);
107 void printT2AddrModeImm8s4Operand(const MachineInstr *MI, int OpNum);
108 void printT2AddrModeImm8OffsetOperand(const MachineInstr *MI, int OpNum);
109 void printT2AddrModeSoRegOperand(const MachineInstr *MI, int OpNum);
111 void printPredicateOperand(const MachineInstr *MI, int OpNum);
112 void printSBitModifierOperand(const MachineInstr *MI, int OpNum);
113 void printPCLabel(const MachineInstr *MI, int OpNum);
114 void printRegisterList(const MachineInstr *MI, int OpNum);
115 void printCPInstOperand(const MachineInstr *MI, int OpNum,
116 const char *Modifier);
117 void printJTBlockOperand(const MachineInstr *MI, int OpNum);
118 void printJT2BlockOperand(const MachineInstr *MI, int OpNum);
119 void printTBAddrMode(const MachineInstr *MI, int OpNum);
120 void printNoHashImmediate(const MachineInstr *MI, int OpNum);
122 virtual bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNum,
123 unsigned AsmVariant, const char *ExtraCode);
124 virtual bool PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNum,
126 const char *ExtraCode);
128 void PrintGlobalVariable(const GlobalVariable* GVar);
129 void printInstruction(const MachineInstr *MI); // autogenerated.
130 static const char *getRegisterName(unsigned RegNo);
132 void printMachineInstruction(const MachineInstr *MI);
133 bool runOnMachineFunction(MachineFunction &F);
134 void EmitStartOfAsmFile(Module &M);
135 void EmitEndOfAsmFile(Module &M);
137 /// EmitMachineConstantPoolValue - Print a machine constantpool value to
139 virtual void EmitMachineConstantPoolValue(MachineConstantPoolValue *MCPV) {
140 printDataDirective(MCPV->getType());
142 ARMConstantPoolValue *ACPV = static_cast<ARMConstantPoolValue*>(MCPV);
143 GlobalValue *GV = ACPV->getGV();
146 if (ACPV->isLSDA()) {
147 SmallString<16> LSDAName;
148 raw_svector_ostream(LSDAName) << MAI->getPrivateGlobalPrefix() <<
149 "_LSDA_" << getFunctionNumber();
150 Name = LSDAName.str();
152 bool isIndirect = Subtarget->isTargetDarwin() &&
153 Subtarget->GVIsIndirectSymbol(GV, TM.getRelocationModel());
155 Name = Mang->getMangledName(GV);
157 // FIXME: Remove this when Darwin transition to @GOT like syntax.
158 Name = Mang->getMangledName(GV, "$non_lazy_ptr", true);
159 MCSymbol *Sym = OutContext.GetOrCreateSymbol(Name.c_str());
161 if (GV->hasHiddenVisibility()) {
162 const MCSymbol *&StubSym =
163 MMI->getObjFileInfo<MachineModuleInfoMachO>()
164 .getHiddenGVStubEntry(Sym);
167 //Mang->getNameWithPrefix(NameStr, GV, false);
168 std::string SymName = Mang->getMangledName(GV);
169 StubSym = OutContext.GetOrCreateSymbol(SymName.c_str());
172 const MCSymbol *&StubSym =
173 MMI->getObjFileInfo<MachineModuleInfoMachO>().getGVStubEntry(Sym);
176 //Mang->getNameWithPrefix(NameStr, GV, false);
177 std::string SymName = Mang->getMangledName(GV);
178 StubSym = OutContext.GetOrCreateSymbol(SymName.c_str());
183 Name = Mang->makeNameProper(ACPV->getSymbol());
186 if (ACPV->hasModifier()) O << "(" << ACPV->getModifier() << ")";
187 if (ACPV->getPCAdjustment() != 0) {
188 O << "-(" << MAI->getPrivateGlobalPrefix() << "PC"
189 << ACPV->getLabelId()
190 << "+" << (unsigned)ACPV->getPCAdjustment();
191 if (ACPV->mustAddCurrentAddress())
198 void getAnalysisUsage(AnalysisUsage &AU) const {
199 AsmPrinter::getAnalysisUsage(AU);
200 AU.setPreservesAll();
201 AU.addRequired<MachineModuleInfo>();
202 AU.addRequired<DwarfWriter>();
205 } // end of anonymous namespace
207 #include "ARMGenAsmWriter.inc"
209 /// runOnMachineFunction - This uses the printInstruction()
210 /// method to print assembly for each instruction.
212 bool ARMAsmPrinter::runOnMachineFunction(MachineFunction &MF) {
215 AFI = MF.getInfo<ARMFunctionInfo>();
216 MCP = MF.getConstantPool();
218 SetupMachineFunction(MF);
221 // NOTE: we don't print out constant pools here, they are handled as
226 // Print out labels for the function.
227 const Function *F = MF.getFunction();
228 OutStreamer.SwitchSection(getObjFileLowering().SectionForGlobal(F, Mang, TM));
230 switch (F->getLinkage()) {
231 default: llvm_unreachable("Unknown linkage type!");
232 case Function::PrivateLinkage:
233 case Function::InternalLinkage:
235 case Function::ExternalLinkage:
236 O << "\t.globl\t" << CurrentFnName << "\n";
238 case Function::LinkerPrivateLinkage:
239 case Function::WeakAnyLinkage:
240 case Function::WeakODRLinkage:
241 case Function::LinkOnceAnyLinkage:
242 case Function::LinkOnceODRLinkage:
243 if (Subtarget->isTargetDarwin()) {
244 O << "\t.globl\t" << CurrentFnName << "\n";
245 O << "\t.weak_definition\t" << CurrentFnName << "\n";
247 O << MAI->getWeakRefDirective() << CurrentFnName << "\n";
252 printVisibility(CurrentFnName, F->getVisibility());
254 unsigned FnAlign = 1 << MF.getAlignment(); // MF alignment is log2.
255 if (AFI->isThumbFunction()) {
256 EmitAlignment(FnAlign, F, AFI->getAlign());
257 O << "\t.code\t16\n";
258 O << "\t.thumb_func";
259 if (Subtarget->isTargetDarwin())
260 O << "\t" << CurrentFnName;
263 EmitAlignment(FnAlign, F);
266 O << CurrentFnName << ":\n";
267 // Emit pre-function debug information.
268 DW->BeginFunction(&MF);
270 if (Subtarget->isTargetDarwin()) {
271 // If the function is empty, then we need to emit *something*. Otherwise,
272 // the function's label might be associated with something that it wasn't
273 // meant to be associated with. We emit a noop in this situation.
274 MachineFunction::iterator I = MF.begin();
276 if (++I == MF.end() && MF.front().empty())
280 // Print out code for the function.
281 for (MachineFunction::const_iterator I = MF.begin(), E = MF.end();
283 // Print a label for the basic block.
284 if (I != MF.begin()) {
285 EmitBasicBlockStart(I);
287 for (MachineBasicBlock::const_iterator II = I->begin(), E = I->end();
289 // Print the assembly for the instruction.
290 printMachineInstruction(II);
294 if (MAI->hasDotTypeDotSizeDirective())
295 O << "\t.size " << CurrentFnName << ", .-" << CurrentFnName << "\n";
297 // Emit post-function debug information.
298 DW->EndFunction(&MF);
303 void ARMAsmPrinter::printOperand(const MachineInstr *MI, int OpNum,
304 const char *Modifier) {
305 const MachineOperand &MO = MI->getOperand(OpNum);
306 switch (MO.getType()) {
307 case MachineOperand::MO_Register: {
308 unsigned Reg = MO.getReg();
309 if (TargetRegisterInfo::isPhysicalRegister(Reg)) {
310 if (Modifier && strcmp(Modifier, "dregpair") == 0) {
311 unsigned DRegLo = TRI->getSubReg(Reg, 5); // arm_dsubreg_0
312 unsigned DRegHi = TRI->getSubReg(Reg, 6); // arm_dsubreg_1
314 << getRegisterName(DRegLo) << ',' << getRegisterName(DRegHi)
316 } else if (Modifier && strcmp(Modifier, "lane") == 0) {
317 unsigned RegNum = ARMRegisterInfo::getRegisterNumbering(Reg);
318 unsigned DReg = TRI->getMatchingSuperReg(Reg, RegNum & 1 ? 2 : 1,
319 &ARM::DPR_VFP2RegClass);
320 O << getRegisterName(DReg) << '[' << (RegNum & 1) << ']';
322 O << getRegisterName(Reg);
325 llvm_unreachable("not implemented");
328 case MachineOperand::MO_Immediate: {
329 int64_t Imm = MO.getImm();
332 if (strcmp(Modifier, "lo16") == 0)
334 else if (strcmp(Modifier, "hi16") == 0)
340 case MachineOperand::MO_MachineBasicBlock:
341 GetMBBSymbol(MO.getMBB()->getNumber())->print(O, MAI);
343 case MachineOperand::MO_GlobalAddress: {
344 bool isCallOp = Modifier && !strcmp(Modifier, "call");
345 GlobalValue *GV = MO.getGlobal();
346 O << Mang->getMangledName(GV);
348 printOffset(MO.getOffset());
350 if (isCallOp && Subtarget->isTargetELF() &&
351 TM.getRelocationModel() == Reloc::PIC_)
355 case MachineOperand::MO_ExternalSymbol: {
356 bool isCallOp = Modifier && !strcmp(Modifier, "call");
357 std::string Name = Mang->makeNameProper(MO.getSymbolName());
360 if (isCallOp && Subtarget->isTargetELF() &&
361 TM.getRelocationModel() == Reloc::PIC_)
365 case MachineOperand::MO_ConstantPoolIndex:
366 O << MAI->getPrivateGlobalPrefix() << "CPI" << getFunctionNumber()
367 << '_' << MO.getIndex();
369 case MachineOperand::MO_JumpTableIndex:
370 O << MAI->getPrivateGlobalPrefix() << "JTI" << getFunctionNumber()
371 << '_' << MO.getIndex();
374 O << "<unknown operand type>"; abort (); break;
378 static void printSOImm(formatted_raw_ostream &O, int64_t V, bool VerboseAsm,
379 const MCAsmInfo *MAI) {
380 // Break it up into two parts that make up a shifter immediate.
381 V = ARM_AM::getSOImmVal(V);
382 assert(V != -1 && "Not a valid so_imm value!");
384 unsigned Imm = ARM_AM::getSOImmValImm(V);
385 unsigned Rot = ARM_AM::getSOImmValRot(V);
387 // Print low-level immediate formation info, per
388 // A5.1.3: "Data-processing operands - Immediate".
390 O << "#" << Imm << ", " << Rot;
391 // Pretty printed version.
393 O << ' ' << MAI->getCommentString()
394 << ' ' << (int)ARM_AM::rotr32(Imm, Rot);
400 /// printSOImmOperand - SOImm is 4-bit rotate amount in bits 8-11 with 8-bit
401 /// immediate in bits 0-7.
402 void ARMAsmPrinter::printSOImmOperand(const MachineInstr *MI, int OpNum) {
403 const MachineOperand &MO = MI->getOperand(OpNum);
404 assert(MO.isImm() && "Not a valid so_imm value!");
405 printSOImm(O, MO.getImm(), VerboseAsm, MAI);
408 /// printSOImm2PartOperand - SOImm is broken into two pieces using a 'mov'
409 /// followed by an 'orr' to materialize.
410 void ARMAsmPrinter::printSOImm2PartOperand(const MachineInstr *MI, int OpNum) {
411 const MachineOperand &MO = MI->getOperand(OpNum);
412 assert(MO.isImm() && "Not a valid so_imm value!");
413 unsigned V1 = ARM_AM::getSOImmTwoPartFirst(MO.getImm());
414 unsigned V2 = ARM_AM::getSOImmTwoPartSecond(MO.getImm());
415 printSOImm(O, V1, VerboseAsm, MAI);
417 printPredicateOperand(MI, 2);
423 printSOImm(O, V2, VerboseAsm, MAI);
426 // so_reg is a 4-operand unit corresponding to register forms of the A5.1
427 // "Addressing Mode 1 - Data-processing operands" forms. This includes:
429 // REG REG 0,SH_OPC - e.g. R5, ROR R3
430 // REG 0 IMM,SH_OPC - e.g. R5, LSL #3
431 void ARMAsmPrinter::printSORegOperand(const MachineInstr *MI, int Op) {
432 const MachineOperand &MO1 = MI->getOperand(Op);
433 const MachineOperand &MO2 = MI->getOperand(Op+1);
434 const MachineOperand &MO3 = MI->getOperand(Op+2);
436 O << getRegisterName(MO1.getReg());
438 // Print the shift opc.
440 << ARM_AM::getShiftOpcStr(ARM_AM::getSORegShOp(MO3.getImm()))
444 O << getRegisterName(MO2.getReg());
445 assert(ARM_AM::getSORegOffset(MO3.getImm()) == 0);
447 O << "#" << ARM_AM::getSORegOffset(MO3.getImm());
451 void ARMAsmPrinter::printAddrMode2Operand(const MachineInstr *MI, int Op) {
452 const MachineOperand &MO1 = MI->getOperand(Op);
453 const MachineOperand &MO2 = MI->getOperand(Op+1);
454 const MachineOperand &MO3 = MI->getOperand(Op+2);
456 if (!MO1.isReg()) { // FIXME: This is for CP entries, but isn't right.
457 printOperand(MI, Op);
461 O << "[" << getRegisterName(MO1.getReg());
464 if (ARM_AM::getAM2Offset(MO3.getImm())) // Don't print +0.
466 << (char)ARM_AM::getAM2Op(MO3.getImm())
467 << ARM_AM::getAM2Offset(MO3.getImm());
473 << (char)ARM_AM::getAM2Op(MO3.getImm())
474 << getRegisterName(MO2.getReg());
476 if (unsigned ShImm = ARM_AM::getAM2Offset(MO3.getImm()))
478 << ARM_AM::getShiftOpcStr(ARM_AM::getAM2ShiftOpc(MO3.getImm()))
483 void ARMAsmPrinter::printAddrMode2OffsetOperand(const MachineInstr *MI, int Op){
484 const MachineOperand &MO1 = MI->getOperand(Op);
485 const MachineOperand &MO2 = MI->getOperand(Op+1);
488 unsigned ImmOffs = ARM_AM::getAM2Offset(MO2.getImm());
489 assert(ImmOffs && "Malformed indexed load / store!");
491 << (char)ARM_AM::getAM2Op(MO2.getImm())
496 O << (char)ARM_AM::getAM2Op(MO2.getImm())
497 << getRegisterName(MO1.getReg());
499 if (unsigned ShImm = ARM_AM::getAM2Offset(MO2.getImm()))
501 << ARM_AM::getShiftOpcStr(ARM_AM::getAM2ShiftOpc(MO2.getImm()))
505 void ARMAsmPrinter::printAddrMode3Operand(const MachineInstr *MI, int Op) {
506 const MachineOperand &MO1 = MI->getOperand(Op);
507 const MachineOperand &MO2 = MI->getOperand(Op+1);
508 const MachineOperand &MO3 = MI->getOperand(Op+2);
510 assert(TargetRegisterInfo::isPhysicalRegister(MO1.getReg()));
511 O << "[" << getRegisterName(MO1.getReg());
515 << (char)ARM_AM::getAM3Op(MO3.getImm())
516 << getRegisterName(MO2.getReg())
521 if (unsigned ImmOffs = ARM_AM::getAM3Offset(MO3.getImm()))
523 << (char)ARM_AM::getAM3Op(MO3.getImm())
528 void ARMAsmPrinter::printAddrMode3OffsetOperand(const MachineInstr *MI, int Op){
529 const MachineOperand &MO1 = MI->getOperand(Op);
530 const MachineOperand &MO2 = MI->getOperand(Op+1);
533 O << (char)ARM_AM::getAM3Op(MO2.getImm())
534 << getRegisterName(MO1.getReg());
538 unsigned ImmOffs = ARM_AM::getAM3Offset(MO2.getImm());
539 assert(ImmOffs && "Malformed indexed load / store!");
541 << (char)ARM_AM::getAM3Op(MO2.getImm())
545 void ARMAsmPrinter::printAddrMode4Operand(const MachineInstr *MI, int Op,
546 const char *Modifier) {
547 const MachineOperand &MO1 = MI->getOperand(Op);
548 const MachineOperand &MO2 = MI->getOperand(Op+1);
549 ARM_AM::AMSubMode Mode = ARM_AM::getAM4SubMode(MO2.getImm());
550 if (Modifier && strcmp(Modifier, "submode") == 0) {
551 if (MO1.getReg() == ARM::SP) {
553 bool isLDM = (MI->getOpcode() == ARM::LDM ||
554 MI->getOpcode() == ARM::LDM_RET ||
555 MI->getOpcode() == ARM::t2LDM ||
556 MI->getOpcode() == ARM::t2LDM_RET);
557 O << ARM_AM::getAMSubModeAltStr(Mode, isLDM);
559 O << ARM_AM::getAMSubModeStr(Mode);
560 } else if (Modifier && strcmp(Modifier, "wide") == 0) {
561 ARM_AM::AMSubMode Mode = ARM_AM::getAM4SubMode(MO2.getImm());
562 if (Mode == ARM_AM::ia)
565 printOperand(MI, Op);
566 if (ARM_AM::getAM4WBFlag(MO2.getImm()))
571 void ARMAsmPrinter::printAddrMode5Operand(const MachineInstr *MI, int Op,
572 const char *Modifier) {
573 const MachineOperand &MO1 = MI->getOperand(Op);
574 const MachineOperand &MO2 = MI->getOperand(Op+1);
576 if (!MO1.isReg()) { // FIXME: This is for CP entries, but isn't right.
577 printOperand(MI, Op);
581 assert(TargetRegisterInfo::isPhysicalRegister(MO1.getReg()));
583 if (Modifier && strcmp(Modifier, "submode") == 0) {
584 ARM_AM::AMSubMode Mode = ARM_AM::getAM5SubMode(MO2.getImm());
585 if (MO1.getReg() == ARM::SP) {
586 bool isFLDM = (MI->getOpcode() == ARM::FLDMD ||
587 MI->getOpcode() == ARM::FLDMS);
588 O << ARM_AM::getAMSubModeAltStr(Mode, isFLDM);
590 O << ARM_AM::getAMSubModeStr(Mode);
592 } else if (Modifier && strcmp(Modifier, "base") == 0) {
593 // Used for FSTM{D|S} and LSTM{D|S} operations.
594 O << getRegisterName(MO1.getReg());
595 if (ARM_AM::getAM5WBFlag(MO2.getImm()))
600 O << "[" << getRegisterName(MO1.getReg());
602 if (unsigned ImmOffs = ARM_AM::getAM5Offset(MO2.getImm())) {
604 << (char)ARM_AM::getAM5Op(MO2.getImm())
610 void ARMAsmPrinter::printAddrMode6Operand(const MachineInstr *MI, int Op) {
611 const MachineOperand &MO1 = MI->getOperand(Op);
612 const MachineOperand &MO2 = MI->getOperand(Op+1);
613 const MachineOperand &MO3 = MI->getOperand(Op+2);
615 // FIXME: No support yet for specifying alignment.
616 O << "[" << getRegisterName(MO1.getReg()) << "]";
618 if (ARM_AM::getAM6WBFlag(MO3.getImm())) {
619 if (MO2.getReg() == 0)
622 O << ", " << getRegisterName(MO2.getReg());
626 void ARMAsmPrinter::printAddrModePCOperand(const MachineInstr *MI, int Op,
627 const char *Modifier) {
628 if (Modifier && strcmp(Modifier, "label") == 0) {
629 printPCLabel(MI, Op+1);
633 const MachineOperand &MO1 = MI->getOperand(Op);
634 assert(TargetRegisterInfo::isPhysicalRegister(MO1.getReg()));
635 O << "[pc, +" << getRegisterName(MO1.getReg()) << "]";
639 ARMAsmPrinter::printBitfieldInvMaskImmOperand(const MachineInstr *MI, int Op) {
640 const MachineOperand &MO = MI->getOperand(Op);
641 uint32_t v = ~MO.getImm();
642 int32_t lsb = CountTrailingZeros_32(v);
643 int32_t width = (32 - CountLeadingZeros_32 (v)) - lsb;
644 assert(MO.isImm() && "Not a valid bf_inv_mask_imm value!");
645 O << "#" << lsb << ", #" << width;
648 //===--------------------------------------------------------------------===//
651 ARMAsmPrinter::printThumbITMask(const MachineInstr *MI, int Op) {
652 // (3 - the number of trailing zeros) is the number of then / else.
653 unsigned Mask = MI->getOperand(Op).getImm();
654 unsigned NumTZ = CountTrailingZeros_32(Mask);
655 assert(NumTZ <= 3 && "Invalid IT mask!");
656 for (unsigned Pos = 3, e = NumTZ; Pos > e; --Pos) {
657 bool T = (Mask & (1 << Pos)) == 0;
666 ARMAsmPrinter::printThumbAddrModeRROperand(const MachineInstr *MI, int Op) {
667 const MachineOperand &MO1 = MI->getOperand(Op);
668 const MachineOperand &MO2 = MI->getOperand(Op+1);
669 O << "[" << getRegisterName(MO1.getReg());
670 O << ", " << getRegisterName(MO2.getReg()) << "]";
674 ARMAsmPrinter::printThumbAddrModeRI5Operand(const MachineInstr *MI, int Op,
676 const MachineOperand &MO1 = MI->getOperand(Op);
677 const MachineOperand &MO2 = MI->getOperand(Op+1);
678 const MachineOperand &MO3 = MI->getOperand(Op+2);
680 if (!MO1.isReg()) { // FIXME: This is for CP entries, but isn't right.
681 printOperand(MI, Op);
685 O << "[" << getRegisterName(MO1.getReg());
687 O << ", " << getRegisterName(MO3.getReg());
688 else if (unsigned ImmOffs = MO2.getImm()) {
689 O << ", #" << ImmOffs;
697 ARMAsmPrinter::printThumbAddrModeS1Operand(const MachineInstr *MI, int Op) {
698 printThumbAddrModeRI5Operand(MI, Op, 1);
701 ARMAsmPrinter::printThumbAddrModeS2Operand(const MachineInstr *MI, int Op) {
702 printThumbAddrModeRI5Operand(MI, Op, 2);
705 ARMAsmPrinter::printThumbAddrModeS4Operand(const MachineInstr *MI, int Op) {
706 printThumbAddrModeRI5Operand(MI, Op, 4);
709 void ARMAsmPrinter::printThumbAddrModeSPOperand(const MachineInstr *MI,int Op) {
710 const MachineOperand &MO1 = MI->getOperand(Op);
711 const MachineOperand &MO2 = MI->getOperand(Op+1);
712 O << "[" << getRegisterName(MO1.getReg());
713 if (unsigned ImmOffs = MO2.getImm())
714 O << ", #" << ImmOffs << " * 4";
718 //===--------------------------------------------------------------------===//
720 // Constant shifts t2_so_reg is a 2-operand unit corresponding to the Thumb2
721 // register with shift forms.
723 // REG IMM, SH_OPC - e.g. R5, LSL #3
724 void ARMAsmPrinter::printT2SOOperand(const MachineInstr *MI, int OpNum) {
725 const MachineOperand &MO1 = MI->getOperand(OpNum);
726 const MachineOperand &MO2 = MI->getOperand(OpNum+1);
728 unsigned Reg = MO1.getReg();
729 assert(TargetRegisterInfo::isPhysicalRegister(Reg));
730 O << getRegisterName(Reg);
732 // Print the shift opc.
734 << ARM_AM::getShiftOpcStr(ARM_AM::getSORegShOp(MO2.getImm()))
737 assert(MO2.isImm() && "Not a valid t2_so_reg value!");
738 O << "#" << ARM_AM::getSORegOffset(MO2.getImm());
741 void ARMAsmPrinter::printT2AddrModeImm12Operand(const MachineInstr *MI,
743 const MachineOperand &MO1 = MI->getOperand(OpNum);
744 const MachineOperand &MO2 = MI->getOperand(OpNum+1);
746 O << "[" << getRegisterName(MO1.getReg());
748 unsigned OffImm = MO2.getImm();
749 if (OffImm) // Don't print +0.
750 O << ", #+" << OffImm;
754 void ARMAsmPrinter::printT2AddrModeImm8Operand(const MachineInstr *MI,
756 const MachineOperand &MO1 = MI->getOperand(OpNum);
757 const MachineOperand &MO2 = MI->getOperand(OpNum+1);
759 O << "[" << getRegisterName(MO1.getReg());
761 int32_t OffImm = (int32_t)MO2.getImm();
764 O << ", #-" << -OffImm;
766 O << ", #+" << OffImm;
770 void ARMAsmPrinter::printT2AddrModeImm8s4Operand(const MachineInstr *MI,
772 const MachineOperand &MO1 = MI->getOperand(OpNum);
773 const MachineOperand &MO2 = MI->getOperand(OpNum+1);
775 O << "[" << getRegisterName(MO1.getReg());
777 int32_t OffImm = (int32_t)MO2.getImm() / 4;
780 O << ", #-" << -OffImm << " * 4";
782 O << ", #+" << OffImm << " * 4";
786 void ARMAsmPrinter::printT2AddrModeImm8OffsetOperand(const MachineInstr *MI,
788 const MachineOperand &MO1 = MI->getOperand(OpNum);
789 int32_t OffImm = (int32_t)MO1.getImm();
792 O << "#-" << -OffImm;
797 void ARMAsmPrinter::printT2AddrModeSoRegOperand(const MachineInstr *MI,
799 const MachineOperand &MO1 = MI->getOperand(OpNum);
800 const MachineOperand &MO2 = MI->getOperand(OpNum+1);
801 const MachineOperand &MO3 = MI->getOperand(OpNum+2);
803 O << "[" << getRegisterName(MO1.getReg());
805 assert(MO2.getReg() && "Invalid so_reg load / store address!");
806 O << ", " << getRegisterName(MO2.getReg());
808 unsigned ShAmt = MO3.getImm();
810 assert(ShAmt <= 3 && "Not a valid Thumb2 addressing mode!");
811 O << ", lsl #" << ShAmt;
817 //===--------------------------------------------------------------------===//
819 void ARMAsmPrinter::printPredicateOperand(const MachineInstr *MI, int OpNum) {
820 ARMCC::CondCodes CC = (ARMCC::CondCodes)MI->getOperand(OpNum).getImm();
822 O << ARMCondCodeToString(CC);
825 void ARMAsmPrinter::printSBitModifierOperand(const MachineInstr *MI, int OpNum){
826 unsigned Reg = MI->getOperand(OpNum).getReg();
828 assert(Reg == ARM::CPSR && "Expect ARM CPSR register!");
833 void ARMAsmPrinter::printPCLabel(const MachineInstr *MI, int OpNum) {
834 int Id = (int)MI->getOperand(OpNum).getImm();
835 O << MAI->getPrivateGlobalPrefix() << "PC" << Id;
838 void ARMAsmPrinter::printRegisterList(const MachineInstr *MI, int OpNum) {
840 // Always skip the first operand, it's the optional (and implicit writeback).
841 for (unsigned i = OpNum+1, e = MI->getNumOperands(); i != e; ++i) {
842 if (MI->getOperand(i).isImplicit())
844 if ((int)i != OpNum+1) O << ", ";
850 void ARMAsmPrinter::printCPInstOperand(const MachineInstr *MI, int OpNum,
851 const char *Modifier) {
852 assert(Modifier && "This operand only works with a modifier!");
853 // There are two aspects to a CONSTANTPOOL_ENTRY operand, the label and the
855 if (!strcmp(Modifier, "label")) {
856 unsigned ID = MI->getOperand(OpNum).getImm();
857 O << MAI->getPrivateGlobalPrefix() << "CPI" << getFunctionNumber()
858 << '_' << ID << ":\n";
860 assert(!strcmp(Modifier, "cpentry") && "Unknown modifier for CPE");
861 unsigned CPI = MI->getOperand(OpNum).getIndex();
863 const MachineConstantPoolEntry &MCPE = MCP->getConstants()[CPI];
865 if (MCPE.isMachineConstantPoolEntry()) {
866 EmitMachineConstantPoolValue(MCPE.Val.MachineCPVal);
868 EmitGlobalConstant(MCPE.Val.ConstVal);
873 void ARMAsmPrinter::printJTBlockOperand(const MachineInstr *MI, int OpNum) {
874 assert(!Subtarget->isThumb2() && "Thumb2 should use double-jump jumptables!");
876 const MachineOperand &MO1 = MI->getOperand(OpNum);
877 const MachineOperand &MO2 = MI->getOperand(OpNum+1); // Unique Id
878 unsigned JTI = MO1.getIndex();
879 O << MAI->getPrivateGlobalPrefix() << "JTI" << getFunctionNumber()
880 << '_' << JTI << '_' << MO2.getImm() << ":\n";
882 const char *JTEntryDirective = MAI->getData32bitsDirective();
884 const MachineFunction *MF = MI->getParent()->getParent();
885 const MachineJumpTableInfo *MJTI = MF->getJumpTableInfo();
886 const std::vector<MachineJumpTableEntry> &JT = MJTI->getJumpTables();
887 const std::vector<MachineBasicBlock*> &JTBBs = JT[JTI].MBBs;
888 bool UseSet= MAI->getSetDirective() && TM.getRelocationModel() == Reloc::PIC_;
889 SmallPtrSet<MachineBasicBlock*, 8> JTSets;
890 for (unsigned i = 0, e = JTBBs.size(); i != e; ++i) {
891 MachineBasicBlock *MBB = JTBBs[i];
892 bool isNew = JTSets.insert(MBB);
895 printPICJumpTableSetLabel(JTI, MO2.getImm(), MBB);
897 O << JTEntryDirective << ' ';
899 O << MAI->getPrivateGlobalPrefix() << getFunctionNumber()
900 << '_' << JTI << '_' << MO2.getImm()
901 << "_set_" << MBB->getNumber();
902 else if (TM.getRelocationModel() == Reloc::PIC_) {
903 GetMBBSymbol(MBB->getNumber())->print(O, MAI);
904 O << '-' << MAI->getPrivateGlobalPrefix() << "JTI"
905 << getFunctionNumber() << '_' << JTI << '_' << MO2.getImm();
907 GetMBBSymbol(MBB->getNumber())->print(O, MAI);
914 void ARMAsmPrinter::printJT2BlockOperand(const MachineInstr *MI, int OpNum) {
915 const MachineOperand &MO1 = MI->getOperand(OpNum);
916 const MachineOperand &MO2 = MI->getOperand(OpNum+1); // Unique Id
917 unsigned JTI = MO1.getIndex();
918 O << MAI->getPrivateGlobalPrefix() << "JTI" << getFunctionNumber()
919 << '_' << JTI << '_' << MO2.getImm() << ":\n";
921 const MachineFunction *MF = MI->getParent()->getParent();
922 const MachineJumpTableInfo *MJTI = MF->getJumpTableInfo();
923 const std::vector<MachineJumpTableEntry> &JT = MJTI->getJumpTables();
924 const std::vector<MachineBasicBlock*> &JTBBs = JT[JTI].MBBs;
925 bool ByteOffset = false, HalfWordOffset = false;
926 if (MI->getOpcode() == ARM::t2TBB)
928 else if (MI->getOpcode() == ARM::t2TBH)
929 HalfWordOffset = true;
931 for (unsigned i = 0, e = JTBBs.size(); i != e; ++i) {
932 MachineBasicBlock *MBB = JTBBs[i];
934 O << MAI->getData8bitsDirective();
935 else if (HalfWordOffset)
936 O << MAI->getData16bitsDirective();
937 if (ByteOffset || HalfWordOffset) {
939 GetMBBSymbol(MBB->getNumber())->print(O, MAI);
940 O << "-" << MAI->getPrivateGlobalPrefix() << "JTI" << getFunctionNumber()
941 << '_' << JTI << '_' << MO2.getImm() << ")/2";
944 GetMBBSymbol(MBB->getNumber())->print(O, MAI);
950 // Make sure the instruction that follows TBB is 2-byte aligned.
951 // FIXME: Constant island pass should insert an "ALIGN" instruction instead.
952 if (ByteOffset && (JTBBs.size() & 1)) {
958 void ARMAsmPrinter::printTBAddrMode(const MachineInstr *MI, int OpNum) {
959 O << "[pc, " << getRegisterName(MI->getOperand(OpNum).getReg());
960 if (MI->getOpcode() == ARM::t2TBH)
965 void ARMAsmPrinter::printNoHashImmediate(const MachineInstr *MI, int OpNum) {
966 O << MI->getOperand(OpNum).getImm();
969 bool ARMAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNum,
970 unsigned AsmVariant, const char *ExtraCode){
971 // Does this asm operand have a single letter operand modifier?
972 if (ExtraCode && ExtraCode[0]) {
973 if (ExtraCode[1] != 0) return true; // Unknown modifier.
975 switch (ExtraCode[0]) {
976 default: return true; // Unknown modifier.
977 case 'a': // Print as a memory address.
978 if (MI->getOperand(OpNum).isReg()) {
979 O << "[" << getRegisterName(MI->getOperand(OpNum).getReg()) << "]";
983 case 'c': // Don't print "#" before an immediate operand.
984 if (!MI->getOperand(OpNum).isImm())
986 printNoHashImmediate(MI, OpNum);
988 case 'P': // Print a VFP double precision register.
989 printOperand(MI, OpNum);
992 if (TM.getTargetData()->isLittleEndian())
996 if (TM.getTargetData()->isBigEndian())
999 case 'H': // Write second word of DI / DF reference.
1000 // Verify that this operand has two consecutive registers.
1001 if (!MI->getOperand(OpNum).isReg() ||
1002 OpNum+1 == MI->getNumOperands() ||
1003 !MI->getOperand(OpNum+1).isReg())
1005 ++OpNum; // Return the high-part.
1009 printOperand(MI, OpNum);
1013 bool ARMAsmPrinter::PrintAsmMemoryOperand(const MachineInstr *MI,
1014 unsigned OpNum, unsigned AsmVariant,
1015 const char *ExtraCode) {
1016 if (ExtraCode && ExtraCode[0])
1017 return true; // Unknown modifier.
1019 const MachineOperand &MO = MI->getOperand(OpNum);
1020 assert(MO.isReg() && "unexpected inline asm memory operand");
1021 O << "[" << getRegisterName(MO.getReg()) << "]";
1025 void ARMAsmPrinter::printMachineInstruction(const MachineInstr *MI) {
1028 int Opc = MI->getOpcode();
1029 if (Opc == ARM::CONSTPOOL_ENTRY)
1032 // Call the autogenerated instruction printer routines.
1033 processDebugLoc(MI, true);
1034 printInstruction(MI);
1035 if (VerboseAsm && !MI->getDebugLoc().isUnknown())
1038 processDebugLoc(MI, false);
1041 void ARMAsmPrinter::EmitStartOfAsmFile(Module &M) {
1042 if (Subtarget->isTargetDarwin()) {
1043 Reloc::Model RelocM = TM.getRelocationModel();
1044 if (RelocM == Reloc::PIC_ || RelocM == Reloc::DynamicNoPIC) {
1045 // Declare all the text sections up front (before the DWARF sections
1046 // emitted by AsmPrinter::doInitialization) so the assembler will keep
1047 // them together at the beginning of the object file. This helps
1048 // avoid out-of-range branches that are due a fundamental limitation of
1049 // the way symbol offsets are encoded with the current Darwin ARM
1051 TargetLoweringObjectFileMachO &TLOFMacho =
1052 static_cast<TargetLoweringObjectFileMachO &>(getObjFileLowering());
1053 OutStreamer.SwitchSection(TLOFMacho.getTextSection());
1054 OutStreamer.SwitchSection(TLOFMacho.getTextCoalSection());
1055 OutStreamer.SwitchSection(TLOFMacho.getConstTextCoalSection());
1056 if (RelocM == Reloc::DynamicNoPIC) {
1057 const MCSection *sect =
1058 TLOFMacho.getMachOSection("__TEXT", "__symbol_stub4",
1059 MCSectionMachO::S_SYMBOL_STUBS,
1060 12, SectionKind::getText());
1061 OutStreamer.SwitchSection(sect);
1063 const MCSection *sect =
1064 TLOFMacho.getMachOSection("__TEXT", "__picsymbolstub4",
1065 MCSectionMachO::S_SYMBOL_STUBS,
1066 16, SectionKind::getText());
1067 OutStreamer.SwitchSection(sect);
1072 // Use unified assembler syntax mode for Thumb.
1073 if (Subtarget->isThumb())
1074 O << "\t.syntax unified\n";
1076 // Emit ARM Build Attributes
1077 if (Subtarget->isTargetELF()) {
1079 std::string CPUString = Subtarget->getCPUString();
1080 if (CPUString != "generic")
1081 O << "\t.cpu " << CPUString << '\n';
1083 // FIXME: Emit FPU type
1084 if (Subtarget->hasVFP2())
1085 O << "\t.eabi_attribute " << ARMBuildAttrs::VFP_arch << ", 2\n";
1087 // Signal various FP modes.
1089 O << "\t.eabi_attribute " << ARMBuildAttrs::ABI_FP_denormal << ", 1\n"
1090 << "\t.eabi_attribute " << ARMBuildAttrs::ABI_FP_exceptions << ", 1\n";
1092 if (FiniteOnlyFPMath())
1093 O << "\t.eabi_attribute " << ARMBuildAttrs::ABI_FP_number_model << ", 1\n";
1095 O << "\t.eabi_attribute " << ARMBuildAttrs::ABI_FP_number_model << ", 3\n";
1097 // 8-bytes alignment stuff.
1098 O << "\t.eabi_attribute " << ARMBuildAttrs::ABI_align8_needed << ", 1\n"
1099 << "\t.eabi_attribute " << ARMBuildAttrs::ABI_align8_preserved << ", 1\n";
1101 // Hard float. Use both S and D registers and conform to AAPCS-VFP.
1102 if (Subtarget->isAAPCS_ABI() && FloatABIType == FloatABI::Hard)
1103 O << "\t.eabi_attribute " << ARMBuildAttrs::ABI_HardFP_use << ", 3\n"
1104 << "\t.eabi_attribute " << ARMBuildAttrs::ABI_VFP_args << ", 1\n";
1106 // FIXME: Should we signal R9 usage?
1110 void ARMAsmPrinter::PrintGlobalVariable(const GlobalVariable* GVar) {
1111 const TargetData *TD = TM.getTargetData();
1113 if (!GVar->hasInitializer()) // External global require no code
1116 // Check to see if this is a special global used by LLVM, if so, emit it.
1118 if (EmitSpecialLLVMGlobal(GVar)) {
1119 if (Subtarget->isTargetDarwin() &&
1120 TM.getRelocationModel() == Reloc::Static) {
1121 if (GVar->getName() == "llvm.global_ctors")
1122 O << ".reference .constructors_used\n";
1123 else if (GVar->getName() == "llvm.global_dtors")
1124 O << ".reference .destructors_used\n";
1129 std::string name = Mang->getMangledName(GVar);
1130 Constant *C = GVar->getInitializer();
1131 const Type *Type = C->getType();
1132 unsigned Size = TD->getTypeAllocSize(Type);
1133 unsigned Align = TD->getPreferredAlignmentLog(GVar);
1134 bool isDarwin = Subtarget->isTargetDarwin();
1136 printVisibility(name, GVar->getVisibility());
1138 if (Subtarget->isTargetELF())
1139 O << "\t.type " << name << ",%object\n";
1141 const MCSection *TheSection =
1142 getObjFileLowering().SectionForGlobal(GVar, Mang, TM);
1143 OutStreamer.SwitchSection(TheSection);
1145 // FIXME: get this stuff from section kind flags.
1146 if (C->isNullValue() && !GVar->hasSection() && !GVar->isThreadLocal() &&
1147 // Don't put things that should go in the cstring section into "comm".
1148 !TheSection->getKind().isMergeableCString()) {
1149 if (GVar->hasExternalLinkage()) {
1150 if (const char *Directive = MAI->getZeroFillDirective()) {
1151 O << "\t.globl\t" << name << "\n";
1152 O << Directive << "__DATA, __common, " << name << ", "
1153 << Size << ", " << Align << "\n";
1158 if (GVar->hasLocalLinkage() || GVar->isWeakForLinker()) {
1159 if (Size == 0) Size = 1; // .comm Foo, 0 is undefined, avoid it.
1162 if (GVar->hasLocalLinkage()) {
1163 O << MAI->getLCOMMDirective() << name << "," << Size
1165 } else if (GVar->hasCommonLinkage()) {
1166 O << MAI->getCOMMDirective() << name << "," << Size
1169 OutStreamer.SwitchSection(TheSection);
1170 O << "\t.globl " << name << '\n'
1171 << MAI->getWeakDefDirective() << name << '\n';
1172 EmitAlignment(Align, GVar);
1175 O << "\t\t\t\t" << MAI->getCommentString() << ' ';
1176 WriteAsOperand(O, GVar, /*PrintType=*/false, GVar->getParent());
1179 EmitGlobalConstant(C);
1182 } else if (MAI->getLCOMMDirective() != NULL) {
1183 if (GVar->hasLocalLinkage()) {
1184 O << MAI->getLCOMMDirective() << name << "," << Size;
1186 O << MAI->getCOMMDirective() << name << "," << Size;
1187 if (MAI->getCOMMDirectiveTakesAlignment())
1188 O << ',' << (MAI->getAlignmentIsInBytes() ? (1 << Align) : Align);
1191 if (GVar->hasLocalLinkage())
1192 O << "\t.local\t" << name << "\n";
1193 O << MAI->getCOMMDirective() << name << "," << Size;
1194 if (MAI->getCOMMDirectiveTakesAlignment())
1195 O << "," << (MAI->getAlignmentIsInBytes() ? (1 << Align) : Align);
1198 O << "\t\t" << MAI->getCommentString() << " ";
1199 WriteAsOperand(O, GVar, /*PrintType=*/false, GVar->getParent());
1206 switch (GVar->getLinkage()) {
1207 case GlobalValue::CommonLinkage:
1208 case GlobalValue::LinkOnceAnyLinkage:
1209 case GlobalValue::LinkOnceODRLinkage:
1210 case GlobalValue::WeakAnyLinkage:
1211 case GlobalValue::WeakODRLinkage:
1212 case GlobalValue::LinkerPrivateLinkage:
1214 O << "\t.globl " << name << "\n"
1215 << "\t.weak_definition " << name << "\n";
1217 O << "\t.weak " << name << "\n";
1220 case GlobalValue::AppendingLinkage:
1221 // FIXME: appending linkage variables should go into a section of
1222 // their name or something. For now, just emit them as external.
1223 case GlobalValue::ExternalLinkage:
1224 O << "\t.globl " << name << "\n";
1226 case GlobalValue::PrivateLinkage:
1227 case GlobalValue::InternalLinkage:
1230 llvm_unreachable("Unknown linkage type!");
1233 EmitAlignment(Align, GVar);
1236 O << "\t\t\t\t" << MAI->getCommentString() << " ";
1237 WriteAsOperand(O, GVar, /*PrintType=*/false, GVar->getParent());
1240 if (MAI->hasDotTypeDotSizeDirective())
1241 O << "\t.size " << name << ", " << Size << "\n";
1243 EmitGlobalConstant(C);
1248 void ARMAsmPrinter::EmitEndOfAsmFile(Module &M) {
1249 if (Subtarget->isTargetDarwin()) {
1250 // All darwin targets use mach-o.
1251 TargetLoweringObjectFileMachO &TLOFMacho =
1252 static_cast<TargetLoweringObjectFileMachO &>(getObjFileLowering());
1253 MachineModuleInfoMachO &MMIMacho =
1254 MMI->getObjFileInfo<MachineModuleInfoMachO>();
1258 // Output non-lazy-pointers for external and common global variables.
1259 MachineModuleInfoMachO::SymbolListTy Stubs = MMIMacho.GetGVStubList();
1261 if (!Stubs.empty()) {
1262 // Switch with ".non_lazy_symbol_pointer" directive.
1263 OutStreamer.SwitchSection(TLOFMacho.getNonLazySymbolPointerSection());
1265 for (unsigned i = 0, e = Stubs.size(); i != e; ++i) {
1266 Stubs[i].first->print(O, MAI);
1267 O << ":\n\t.indirect_symbol ";
1268 Stubs[i].second->print(O, MAI);
1269 O << "\n\t.long\t0\n";
1273 Stubs = MMIMacho.GetHiddenGVStubList();
1274 if (!Stubs.empty()) {
1275 OutStreamer.SwitchSection(getObjFileLowering().getDataSection());
1277 for (unsigned i = 0, e = Stubs.size(); i != e; ++i) {
1278 Stubs[i].first->print(O, MAI);
1280 Stubs[i].second->print(O, MAI);
1285 // Funny Darwin hack: This flag tells the linker that no global symbols
1286 // contain code that falls through to other global symbols (e.g. the obvious
1287 // implementation of multiple entry points). If this doesn't occur, the
1288 // linker can safely perform dead code stripping. Since LLVM never
1289 // generates code that does this, it is always safe to set.
1290 OutStreamer.EmitAssemblerFlag(MCStreamer::SubsectionsViaSymbols);
1294 // Force static initialization.
1295 extern "C" void LLVMInitializeARMAsmPrinter() {
1296 RegisterAsmPrinter<ARMAsmPrinter> X(TheARMTarget);
1297 RegisterAsmPrinter<ARMAsmPrinter> Y(TheThumbTarget);