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