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