Temporary revert my last commit: it seems it's triggering some subtle bug in backend
[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     if (MO.getOffset() > 0)
305       O << '+' << MO.getOffset();
306     else if (MO.getOffset() < 0)
307       O << MO.getOffset();
308     
309     if (isCallOp && Subtarget->isTargetELF() &&
310         TM.getRelocationModel() == Reloc::PIC_)
311       O << "(PLT)";
312     if (GV->hasExternalWeakLinkage())
313       ExtWeakSymbols.insert(GV);
314     break;
315   }
316   case MachineOperand::MO_ExternalSymbol: {
317     bool isCallOp = Modifier && !strcmp(Modifier, "call");
318     std::string Name(TAI->getGlobalPrefix());
319     Name += MO.getSymbolName();
320     if (isCallOp && Subtarget->isTargetDarwin() &&
321         TM.getRelocationModel() != Reloc::Static) {
322       printSuffixedName(Name, "$stub");
323       FnStubs.insert(Name);
324     } else
325       O << Name;
326     if (isCallOp && Subtarget->isTargetELF() &&
327         TM.getRelocationModel() == Reloc::PIC_)
328       O << "(PLT)";
329     break;
330   }
331   case MachineOperand::MO_ConstantPoolIndex:
332     O << TAI->getPrivateGlobalPrefix() << "CPI" << getFunctionNumber()
333       << '_' << MO.getIndex();
334     break;
335   case MachineOperand::MO_JumpTableIndex:
336     O << TAI->getPrivateGlobalPrefix() << "JTI" << getFunctionNumber()
337       << '_' << MO.getIndex();
338     break;
339   default:
340     O << "<unknown operand type>"; abort (); break;
341   }
342 }
343
344 static void printSOImm(raw_ostream &O, int64_t V, const TargetAsmInfo *TAI) {
345   assert(V < (1 << 12) && "Not a valid so_imm value!");
346   unsigned Imm = ARM_AM::getSOImmValImm(V);
347   unsigned Rot = ARM_AM::getSOImmValRot(V);
348   
349   // Print low-level immediate formation info, per
350   // A5.1.3: "Data-processing operands - Immediate".
351   if (Rot) {
352     O << "#" << Imm << ", " << Rot;
353     // Pretty printed version.
354     O << ' ' << TAI->getCommentString() << ' ' << (int)ARM_AM::rotr32(Imm, Rot);
355   } else {
356     O << "#" << Imm;
357   }
358 }
359
360 /// printSOImmOperand - SOImm is 4-bit rotate amount in bits 8-11 with 8-bit
361 /// immediate in bits 0-7.
362 void ARMAsmPrinter::printSOImmOperand(const MachineInstr *MI, int OpNum) {
363   const MachineOperand &MO = MI->getOperand(OpNum);
364   assert(MO.isImm() && "Not a valid so_imm value!");
365   printSOImm(O, MO.getImm(), TAI);
366 }
367
368 /// printSOImm2PartOperand - SOImm is broken into two pieces using a 'mov'
369 /// followed by an 'orr' to materialize.
370 void ARMAsmPrinter::printSOImm2PartOperand(const MachineInstr *MI, int OpNum) {
371   const MachineOperand &MO = MI->getOperand(OpNum);
372   assert(MO.isImm() && "Not a valid so_imm value!");
373   unsigned V1 = ARM_AM::getSOImmTwoPartFirst(MO.getImm());
374   unsigned V2 = ARM_AM::getSOImmTwoPartSecond(MO.getImm());
375   printSOImm(O, ARM_AM::getSOImmVal(V1), TAI);
376   O << "\n\torr";
377   printPredicateOperand(MI, 2);
378   O << " ";
379   printOperand(MI, 0); 
380   O << ", ";
381   printOperand(MI, 0); 
382   O << ", ";
383   printSOImm(O, ARM_AM::getSOImmVal(V2), TAI);
384 }
385
386 // so_reg is a 4-operand unit corresponding to register forms of the A5.1
387 // "Addressing Mode 1 - Data-processing operands" forms.  This includes:
388 //    REG 0   0    - e.g. R5
389 //    REG REG 0,SH_OPC     - e.g. R5, ROR R3
390 //    REG 0   IMM,SH_OPC  - e.g. R5, LSL #3
391 void ARMAsmPrinter::printSORegOperand(const MachineInstr *MI, int Op) {
392   const MachineOperand &MO1 = MI->getOperand(Op);
393   const MachineOperand &MO2 = MI->getOperand(Op+1);
394   const MachineOperand &MO3 = MI->getOperand(Op+2);
395
396   assert(TargetRegisterInfo::isPhysicalRegister(MO1.getReg()));
397   O << TM.getRegisterInfo()->get(MO1.getReg()).AsmName;
398
399   // Print the shift opc.
400   O << ", "
401     << ARM_AM::getShiftOpcStr(ARM_AM::getSORegShOp(MO3.getImm()))
402     << " ";
403
404   if (MO2.getReg()) {
405     assert(TargetRegisterInfo::isPhysicalRegister(MO2.getReg()));
406     O << TM.getRegisterInfo()->get(MO2.getReg()).AsmName;
407     assert(ARM_AM::getSORegOffset(MO3.getImm()) == 0);
408   } else {
409     O << "#" << ARM_AM::getSORegOffset(MO3.getImm());
410   }
411 }
412
413 void ARMAsmPrinter::printAddrMode2Operand(const MachineInstr *MI, int Op) {
414   const MachineOperand &MO1 = MI->getOperand(Op);
415   const MachineOperand &MO2 = MI->getOperand(Op+1);
416   const MachineOperand &MO3 = MI->getOperand(Op+2);
417
418   if (!MO1.isReg()) {   // FIXME: This is for CP entries, but isn't right.
419     printOperand(MI, Op);
420     return;
421   }
422
423   O << "[" << TM.getRegisterInfo()->get(MO1.getReg()).AsmName;
424
425   if (!MO2.getReg()) {
426     if (ARM_AM::getAM2Offset(MO3.getImm()))  // Don't print +0.
427       O << ", #"
428         << (char)ARM_AM::getAM2Op(MO3.getImm())
429         << ARM_AM::getAM2Offset(MO3.getImm());
430     O << "]";
431     return;
432   }
433
434   O << ", "
435     << (char)ARM_AM::getAM2Op(MO3.getImm())
436     << TM.getRegisterInfo()->get(MO2.getReg()).AsmName;
437   
438   if (unsigned ShImm = ARM_AM::getAM2Offset(MO3.getImm()))
439     O << ", "
440       << ARM_AM::getShiftOpcStr(ARM_AM::getAM2ShiftOpc(MO3.getImm()))
441       << " #" << ShImm;
442   O << "]";
443 }
444
445 void ARMAsmPrinter::printAddrMode2OffsetOperand(const MachineInstr *MI, int Op){
446   const MachineOperand &MO1 = MI->getOperand(Op);
447   const MachineOperand &MO2 = MI->getOperand(Op+1);
448
449   if (!MO1.getReg()) {
450     unsigned ImmOffs = ARM_AM::getAM2Offset(MO2.getImm());
451     assert(ImmOffs && "Malformed indexed load / store!");
452     O << "#"
453       << (char)ARM_AM::getAM2Op(MO2.getImm())
454       << ImmOffs;
455     return;
456   }
457
458   O << (char)ARM_AM::getAM2Op(MO2.getImm())
459     << TM.getRegisterInfo()->get(MO1.getReg()).AsmName;
460   
461   if (unsigned ShImm = ARM_AM::getAM2Offset(MO2.getImm()))
462     O << ", "
463       << ARM_AM::getShiftOpcStr(ARM_AM::getAM2ShiftOpc(MO2.getImm()))
464       << " #" << ShImm;
465 }
466
467 void ARMAsmPrinter::printAddrMode3Operand(const MachineInstr *MI, int Op) {
468   const MachineOperand &MO1 = MI->getOperand(Op);
469   const MachineOperand &MO2 = MI->getOperand(Op+1);
470   const MachineOperand &MO3 = MI->getOperand(Op+2);
471   
472   assert(TargetRegisterInfo::isPhysicalRegister(MO1.getReg()));
473   O << "[" << TM.getRegisterInfo()->get(MO1.getReg()).AsmName;
474
475   if (MO2.getReg()) {
476     O << ", "
477       << (char)ARM_AM::getAM3Op(MO3.getImm())
478       << TM.getRegisterInfo()->get(MO2.getReg()).AsmName
479       << "]";
480     return;
481   }
482   
483   if (unsigned ImmOffs = ARM_AM::getAM3Offset(MO3.getImm()))
484     O << ", #"
485       << (char)ARM_AM::getAM3Op(MO3.getImm())
486       << ImmOffs;
487   O << "]";
488 }
489
490 void ARMAsmPrinter::printAddrMode3OffsetOperand(const MachineInstr *MI, int Op){
491   const MachineOperand &MO1 = MI->getOperand(Op);
492   const MachineOperand &MO2 = MI->getOperand(Op+1);
493
494   if (MO1.getReg()) {
495     O << (char)ARM_AM::getAM3Op(MO2.getImm())
496       << TM.getRegisterInfo()->get(MO1.getReg()).AsmName;
497     return;
498   }
499
500   unsigned ImmOffs = ARM_AM::getAM3Offset(MO2.getImm());
501   assert(ImmOffs && "Malformed indexed load / store!");
502   O << "#"
503     << (char)ARM_AM::getAM3Op(MO2.getImm())
504     << ImmOffs;
505 }
506   
507 void ARMAsmPrinter::printAddrMode4Operand(const MachineInstr *MI, int Op,
508                                           const char *Modifier) {
509   const MachineOperand &MO1 = MI->getOperand(Op);
510   const MachineOperand &MO2 = MI->getOperand(Op+1);
511   ARM_AM::AMSubMode Mode = ARM_AM::getAM4SubMode(MO2.getImm());
512   if (Modifier && strcmp(Modifier, "submode") == 0) {
513     if (MO1.getReg() == ARM::SP) {
514       bool isLDM = (MI->getOpcode() == ARM::LDM ||
515                     MI->getOpcode() == ARM::LDM_RET);
516       O << ARM_AM::getAMSubModeAltStr(Mode, isLDM);
517     } else
518       O << ARM_AM::getAMSubModeStr(Mode);
519   } else {
520     printOperand(MI, Op);
521     if (ARM_AM::getAM4WBFlag(MO2.getImm()))
522       O << "!";
523   }
524 }
525
526 void ARMAsmPrinter::printAddrMode5Operand(const MachineInstr *MI, int Op,
527                                           const char *Modifier) {
528   const MachineOperand &MO1 = MI->getOperand(Op);
529   const MachineOperand &MO2 = MI->getOperand(Op+1);
530
531   if (!MO1.isReg()) {   // FIXME: This is for CP entries, but isn't right.
532     printOperand(MI, Op);
533     return;
534   }
535   
536   assert(TargetRegisterInfo::isPhysicalRegister(MO1.getReg()));
537
538   if (Modifier && strcmp(Modifier, "submode") == 0) {
539     ARM_AM::AMSubMode Mode = ARM_AM::getAM5SubMode(MO2.getImm());
540     if (MO1.getReg() == ARM::SP) {
541       bool isFLDM = (MI->getOpcode() == ARM::FLDMD ||
542                      MI->getOpcode() == ARM::FLDMS);
543       O << ARM_AM::getAMSubModeAltStr(Mode, isFLDM);
544     } else
545       O << ARM_AM::getAMSubModeStr(Mode);
546     return;
547   } else if (Modifier && strcmp(Modifier, "base") == 0) {
548     // Used for FSTM{D|S} and LSTM{D|S} operations.
549     O << TM.getRegisterInfo()->get(MO1.getReg()).AsmName;
550     if (ARM_AM::getAM5WBFlag(MO2.getImm()))
551       O << "!";
552     return;
553   }
554   
555   O << "[" << TM.getRegisterInfo()->get(MO1.getReg()).AsmName;
556   
557   if (unsigned ImmOffs = ARM_AM::getAM5Offset(MO2.getImm())) {
558     O << ", #"
559       << (char)ARM_AM::getAM5Op(MO2.getImm())
560       << ImmOffs*4;
561   }
562   O << "]";
563 }
564
565 void ARMAsmPrinter::printAddrModePCOperand(const MachineInstr *MI, int Op,
566                                            const char *Modifier) {
567   if (Modifier && strcmp(Modifier, "label") == 0) {
568     printPCLabel(MI, Op+1);
569     return;
570   }
571
572   const MachineOperand &MO1 = MI->getOperand(Op);
573   assert(TargetRegisterInfo::isPhysicalRegister(MO1.getReg()));
574   O << "[pc, +" << TM.getRegisterInfo()->get(MO1.getReg()).AsmName << "]";
575 }
576
577 void
578 ARMAsmPrinter::printThumbAddrModeRROperand(const MachineInstr *MI, int Op) {
579   const MachineOperand &MO1 = MI->getOperand(Op);
580   const MachineOperand &MO2 = MI->getOperand(Op+1);
581   O << "[" << TM.getRegisterInfo()->get(MO1.getReg()).AsmName;
582   O << ", " << TM.getRegisterInfo()->get(MO2.getReg()).AsmName << "]";
583 }
584
585 void
586 ARMAsmPrinter::printThumbAddrModeRI5Operand(const MachineInstr *MI, int Op,
587                                             unsigned Scale) {
588   const MachineOperand &MO1 = MI->getOperand(Op);
589   const MachineOperand &MO2 = MI->getOperand(Op+1);
590   const MachineOperand &MO3 = MI->getOperand(Op+2);
591
592   if (!MO1.isReg()) {   // FIXME: This is for CP entries, but isn't right.
593     printOperand(MI, Op);
594     return;
595   }
596
597   O << "[" << TM.getRegisterInfo()->get(MO1.getReg()).AsmName;
598   if (MO3.getReg())
599     O << ", " << TM.getRegisterInfo()->get(MO3.getReg()).AsmName;
600   else if (unsigned ImmOffs = MO2.getImm()) {
601     O << ", #" << ImmOffs;
602     if (Scale > 1)
603       O << " * " << Scale;
604   }
605   O << "]";
606 }
607
608 void
609 ARMAsmPrinter::printThumbAddrModeS1Operand(const MachineInstr *MI, int Op) {
610   printThumbAddrModeRI5Operand(MI, Op, 1);
611 }
612 void
613 ARMAsmPrinter::printThumbAddrModeS2Operand(const MachineInstr *MI, int Op) {
614   printThumbAddrModeRI5Operand(MI, Op, 2);
615 }
616 void
617 ARMAsmPrinter::printThumbAddrModeS4Operand(const MachineInstr *MI, int Op) {
618   printThumbAddrModeRI5Operand(MI, Op, 4);
619 }
620
621 void ARMAsmPrinter::printThumbAddrModeSPOperand(const MachineInstr *MI,int Op) {
622   const MachineOperand &MO1 = MI->getOperand(Op);
623   const MachineOperand &MO2 = MI->getOperand(Op+1);
624   O << "[" << TM.getRegisterInfo()->get(MO1.getReg()).AsmName;
625   if (unsigned ImmOffs = MO2.getImm())
626     O << ", #" << ImmOffs << " * 4";
627   O << "]";
628 }
629
630 void ARMAsmPrinter::printPredicateOperand(const MachineInstr *MI, int opNum) {
631   ARMCC::CondCodes CC = (ARMCC::CondCodes)MI->getOperand(opNum).getImm();
632   if (CC != ARMCC::AL)
633     O << ARMCondCodeToString(CC);
634 }
635
636 void ARMAsmPrinter::printSBitModifierOperand(const MachineInstr *MI, int opNum){
637   unsigned Reg = MI->getOperand(opNum).getReg();
638   if (Reg) {
639     assert(Reg == ARM::CPSR && "Expect ARM CPSR register!");
640     O << 's';
641   }
642 }
643
644 void ARMAsmPrinter::printPCLabel(const MachineInstr *MI, int opNum) {
645   int Id = (int)MI->getOperand(opNum).getImm();
646   O << TAI->getPrivateGlobalPrefix() << "PC" << Id;
647 }
648
649 void ARMAsmPrinter::printRegisterList(const MachineInstr *MI, int opNum) {
650   O << "{";
651   for (unsigned i = opNum, e = MI->getNumOperands(); i != e; ++i) {
652     printOperand(MI, i);
653     if (i != e-1) O << ", ";
654   }
655   O << "}";
656 }
657
658 void ARMAsmPrinter::printCPInstOperand(const MachineInstr *MI, int OpNo,
659                                        const char *Modifier) {
660   assert(Modifier && "This operand only works with a modifier!");
661   // There are two aspects to a CONSTANTPOOL_ENTRY operand, the label and the
662   // data itself.
663   if (!strcmp(Modifier, "label")) {
664     unsigned ID = MI->getOperand(OpNo).getImm();
665     O << TAI->getPrivateGlobalPrefix() << "CPI" << getFunctionNumber()
666       << '_' << ID << ":\n";
667   } else {
668     assert(!strcmp(Modifier, "cpentry") && "Unknown modifier for CPE");
669     unsigned CPI = MI->getOperand(OpNo).getIndex();
670
671     const MachineConstantPoolEntry &MCPE = MCP->getConstants()[CPI];
672     
673     if (MCPE.isMachineConstantPoolEntry()) {
674       EmitMachineConstantPoolValue(MCPE.Val.MachineCPVal);
675       ARMConstantPoolValue *ACPV =
676         static_cast<ARMConstantPoolValue*>(MCPE.Val.MachineCPVal);
677       if (ACPV->getPCAdjustment() != 0) {
678         const GlobalValue *GV = ACPV->getGV();
679         PCRelGVs.insert(GV);
680       }
681     } else {
682       EmitGlobalConstant(MCPE.Val.ConstVal);
683       // remember to emit the weak reference
684       if (const GlobalValue *GV = dyn_cast<GlobalValue>(MCPE.Val.ConstVal))
685         if (GV->hasExternalWeakLinkage())
686           ExtWeakSymbols.insert(GV);
687     }
688   }
689 }
690
691 void ARMAsmPrinter::printJTBlockOperand(const MachineInstr *MI, int OpNo) {
692   const MachineOperand &MO1 = MI->getOperand(OpNo);
693   const MachineOperand &MO2 = MI->getOperand(OpNo+1); // Unique Id
694   unsigned JTI = MO1.getIndex();
695   O << TAI->getPrivateGlobalPrefix() << "JTI" << getFunctionNumber()
696     << '_' << JTI << '_' << MO2.getImm() << ":\n";
697
698   const char *JTEntryDirective = TAI->getJumpTableDirective();
699   if (!JTEntryDirective)
700     JTEntryDirective = TAI->getData32bitsDirective();
701
702   const MachineFunction *MF = MI->getParent()->getParent();
703   const MachineJumpTableInfo *MJTI = MF->getJumpTableInfo();
704   const std::vector<MachineJumpTableEntry> &JT = MJTI->getJumpTables();
705   const std::vector<MachineBasicBlock*> &JTBBs = JT[JTI].MBBs;
706   bool UseSet= TAI->getSetDirective() && TM.getRelocationModel() == Reloc::PIC_;
707   std::set<MachineBasicBlock*> JTSets;
708   for (unsigned i = 0, e = JTBBs.size(); i != e; ++i) {
709     MachineBasicBlock *MBB = JTBBs[i];
710     if (UseSet && JTSets.insert(MBB).second)
711       printPICJumpTableSetLabel(JTI, MO2.getImm(), MBB);
712
713     O << JTEntryDirective << ' ';
714     if (UseSet)
715       O << TAI->getPrivateGlobalPrefix() << getFunctionNumber()
716         << '_' << JTI << '_' << MO2.getImm()
717         << "_set_" << MBB->getNumber();
718     else if (TM.getRelocationModel() == Reloc::PIC_) {
719       printBasicBlockLabel(MBB, false, false, false);
720       // If the arch uses custom Jump Table directives, don't calc relative to JT
721       if (!TAI->getJumpTableDirective()) 
722         O << '-' << TAI->getPrivateGlobalPrefix() << "JTI"
723           << getFunctionNumber() << '_' << JTI << '_' << MO2.getImm();
724     } else
725       printBasicBlockLabel(MBB, false, false, false);
726     if (i != e-1)
727       O << '\n';
728   }
729 }
730
731
732 bool ARMAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,
733                                     unsigned AsmVariant, const char *ExtraCode){
734   // Does this asm operand have a single letter operand modifier?
735   if (ExtraCode && ExtraCode[0]) {
736     if (ExtraCode[1] != 0) return true; // Unknown modifier.
737     
738     switch (ExtraCode[0]) {
739     default: return true;  // Unknown modifier.
740     case 'c': // Don't print "$" before a global var name or constant.
741     case 'P': // Print a VFP double precision register.
742       printOperand(MI, OpNo);
743       return false;
744     case 'Q':
745       if (TM.getTargetData()->isLittleEndian())
746         break;
747       // Fallthrough
748     case 'R':
749       if (TM.getTargetData()->isBigEndian())
750         break;
751       // Fallthrough
752     case 'H': // Write second word of DI / DF reference.  
753       // Verify that this operand has two consecutive registers.
754       if (!MI->getOperand(OpNo).isReg() ||
755           OpNo+1 == MI->getNumOperands() ||
756           !MI->getOperand(OpNo+1).isReg())
757         return true;
758       ++OpNo;   // Return the high-part.
759     }
760   }
761   
762   printOperand(MI, OpNo);
763   return false;
764 }
765
766 void ARMAsmPrinter::printMachineInstruction(const MachineInstr *MI) {
767   ++EmittedInsts;
768
769   int Opc = MI->getOpcode();
770   switch (Opc) {
771   case ARM::CONSTPOOL_ENTRY:
772     if (!InCPMode && AFI->isThumbFunction()) {
773       EmitAlignment(2);
774       InCPMode = true;
775     }
776     break;
777   default: {
778     if (InCPMode && AFI->isThumbFunction())
779       InCPMode = false;
780   }}
781
782   // Call the autogenerated instruction printer routines.
783   printInstruction(MI);
784 }
785
786 bool ARMAsmPrinter::doInitialization(Module &M) {
787   // Emit initial debug information.
788   // FIXME: Dwarf support.
789   //DW.BeginModule(&M);
790   
791   bool Result = AsmPrinter::doInitialization(M);
792
793   // AsmPrinter::doInitialization should have done this analysis.
794   MMI = getAnalysisToUpdate<MachineModuleInfo>();
795   assert(MMI);
796   // FIXME: Dwarf support.
797   //DW.SetModuleInfo(MMI);
798
799   // Darwin wants symbols to be quoted if they have complex names.
800   if (Subtarget->isTargetDarwin())
801     Mang->setUseQuotes(true);
802
803   return Result;
804 }
805
806 /// PrintUnmangledNameSafely - Print out the printable characters in the name.
807 /// Don't print things like \n or \0.
808 static void PrintUnmangledNameSafely(const Value *V, raw_ostream &OS) {
809   for (const char *Name = V->getNameStart(), *E = Name+V->getNameLen();
810        Name != E; ++Name)
811     if (isprint(*Name))
812       OS << *Name;
813 }
814
815 void ARMAsmPrinter::printModuleLevelGV(const GlobalVariable* GVar) {
816   const TargetData *TD = TM.getTargetData();
817
818   if (!GVar->hasInitializer())   // External global require no code
819     return;
820
821   // Check to see if this is a special global used by LLVM, if so, emit it.
822
823   if (EmitSpecialLLVMGlobal(GVar)) {
824     if (Subtarget->isTargetDarwin() &&
825         TM.getRelocationModel() == Reloc::Static) {
826       if (GVar->getName() == "llvm.global_ctors")
827         O << ".reference .constructors_used\n";
828       else if (GVar->getName() == "llvm.global_dtors")
829         O << ".reference .destructors_used\n";
830     }
831     return;
832   }
833
834   std::string name = Mang->getValueName(GVar);
835   Constant *C = GVar->getInitializer();
836   const Type *Type = C->getType();
837   unsigned Size = TD->getABITypeSize(Type);
838   unsigned Align = TD->getPreferredAlignmentLog(GVar);
839
840   printVisibility(name, GVar->getVisibility());
841
842   if (Subtarget->isTargetELF())
843     O << "\t.type " << name << ",%object\n";
844
845   SwitchToSection(TAI->SectionForGlobal(GVar));
846
847   if (C->isNullValue() && !GVar->hasSection() && !GVar->isThreadLocal()) {
848     // FIXME: This seems to be pretty darwin-specific
849
850     if (GVar->hasExternalLinkage()) {
851       if (const char *Directive = TAI->getZeroFillDirective()) {
852         O << "\t.globl\t" << name << "\n";
853         O << Directive << "__DATA, __common, " << name << ", "
854           << Size << ", " << Align << "\n";
855         return;
856       }
857     }
858
859     if (GVar->hasInternalLinkage() || GVar->mayBeOverridden()) {
860       if (Size == 0) Size = 1;   // .comm Foo, 0 is undefined, avoid it.
861
862       if (TAI->getLCOMMDirective() != NULL) {
863         if (PCRelGVs.count(GVar) || GVar->hasInternalLinkage()) {
864           O << TAI->getLCOMMDirective() << name << "," << Size;
865           if (Subtarget->isTargetDarwin())
866             O << "," << Align;
867         } else
868           O << TAI->getCOMMDirective()  << name << "," << Size;
869       } else {
870         if (GVar->hasInternalLinkage())
871           O << "\t.local\t" << name << "\n";
872         O << TAI->getCOMMDirective()  << name << "," << Size;
873         if (TAI->getCOMMDirectiveTakesAlignment())
874           O << "," << (TAI->getAlignmentIsInBytes() ? (1 << Align) : Align);
875       }
876       O << "\t\t" << TAI->getCommentString() << " ";
877       PrintUnmangledNameSafely(GVar, O);
878       O << "\n";
879       return;
880     }
881   }
882
883   switch (GVar->getLinkage()) {
884    case GlobalValue::LinkOnceLinkage:
885    case GlobalValue::WeakLinkage:
886     if (Subtarget->isTargetDarwin()) {
887       O << "\t.globl " << name << "\n"
888         << "\t.weak_definition " << name << "\n";
889     } else {
890       O << "\t.weak " << name << "\n";
891     }
892     break;
893    case GlobalValue::AppendingLinkage:
894     // FIXME: appending linkage variables should go into a section of
895     // their name or something.  For now, just emit them as external.
896    case GlobalValue::ExternalLinkage:
897     O << "\t.globl " << name << "\n";
898     // FALL THROUGH
899    case GlobalValue::InternalLinkage:
900     break;
901    default:
902     assert(0 && "Unknown linkage type!");
903     break;
904   }
905
906   EmitAlignment(Align, GVar);
907   O << name << ":\t\t\t\t" << TAI->getCommentString() << " ";
908   PrintUnmangledNameSafely(GVar, O);
909   O << "\n";
910   if (TAI->hasDotTypeDotSizeDirective())
911     O << "\t.size " << name << ", " << Size << "\n";
912
913   // If the initializer is a extern weak symbol, remember to emit the weak
914   // reference!
915   if (const GlobalValue *GV = dyn_cast<GlobalValue>(C))
916     if (GV->hasExternalWeakLinkage())
917       ExtWeakSymbols.insert(GV);
918
919   EmitGlobalConstant(C);
920   O << '\n';
921 }
922
923
924 bool ARMAsmPrinter::doFinalization(Module &M) {
925   for (Module::const_global_iterator I = M.global_begin(), E = M.global_end();
926        I != E; ++I)
927     printModuleLevelGV(I);
928
929   if (Subtarget->isTargetDarwin()) {
930     SwitchToDataSection("");
931
932     // Output stubs for dynamically-linked functions
933     unsigned j = 1;
934     for (std::set<std::string>::iterator i = FnStubs.begin(), e = FnStubs.end();
935          i != e; ++i, ++j) {
936       if (TM.getRelocationModel() == Reloc::PIC_)
937         SwitchToTextSection(".section __TEXT,__picsymbolstub4,symbol_stubs,"
938                             "none,16", 0);
939       else
940         SwitchToTextSection(".section __TEXT,__symbol_stub4,symbol_stubs,"
941                             "none,12", 0);
942
943       EmitAlignment(2);
944       O << "\t.code\t32\n";
945
946       std::string p = *i;
947       printSuffixedName(p, "$stub");
948       O << ":\n";
949       O << "\t.indirect_symbol " << *i << "\n";
950       O << "\tldr ip, ";
951       printSuffixedName(p, "$slp");
952       O << "\n";
953       if (TM.getRelocationModel() == Reloc::PIC_) {
954         printSuffixedName(p, "$scv");
955         O << ":\n";
956         O << "\tadd ip, pc, ip\n";
957       }
958       O << "\tldr pc, [ip, #0]\n";
959       printSuffixedName(p, "$slp");
960       O << ":\n";
961       O << "\t.long\t";
962       printSuffixedName(p, "$lazy_ptr");
963       if (TM.getRelocationModel() == Reloc::PIC_) {
964         O << "-(";
965         printSuffixedName(p, "$scv");
966         O << "+8)\n";
967       } else
968         O << "\n";
969       SwitchToDataSection(".lazy_symbol_pointer", 0);
970       printSuffixedName(p, "$lazy_ptr");
971       O << ":\n";
972       O << "\t.indirect_symbol " << *i << "\n";
973       O << "\t.long\tdyld_stub_binding_helper\n";
974     }
975     O << "\n";
976
977     // Output non-lazy-pointers for external and common global variables.
978     if (!GVNonLazyPtrs.empty())
979       SwitchToDataSection(".non_lazy_symbol_pointer", 0);
980     for (std::set<std::string>::iterator i = GVNonLazyPtrs.begin(),
981            e = GVNonLazyPtrs.end(); i != e; ++i) {
982       std::string p = *i;
983       printSuffixedName(p, "$non_lazy_ptr");
984       O << ":\n";
985       O << "\t.indirect_symbol " << *i << "\n";
986       O << "\t.long\t0\n";
987     }
988
989     // Emit initial debug information.
990     // FIXME: Dwarf support.
991     //DW.EndModule();
992
993     // Funny Darwin hack: This flag tells the linker that no global symbols
994     // contain code that falls through to other global symbols (e.g. the obvious
995     // implementation of multiple entry points).  If this doesn't occur, the
996     // linker can safely perform dead code stripping.  Since LLVM never
997     // generates code that does this, it is always safe to set.
998     O << "\t.subsections_via_symbols\n";
999   } else {
1000     // Emit final debug information for ELF.
1001     // FIXME: Dwarf support.
1002     //DW.EndModule();
1003   }
1004
1005   return AsmPrinter::doFinalization(M);
1006 }
1007
1008 /// createARMCodePrinterPass - Returns a pass that prints the ARM
1009 /// assembly code for a MachineFunction to the given output stream,
1010 /// using the given target machine description.  This should work
1011 /// regardless of whether the function is in SSA form.
1012 ///
1013 FunctionPass *llvm::createARMCodePrinterPass(raw_ostream &o,
1014                                              ARMTargetMachine &tm) {
1015   return new ARMAsmPrinter(o, tm, tm.getTargetAsmInfo());
1016 }
1017
1018 namespace {
1019   static struct Register {
1020     Register() {
1021       ARMTargetMachine::registerAsmPrinter(createARMCodePrinterPass);
1022     }
1023   } Registrator;
1024 }