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