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