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