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