eliminate the ExtWeakSymbols set from AsmPrinter. This eliminates
[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
49     /// Subtarget - Keep a pointer to the ARMSubtarget around so that we can
50     /// make the right decision when printing asm code for different targets.
51     const ARMSubtarget *Subtarget;
52
53     /// AFI - Keep a pointer to ARMFunctionInfo for the current
54     /// MachineFunction.
55     ARMFunctionInfo *AFI;
56
57     /// MCP - Keep a pointer to constantpool entries of the current
58     /// MachineFunction.
59     const MachineConstantPool *MCP;
60
61     /// We name each basic block in a Function with a unique number, so
62     /// that we can consistently refer to them later. This is cleared
63     /// at the beginning of each call to runOnMachineFunction().
64     ///
65     typedef std::map<const Value *, unsigned> ValueMapTy;
66     ValueMapTy NumberForBB;
67
68     /// GVNonLazyPtrs - Keeps the set of GlobalValues that require
69     /// non-lazy-pointers for indirect access.
70     StringSet<> GVNonLazyPtrs;
71
72     /// HiddenGVNonLazyPtrs - Keeps the set of GlobalValues with hidden
73     /// visibility that require non-lazy-pointers for indirect access.
74     StringSet<> HiddenGVNonLazyPtrs;
75
76     /// FnStubs - Keeps the set of external function GlobalAddresses that the
77     /// asm printer should generate stubs for.
78     StringSet<> FnStubs;
79
80     /// True if asm printer is printing a series of CONSTPOOL_ENTRY.
81     bool InCPMode;
82   public:
83     explicit ARMAsmPrinter(raw_ostream &O, TargetMachine &TM,
84                            const TargetAsmInfo *T, CodeGenOpt::Level OL,
85                            bool V)
86       : AsmPrinter(O, TM, T, OL, V), DW(0), AFI(NULL), MCP(NULL),
87         InCPMode(false) {
88       Subtarget = &TM.getSubtarget<ARMSubtarget>();
89     }
90
91     virtual const char *getPassName() const {
92       return "ARM Assembly Printer";
93     }
94
95     void printOperand(const MachineInstr *MI, int opNum,
96                       const char *Modifier = 0);
97     void printSOImmOperand(const MachineInstr *MI, int opNum);
98     void printSOImm2PartOperand(const MachineInstr *MI, int opNum);
99     void printSOOperand(const MachineInstr *MI, int OpNum);
100     void printSORegOperand(const MachineInstr *MI, int opNum);
101     void printT2SOImmOperand(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 printBitfieldInvMaskImmOperand (const MachineInstr *MI, int OpNo);
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     void printPredicateOperand(const MachineInstr *MI, int opNum);
121     void printSBitModifierOperand(const MachineInstr *MI, int opNum);
122     void printPCLabel(const MachineInstr *MI, int opNum);
123     void printRegisterList(const MachineInstr *MI, int opNum);
124     void printCPInstOperand(const MachineInstr *MI, int opNum,
125                             const char *Modifier);
126     void printJTBlockOperand(const MachineInstr *MI, int opNum);
127
128     virtual bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,
129                                  unsigned AsmVariant, const char *ExtraCode);
130     virtual bool PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNo,
131                                        unsigned AsmVariant,
132                                        const char *ExtraCode);
133
134     void printModuleLevelGV(const GlobalVariable* GVar);
135     bool printInstruction(const MachineInstr *MI);  // autogenerated.
136     void printMachineInstruction(const MachineInstr *MI);
137     bool runOnMachineFunction(MachineFunction &F);
138     bool doInitialization(Module &M);
139     bool doFinalization(Module &M);
140
141     /// EmitMachineConstantPoolValue - Print a machine constantpool value to
142     /// the .s file.
143     virtual void EmitMachineConstantPoolValue(MachineConstantPoolValue *MCPV) {
144       printDataDirective(MCPV->getType());
145
146       ARMConstantPoolValue *ACPV = static_cast<ARMConstantPoolValue*>(MCPV);
147       GlobalValue *GV = ACPV->getGV();
148       std::string Name = GV ? Mang->getValueName(GV) : TAI->getGlobalPrefix();
149       if (!GV)
150         Name += ACPV->getSymbol();
151       if (ACPV->isNonLazyPointer()) {
152         if (GV->hasHiddenVisibility())
153           HiddenGVNonLazyPtrs.insert(Name);
154         else
155           GVNonLazyPtrs.insert(Name);
156         printSuffixedName(Name, "$non_lazy_ptr");
157       } else if (ACPV->isStub()) {
158         FnStubs.insert(Name);
159         printSuffixedName(Name, "$stub");
160       } else
161         O << Name;
162       if (ACPV->hasModifier()) O << "(" << ACPV->getModifier() << ")";
163       if (ACPV->getPCAdjustment() != 0) {
164         O << "-(" << TAI->getPrivateGlobalPrefix() << "PC"
165           << utostr(ACPV->getLabelId())
166           << "+" << (unsigned)ACPV->getPCAdjustment();
167          if (ACPV->mustAddCurrentAddress())
168            O << "-.";
169          O << ")";
170       }
171       O << "\n";
172     }
173     
174     void getAnalysisUsage(AnalysisUsage &AU) const {
175       AsmPrinter::getAnalysisUsage(AU);
176       AU.setPreservesAll();
177       AU.addRequired<MachineModuleInfo>();
178       AU.addRequired<DwarfWriter>();
179     }
180   };
181 } // end of anonymous namespace
182
183 #include "ARMGenAsmWriter.inc"
184
185 /// runOnMachineFunction - This uses the printInstruction()
186 /// method to print assembly for each instruction.
187 ///
188 bool ARMAsmPrinter::runOnMachineFunction(MachineFunction &MF) {
189   this->MF = &MF;
190
191   AFI = MF.getInfo<ARMFunctionInfo>();
192   MCP = MF.getConstantPool();
193
194   SetupMachineFunction(MF);
195   O << "\n";
196
197   // NOTE: we don't print out constant pools here, they are handled as
198   // instructions.
199
200   O << "\n";
201   // Print out labels for the function.
202   const Function *F = MF.getFunction();
203   switch (F->getLinkage()) {
204   default: assert(0 && "Unknown linkage type!");
205   case Function::PrivateLinkage:
206   case Function::InternalLinkage:
207     SwitchToTextSection("\t.text", F);
208     break;
209   case Function::ExternalLinkage:
210     SwitchToTextSection("\t.text", F);
211     O << "\t.globl\t" << CurrentFnName << "\n";
212     break;
213   case Function::WeakAnyLinkage:
214   case Function::WeakODRLinkage:
215   case Function::LinkOnceAnyLinkage:
216   case Function::LinkOnceODRLinkage:
217     if (Subtarget->isTargetDarwin()) {
218       SwitchToTextSection(
219                 ".section __TEXT,__textcoal_nt,coalesced,pure_instructions", F);
220       O << "\t.globl\t" << CurrentFnName << "\n";
221       O << "\t.weak_definition\t" << CurrentFnName << "\n";
222     } else {
223       O << TAI->getWeakRefDirective() << CurrentFnName << "\n";
224     }
225     break;
226   }
227
228   printVisibility(CurrentFnName, F->getVisibility());
229
230   if (AFI->isThumbFunction()) {
231     EmitAlignment(1, F, AFI->getAlign());
232     O << "\t.code\t16\n";
233     O << "\t.thumb_func";
234     if (Subtarget->isTargetDarwin())
235       O << "\t" << CurrentFnName;
236     O << "\n";
237     InCPMode = false;
238   } else
239     EmitAlignment(2, F);
240
241   O << CurrentFnName << ":\n";
242   // Emit pre-function debug information.
243   DW->BeginFunction(&MF);
244
245   if (Subtarget->isTargetDarwin()) {
246     // If the function is empty, then we need to emit *something*. Otherwise,
247     // the function's label might be associated with something that it wasn't
248     // meant to be associated with. We emit a noop in this situation.
249     MachineFunction::iterator I = MF.begin();
250
251     if (++I == MF.end() && MF.front().empty())
252       O << "\tnop\n";
253   }
254
255   // Print out code for the function.
256   for (MachineFunction::const_iterator I = MF.begin(), E = MF.end();
257        I != E; ++I) {
258     // Print a label for the basic block.
259     if (I != MF.begin()) {
260       printBasicBlockLabel(I, true, true, VerboseAsm);
261       O << '\n';
262     }
263     for (MachineBasicBlock::const_iterator II = I->begin(), E = I->end();
264          II != E; ++II) {
265       // Print the assembly for the instruction.
266       printMachineInstruction(II);
267     }
268   }
269
270   if (TAI->hasDotTypeDotSizeDirective())
271     O << "\t.size " << CurrentFnName << ", .-" << CurrentFnName << "\n";
272
273   // Emit post-function debug information.
274   DW->EndFunction(&MF);
275
276   O.flush();
277
278   return false;
279 }
280
281 void ARMAsmPrinter::printOperand(const MachineInstr *MI, int opNum,
282                                  const char *Modifier) {
283   const MachineOperand &MO = MI->getOperand(opNum);
284   switch (MO.getType()) {
285   case MachineOperand::MO_Register: {
286     unsigned Reg = MO.getReg();
287     if (TargetRegisterInfo::isPhysicalRegister(Reg)) {
288       if (Modifier && strcmp(Modifier, "dregpair") == 0) {
289         unsigned DRegLo = TRI->getSubReg(Reg, 5); // arm_dsubreg_0
290         unsigned DRegHi = TRI->getSubReg(Reg, 6); // arm_dsubreg_1
291         O << '{'
292           << TRI->getAsmName(DRegLo) << "-" << TRI->getAsmName(DRegHi)
293           << '}';
294       } else {
295         O << TRI->getAsmName(Reg);
296       }
297     } else
298       assert(0 && "not implemented");
299     break;
300   }
301   case MachineOperand::MO_Immediate: {
302     if (!Modifier || strcmp(Modifier, "no_hash") != 0)
303       O << "#";
304
305     O << MO.getImm();
306     break;
307   }
308   case MachineOperand::MO_MachineBasicBlock:
309     printBasicBlockLabel(MO.getMBB());
310     return;
311   case MachineOperand::MO_GlobalAddress: {
312     bool isCallOp = Modifier && !strcmp(Modifier, "call");
313     GlobalValue *GV = MO.getGlobal();
314     std::string Name = Mang->getValueName(GV);
315     bool isExt = (GV->isDeclaration() || GV->hasWeakLinkage() ||
316                   GV->hasLinkOnceLinkage());
317     if (isExt && isCallOp && Subtarget->isTargetDarwin() &&
318         TM.getRelocationModel() != Reloc::Static) {
319       printSuffixedName(Name, "$stub");
320       FnStubs.insert(Name);
321     } else
322       O << Name;
323
324     printOffset(MO.getOffset());
325
326     if (isCallOp && Subtarget->isTargetELF() &&
327         TM.getRelocationModel() == Reloc::PIC_)
328       O << "(PLT)";
329     break;
330   }
331   case MachineOperand::MO_ExternalSymbol: {
332     bool isCallOp = Modifier && !strcmp(Modifier, "call");
333     std::string Name(TAI->getGlobalPrefix());
334     Name += MO.getSymbolName();
335     if (isCallOp && Subtarget->isTargetDarwin() &&
336         TM.getRelocationModel() != Reloc::Static) {
337       printSuffixedName(Name, "$stub");
338       FnStubs.insert(Name);
339     } else
340       O << Name;
341     if (isCallOp && Subtarget->isTargetELF() &&
342         TM.getRelocationModel() == Reloc::PIC_)
343       O << "(PLT)";
344     break;
345   }
346   case MachineOperand::MO_ConstantPoolIndex:
347     O << TAI->getPrivateGlobalPrefix() << "CPI" << getFunctionNumber()
348       << '_' << MO.getIndex();
349     break;
350   case MachineOperand::MO_JumpTableIndex:
351     O << TAI->getPrivateGlobalPrefix() << "JTI" << getFunctionNumber()
352       << '_' << MO.getIndex();
353     break;
354   default:
355     O << "<unknown operand type>"; abort (); break;
356   }
357 }
358
359 static void printSOImm(raw_ostream &O, int64_t V, bool VerboseAsm,
360                        const TargetAsmInfo *TAI) {
361   assert(V < (1 << 12) && "Not a valid so_imm value!");
362   unsigned Imm = ARM_AM::getSOImmValImm(V);
363   unsigned Rot = ARM_AM::getSOImmValRot(V);
364
365   // Print low-level immediate formation info, per
366   // A5.1.3: "Data-processing operands - Immediate".
367   if (Rot) {
368     O << "#" << Imm << ", " << Rot;
369     // Pretty printed version.
370     if (VerboseAsm)
371       O << ' ' << TAI->getCommentString()
372         << ' ' << (int)ARM_AM::rotr32(Imm, Rot);
373   } else {
374     O << "#" << Imm;
375   }
376 }
377
378 /// printSOImmOperand - SOImm is 4-bit rotate amount in bits 8-11 with 8-bit
379 /// immediate in bits 0-7.
380 void ARMAsmPrinter::printSOImmOperand(const MachineInstr *MI, int OpNum) {
381   const MachineOperand &MO = MI->getOperand(OpNum);
382   assert(MO.isImm() && "Not a valid so_imm value!");
383   printSOImm(O, MO.getImm(), VerboseAsm, TAI);
384 }
385
386 /// printSOImm2PartOperand - SOImm is broken into two pieces using a 'mov'
387 /// followed by an 'orr' to materialize.
388 void ARMAsmPrinter::printSOImm2PartOperand(const MachineInstr *MI, int OpNum) {
389   const MachineOperand &MO = MI->getOperand(OpNum);
390   assert(MO.isImm() && "Not a valid so_imm value!");
391   unsigned V1 = ARM_AM::getSOImmTwoPartFirst(MO.getImm());
392   unsigned V2 = ARM_AM::getSOImmTwoPartSecond(MO.getImm());
393   printSOImm(O, ARM_AM::getSOImmVal(V1), VerboseAsm, TAI);
394   O << "\n\torr";
395   printPredicateOperand(MI, 2);
396   O << " ";
397   printOperand(MI, 0); 
398   O << ", ";
399   printOperand(MI, 0); 
400   O << ", ";
401   printSOImm(O, ARM_AM::getSOImmVal(V2), VerboseAsm, TAI);
402 }
403
404 // Constant shifts so_reg is a 3-operand unit corresponding to register forms of
405 // the A5.1 "Addressing Mode 1 - Data-processing operands" forms.  This
406 // includes:
407 // REG 0 - e.g. R5
408 // REG IMM, SH_OPC - e.g. R5, LSL #3
409 void ARMAsmPrinter::printSOOperand(const MachineInstr *MI, int OpNum) {
410   const MachineOperand &MO1 = MI->getOperand(OpNum);
411   const MachineOperand &MO2 = MI->getOperand(OpNum+1);
412
413   unsigned Reg = MO1.getReg();
414   assert(TargetRegisterInfo::isPhysicalRegister(Reg));
415   O << TM.getRegisterInfo()->getAsmName(Reg);
416
417   // Print the shift opc.
418   O << ", "
419     << ARM_AM::getShiftOpcStr(ARM_AM::getSORegShOp(MO2.getImm()))
420     << " ";
421
422   assert(MO2.isImm() && "Not a valid t2_so_reg value!");
423   O << "#" << ARM_AM::getSORegOffset(MO2.getImm());
424 }
425
426 // so_reg is a 4-operand unit corresponding to register forms of the A5.1
427 // "Addressing Mode 1 - Data-processing operands" forms.  This includes:
428 //    REG 0   0    - e.g. R5
429 //    REG REG 0,SH_OPC     - e.g. R5, ROR R3
430 //    REG 0   IMM,SH_OPC  - e.g. R5, LSL #3
431 void ARMAsmPrinter::printSORegOperand(const MachineInstr *MI, int Op) {
432   const MachineOperand &MO1 = MI->getOperand(Op);
433   const MachineOperand &MO2 = MI->getOperand(Op+1);
434   const MachineOperand &MO3 = MI->getOperand(Op+2);
435
436   assert(TargetRegisterInfo::isPhysicalRegister(MO1.getReg()));
437   O << TM.getRegisterInfo()->get(MO1.getReg()).AsmName;
438
439   // Print the shift opc.
440   O << ", "
441     << ARM_AM::getShiftOpcStr(ARM_AM::getSORegShOp(MO3.getImm()))
442     << " ";
443
444   if (MO2.getReg()) {
445     assert(TargetRegisterInfo::isPhysicalRegister(MO2.getReg()));
446     O << TM.getRegisterInfo()->get(MO2.getReg()).AsmName;
447     assert(ARM_AM::getSORegOffset(MO3.getImm()) == 0);
448   } else {
449     O << "#" << ARM_AM::getSORegOffset(MO3.getImm());
450   }
451 }
452
453 static void printT2SOImm(raw_ostream &O, int64_t V) {
454   unsigned Imm = ARM_AM::getT2SOImmValDecode(V);
455   
456   // Always print the immediate directly, as the "rotate" form
457   // is deprecated in some contexts.
458   O << "#" << Imm;
459 }
460
461 /// printT2SOImmOperand - T2SOImm is:
462 ///  1. a 4-bit splat control value and 8 bit immediate value
463 ///  2. a 5-bit rotate amount and a non-zero 8-bit immediate value
464 ///     represented by a normalizedin 7-bit value (msb is always 1)
465 void ARMAsmPrinter::printT2SOImmOperand(const MachineInstr *MI, int OpNum) {
466   const MachineOperand &MO = MI->getOperand(OpNum);
467   assert(MO.isImm() && "Not a valid so_imm value!");
468   printT2SOImm(O, MO.getImm());
469 }
470
471 void ARMAsmPrinter::printAddrMode2Operand(const MachineInstr *MI, int Op) {
472   const MachineOperand &MO1 = MI->getOperand(Op);
473   const MachineOperand &MO2 = MI->getOperand(Op+1);
474   const MachineOperand &MO3 = MI->getOperand(Op+2);
475
476   if (!MO1.isReg()) {   // FIXME: This is for CP entries, but isn't right.
477     printOperand(MI, Op);
478     return;
479   }
480
481   O << "[" << TM.getRegisterInfo()->get(MO1.getReg()).AsmName;
482
483   if (!MO2.getReg()) {
484     if (ARM_AM::getAM2Offset(MO3.getImm()))  // Don't print +0.
485       O << ", #"
486         << (char)ARM_AM::getAM2Op(MO3.getImm())
487         << ARM_AM::getAM2Offset(MO3.getImm());
488     O << "]";
489     return;
490   }
491
492   O << ", "
493     << (char)ARM_AM::getAM2Op(MO3.getImm())
494     << TM.getRegisterInfo()->get(MO2.getReg()).AsmName;
495   
496   if (unsigned ShImm = ARM_AM::getAM2Offset(MO3.getImm()))
497     O << ", "
498       << ARM_AM::getShiftOpcStr(ARM_AM::getAM2ShiftOpc(MO3.getImm()))
499       << " #" << ShImm;
500   O << "]";
501 }
502
503 void ARMAsmPrinter::printAddrMode2OffsetOperand(const MachineInstr *MI, int Op){
504   const MachineOperand &MO1 = MI->getOperand(Op);
505   const MachineOperand &MO2 = MI->getOperand(Op+1);
506
507   if (!MO1.getReg()) {
508     unsigned ImmOffs = ARM_AM::getAM2Offset(MO2.getImm());
509     assert(ImmOffs && "Malformed indexed load / store!");
510     O << "#"
511       << (char)ARM_AM::getAM2Op(MO2.getImm())
512       << ImmOffs;
513     return;
514   }
515
516   O << (char)ARM_AM::getAM2Op(MO2.getImm())
517     << TM.getRegisterInfo()->get(MO1.getReg()).AsmName;
518   
519   if (unsigned ShImm = ARM_AM::getAM2Offset(MO2.getImm()))
520     O << ", "
521       << ARM_AM::getShiftOpcStr(ARM_AM::getAM2ShiftOpc(MO2.getImm()))
522       << " #" << ShImm;
523 }
524
525 void ARMAsmPrinter::printAddrMode3Operand(const MachineInstr *MI, int Op) {
526   const MachineOperand &MO1 = MI->getOperand(Op);
527   const MachineOperand &MO2 = MI->getOperand(Op+1);
528   const MachineOperand &MO3 = MI->getOperand(Op+2);
529   
530   assert(TargetRegisterInfo::isPhysicalRegister(MO1.getReg()));
531   O << "[" << TM.getRegisterInfo()->get(MO1.getReg()).AsmName;
532
533   if (MO2.getReg()) {
534     O << ", "
535       << (char)ARM_AM::getAM3Op(MO3.getImm())
536       << TM.getRegisterInfo()->get(MO2.getReg()).AsmName
537       << "]";
538     return;
539   }
540   
541   if (unsigned ImmOffs = ARM_AM::getAM3Offset(MO3.getImm()))
542     O << ", #"
543       << (char)ARM_AM::getAM3Op(MO3.getImm())
544       << ImmOffs;
545   O << "]";
546 }
547
548 void ARMAsmPrinter::printAddrMode3OffsetOperand(const MachineInstr *MI, int Op){
549   const MachineOperand &MO1 = MI->getOperand(Op);
550   const MachineOperand &MO2 = MI->getOperand(Op+1);
551
552   if (MO1.getReg()) {
553     O << (char)ARM_AM::getAM3Op(MO2.getImm())
554       << TM.getRegisterInfo()->get(MO1.getReg()).AsmName;
555     return;
556   }
557
558   unsigned ImmOffs = ARM_AM::getAM3Offset(MO2.getImm());
559   assert(ImmOffs && "Malformed indexed load / store!");
560   O << "#"
561     << (char)ARM_AM::getAM3Op(MO2.getImm())
562     << ImmOffs;
563 }
564   
565 void ARMAsmPrinter::printAddrMode4Operand(const MachineInstr *MI, int Op,
566                                           const char *Modifier) {
567   const MachineOperand &MO1 = MI->getOperand(Op);
568   const MachineOperand &MO2 = MI->getOperand(Op+1);
569   ARM_AM::AMSubMode Mode = ARM_AM::getAM4SubMode(MO2.getImm());
570   if (Modifier && strcmp(Modifier, "submode") == 0) {
571     if (MO1.getReg() == ARM::SP) {
572       bool isLDM = (MI->getOpcode() == ARM::LDM ||
573                     MI->getOpcode() == ARM::LDM_RET);
574       O << ARM_AM::getAMSubModeAltStr(Mode, isLDM);
575     } else
576       O << ARM_AM::getAMSubModeStr(Mode);
577   } else {
578     printOperand(MI, Op);
579     if (ARM_AM::getAM4WBFlag(MO2.getImm()))
580       O << "!";
581   }
582 }
583
584 void ARMAsmPrinter::printAddrMode5Operand(const MachineInstr *MI, int Op,
585                                           const char *Modifier) {
586   const MachineOperand &MO1 = MI->getOperand(Op);
587   const MachineOperand &MO2 = MI->getOperand(Op+1);
588
589   if (!MO1.isReg()) {   // FIXME: This is for CP entries, but isn't right.
590     printOperand(MI, Op);
591     return;
592   }
593   
594   assert(TargetRegisterInfo::isPhysicalRegister(MO1.getReg()));
595
596   if (Modifier && strcmp(Modifier, "submode") == 0) {
597     ARM_AM::AMSubMode Mode = ARM_AM::getAM5SubMode(MO2.getImm());
598     if (MO1.getReg() == ARM::SP) {
599       bool isFLDM = (MI->getOpcode() == ARM::FLDMD ||
600                      MI->getOpcode() == ARM::FLDMS);
601       O << ARM_AM::getAMSubModeAltStr(Mode, isFLDM);
602     } else
603       O << ARM_AM::getAMSubModeStr(Mode);
604     return;
605   } else if (Modifier && strcmp(Modifier, "base") == 0) {
606     // Used for FSTM{D|S} and LSTM{D|S} operations.
607     O << TM.getRegisterInfo()->get(MO1.getReg()).AsmName;
608     if (ARM_AM::getAM5WBFlag(MO2.getImm()))
609       O << "!";
610     return;
611   }
612   
613   O << "[" << TM.getRegisterInfo()->get(MO1.getReg()).AsmName;
614   
615   if (unsigned ImmOffs = ARM_AM::getAM5Offset(MO2.getImm())) {
616     O << ", #"
617       << (char)ARM_AM::getAM5Op(MO2.getImm())
618       << ImmOffs*4;
619   }
620   O << "]";
621 }
622
623 void ARMAsmPrinter::printAddrModePCOperand(const MachineInstr *MI, int Op,
624                                            const char *Modifier) {
625   if (Modifier && strcmp(Modifier, "label") == 0) {
626     printPCLabel(MI, Op+1);
627     return;
628   }
629
630   const MachineOperand &MO1 = MI->getOperand(Op);
631   assert(TargetRegisterInfo::isPhysicalRegister(MO1.getReg()));
632   O << "[pc, +" << TM.getRegisterInfo()->get(MO1.getReg()).AsmName << "]";
633 }
634
635 void
636 ARMAsmPrinter::printBitfieldInvMaskImmOperand(const MachineInstr *MI, int Op) {
637   const MachineOperand &MO = MI->getOperand(Op);
638   uint32_t v = ~MO.getImm();
639   int32_t lsb = ffs (v) - 1;
640   int32_t width = (32 - CountLeadingZeros_32 (v)) - lsb;
641   assert(MO.isImm() && "Not a valid bf_inv_mask_imm value!");
642   O << "#" << lsb << ", #" << width;
643 }
644
645 void
646 ARMAsmPrinter::printThumbAddrModeRROperand(const MachineInstr *MI, int Op) {
647   const MachineOperand &MO1 = MI->getOperand(Op);
648   const MachineOperand &MO2 = MI->getOperand(Op+1);
649   O << "[" << TM.getRegisterInfo()->get(MO1.getReg()).AsmName;
650   O << ", " << TM.getRegisterInfo()->get(MO2.getReg()).AsmName << "]";
651 }
652
653 void
654 ARMAsmPrinter::printThumbAddrModeRI5Operand(const MachineInstr *MI, int Op,
655                                             unsigned Scale) {
656   const MachineOperand &MO1 = MI->getOperand(Op);
657   const MachineOperand &MO2 = MI->getOperand(Op+1);
658   const MachineOperand &MO3 = MI->getOperand(Op+2);
659
660   if (!MO1.isReg()) {   // FIXME: This is for CP entries, but isn't right.
661     printOperand(MI, Op);
662     return;
663   }
664
665   O << "[" << TM.getRegisterInfo()->get(MO1.getReg()).AsmName;
666   if (MO3.getReg())
667     O << ", " << TM.getRegisterInfo()->get(MO3.getReg()).AsmName;
668   else if (unsigned ImmOffs = MO2.getImm()) {
669     O << ", #" << ImmOffs;
670     if (Scale > 1)
671       O << " * " << Scale;
672   }
673   O << "]";
674 }
675
676 void
677 ARMAsmPrinter::printThumbAddrModeS1Operand(const MachineInstr *MI, int Op) {
678   printThumbAddrModeRI5Operand(MI, Op, 1);
679 }
680 void
681 ARMAsmPrinter::printThumbAddrModeS2Operand(const MachineInstr *MI, int Op) {
682   printThumbAddrModeRI5Operand(MI, Op, 2);
683 }
684 void
685 ARMAsmPrinter::printThumbAddrModeS4Operand(const MachineInstr *MI, int Op) {
686   printThumbAddrModeRI5Operand(MI, Op, 4);
687 }
688
689 void ARMAsmPrinter::printThumbAddrModeSPOperand(const MachineInstr *MI,int Op) {
690   const MachineOperand &MO1 = MI->getOperand(Op);
691   const MachineOperand &MO2 = MI->getOperand(Op+1);
692   O << "[" << TM.getRegisterInfo()->get(MO1.getReg()).AsmName;
693   if (unsigned ImmOffs = MO2.getImm())
694     O << ", #" << ImmOffs << " * 4";
695   O << "]";
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   const Type *Type = C->getType();
927   unsigned Size = TD->getTypeAllocSize(Type);
928   unsigned Align = TD->getPreferredAlignmentLog(GVar);
929   bool isDarwin = Subtarget->isTargetDarwin();
930
931   printVisibility(name, GVar->getVisibility());
932
933   if (Subtarget->isTargetELF())
934     O << "\t.type " << name << ",%object\n";
935
936   if (C->isNullValue() && !GVar->hasSection() && !GVar->isThreadLocal() &&
937       !(isDarwin &&
938         TAI->SectionKindForGlobal(GVar) == SectionKind::RODataMergeStr)) {
939     // FIXME: This seems to be pretty darwin-specific
940
941     if (GVar->hasExternalLinkage()) {
942       SwitchToSection(TAI->SectionForGlobal(GVar));
943       if (const char *Directive = TAI->getZeroFillDirective()) {
944         O << "\t.globl\t" << name << "\n";
945         O << Directive << "__DATA, __common, " << name << ", "
946           << Size << ", " << Align << "\n";
947         return;
948       }
949     }
950
951     if (GVar->hasLocalLinkage() || GVar->isWeakForLinker()) {
952       if (Size == 0) Size = 1;   // .comm Foo, 0 is undefined, avoid it.
953
954       if (isDarwin) {
955         if (GVar->hasLocalLinkage()) {
956           O << TAI->getLCOMMDirective()  << name << "," << Size
957             << ',' << Align;
958         } else if (GVar->hasCommonLinkage()) {
959           O << TAI->getCOMMDirective()  << name << "," << Size
960             << ',' << Align;
961         } else {
962           SwitchToSection(TAI->SectionForGlobal(GVar));
963           O << "\t.globl " << name << '\n'
964             << TAI->getWeakDefDirective() << name << '\n';
965           EmitAlignment(Align, GVar);
966           O << name << ":";
967           if (VerboseAsm) {
968             O << "\t\t\t\t" << TAI->getCommentString() << ' ';
969             PrintUnmangledNameSafely(GVar, O);
970           }
971           O << '\n';
972           EmitGlobalConstant(C);
973           return;
974         }
975       } else if (TAI->getLCOMMDirective() != NULL) {
976         if (GVar->hasLocalLinkage()) {
977           O << TAI->getLCOMMDirective() << name << "," << Size;
978         } else {
979           O << TAI->getCOMMDirective()  << name << "," << Size;
980           if (TAI->getCOMMDirectiveTakesAlignment())
981             O << ',' << (TAI->getAlignmentIsInBytes() ? (1 << Align) : Align);
982         }
983       } else {
984         SwitchToSection(TAI->SectionForGlobal(GVar));
985         if (GVar->hasLocalLinkage())
986           O << "\t.local\t" << name << "\n";
987         O << TAI->getCOMMDirective()  << name << "," << Size;
988         if (TAI->getCOMMDirectiveTakesAlignment())
989           O << "," << (TAI->getAlignmentIsInBytes() ? (1 << Align) : Align);
990       }
991       if (VerboseAsm) {
992         O << "\t\t" << TAI->getCommentString() << " ";
993         PrintUnmangledNameSafely(GVar, O);
994       }
995       O << "\n";
996       return;
997     }
998   }
999
1000   SwitchToSection(TAI->SectionForGlobal(GVar));
1001   switch (GVar->getLinkage()) {
1002    case GlobalValue::CommonLinkage:
1003    case GlobalValue::LinkOnceAnyLinkage:
1004    case GlobalValue::LinkOnceODRLinkage:
1005    case GlobalValue::WeakAnyLinkage:
1006    case GlobalValue::WeakODRLinkage:
1007     if (isDarwin) {
1008       O << "\t.globl " << name << "\n"
1009         << "\t.weak_definition " << name << "\n";
1010     } else {
1011       O << "\t.weak " << name << "\n";
1012     }
1013     break;
1014    case GlobalValue::AppendingLinkage:
1015     // FIXME: appending linkage variables should go into a section of
1016     // their name or something.  For now, just emit them as external.
1017    case GlobalValue::ExternalLinkage:
1018     O << "\t.globl " << name << "\n";
1019     // FALL THROUGH
1020    case GlobalValue::PrivateLinkage:
1021    case GlobalValue::InternalLinkage:
1022     break;
1023    default:
1024     assert(0 && "Unknown linkage type!");
1025     break;
1026   }
1027
1028   EmitAlignment(Align, GVar);
1029   O << name << ":";
1030   if (VerboseAsm) {
1031     O << "\t\t\t\t" << TAI->getCommentString() << " ";
1032     PrintUnmangledNameSafely(GVar, O);
1033   }
1034   O << "\n";
1035   if (TAI->hasDotTypeDotSizeDirective())
1036     O << "\t.size " << name << ", " << Size << "\n";
1037
1038   EmitGlobalConstant(C);
1039   O << '\n';
1040 }
1041
1042
1043 bool ARMAsmPrinter::doFinalization(Module &M) {
1044   for (Module::const_global_iterator I = M.global_begin(), E = M.global_end();
1045        I != E; ++I)
1046     printModuleLevelGV(I);
1047
1048   if (Subtarget->isTargetDarwin()) {
1049     SwitchToDataSection("");
1050
1051     // Output stubs for dynamically-linked functions
1052     for (StringSet<>::iterator i = FnStubs.begin(), e = FnStubs.end();
1053          i != e; ++i) {
1054       if (TM.getRelocationModel() == Reloc::PIC_)
1055         SwitchToTextSection(".section __TEXT,__picsymbolstub4,symbol_stubs,"
1056                             "none,16", 0);
1057       else
1058         SwitchToTextSection(".section __TEXT,__symbol_stub4,symbol_stubs,"
1059                             "none,12", 0);
1060
1061       EmitAlignment(2);
1062       O << "\t.code\t32\n";
1063
1064       const char *p = i->getKeyData();
1065       printSuffixedName(p, "$stub");
1066       O << ":\n";
1067       O << "\t.indirect_symbol " << p << "\n";
1068       O << "\tldr ip, ";
1069       printSuffixedName(p, "$slp");
1070       O << "\n";
1071       if (TM.getRelocationModel() == Reloc::PIC_) {
1072         printSuffixedName(p, "$scv");
1073         O << ":\n";
1074         O << "\tadd ip, pc, ip\n";
1075       }
1076       O << "\tldr pc, [ip, #0]\n";
1077       printSuffixedName(p, "$slp");
1078       O << ":\n";
1079       O << "\t.long\t";
1080       printSuffixedName(p, "$lazy_ptr");
1081       if (TM.getRelocationModel() == Reloc::PIC_) {
1082         O << "-(";
1083         printSuffixedName(p, "$scv");
1084         O << "+8)\n";
1085       } else
1086         O << "\n";
1087       SwitchToDataSection(".lazy_symbol_pointer", 0);
1088       printSuffixedName(p, "$lazy_ptr");
1089       O << ":\n";
1090       O << "\t.indirect_symbol " << p << "\n";
1091       O << "\t.long\tdyld_stub_binding_helper\n";
1092     }
1093     O << "\n";
1094
1095     // Output non-lazy-pointers for external and common global variables.
1096     if (!GVNonLazyPtrs.empty()) {
1097       SwitchToDataSection("\t.non_lazy_symbol_pointer", 0);
1098       for (StringSet<>::iterator i =  GVNonLazyPtrs.begin(),
1099              e = GVNonLazyPtrs.end(); i != e; ++i) {
1100         const char *p = i->getKeyData();
1101         printSuffixedName(p, "$non_lazy_ptr");
1102         O << ":\n";
1103         O << "\t.indirect_symbol " << p << "\n";
1104         O << "\t.long\t0\n";
1105       }
1106     }
1107
1108     if (!HiddenGVNonLazyPtrs.empty()) {
1109       SwitchToSection(TAI->getDataSection());
1110       for (StringSet<>::iterator i = HiddenGVNonLazyPtrs.begin(),
1111              e = HiddenGVNonLazyPtrs.end(); i != e; ++i) {
1112         const char *p = i->getKeyData();
1113         EmitAlignment(2);
1114         printSuffixedName(p, "$non_lazy_ptr");
1115         O << ":\n";
1116         O << "\t.long " << p << "\n";
1117       }
1118     }
1119
1120
1121     // Emit initial debug information.
1122     DW->EndModule();
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   } else {
1131     // Emit final debug information for ELF.
1132     DW->EndModule();
1133   }
1134
1135   return AsmPrinter::doFinalization(M);
1136 }
1137
1138 /// createARMCodePrinterPass - Returns a pass that prints the ARM
1139 /// assembly code for a MachineFunction to the given output stream,
1140 /// using the given target machine description.  This should work
1141 /// regardless of whether the function is in SSA form.
1142 ///
1143 FunctionPass *llvm::createARMCodePrinterPass(raw_ostream &o,
1144                                              ARMTargetMachine &tm,
1145                                              CodeGenOpt::Level OptLevel,
1146                                              bool verbose) {
1147   return new ARMAsmPrinter(o, tm, tm.getTargetAsmInfo(), OptLevel, verbose);
1148 }
1149
1150 namespace {
1151   static struct Register {
1152     Register() {
1153       ARMTargetMachine::registerAsmPrinter(createARMCodePrinterPass);
1154     }
1155   } Registrator;
1156 }
1157
1158 // Force static initialization.
1159 extern "C" void LLVMInitializeARMAsmPrinter() { }