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