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