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