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