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