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