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