Renaming for consistency.
[oota-llvm.git] / lib / Target / ARM / AsmPrinter / ARMAsmPrinter.cpp
1 //===-- ARMAsmPrinter.cpp - ARM LLVM assembly writer ----------------------===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This file contains a printer that converts from our internal representation
11 // of machine-dependent LLVM code to GAS-format ARM assembly language.
12 //
13 //===----------------------------------------------------------------------===//
14
15 #define DEBUG_TYPE "asm-printer"
16 #include "ARM.h"
17 #include "ARMBuildAttrs.h"
18 #include "ARMTargetMachine.h"
19 #include "ARMAddressingModes.h"
20 #include "ARMConstantPoolValue.h"
21 #include "ARMMachineFunctionInfo.h"
22 #include "llvm/Constants.h"
23 #include "llvm/Module.h"
24 #include "llvm/MDNode.h"
25 #include "llvm/CodeGen/AsmPrinter.h"
26 #include "llvm/CodeGen/DwarfWriter.h"
27 #include "llvm/CodeGen/MachineModuleInfo.h"
28 #include "llvm/CodeGen/MachineFunctionPass.h"
29 #include "llvm/CodeGen/MachineJumpTableInfo.h"
30 #include "llvm/Target/TargetAsmInfo.h"
31 #include "llvm/Target/TargetData.h"
32 #include "llvm/Target/TargetMachine.h"
33 #include "llvm/Target/TargetOptions.h"
34 #include "llvm/ADT/Statistic.h"
35 #include "llvm/ADT/StringExtras.h"
36 #include "llvm/ADT/StringSet.h"
37 #include "llvm/Support/Compiler.h"
38 #include "llvm/Support/Mangler.h"
39 #include "llvm/Support/MathExtras.h"
40 #include "llvm/Support/raw_ostream.h"
41 #include <cctype>
42 using namespace llvm;
43
44 STATISTIC(EmittedInsts, "Number of machine instrs printed");
45
46 namespace {
47   class VISIBILITY_HIDDEN ARMAsmPrinter : public AsmPrinter {
48     DwarfWriter *DW;
49
50     /// Subtarget - Keep a pointer to the ARMSubtarget around so that we can
51     /// make the right decision when printing asm code for different targets.
52     const ARMSubtarget *Subtarget;
53
54     /// AFI - Keep a pointer to ARMFunctionInfo for the current
55     /// MachineFunction.
56     ARMFunctionInfo *AFI;
57
58     /// MCP - Keep a pointer to constantpool entries of the current
59     /// MachineFunction.
60     const MachineConstantPool *MCP;
61
62     /// We name each basic block in a Function with a unique number, so
63     /// that we can consistently refer to them later. This is cleared
64     /// at the beginning of each call to runOnMachineFunction().
65     ///
66     typedef std::map<const Value *, unsigned> ValueMapTy;
67     ValueMapTy NumberForBB;
68
69     /// GVNonLazyPtrs - Keeps the set of GlobalValues that require
70     /// non-lazy-pointers for indirect access.
71     StringSet<> GVNonLazyPtrs;
72
73     /// HiddenGVNonLazyPtrs - Keeps the set of GlobalValues with hidden
74     /// visibility that require non-lazy-pointers for indirect access.
75     StringSet<> HiddenGVNonLazyPtrs;
76
77     /// FnStubs - Keeps the set of external function GlobalAddresses that the
78     /// asm printer should generate stubs for.
79     StringSet<> FnStubs;
80
81     /// True if asm printer is printing a series of CONSTPOOL_ENTRY.
82     bool InCPMode;
83   public:
84     explicit ARMAsmPrinter(raw_ostream &O, TargetMachine &TM,
85                            const TargetAsmInfo *T, CodeGenOpt::Level OL,
86                            bool V)
87       : AsmPrinter(O, TM, T, OL, V), DW(0), AFI(NULL), MCP(NULL),
88         InCPMode(false) {
89       Subtarget = &TM.getSubtarget<ARMSubtarget>();
90     }
91
92     virtual const char *getPassName() const {
93       return "ARM Assembly Printer";
94     }
95
96     void printOperand(const MachineInstr *MI, int opNum,
97                       const char *Modifier = 0);
98     void printSOImmOperand(const MachineInstr *MI, int opNum);
99     void printSOImm2PartOperand(const MachineInstr *MI, int opNum);
100     void printSORegOperand(const MachineInstr *MI, int opNum);
101     void printAddrMode2Operand(const MachineInstr *MI, int OpNo);
102     void printAddrMode2OffsetOperand(const MachineInstr *MI, int OpNo);
103     void printAddrMode3Operand(const MachineInstr *MI, int OpNo);
104     void printAddrMode3OffsetOperand(const MachineInstr *MI, int OpNo);
105     void printAddrMode4Operand(const MachineInstr *MI, int OpNo,
106                                const char *Modifier = 0);
107     void printAddrMode5Operand(const MachineInstr *MI, int OpNo,
108                                const char *Modifier = 0);
109     void printAddrModePCOperand(const MachineInstr *MI, int OpNo,
110                                 const char *Modifier = 0);
111     void printBitfieldInvMaskImmOperand (const MachineInstr *MI, int OpNo);
112
113     void printThumbAddrModeRROperand(const MachineInstr *MI, int OpNo);
114     void printThumbAddrModeRI5Operand(const MachineInstr *MI, int OpNo,
115                                       unsigned Scale);
116     void printThumbAddrModeS1Operand(const MachineInstr *MI, int OpNo);
117     void printThumbAddrModeS2Operand(const MachineInstr *MI, int OpNo);
118     void printThumbAddrModeS4Operand(const MachineInstr *MI, int OpNo);
119     void printThumbAddrModeSPOperand(const MachineInstr *MI, int OpNo);
120
121     void printT2SOImmOperand(const MachineInstr *MI, int opNum);
122     void printT2SOOperand(const MachineInstr *MI, int OpNum);
123
124     void printPredicateOperand(const MachineInstr *MI, int opNum);
125     void printSBitModifierOperand(const MachineInstr *MI, int opNum);
126     void printPCLabel(const MachineInstr *MI, int opNum);
127     void printRegisterList(const MachineInstr *MI, int opNum);
128     void printCPInstOperand(const MachineInstr *MI, int opNum,
129                             const char *Modifier);
130     void printJTBlockOperand(const MachineInstr *MI, int opNum);
131
132     virtual bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,
133                                  unsigned AsmVariant, const char *ExtraCode);
134     virtual bool PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNo,
135                                        unsigned AsmVariant,
136                                        const char *ExtraCode);
137
138     void printModuleLevelGV(const GlobalVariable* GVar);
139     bool printInstruction(const MachineInstr *MI);  // autogenerated.
140     void printMachineInstruction(const MachineInstr *MI);
141     bool runOnMachineFunction(MachineFunction &F);
142     bool doInitialization(Module &M);
143     bool doFinalization(Module &M);
144
145     /// EmitMachineConstantPoolValue - Print a machine constantpool value to
146     /// the .s file.
147     virtual void EmitMachineConstantPoolValue(MachineConstantPoolValue *MCPV) {
148       printDataDirective(MCPV->getType());
149
150       ARMConstantPoolValue *ACPV = static_cast<ARMConstantPoolValue*>(MCPV);
151       GlobalValue *GV = ACPV->getGV();
152       std::string Name = GV ? Mang->getValueName(GV) : TAI->getGlobalPrefix();
153       if (!GV)
154         Name += ACPV->getSymbol();
155       if (ACPV->isNonLazyPointer()) {
156         if (GV->hasHiddenVisibility())
157           HiddenGVNonLazyPtrs.insert(Name);
158         else
159           GVNonLazyPtrs.insert(Name);
160         printSuffixedName(Name, "$non_lazy_ptr");
161       } else if (ACPV->isStub()) {
162         FnStubs.insert(Name);
163         printSuffixedName(Name, "$stub");
164       } else
165         O << Name;
166       if (ACPV->hasModifier()) O << "(" << ACPV->getModifier() << ")";
167       if (ACPV->getPCAdjustment() != 0) {
168         O << "-(" << TAI->getPrivateGlobalPrefix() << "PC"
169           << utostr(ACPV->getLabelId())
170           << "+" << (unsigned)ACPV->getPCAdjustment();
171          if (ACPV->mustAddCurrentAddress())
172            O << "-.";
173          O << ")";
174       }
175       O << "\n";
176     }
177     
178     void getAnalysisUsage(AnalysisUsage &AU) const {
179       AsmPrinter::getAnalysisUsage(AU);
180       AU.setPreservesAll();
181       AU.addRequired<MachineModuleInfo>();
182       AU.addRequired<DwarfWriter>();
183     }
184   };
185 } // end of anonymous namespace
186
187 #include "ARMGenAsmWriter.inc"
188
189 /// runOnMachineFunction - This uses the printInstruction()
190 /// method to print assembly for each instruction.
191 ///
192 bool ARMAsmPrinter::runOnMachineFunction(MachineFunction &MF) {
193   this->MF = &MF;
194
195   AFI = MF.getInfo<ARMFunctionInfo>();
196   MCP = MF.getConstantPool();
197
198   SetupMachineFunction(MF);
199   O << "\n";
200
201   // NOTE: we don't print out constant pools here, they are handled as
202   // instructions.
203
204   O << "\n";
205   // Print out labels for the function.
206   const Function *F = MF.getFunction();
207   switch (F->getLinkage()) {
208   default: assert(0 && "Unknown linkage type!");
209   case Function::PrivateLinkage:
210   case Function::InternalLinkage:
211     SwitchToTextSection("\t.text", F);
212     break;
213   case Function::ExternalLinkage:
214     SwitchToTextSection("\t.text", F);
215     O << "\t.globl\t" << CurrentFnName << "\n";
216     break;
217   case Function::WeakAnyLinkage:
218   case Function::WeakODRLinkage:
219   case Function::LinkOnceAnyLinkage:
220   case Function::LinkOnceODRLinkage:
221     if (Subtarget->isTargetDarwin()) {
222       SwitchToTextSection(
223                 ".section __TEXT,__textcoal_nt,coalesced,pure_instructions", F);
224       O << "\t.globl\t" << CurrentFnName << "\n";
225       O << "\t.weak_definition\t" << CurrentFnName << "\n";
226     } else {
227       O << TAI->getWeakRefDirective() << CurrentFnName << "\n";
228     }
229     break;
230   }
231
232   printVisibility(CurrentFnName, F->getVisibility());
233
234   if (AFI->isThumbFunction()) {
235     EmitAlignment(1, F, AFI->getAlign());
236     O << "\t.code\t16\n";
237     O << "\t.thumb_func";
238     if (Subtarget->isTargetDarwin())
239       O << "\t" << CurrentFnName;
240     O << "\n";
241     InCPMode = false;
242   } else
243     EmitAlignment(2, F);
244
245   O << CurrentFnName << ":\n";
246   // Emit pre-function debug information.
247   DW->BeginFunction(&MF);
248
249   if (Subtarget->isTargetDarwin()) {
250     // If the function is empty, then we need to emit *something*. Otherwise,
251     // the function's label might be associated with something that it wasn't
252     // meant to be associated with. We emit a noop in this situation.
253     MachineFunction::iterator I = MF.begin();
254
255     if (++I == MF.end() && MF.front().empty())
256       O << "\tnop\n";
257   }
258
259   // Print out code for the function.
260   for (MachineFunction::const_iterator I = MF.begin(), E = MF.end();
261        I != E; ++I) {
262     // Print a label for the basic block.
263     if (I != MF.begin()) {
264       printBasicBlockLabel(I, true, true, VerboseAsm);
265       O << '\n';
266     }
267     for (MachineBasicBlock::const_iterator II = I->begin(), E = I->end();
268          II != E; ++II) {
269       // Print the assembly for the instruction.
270       printMachineInstruction(II);
271     }
272   }
273
274   if (TAI->hasDotTypeDotSizeDirective())
275     O << "\t.size " << CurrentFnName << ", .-" << CurrentFnName << "\n";
276
277   // Emit post-function debug information.
278   DW->EndFunction(&MF);
279
280   O.flush();
281
282   return false;
283 }
284
285 void ARMAsmPrinter::printOperand(const MachineInstr *MI, int opNum,
286                                  const char *Modifier) {
287   const MachineOperand &MO = MI->getOperand(opNum);
288   switch (MO.getType()) {
289   case MachineOperand::MO_Register: {
290     unsigned Reg = MO.getReg();
291     if (TargetRegisterInfo::isPhysicalRegister(Reg)) {
292       if (Modifier && strcmp(Modifier, "dregpair") == 0) {
293         unsigned DRegLo = TRI->getSubReg(Reg, 5); // arm_dsubreg_0
294         unsigned DRegHi = TRI->getSubReg(Reg, 6); // arm_dsubreg_1
295         O << '{'
296           << TRI->getAsmName(DRegLo) << "-" << TRI->getAsmName(DRegHi)
297           << '}';
298       } else {
299         O << TRI->getAsmName(Reg);
300       }
301     } else
302       assert(0 && "not implemented");
303     break;
304   }
305   case MachineOperand::MO_Immediate: {
306     if (!Modifier || strcmp(Modifier, "no_hash") != 0)
307       O << "#";
308
309     O << MO.getImm();
310     break;
311   }
312   case MachineOperand::MO_MachineBasicBlock:
313     printBasicBlockLabel(MO.getMBB());
314     return;
315   case MachineOperand::MO_GlobalAddress: {
316     bool isCallOp = Modifier && !strcmp(Modifier, "call");
317     GlobalValue *GV = MO.getGlobal();
318     std::string Name = Mang->getValueName(GV);
319     bool isExt = (GV->isDeclaration() || GV->hasWeakLinkage() ||
320                   GV->hasLinkOnceLinkage());
321     if (isExt && isCallOp && Subtarget->isTargetDarwin() &&
322         TM.getRelocationModel() != Reloc::Static) {
323       printSuffixedName(Name, "$stub");
324       FnStubs.insert(Name);
325     } else
326       O << Name;
327
328     printOffset(MO.getOffset());
329
330     if (isCallOp && Subtarget->isTargetELF() &&
331         TM.getRelocationModel() == Reloc::PIC_)
332       O << "(PLT)";
333     break;
334   }
335   case MachineOperand::MO_ExternalSymbol: {
336     bool isCallOp = Modifier && !strcmp(Modifier, "call");
337     std::string Name(TAI->getGlobalPrefix());
338     Name += MO.getSymbolName();
339     if (isCallOp && Subtarget->isTargetDarwin() &&
340         TM.getRelocationModel() != Reloc::Static) {
341       printSuffixedName(Name, "$stub");
342       FnStubs.insert(Name);
343     } else
344       O << Name;
345     if (isCallOp && Subtarget->isTargetELF() &&
346         TM.getRelocationModel() == Reloc::PIC_)
347       O << "(PLT)";
348     break;
349   }
350   case MachineOperand::MO_ConstantPoolIndex:
351     O << TAI->getPrivateGlobalPrefix() << "CPI" << getFunctionNumber()
352       << '_' << MO.getIndex();
353     break;
354   case MachineOperand::MO_JumpTableIndex:
355     O << TAI->getPrivateGlobalPrefix() << "JTI" << getFunctionNumber()
356       << '_' << MO.getIndex();
357     break;
358   default:
359     O << "<unknown operand type>"; abort (); break;
360   }
361 }
362
363 static void printSOImm(raw_ostream &O, int64_t V, bool VerboseAsm,
364                        const TargetAsmInfo *TAI) {
365   assert(V < (1 << 12) && "Not a valid so_imm value!");
366   unsigned Imm = ARM_AM::getSOImmValImm(V);
367   unsigned Rot = ARM_AM::getSOImmValRot(V);
368
369   // Print low-level immediate formation info, per
370   // A5.1.3: "Data-processing operands - Immediate".
371   if (Rot) {
372     O << "#" << Imm << ", " << Rot;
373     // Pretty printed version.
374     if (VerboseAsm)
375       O << ' ' << TAI->getCommentString()
376         << ' ' << (int)ARM_AM::rotr32(Imm, Rot);
377   } else {
378     O << "#" << Imm;
379   }
380 }
381
382 /// printSOImmOperand - SOImm is 4-bit rotate amount in bits 8-11 with 8-bit
383 /// immediate in bits 0-7.
384 void ARMAsmPrinter::printSOImmOperand(const MachineInstr *MI, int OpNum) {
385   const MachineOperand &MO = MI->getOperand(OpNum);
386   assert(MO.isImm() && "Not a valid so_imm value!");
387   printSOImm(O, MO.getImm(), VerboseAsm, TAI);
388 }
389
390 /// printSOImm2PartOperand - SOImm is broken into two pieces using a 'mov'
391 /// followed by an 'orr' to materialize.
392 void ARMAsmPrinter::printSOImm2PartOperand(const MachineInstr *MI, int OpNum) {
393   const MachineOperand &MO = MI->getOperand(OpNum);
394   assert(MO.isImm() && "Not a valid so_imm value!");
395   unsigned V1 = ARM_AM::getSOImmTwoPartFirst(MO.getImm());
396   unsigned V2 = ARM_AM::getSOImmTwoPartSecond(MO.getImm());
397   printSOImm(O, ARM_AM::getSOImmVal(V1), VerboseAsm, TAI);
398   O << "\n\torr";
399   printPredicateOperand(MI, 2);
400   O << " ";
401   printOperand(MI, 0); 
402   O << ", ";
403   printOperand(MI, 0); 
404   O << ", ";
405   printSOImm(O, ARM_AM::getSOImmVal(V2), VerboseAsm, TAI);
406 }
407
408 // so_reg is a 4-operand unit corresponding to register forms of the A5.1
409 // "Addressing Mode 1 - Data-processing operands" forms.  This includes:
410 //    REG 0   0           - e.g. R5
411 //    REG REG 0,SH_OPC    - e.g. R5, ROR R3
412 //    REG 0   IMM,SH_OPC  - e.g. R5, LSL #3
413 void ARMAsmPrinter::printSORegOperand(const MachineInstr *MI, int Op) {
414   const MachineOperand &MO1 = MI->getOperand(Op);
415   const MachineOperand &MO2 = MI->getOperand(Op+1);
416   const MachineOperand &MO3 = MI->getOperand(Op+2);
417
418   assert(TargetRegisterInfo::isPhysicalRegister(MO1.getReg()));
419   O << TM.getRegisterInfo()->get(MO1.getReg()).AsmName;
420
421   // Print the shift opc.
422   O << ", "
423     << ARM_AM::getShiftOpcStr(ARM_AM::getSORegShOp(MO3.getImm()))
424     << " ";
425
426   if (MO2.getReg()) {
427     assert(TargetRegisterInfo::isPhysicalRegister(MO2.getReg()));
428     O << TM.getRegisterInfo()->get(MO2.getReg()).AsmName;
429     assert(ARM_AM::getSORegOffset(MO3.getImm()) == 0);
430   } else {
431     O << "#" << ARM_AM::getSORegOffset(MO3.getImm());
432   }
433 }
434
435 void ARMAsmPrinter::printAddrMode2Operand(const MachineInstr *MI, int Op) {
436   const MachineOperand &MO1 = MI->getOperand(Op);
437   const MachineOperand &MO2 = MI->getOperand(Op+1);
438   const MachineOperand &MO3 = MI->getOperand(Op+2);
439
440   if (!MO1.isReg()) {   // FIXME: This is for CP entries, but isn't right.
441     printOperand(MI, Op);
442     return;
443   }
444
445   O << "[" << TM.getRegisterInfo()->get(MO1.getReg()).AsmName;
446
447   if (!MO2.getReg()) {
448     if (ARM_AM::getAM2Offset(MO3.getImm()))  // Don't print +0.
449       O << ", #"
450         << (char)ARM_AM::getAM2Op(MO3.getImm())
451         << ARM_AM::getAM2Offset(MO3.getImm());
452     O << "]";
453     return;
454   }
455
456   O << ", "
457     << (char)ARM_AM::getAM2Op(MO3.getImm())
458     << TM.getRegisterInfo()->get(MO2.getReg()).AsmName;
459   
460   if (unsigned ShImm = ARM_AM::getAM2Offset(MO3.getImm()))
461     O << ", "
462       << ARM_AM::getShiftOpcStr(ARM_AM::getAM2ShiftOpc(MO3.getImm()))
463       << " #" << ShImm;
464   O << "]";
465 }
466
467 void ARMAsmPrinter::printAddrMode2OffsetOperand(const MachineInstr *MI, int Op){
468   const MachineOperand &MO1 = MI->getOperand(Op);
469   const MachineOperand &MO2 = MI->getOperand(Op+1);
470
471   if (!MO1.getReg()) {
472     unsigned ImmOffs = ARM_AM::getAM2Offset(MO2.getImm());
473     assert(ImmOffs && "Malformed indexed load / store!");
474     O << "#"
475       << (char)ARM_AM::getAM2Op(MO2.getImm())
476       << ImmOffs;
477     return;
478   }
479
480   O << (char)ARM_AM::getAM2Op(MO2.getImm())
481     << TM.getRegisterInfo()->get(MO1.getReg()).AsmName;
482   
483   if (unsigned ShImm = ARM_AM::getAM2Offset(MO2.getImm()))
484     O << ", "
485       << ARM_AM::getShiftOpcStr(ARM_AM::getAM2ShiftOpc(MO2.getImm()))
486       << " #" << ShImm;
487 }
488
489 void ARMAsmPrinter::printAddrMode3Operand(const MachineInstr *MI, int Op) {
490   const MachineOperand &MO1 = MI->getOperand(Op);
491   const MachineOperand &MO2 = MI->getOperand(Op+1);
492   const MachineOperand &MO3 = MI->getOperand(Op+2);
493   
494   assert(TargetRegisterInfo::isPhysicalRegister(MO1.getReg()));
495   O << "[" << TM.getRegisterInfo()->get(MO1.getReg()).AsmName;
496
497   if (MO2.getReg()) {
498     O << ", "
499       << (char)ARM_AM::getAM3Op(MO3.getImm())
500       << TM.getRegisterInfo()->get(MO2.getReg()).AsmName
501       << "]";
502     return;
503   }
504   
505   if (unsigned ImmOffs = ARM_AM::getAM3Offset(MO3.getImm()))
506     O << ", #"
507       << (char)ARM_AM::getAM3Op(MO3.getImm())
508       << ImmOffs;
509   O << "]";
510 }
511
512 void ARMAsmPrinter::printAddrMode3OffsetOperand(const MachineInstr *MI, int Op){
513   const MachineOperand &MO1 = MI->getOperand(Op);
514   const MachineOperand &MO2 = MI->getOperand(Op+1);
515
516   if (MO1.getReg()) {
517     O << (char)ARM_AM::getAM3Op(MO2.getImm())
518       << TM.getRegisterInfo()->get(MO1.getReg()).AsmName;
519     return;
520   }
521
522   unsigned ImmOffs = ARM_AM::getAM3Offset(MO2.getImm());
523   assert(ImmOffs && "Malformed indexed load / store!");
524   O << "#"
525     << (char)ARM_AM::getAM3Op(MO2.getImm())
526     << ImmOffs;
527 }
528   
529 void ARMAsmPrinter::printAddrMode4Operand(const MachineInstr *MI, int Op,
530                                           const char *Modifier) {
531   const MachineOperand &MO1 = MI->getOperand(Op);
532   const MachineOperand &MO2 = MI->getOperand(Op+1);
533   ARM_AM::AMSubMode Mode = ARM_AM::getAM4SubMode(MO2.getImm());
534   if (Modifier && strcmp(Modifier, "submode") == 0) {
535     if (MO1.getReg() == ARM::SP) {
536       bool isLDM = (MI->getOpcode() == ARM::LDM ||
537                     MI->getOpcode() == ARM::LDM_RET);
538       O << ARM_AM::getAMSubModeAltStr(Mode, isLDM);
539     } else
540       O << ARM_AM::getAMSubModeStr(Mode);
541   } else {
542     printOperand(MI, Op);
543     if (ARM_AM::getAM4WBFlag(MO2.getImm()))
544       O << "!";
545   }
546 }
547
548 void ARMAsmPrinter::printAddrMode5Operand(const MachineInstr *MI, int Op,
549                                           const char *Modifier) {
550   const MachineOperand &MO1 = MI->getOperand(Op);
551   const MachineOperand &MO2 = MI->getOperand(Op+1);
552
553   if (!MO1.isReg()) {   // FIXME: This is for CP entries, but isn't right.
554     printOperand(MI, Op);
555     return;
556   }
557   
558   assert(TargetRegisterInfo::isPhysicalRegister(MO1.getReg()));
559
560   if (Modifier && strcmp(Modifier, "submode") == 0) {
561     ARM_AM::AMSubMode Mode = ARM_AM::getAM5SubMode(MO2.getImm());
562     if (MO1.getReg() == ARM::SP) {
563       bool isFLDM = (MI->getOpcode() == ARM::FLDMD ||
564                      MI->getOpcode() == ARM::FLDMS);
565       O << ARM_AM::getAMSubModeAltStr(Mode, isFLDM);
566     } else
567       O << ARM_AM::getAMSubModeStr(Mode);
568     return;
569   } else if (Modifier && strcmp(Modifier, "base") == 0) {
570     // Used for FSTM{D|S} and LSTM{D|S} operations.
571     O << TM.getRegisterInfo()->get(MO1.getReg()).AsmName;
572     if (ARM_AM::getAM5WBFlag(MO2.getImm()))
573       O << "!";
574     return;
575   }
576   
577   O << "[" << TM.getRegisterInfo()->get(MO1.getReg()).AsmName;
578   
579   if (unsigned ImmOffs = ARM_AM::getAM5Offset(MO2.getImm())) {
580     O << ", #"
581       << (char)ARM_AM::getAM5Op(MO2.getImm())
582       << ImmOffs*4;
583   }
584   O << "]";
585 }
586
587 void ARMAsmPrinter::printAddrModePCOperand(const MachineInstr *MI, int Op,
588                                            const char *Modifier) {
589   if (Modifier && strcmp(Modifier, "label") == 0) {
590     printPCLabel(MI, Op+1);
591     return;
592   }
593
594   const MachineOperand &MO1 = MI->getOperand(Op);
595   assert(TargetRegisterInfo::isPhysicalRegister(MO1.getReg()));
596   O << "[pc, +" << TM.getRegisterInfo()->get(MO1.getReg()).AsmName << "]";
597 }
598
599 void
600 ARMAsmPrinter::printBitfieldInvMaskImmOperand(const MachineInstr *MI, int Op) {
601   const MachineOperand &MO = MI->getOperand(Op);
602   uint32_t v = ~MO.getImm();
603   int32_t lsb = CountTrailingZeros_32(v);
604   int32_t width = (32 - CountLeadingZeros_32 (v)) - lsb;
605   assert(MO.isImm() && "Not a valid bf_inv_mask_imm value!");
606   O << "#" << lsb << ", #" << width;
607 }
608
609 void
610 ARMAsmPrinter::printThumbAddrModeRROperand(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()).AsmName;
614   O << ", " << TM.getRegisterInfo()->get(MO2.getReg()).AsmName << "]";
615 }
616
617 void
618 ARMAsmPrinter::printThumbAddrModeRI5Operand(const MachineInstr *MI, int Op,
619                                             unsigned Scale) {
620   const MachineOperand &MO1 = MI->getOperand(Op);
621   const MachineOperand &MO2 = MI->getOperand(Op+1);
622   const MachineOperand &MO3 = MI->getOperand(Op+2);
623
624   if (!MO1.isReg()) {   // FIXME: This is for CP entries, but isn't right.
625     printOperand(MI, Op);
626     return;
627   }
628
629   O << "[" << TM.getRegisterInfo()->get(MO1.getReg()).AsmName;
630   if (MO3.getReg())
631     O << ", " << TM.getRegisterInfo()->get(MO3.getReg()).AsmName;
632   else if (unsigned ImmOffs = MO2.getImm()) {
633     O << ", #" << ImmOffs;
634     if (Scale > 1)
635       O << " * " << Scale;
636   }
637   O << "]";
638 }
639
640 void
641 ARMAsmPrinter::printThumbAddrModeS1Operand(const MachineInstr *MI, int Op) {
642   printThumbAddrModeRI5Operand(MI, Op, 1);
643 }
644 void
645 ARMAsmPrinter::printThumbAddrModeS2Operand(const MachineInstr *MI, int Op) {
646   printThumbAddrModeRI5Operand(MI, Op, 2);
647 }
648 void
649 ARMAsmPrinter::printThumbAddrModeS4Operand(const MachineInstr *MI, int Op) {
650   printThumbAddrModeRI5Operand(MI, Op, 4);
651 }
652
653 void ARMAsmPrinter::printThumbAddrModeSPOperand(const MachineInstr *MI,int Op) {
654   const MachineOperand &MO1 = MI->getOperand(Op);
655   const MachineOperand &MO2 = MI->getOperand(Op+1);
656   O << "[" << TM.getRegisterInfo()->get(MO1.getReg()).AsmName;
657   if (unsigned ImmOffs = MO2.getImm())
658     O << ", #" << ImmOffs << " * 4";
659   O << "]";
660 }
661
662 /// printT2SOImmOperand - T2SOImm is:
663 ///  1. a 4-bit splat control value and 8 bit immediate value
664 ///  2. a 5-bit rotate amount and a non-zero 8-bit immediate value
665 ///     represented by a normalizedin 7-bit value (msb is always 1)
666 void ARMAsmPrinter::printT2SOImmOperand(const MachineInstr *MI, int OpNum) {
667   const MachineOperand &MO = MI->getOperand(OpNum);
668   assert(MO.isImm() && "Not a valid so_imm value!");
669
670   unsigned Imm = ARM_AM::getT2SOImmValDecode(MO.getImm());  
671   // Always print the immediate directly, as the "rotate" form
672   // is deprecated in some contexts.
673   O << "#" << Imm;
674 }
675
676 // Constant shifts t2_so_reg is a 2-operand unit corresponding to the Thumb2
677 // register with shift forms.
678 // REG 0   0           - e.g. R5
679 // REG IMM, SH_OPC     - e.g. R5, LSL #3
680 void ARMAsmPrinter::printT2SOOperand(const MachineInstr *MI, int OpNum) {
681   const MachineOperand &MO1 = MI->getOperand(OpNum);
682   const MachineOperand &MO2 = MI->getOperand(OpNum+1);
683
684   unsigned Reg = MO1.getReg();
685   assert(TargetRegisterInfo::isPhysicalRegister(Reg));
686   O << TM.getRegisterInfo()->getAsmName(Reg);
687
688   // Print the shift opc.
689   O << ", "
690     << ARM_AM::getShiftOpcStr(ARM_AM::getSORegShOp(MO2.getImm()))
691     << " ";
692
693   assert(MO2.isImm() && "Not a valid t2_so_reg value!");
694   O << "#" << ARM_AM::getSORegOffset(MO2.getImm());
695 }
696
697
698 void ARMAsmPrinter::printPredicateOperand(const MachineInstr *MI, int opNum) {
699   ARMCC::CondCodes CC = (ARMCC::CondCodes)MI->getOperand(opNum).getImm();
700   if (CC != ARMCC::AL)
701     O << ARMCondCodeToString(CC);
702 }
703
704 void ARMAsmPrinter::printSBitModifierOperand(const MachineInstr *MI, int opNum){
705   unsigned Reg = MI->getOperand(opNum).getReg();
706   if (Reg) {
707     assert(Reg == ARM::CPSR && "Expect ARM CPSR register!");
708     O << 's';
709   }
710 }
711
712 void ARMAsmPrinter::printPCLabel(const MachineInstr *MI, int opNum) {
713   int Id = (int)MI->getOperand(opNum).getImm();
714   O << TAI->getPrivateGlobalPrefix() << "PC" << Id;
715 }
716
717 void ARMAsmPrinter::printRegisterList(const MachineInstr *MI, int opNum) {
718   O << "{";
719   for (unsigned i = opNum, e = MI->getNumOperands(); i != e; ++i) {
720     printOperand(MI, i);
721     if (i != e-1) O << ", ";
722   }
723   O << "}";
724 }
725
726 void ARMAsmPrinter::printCPInstOperand(const MachineInstr *MI, int OpNo,
727                                        const char *Modifier) {
728   assert(Modifier && "This operand only works with a modifier!");
729   // There are two aspects to a CONSTANTPOOL_ENTRY operand, the label and the
730   // data itself.
731   if (!strcmp(Modifier, "label")) {
732     unsigned ID = MI->getOperand(OpNo).getImm();
733     O << TAI->getPrivateGlobalPrefix() << "CPI" << getFunctionNumber()
734       << '_' << ID << ":\n";
735   } else {
736     assert(!strcmp(Modifier, "cpentry") && "Unknown modifier for CPE");
737     unsigned CPI = MI->getOperand(OpNo).getIndex();
738
739     const MachineConstantPoolEntry &MCPE = MCP->getConstants()[CPI];
740     
741     if (MCPE.isMachineConstantPoolEntry()) {
742       EmitMachineConstantPoolValue(MCPE.Val.MachineCPVal);
743     } else {
744       EmitGlobalConstant(MCPE.Val.ConstVal);
745     }
746   }
747 }
748
749 void ARMAsmPrinter::printJTBlockOperand(const MachineInstr *MI, int OpNo) {
750   const MachineOperand &MO1 = MI->getOperand(OpNo);
751   const MachineOperand &MO2 = MI->getOperand(OpNo+1); // Unique Id
752   unsigned JTI = MO1.getIndex();
753   O << TAI->getPrivateGlobalPrefix() << "JTI" << getFunctionNumber()
754     << '_' << JTI << '_' << MO2.getImm() << ":\n";
755
756   const char *JTEntryDirective = TAI->getJumpTableDirective();
757   if (!JTEntryDirective)
758     JTEntryDirective = TAI->getData32bitsDirective();
759
760   const MachineFunction *MF = MI->getParent()->getParent();
761   const MachineJumpTableInfo *MJTI = MF->getJumpTableInfo();
762   const std::vector<MachineJumpTableEntry> &JT = MJTI->getJumpTables();
763   const std::vector<MachineBasicBlock*> &JTBBs = JT[JTI].MBBs;
764   bool UseSet= TAI->getSetDirective() && TM.getRelocationModel() == Reloc::PIC_;
765   std::set<MachineBasicBlock*> JTSets;
766   for (unsigned i = 0, e = JTBBs.size(); i != e; ++i) {
767     MachineBasicBlock *MBB = JTBBs[i];
768     if (UseSet && JTSets.insert(MBB).second)
769       printPICJumpTableSetLabel(JTI, MO2.getImm(), MBB);
770
771     O << JTEntryDirective << ' ';
772     if (UseSet)
773       O << TAI->getPrivateGlobalPrefix() << getFunctionNumber()
774         << '_' << JTI << '_' << MO2.getImm()
775         << "_set_" << MBB->getNumber();
776     else if (TM.getRelocationModel() == Reloc::PIC_) {
777       printBasicBlockLabel(MBB, false, false, false);
778       // If the arch uses custom Jump Table directives, don't calc relative to JT
779       if (!TAI->getJumpTableDirective()) 
780         O << '-' << TAI->getPrivateGlobalPrefix() << "JTI"
781           << getFunctionNumber() << '_' << JTI << '_' << MO2.getImm();
782     } else
783       printBasicBlockLabel(MBB, false, false, false);
784     if (i != e-1)
785       O << '\n';
786   }
787 }
788
789
790 bool ARMAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,
791                                     unsigned AsmVariant, const char *ExtraCode){
792   // Does this asm operand have a single letter operand modifier?
793   if (ExtraCode && ExtraCode[0]) {
794     if (ExtraCode[1] != 0) return true; // Unknown modifier.
795     
796     switch (ExtraCode[0]) {
797     default: return true;  // Unknown modifier.
798     case 'a': // Don't print "#" before a global var name or constant.
799     case 'c': // Don't print "$" before a global var name or constant.
800       printOperand(MI, OpNo, "no_hash");
801       return false;
802     case 'P': // Print a VFP double precision register.
803       printOperand(MI, OpNo);
804       return false;
805     case 'Q':
806       if (TM.getTargetData()->isLittleEndian())
807         break;
808       // Fallthrough
809     case 'R':
810       if (TM.getTargetData()->isBigEndian())
811         break;
812       // Fallthrough
813     case 'H': // Write second word of DI / DF reference.  
814       // Verify that this operand has two consecutive registers.
815       if (!MI->getOperand(OpNo).isReg() ||
816           OpNo+1 == MI->getNumOperands() ||
817           !MI->getOperand(OpNo+1).isReg())
818         return true;
819       ++OpNo;   // Return the high-part.
820     }
821   }
822   
823   printOperand(MI, OpNo);
824   return false;
825 }
826
827 bool ARMAsmPrinter::PrintAsmMemoryOperand(const MachineInstr *MI,
828                                           unsigned OpNo, unsigned AsmVariant,
829                                           const char *ExtraCode) {
830   if (ExtraCode && ExtraCode[0])
831     return true; // Unknown modifier.
832   printAddrMode2Operand(MI, OpNo);
833   return false;
834 }
835
836 void ARMAsmPrinter::printMachineInstruction(const MachineInstr *MI) {
837   ++EmittedInsts;
838
839   int Opc = MI->getOpcode();
840   switch (Opc) {
841   case ARM::CONSTPOOL_ENTRY:
842     if (!InCPMode && AFI->isThumbFunction()) {
843       EmitAlignment(2);
844       InCPMode = true;
845     }
846     break;
847   default: {
848     if (InCPMode && AFI->isThumbFunction())
849       InCPMode = false;
850   }}
851
852   // Call the autogenerated instruction printer routines.
853   printInstruction(MI);
854 }
855
856 bool ARMAsmPrinter::doInitialization(Module &M) {
857
858   bool Result = AsmPrinter::doInitialization(M);
859   DW = getAnalysisIfAvailable<DwarfWriter>();
860
861   // Thumb-2 instructions are supported only in unified assembler syntax mode.
862   if (Subtarget->hasThumb2())
863     O << "\t.syntax unified\n";
864
865   // Emit ARM Build Attributes
866   if (Subtarget->isTargetELF()) {
867     // CPU Type
868     std::string CPUString = Subtarget->getCPUString();
869     if (CPUString != "generic")
870       O << "\t.cpu " << CPUString << '\n';
871
872     // FIXME: Emit FPU type
873     if (Subtarget->hasVFP2())
874       O << "\t.eabi_attribute " << ARMBuildAttrs::VFP_arch << ", 2\n";
875
876     // Signal various FP modes.
877     if (!UnsafeFPMath)
878       O << "\t.eabi_attribute " << ARMBuildAttrs::ABI_FP_denormal << ", 1\n"
879         << "\t.eabi_attribute " << ARMBuildAttrs::ABI_FP_exceptions << ", 1\n";
880
881     if (FiniteOnlyFPMath())
882       O << "\t.eabi_attribute " << ARMBuildAttrs::ABI_FP_number_model << ", 1\n";
883     else
884       O << "\t.eabi_attribute " << ARMBuildAttrs::ABI_FP_number_model << ", 3\n";
885
886     // 8-bytes alignment stuff.
887     O << "\t.eabi_attribute " << ARMBuildAttrs::ABI_align8_needed << ", 1\n"
888       << "\t.eabi_attribute " << ARMBuildAttrs::ABI_align8_preserved << ", 1\n";
889
890     // FIXME: Should we signal R9 usage?
891   }
892
893   return Result;
894 }
895
896 /// PrintUnmangledNameSafely - Print out the printable characters in the name.
897 /// Don't print things like \\n or \\0.
898 static void PrintUnmangledNameSafely(const Value *V, raw_ostream &OS) {
899   for (const char *Name = V->getNameStart(), *E = Name+V->getNameLen();
900        Name != E; ++Name)
901     if (isprint(*Name))
902       OS << *Name;
903 }
904
905 void ARMAsmPrinter::printModuleLevelGV(const GlobalVariable* GVar) {
906   const TargetData *TD = TM.getTargetData();
907
908   if (!GVar->hasInitializer())   // External global require no code
909     return;
910
911   // Check to see if this is a special global used by LLVM, if so, emit it.
912
913   if (EmitSpecialLLVMGlobal(GVar)) {
914     if (Subtarget->isTargetDarwin() &&
915         TM.getRelocationModel() == Reloc::Static) {
916       if (GVar->getName() == "llvm.global_ctors")
917         O << ".reference .constructors_used\n";
918       else if (GVar->getName() == "llvm.global_dtors")
919         O << ".reference .destructors_used\n";
920     }
921     return;
922   }
923
924   std::string name = Mang->getValueName(GVar);
925   Constant *C = GVar->getInitializer();
926   if (isa<MDNode>(C) || isa<MDString>(C))
927     return;
928   const Type *Type = C->getType();
929   unsigned Size = TD->getTypeAllocSize(Type);
930   unsigned Align = TD->getPreferredAlignmentLog(GVar);
931   bool isDarwin = Subtarget->isTargetDarwin();
932
933   printVisibility(name, GVar->getVisibility());
934
935   if (Subtarget->isTargetELF())
936     O << "\t.type " << name << ",%object\n";
937
938   if (C->isNullValue() && !GVar->hasSection() && !GVar->isThreadLocal() &&
939       !(isDarwin &&
940         TAI->SectionKindForGlobal(GVar) == SectionKind::RODataMergeStr)) {
941     // FIXME: This seems to be pretty darwin-specific
942
943     if (GVar->hasExternalLinkage()) {
944       SwitchToSection(TAI->SectionForGlobal(GVar));
945       if (const char *Directive = TAI->getZeroFillDirective()) {
946         O << "\t.globl\t" << name << "\n";
947         O << Directive << "__DATA, __common, " << name << ", "
948           << Size << ", " << Align << "\n";
949         return;
950       }
951     }
952
953     if (GVar->hasLocalLinkage() || GVar->isWeakForLinker()) {
954       if (Size == 0) Size = 1;   // .comm Foo, 0 is undefined, avoid it.
955
956       if (isDarwin) {
957         if (GVar->hasLocalLinkage()) {
958           O << TAI->getLCOMMDirective()  << name << "," << Size
959             << ',' << Align;
960         } else if (GVar->hasCommonLinkage()) {
961           O << TAI->getCOMMDirective()  << name << "," << Size
962             << ',' << Align;
963         } else {
964           SwitchToSection(TAI->SectionForGlobal(GVar));
965           O << "\t.globl " << name << '\n'
966             << TAI->getWeakDefDirective() << name << '\n';
967           EmitAlignment(Align, GVar);
968           O << name << ":";
969           if (VerboseAsm) {
970             O << "\t\t\t\t" << TAI->getCommentString() << ' ';
971             PrintUnmangledNameSafely(GVar, O);
972           }
973           O << '\n';
974           EmitGlobalConstant(C);
975           return;
976         }
977       } else if (TAI->getLCOMMDirective() != NULL) {
978         if (GVar->hasLocalLinkage()) {
979           O << TAI->getLCOMMDirective() << name << "," << Size;
980         } else {
981           O << TAI->getCOMMDirective()  << name << "," << Size;
982           if (TAI->getCOMMDirectiveTakesAlignment())
983             O << ',' << (TAI->getAlignmentIsInBytes() ? (1 << Align) : Align);
984         }
985       } else {
986         SwitchToSection(TAI->SectionForGlobal(GVar));
987         if (GVar->hasLocalLinkage())
988           O << "\t.local\t" << name << "\n";
989         O << TAI->getCOMMDirective()  << name << "," << Size;
990         if (TAI->getCOMMDirectiveTakesAlignment())
991           O << "," << (TAI->getAlignmentIsInBytes() ? (1 << Align) : Align);
992       }
993       if (VerboseAsm) {
994         O << "\t\t" << TAI->getCommentString() << " ";
995         PrintUnmangledNameSafely(GVar, O);
996       }
997       O << "\n";
998       return;
999     }
1000   }
1001
1002   SwitchToSection(TAI->SectionForGlobal(GVar));
1003   switch (GVar->getLinkage()) {
1004    case GlobalValue::CommonLinkage:
1005    case GlobalValue::LinkOnceAnyLinkage:
1006    case GlobalValue::LinkOnceODRLinkage:
1007    case GlobalValue::WeakAnyLinkage:
1008    case GlobalValue::WeakODRLinkage:
1009     if (isDarwin) {
1010       O << "\t.globl " << name << "\n"
1011         << "\t.weak_definition " << name << "\n";
1012     } else {
1013       O << "\t.weak " << name << "\n";
1014     }
1015     break;
1016    case GlobalValue::AppendingLinkage:
1017     // FIXME: appending linkage variables should go into a section of
1018     // their name or something.  For now, just emit them as external.
1019    case GlobalValue::ExternalLinkage:
1020     O << "\t.globl " << name << "\n";
1021     // FALL THROUGH
1022    case GlobalValue::PrivateLinkage:
1023    case GlobalValue::InternalLinkage:
1024     break;
1025    default:
1026     assert(0 && "Unknown linkage type!");
1027     break;
1028   }
1029
1030   EmitAlignment(Align, GVar);
1031   O << name << ":";
1032   if (VerboseAsm) {
1033     O << "\t\t\t\t" << TAI->getCommentString() << " ";
1034     PrintUnmangledNameSafely(GVar, O);
1035   }
1036   O << "\n";
1037   if (TAI->hasDotTypeDotSizeDirective())
1038     O << "\t.size " << name << ", " << Size << "\n";
1039
1040   EmitGlobalConstant(C);
1041   O << '\n';
1042 }
1043
1044
1045 bool ARMAsmPrinter::doFinalization(Module &M) {
1046   for (Module::const_global_iterator I = M.global_begin(), E = M.global_end();
1047        I != E; ++I)
1048     printModuleLevelGV(I);
1049
1050   if (Subtarget->isTargetDarwin()) {
1051     SwitchToDataSection("");
1052
1053     // Output stubs for dynamically-linked functions
1054     for (StringSet<>::iterator i = FnStubs.begin(), e = FnStubs.end();
1055          i != e; ++i) {
1056       if (TM.getRelocationModel() == Reloc::PIC_)
1057         SwitchToTextSection(".section __TEXT,__picsymbolstub4,symbol_stubs,"
1058                             "none,16", 0);
1059       else
1060         SwitchToTextSection(".section __TEXT,__symbol_stub4,symbol_stubs,"
1061                             "none,12", 0);
1062
1063       EmitAlignment(2);
1064       O << "\t.code\t32\n";
1065
1066       const char *p = i->getKeyData();
1067       printSuffixedName(p, "$stub");
1068       O << ":\n";
1069       O << "\t.indirect_symbol " << p << "\n";
1070       O << "\tldr ip, ";
1071       printSuffixedName(p, "$slp");
1072       O << "\n";
1073       if (TM.getRelocationModel() == Reloc::PIC_) {
1074         printSuffixedName(p, "$scv");
1075         O << ":\n";
1076         O << "\tadd ip, pc, ip\n";
1077       }
1078       O << "\tldr pc, [ip, #0]\n";
1079       printSuffixedName(p, "$slp");
1080       O << ":\n";
1081       O << "\t.long\t";
1082       printSuffixedName(p, "$lazy_ptr");
1083       if (TM.getRelocationModel() == Reloc::PIC_) {
1084         O << "-(";
1085         printSuffixedName(p, "$scv");
1086         O << "+8)\n";
1087       } else
1088         O << "\n";
1089       SwitchToDataSection(".lazy_symbol_pointer", 0);
1090       printSuffixedName(p, "$lazy_ptr");
1091       O << ":\n";
1092       O << "\t.indirect_symbol " << p << "\n";
1093       O << "\t.long\tdyld_stub_binding_helper\n";
1094     }
1095     O << "\n";
1096
1097     // Output non-lazy-pointers for external and common global variables.
1098     if (!GVNonLazyPtrs.empty()) {
1099       SwitchToDataSection("\t.non_lazy_symbol_pointer", 0);
1100       for (StringSet<>::iterator i =  GVNonLazyPtrs.begin(),
1101              e = GVNonLazyPtrs.end(); i != e; ++i) {
1102         const char *p = i->getKeyData();
1103         printSuffixedName(p, "$non_lazy_ptr");
1104         O << ":\n";
1105         O << "\t.indirect_symbol " << p << "\n";
1106         O << "\t.long\t0\n";
1107       }
1108     }
1109
1110     if (!HiddenGVNonLazyPtrs.empty()) {
1111       SwitchToSection(TAI->getDataSection());
1112       for (StringSet<>::iterator i = HiddenGVNonLazyPtrs.begin(),
1113              e = HiddenGVNonLazyPtrs.end(); i != e; ++i) {
1114         const char *p = i->getKeyData();
1115         EmitAlignment(2);
1116         printSuffixedName(p, "$non_lazy_ptr");
1117         O << ":\n";
1118         O << "\t.long " << p << "\n";
1119       }
1120     }
1121
1122
1123     // Funny Darwin hack: This flag tells the linker that no global symbols
1124     // contain code that falls through to other global symbols (e.g. the obvious
1125     // implementation of multiple entry points).  If this doesn't occur, the
1126     // linker can safely perform dead code stripping.  Since LLVM never
1127     // generates code that does this, it is always safe to set.
1128     O << "\t.subsections_via_symbols\n";
1129   }
1130
1131   return AsmPrinter::doFinalization(M);
1132 }
1133
1134 /// createARMCodePrinterPass - Returns a pass that prints the ARM
1135 /// assembly code for a MachineFunction to the given output stream,
1136 /// using the given target machine description.  This should work
1137 /// regardless of whether the function is in SSA form.
1138 ///
1139 FunctionPass *llvm::createARMCodePrinterPass(raw_ostream &o,
1140                                              ARMBaseTargetMachine &tm,
1141                                              CodeGenOpt::Level OptLevel,
1142                                              bool verbose) {
1143   return new ARMAsmPrinter(o, tm, tm.getTargetAsmInfo(), OptLevel, verbose);
1144 }
1145
1146 namespace {
1147   static struct Register {
1148     Register() {
1149       ARMBaseTargetMachine::registerAsmPrinter(createARMCodePrinterPass);
1150     }
1151   } Registrator;
1152 }
1153
1154 // Force static initialization.
1155 extern "C" void LLVMInitializeARMAsmPrinter() { }