Make two piece constant generation as a single instruction. It's re-materialized...
[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 (AFI->isThumbFunction()) {
209     EmitAlignment(1, F);
210     O << "\t.code\t16\n";
211     O << "\t.thumb_func";
212     if (Subtarget->isTargetDarwin())
213       O << "\t" << CurrentFnName;
214     O << "\n";
215     InCPMode = false;
216   } else
217     EmitAlignment(2, F);
218
219   O << CurrentFnName << ":\n";
220   if (Subtarget->isTargetDarwin()) {
221     // Emit pre-function debug information.
222     DW.BeginFunction(&MF);
223   }
224
225   // Print out code for the function.
226   for (MachineFunction::const_iterator I = MF.begin(), E = MF.end();
227        I != E; ++I) {
228     // Print a label for the basic block.
229     if (I != MF.begin()) {
230       printBasicBlockLabel(I, true);
231       O << '\n';
232     }
233     for (MachineBasicBlock::const_iterator II = I->begin(), E = I->end();
234          II != E; ++II) {
235       // Print the assembly for the instruction.
236       printMachineInstruction(II);
237     }
238   }
239
240   if (TAI->hasDotTypeDotSizeDirective())
241     O << "\t.size " << CurrentFnName << ", .-" << CurrentFnName << "\n";
242
243   if (Subtarget->isTargetDarwin()) {
244     // Emit post-function debug information.
245     DW.EndFunction();
246   }
247
248   return false;
249 }
250
251 void ARMAsmPrinter::printOperand(const MachineInstr *MI, int opNum,
252                                  const char *Modifier) {
253   const MachineOperand &MO = MI->getOperand(opNum);
254   switch (MO.getType()) {
255   case MachineOperand::MO_Register:
256     if (MRegisterInfo::isPhysicalRegister(MO.getReg()))
257       O << TM.getRegisterInfo()->get(MO.getReg()).Name;
258     else
259       assert(0 && "not implemented");
260     break;
261   case MachineOperand::MO_Immediate: {
262     if (!Modifier || strcmp(Modifier, "no_hash") != 0)
263       O << "#";
264
265     O << (int)MO.getImmedValue();
266     break;
267   }
268   case MachineOperand::MO_MachineBasicBlock:
269     printBasicBlockLabel(MO.getMachineBasicBlock());
270     return;
271   case MachineOperand::MO_GlobalAddress: {
272     bool isCallOp = Modifier && !strcmp(Modifier, "call");
273     GlobalValue *GV = MO.getGlobal();
274     std::string Name = Mang->getValueName(GV);
275     bool isExt = (GV->isDeclaration() || GV->hasWeakLinkage() ||
276                   GV->hasLinkOnceLinkage());
277     if (isExt && isCallOp && Subtarget->isTargetDarwin() &&
278         TM.getRelocationModel() != Reloc::Static) {
279       O << TAI->getPrivateGlobalPrefix() << Name << "$stub";
280       FnStubs.insert(Name);
281     } else
282       O << Name;
283
284     if (GV->hasExternalWeakLinkage())
285       ExtWeakSymbols.insert(GV);
286     break;
287   }
288   case MachineOperand::MO_ExternalSymbol: {
289     bool isCallOp = Modifier && !strcmp(Modifier, "call");
290     std::string Name(TAI->getGlobalPrefix());
291     Name += MO.getSymbolName();
292     if (isCallOp && Subtarget->isTargetDarwin() &&
293         TM.getRelocationModel() != Reloc::Static) {
294       O << TAI->getPrivateGlobalPrefix() << Name << "$stub";
295       FnStubs.insert(Name);
296     } else
297       O << Name;
298     break;
299   }
300   case MachineOperand::MO_ConstantPoolIndex:
301     O << TAI->getPrivateGlobalPrefix() << "CPI" << getFunctionNumber()
302       << '_' << MO.getConstantPoolIndex();
303     break;
304   case MachineOperand::MO_JumpTableIndex:
305     O << TAI->getPrivateGlobalPrefix() << "JTI" << getFunctionNumber()
306       << '_' << MO.getJumpTableIndex();
307     break;
308   default:
309     O << "<unknown operand type>"; abort (); break;
310   }
311 }
312
313 static void printSOImm(std::ostream &O, int64_t V, const TargetAsmInfo *TAI) {
314   assert(V < (1 << 12) && "Not a valid so_imm value!");
315   unsigned Imm = ARM_AM::getSOImmValImm(V);
316   unsigned Rot = ARM_AM::getSOImmValRot(V);
317   
318   // Print low-level immediate formation info, per
319   // A5.1.3: "Data-processing operands - Immediate".
320   if (Rot) {
321     O << "#" << Imm << ", " << Rot;
322     // Pretty printed version.
323     O << ' ' << TAI->getCommentString() << ' ' << (int)ARM_AM::rotr32(Imm, Rot);
324   } else {
325     O << "#" << Imm;
326   }
327 }
328
329 /// printSOImmOperand - SOImm is 4-bit rotate amount in bits 8-11 with 8-bit
330 /// immediate in bits 0-7.
331 void ARMAsmPrinter::printSOImmOperand(const MachineInstr *MI, int OpNum) {
332   const MachineOperand &MO = MI->getOperand(OpNum);
333   assert(MO.isImmediate() && "Not a valid so_imm value!");
334   printSOImm(O, MO.getImmedValue(), TAI);
335 }
336
337 /// printSOImm2PartOperand - SOImm is broken into two pieces using a mov
338 /// followed by a or to materialize.
339 void ARMAsmPrinter::printSOImm2PartOperand(const MachineInstr *MI, int OpNum) {
340   const MachineOperand &MO = MI->getOperand(OpNum);
341   assert(MO.isImmediate() && "Not a valid so_imm value!");
342   unsigned V1 = ARM_AM::getSOImmTwoPartFirst(MO.getImmedValue());
343   unsigned V2 = ARM_AM::getSOImmTwoPartSecond(MO.getImmedValue());
344   printSOImm(O, ARM_AM::getSOImmVal(V1), TAI);
345   O << "\n\torr ";
346   printOperand(MI, 0); 
347   O << ", ";
348   printOperand(MI, 0); 
349   O << ", ";
350   printSOImm(O, ARM_AM::getSOImmVal(V2), TAI);
351 }
352
353 // so_reg is a 4-operand unit corresponding to register forms of the A5.1
354 // "Addressing Mode 1 - Data-processing operands" forms.  This includes:
355 //    REG 0   0    - e.g. R5
356 //    REG REG 0,SH_OPC     - e.g. R5, ROR R3
357 //    REG 0   IMM,SH_OPC  - e.g. R5, LSL #3
358 void ARMAsmPrinter::printSORegOperand(const MachineInstr *MI, int Op) {
359   const MachineOperand &MO1 = MI->getOperand(Op);
360   const MachineOperand &MO2 = MI->getOperand(Op+1);
361   const MachineOperand &MO3 = MI->getOperand(Op+2);
362
363   assert(MRegisterInfo::isPhysicalRegister(MO1.getReg()));
364   O << TM.getRegisterInfo()->get(MO1.getReg()).Name;
365
366   // Print the shift opc.
367   O << ", "
368     << ARM_AM::getShiftOpcStr(ARM_AM::getSORegShOp(MO3.getImmedValue()))
369     << " ";
370
371   if (MO2.getReg()) {
372     assert(MRegisterInfo::isPhysicalRegister(MO2.getReg()));
373     O << TM.getRegisterInfo()->get(MO2.getReg()).Name;
374     assert(ARM_AM::getSORegOffset(MO3.getImm()) == 0);
375   } else {
376     O << "#" << ARM_AM::getSORegOffset(MO3.getImm());
377   }
378 }
379
380 void ARMAsmPrinter::printAddrMode2Operand(const MachineInstr *MI, int Op) {
381   const MachineOperand &MO1 = MI->getOperand(Op);
382   const MachineOperand &MO2 = MI->getOperand(Op+1);
383   const MachineOperand &MO3 = MI->getOperand(Op+2);
384
385   if (!MO1.isRegister()) {   // FIXME: This is for CP entries, but isn't right.
386     printOperand(MI, Op);
387     return;
388   }
389
390   O << "[" << TM.getRegisterInfo()->get(MO1.getReg()).Name;
391
392   if (!MO2.getReg()) {
393     if (ARM_AM::getAM2Offset(MO3.getImm()))  // Don't print +0.
394       O << ", #"
395         << (char)ARM_AM::getAM2Op(MO3.getImm())
396         << ARM_AM::getAM2Offset(MO3.getImm());
397     O << "]";
398     return;
399   }
400
401   O << ", "
402     << (char)ARM_AM::getAM2Op(MO3.getImm())
403     << TM.getRegisterInfo()->get(MO2.getReg()).Name;
404   
405   if (unsigned ShImm = ARM_AM::getAM2Offset(MO3.getImm()))
406     O << ", "
407       << ARM_AM::getShiftOpcStr(ARM_AM::getAM2ShiftOpc(MO3.getImmedValue()))
408       << " #" << ShImm;
409   O << "]";
410 }
411
412 void ARMAsmPrinter::printAddrMode2OffsetOperand(const MachineInstr *MI, int Op){
413   const MachineOperand &MO1 = MI->getOperand(Op);
414   const MachineOperand &MO2 = MI->getOperand(Op+1);
415
416   if (!MO1.getReg()) {
417     if (ARM_AM::getAM2Offset(MO2.getImm()))  // Don't print +0.
418       O << "#"
419         << (char)ARM_AM::getAM2Op(MO2.getImm())
420         << ARM_AM::getAM2Offset(MO2.getImm());
421     return;
422   }
423
424   O << (char)ARM_AM::getAM2Op(MO2.getImm())
425     << TM.getRegisterInfo()->get(MO1.getReg()).Name;
426   
427   if (unsigned ShImm = ARM_AM::getAM2Offset(MO2.getImm()))
428     O << ", "
429       << ARM_AM::getShiftOpcStr(ARM_AM::getAM2ShiftOpc(MO2.getImmedValue()))
430       << " #" << ShImm;
431 }
432
433 void ARMAsmPrinter::printAddrMode3Operand(const MachineInstr *MI, int Op) {
434   const MachineOperand &MO1 = MI->getOperand(Op);
435   const MachineOperand &MO2 = MI->getOperand(Op+1);
436   const MachineOperand &MO3 = MI->getOperand(Op+2);
437   
438   assert(MRegisterInfo::isPhysicalRegister(MO1.getReg()));
439   O << "[" << TM.getRegisterInfo()->get(MO1.getReg()).Name;
440
441   if (MO2.getReg()) {
442     O << ", "
443       << (char)ARM_AM::getAM3Op(MO3.getImm())
444       << TM.getRegisterInfo()->get(MO2.getReg()).Name
445       << "]";
446     return;
447   }
448   
449   if (unsigned ImmOffs = ARM_AM::getAM3Offset(MO3.getImm()))
450     O << ", #"
451       << (char)ARM_AM::getAM3Op(MO3.getImm())
452       << ImmOffs;
453   O << "]";
454 }
455
456 void ARMAsmPrinter::printAddrMode3OffsetOperand(const MachineInstr *MI, int Op){
457   const MachineOperand &MO1 = MI->getOperand(Op);
458   const MachineOperand &MO2 = MI->getOperand(Op+1);
459
460   if (MO1.getReg()) {
461     O << (char)ARM_AM::getAM3Op(MO2.getImm())
462       << TM.getRegisterInfo()->get(MO1.getReg()).Name;
463     return;
464   }
465
466   unsigned ImmOffs = ARM_AM::getAM3Offset(MO2.getImm());
467   O << "#"
468   << (char)ARM_AM::getAM3Op(MO2.getImm())
469     << ImmOffs;
470 }
471   
472 void ARMAsmPrinter::printAddrMode4Operand(const MachineInstr *MI, int Op,
473                                           const char *Modifier) {
474   const MachineOperand &MO1 = MI->getOperand(Op);
475   const MachineOperand &MO2 = MI->getOperand(Op+1);
476   ARM_AM::AMSubMode Mode = ARM_AM::getAM4SubMode(MO2.getImm());
477   if (Modifier && strcmp(Modifier, "submode") == 0) {
478     if (MO1.getReg() == ARM::SP) {
479       bool isLDM = (MI->getOpcode() == ARM::LDM ||
480                     MI->getOpcode() == ARM::LDM_RET);
481       O << ARM_AM::getAMSubModeAltStr(Mode, isLDM);
482     } else
483       O << ARM_AM::getAMSubModeStr(Mode);
484   } else {
485     printOperand(MI, Op);
486     if (ARM_AM::getAM4WBFlag(MO2.getImm()))
487       O << "!";
488   }
489 }
490
491 void ARMAsmPrinter::printAddrMode5Operand(const MachineInstr *MI, int Op,
492                                           const char *Modifier) {
493   const MachineOperand &MO1 = MI->getOperand(Op);
494   const MachineOperand &MO2 = MI->getOperand(Op+1);
495
496   if (!MO1.isRegister()) {   // FIXME: This is for CP entries, but isn't right.
497     printOperand(MI, Op);
498     return;
499   }
500   
501   assert(MRegisterInfo::isPhysicalRegister(MO1.getReg()));
502
503   if (Modifier && strcmp(Modifier, "submode") == 0) {
504     ARM_AM::AMSubMode Mode = ARM_AM::getAM5SubMode(MO2.getImm());
505     if (MO1.getReg() == ARM::SP) {
506       bool isFLDM = (MI->getOpcode() == ARM::FLDMD ||
507                      MI->getOpcode() == ARM::FLDMS);
508       O << ARM_AM::getAMSubModeAltStr(Mode, isFLDM);
509     } else
510       O << ARM_AM::getAMSubModeStr(Mode);
511     return;
512   } else if (Modifier && strcmp(Modifier, "base") == 0) {
513     // Used for FSTM{D|S} and LSTM{D|S} operations.
514     O << TM.getRegisterInfo()->get(MO1.getReg()).Name;
515     if (ARM_AM::getAM5WBFlag(MO2.getImm()))
516       O << "!";
517     return;
518   }
519   
520   O << "[" << TM.getRegisterInfo()->get(MO1.getReg()).Name;
521   
522   if (unsigned ImmOffs = ARM_AM::getAM5Offset(MO2.getImm())) {
523     O << ", #"
524       << (char)ARM_AM::getAM5Op(MO2.getImm())
525       << ImmOffs*4;
526   }
527   O << "]";
528 }
529
530 void ARMAsmPrinter::printAddrModePCOperand(const MachineInstr *MI, int Op,
531                                            const char *Modifier) {
532   if (Modifier && strcmp(Modifier, "label") == 0) {
533     printPCLabel(MI, Op+1);
534     return;
535   }
536
537   const MachineOperand &MO1 = MI->getOperand(Op);
538   assert(MRegisterInfo::isPhysicalRegister(MO1.getReg()));
539   O << "[pc, +" << TM.getRegisterInfo()->get(MO1.getReg()).Name << "]";
540 }
541
542 void
543 ARMAsmPrinter::printThumbAddrModeRROperand(const MachineInstr *MI, int Op) {
544   const MachineOperand &MO1 = MI->getOperand(Op);
545   const MachineOperand &MO2 = MI->getOperand(Op+1);
546   O << "[" << TM.getRegisterInfo()->get(MO1.getReg()).Name;
547   O << ", " << TM.getRegisterInfo()->get(MO2.getReg()).Name << "]";
548 }
549
550 void
551 ARMAsmPrinter::printThumbAddrModeRI5Operand(const MachineInstr *MI, int Op,
552                                             unsigned Scale) {
553   const MachineOperand &MO1 = MI->getOperand(Op);
554   const MachineOperand &MO2 = MI->getOperand(Op+1);
555   const MachineOperand &MO3 = MI->getOperand(Op+2);
556
557   if (!MO1.isRegister()) {   // FIXME: This is for CP entries, but isn't right.
558     printOperand(MI, Op);
559     return;
560   }
561
562   O << "[" << TM.getRegisterInfo()->get(MO1.getReg()).Name;
563   if (MO3.getReg())
564     O << ", " << TM.getRegisterInfo()->get(MO3.getReg()).Name;
565   else if (unsigned ImmOffs = MO2.getImm()) {
566     O << ", #" << ImmOffs;
567     if (Scale > 1)
568       O << " * " << Scale;
569   }
570   O << "]";
571 }
572
573 void
574 ARMAsmPrinter::printThumbAddrModeS1Operand(const MachineInstr *MI, int Op) {
575   printThumbAddrModeRI5Operand(MI, Op, 1);
576 }
577 void
578 ARMAsmPrinter::printThumbAddrModeS2Operand(const MachineInstr *MI, int Op) {
579   printThumbAddrModeRI5Operand(MI, Op, 2);
580 }
581 void
582 ARMAsmPrinter::printThumbAddrModeS4Operand(const MachineInstr *MI, int Op) {
583   printThumbAddrModeRI5Operand(MI, Op, 4);
584 }
585
586 void ARMAsmPrinter::printThumbAddrModeSPOperand(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()).Name;
590   if (unsigned ImmOffs = MO2.getImm())
591     O << ", #" << ImmOffs << " * 4";
592   O << "]";
593 }
594
595 void ARMAsmPrinter::printCCOperand(const MachineInstr *MI, int opNum) {
596   int CC = (int)MI->getOperand(opNum).getImmedValue();
597   O << ARMCondCodeToString((ARMCC::CondCodes)CC);
598 }
599
600 void ARMAsmPrinter::printPCLabel(const MachineInstr *MI, int opNum) {
601   int Id = (int)MI->getOperand(opNum).getImmedValue();
602   O << TAI->getPrivateGlobalPrefix() << "PC" << Id;
603 }
604
605 void ARMAsmPrinter::printRegisterList(const MachineInstr *MI, int opNum) {
606   O << "{";
607   for (unsigned i = opNum, e = MI->getNumOperands(); i != e; ++i) {
608     printOperand(MI, i);
609     if (i != e-1) O << ", ";
610   }
611   O << "}";
612 }
613
614 void ARMAsmPrinter::printCPInstOperand(const MachineInstr *MI, int OpNo,
615                                        const char *Modifier) {
616   assert(Modifier && "This operand only works with a modifier!");
617   // There are two aspects to a CONSTANTPOOL_ENTRY operand, the label and the
618   // data itself.
619   if (!strcmp(Modifier, "label")) {
620     unsigned ID = MI->getOperand(OpNo).getImm();
621     O << TAI->getPrivateGlobalPrefix() << "CPI" << getFunctionNumber()
622       << '_' << ID << ":\n";
623   } else {
624     assert(!strcmp(Modifier, "cpentry") && "Unknown modifier for CPE");
625     unsigned CPI = MI->getOperand(OpNo).getConstantPoolIndex();
626
627     const MachineConstantPoolEntry &MCPE =  // Chasing pointers is fun?
628       MI->getParent()->getParent()->getConstantPool()->getConstants()[CPI];
629     
630     if (MCPE.isMachineConstantPoolEntry())
631       EmitMachineConstantPoolValue(MCPE.Val.MachineCPVal);
632     else
633       EmitGlobalConstant(MCPE.Val.ConstVal);
634   }
635 }
636
637 void ARMAsmPrinter::printJTBlockOperand(const MachineInstr *MI, int OpNo) {
638   const MachineOperand &MO1 = MI->getOperand(OpNo);
639   const MachineOperand &MO2 = MI->getOperand(OpNo+1); // Unique Id
640   unsigned JTI = MO1.getJumpTableIndex();
641   O << TAI->getPrivateGlobalPrefix() << "JTI" << getFunctionNumber()
642     << '_' << JTI << '_' << MO2.getImmedValue() << ":\n";
643
644   const char *JTEntryDirective = TAI->getJumpTableDirective();
645   if (!JTEntryDirective)
646     JTEntryDirective = TAI->getData32bitsDirective();
647
648   const MachineFunction *MF = MI->getParent()->getParent();
649   MachineJumpTableInfo *MJTI = MF->getJumpTableInfo();
650   const std::vector<MachineJumpTableEntry> &JT = MJTI->getJumpTables();
651   const std::vector<MachineBasicBlock*> &JTBBs = JT[JTI].MBBs;
652   bool UseSet= TAI->getSetDirective() && TM.getRelocationModel() == Reloc::PIC_;
653   std::set<MachineBasicBlock*> JTSets;
654   for (unsigned i = 0, e = JTBBs.size(); i != e; ++i) {
655     MachineBasicBlock *MBB = JTBBs[i];
656     if (UseSet && JTSets.insert(MBB).second)
657       printSetLabel(JTI, MO2.getImmedValue(), MBB);
658
659     O << JTEntryDirective << ' ';
660     if (UseSet)
661       O << TAI->getPrivateGlobalPrefix() << getFunctionNumber()
662         << '_' << JTI << '_' << MO2.getImmedValue()
663         << "_set_" << MBB->getNumber();
664     else if (TM.getRelocationModel() == Reloc::PIC_) {
665       printBasicBlockLabel(MBB, false, false);
666       // If the arch uses custom Jump Table directives, don't calc relative to JT
667       if (!TAI->getJumpTableDirective()) 
668         O << '-' << TAI->getPrivateGlobalPrefix() << "JTI"
669           << getFunctionNumber() << '_' << JTI << '_' << MO2.getImmedValue();
670     } else
671       printBasicBlockLabel(MBB, false, false);
672     if (i != e-1)
673       O << '\n';
674   }
675 }
676
677
678 bool ARMAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,
679                                     unsigned AsmVariant, const char *ExtraCode){
680   // Does this asm operand have a single letter operand modifier?
681   if (ExtraCode && ExtraCode[0]) {
682     if (ExtraCode[1] != 0) return true; // Unknown modifier.
683     
684     switch (ExtraCode[0]) {
685     default: return true;  // Unknown modifier.
686     case 'c': // Don't print "$" before a global var name or constant.
687       printOperand(MI, OpNo);
688       return false;
689     case 'Q':
690       if (TM.getTargetData()->isLittleEndian())
691         break;
692       // Fallthrough
693     case 'R':
694       if (TM.getTargetData()->isBigEndian())
695         break;
696       // Fallthrough
697     case 'H': // Write second word of DI / DF reference.  
698       // Verify that this operand has two consecutive registers.
699       if (!MI->getOperand(OpNo).isRegister() ||
700           OpNo+1 == MI->getNumOperands() ||
701           !MI->getOperand(OpNo+1).isRegister())
702         return true;
703       ++OpNo;   // Return the high-part.
704     }
705   }
706   
707   printOperand(MI, OpNo);
708   return false;
709 }
710
711 void ARMAsmPrinter::printMachineInstruction(const MachineInstr *MI) {
712   ++EmittedInsts;
713
714   int Opc = MI->getOpcode();
715   switch (Opc) {
716   case ARM::CONSTPOOL_ENTRY:
717     if (!InCPMode && AFI->isThumbFunction()) {
718       EmitAlignment(2);
719       InCPMode = true;
720     }
721     break;
722   default: {
723     if (InCPMode && AFI->isThumbFunction())
724       InCPMode = false;
725     switch (Opc) {
726     case ARM::PICADD:
727     case ARM::PICLD:
728     case ARM::tPICADD:
729       break;
730     default:
731       O << "\t";
732       break;
733     }
734   }}
735
736   // Call the autogenerated instruction printer routines.
737   printInstruction(MI);
738 }
739
740 bool ARMAsmPrinter::doInitialization(Module &M) {
741   if (Subtarget->isTargetDarwin()) {
742     // Emit initial debug information.
743     DW.BeginModule(&M);
744   }
745   
746   return AsmPrinter::doInitialization(M);
747 }
748
749 bool ARMAsmPrinter::doFinalization(Module &M) {
750   const TargetData *TD = TM.getTargetData();
751
752   for (Module::const_global_iterator I = M.global_begin(), E = M.global_end();
753        I != E; ++I) {
754     if (!I->hasInitializer())   // External global require no code
755       continue;
756
757     if (EmitSpecialLLVMGlobal(I)) {
758       if (Subtarget->isTargetDarwin() &&
759           TM.getRelocationModel() == Reloc::Static) {
760         if (I->getName() == "llvm.global_ctors")
761           O << ".reference .constructors_used\n";
762         else if (I->getName() == "llvm.global_dtors")
763           O << ".reference .destructors_used\n";
764       }
765       continue;
766     }
767
768     std::string name = Mang->getValueName(I);
769     Constant *C = I->getInitializer();
770     const Type *Type = C->getType();
771     unsigned Size = TD->getTypeSize(Type);
772     unsigned Align = TD->getPreferredAlignmentLog(I);
773
774     if (I->hasHiddenVisibility())
775       if (const char *Directive = TAI->getHiddenDirective())
776         O << Directive << name << "\n";
777     if (Subtarget->isTargetELF())
778       O << "\t.type " << name << ",%object\n";
779     
780     if (C->isNullValue()) {
781       if (I->hasExternalLinkage()) {
782         if (const char *Directive = TAI->getZeroFillDirective()) {
783           O << "\t.globl\t" << name << "\n";
784           O << Directive << "__DATA__, __common, " << name << ", "
785             << Size << ", " << Align << "\n";
786           continue;
787         }
788       }
789
790       if (!I->hasSection() &&
791           (I->hasInternalLinkage() || I->hasWeakLinkage() ||
792            I->hasLinkOnceLinkage())) {
793         if (Size == 0) Size = 1;   // .comm Foo, 0 is undefined, avoid it.
794         if (!NoZerosInBSS && TAI->getBSSSection())
795           SwitchToDataSection(TAI->getBSSSection(), I);
796         else
797           SwitchToDataSection(TAI->getDataSection(), I);
798         if (TAI->getLCOMMDirective() != NULL) {
799           if (I->hasInternalLinkage()) {
800             O << TAI->getLCOMMDirective() << name << "," << Size;
801             if (Subtarget->isTargetDarwin())
802               O << "," << Align;
803           } else
804             O << TAI->getCOMMDirective()  << name << "," << Size;
805         } else {
806           if (I->hasInternalLinkage())
807             O << "\t.local\t" << name << "\n";
808           O << TAI->getCOMMDirective()  << name << "," << Size;
809           if (TAI->getCOMMDirectiveTakesAlignment())
810             O << "," << (TAI->getAlignmentIsInBytes() ? (1 << Align) : Align);
811         }
812         O << "\t\t" << TAI->getCommentString() << " " << I->getName() << "\n";
813         continue;
814       }
815     }
816
817     switch (I->getLinkage()) {
818     case GlobalValue::LinkOnceLinkage:
819     case GlobalValue::WeakLinkage:
820       if (Subtarget->isTargetDarwin()) {
821         O << "\t.globl " << name << "\n"
822           << "\t.weak_definition " << name << "\n";
823         SwitchToDataSection("\t.section __DATA,__const_coal,coalesced", I);
824       } else {
825         std::string SectionName("\t.section\t.llvm.linkonce.d." +
826                                 name +
827                                 ",\"aw\",%progbits");
828         SwitchToDataSection(SectionName.c_str(), I);
829         O << "\t.weak " << name << "\n";
830       }
831       break;
832     case GlobalValue::AppendingLinkage:
833       // FIXME: appending linkage variables should go into a section of
834       // their name or something.  For now, just emit them as external.
835     case GlobalValue::ExternalLinkage:
836       O << "\t.globl " << name << "\n";
837       // FALL THROUGH
838     case GlobalValue::InternalLinkage: {
839       if (I->isConstant()) {
840         const ConstantArray *CVA = dyn_cast<ConstantArray>(C);
841         if (TAI->getCStringSection() && CVA && CVA->isCString()) {
842           SwitchToDataSection(TAI->getCStringSection(), I);
843           break;
844         }
845       }
846       // FIXME: special handling for ".ctors" & ".dtors" sections
847       if (I->hasSection() &&
848           (I->getSection() == ".ctors" ||
849            I->getSection() == ".dtors")) {
850         assert(!Subtarget->isTargetDarwin());
851         std::string SectionName = ".section " + I->getSection();
852         SectionName += ",\"aw\",%progbits";
853         SwitchToDataSection(SectionName.c_str());
854       } else {
855         if (C->isNullValue() && !NoZerosInBSS && TAI->getBSSSection())
856           SwitchToDataSection(TAI->getBSSSection(), I);
857         else if (!I->isConstant())
858           SwitchToDataSection(TAI->getDataSection(), I);
859         else {
860           // Read-only data.
861           bool HasReloc = C->ContainsRelocations();
862           if (HasReloc &&
863               Subtarget->isTargetDarwin() &&
864               TM.getRelocationModel() != Reloc::Static)
865             SwitchToDataSection("\t.const_data\n");
866           else if (!HasReloc && Size == 4 &&
867                    TAI->getFourByteConstantSection())
868             SwitchToDataSection(TAI->getFourByteConstantSection(), I);
869           else if (!HasReloc && Size == 8 &&
870                    TAI->getEightByteConstantSection())
871             SwitchToDataSection(TAI->getEightByteConstantSection(), I);
872           else if (!HasReloc && Size == 16 &&
873                    TAI->getSixteenByteConstantSection())
874             SwitchToDataSection(TAI->getSixteenByteConstantSection(), I);
875           else if (TAI->getReadOnlySection())
876             SwitchToDataSection(TAI->getReadOnlySection(), I);
877           else
878             SwitchToDataSection(TAI->getDataSection(), I);
879         }
880       }
881
882       break;
883     }
884     default:
885       assert(0 && "Unknown linkage type!");
886       break;
887     }
888
889     EmitAlignment(Align, I);
890     O << name << ":\t\t\t\t" << TAI->getCommentString() << " " << I->getName()
891       << "\n";
892     if (TAI->hasDotTypeDotSizeDirective())
893       O << "\t.size " << name << ", " << Size << "\n";
894     // If the initializer is a extern weak symbol, remember to emit the weak
895     // reference!
896     if (const GlobalValue *GV = dyn_cast<GlobalValue>(C))
897       if (GV->hasExternalWeakLinkage())
898       ExtWeakSymbols.insert(GV);
899
900     EmitGlobalConstant(C);
901     O << '\n';
902   }
903
904   if (Subtarget->isTargetDarwin()) {
905     SwitchToDataSection("");
906
907     // Output stubs for dynamically-linked functions
908     unsigned j = 1;
909     for (std::set<std::string>::iterator i = FnStubs.begin(), e = FnStubs.end();
910          i != e; ++i, ++j) {
911       if (TM.getRelocationModel() == Reloc::PIC_)
912         SwitchToTextSection(".section __TEXT,__picsymbolstub4,symbol_stubs,"
913                             "none,16", 0);
914       else
915         SwitchToTextSection(".section __TEXT,__symbol_stub4,symbol_stubs,"
916                             "none,12", 0);
917
918       EmitAlignment(2);
919       O << "\t.code\t32\n";
920
921       O << "L" << *i << "$stub:\n";
922       O << "\t.indirect_symbol " << *i << "\n";
923       O << "\tldr ip, L" << *i << "$slp\n";
924       if (TM.getRelocationModel() == Reloc::PIC_) {
925         O << "L" << *i << "$scv:\n";
926         O << "\tadd ip, pc, ip\n";
927       }
928       O << "\tldr pc, [ip, #0]\n";
929       O << "L" << *i << "$slp:\n";
930       if (TM.getRelocationModel() == Reloc::PIC_)
931         O << "\t.long\tL" << *i << "$lazy_ptr-(L" << *i << "$scv+8)\n";
932       else
933         O << "\t.long\tL" << *i << "$lazy_ptr\n";
934       SwitchToDataSection(".lazy_symbol_pointer", 0);
935       O << "L" << *i << "$lazy_ptr:\n";
936       O << "\t.indirect_symbol " << *i << "\n";
937       O << "\t.long\tdyld_stub_binding_helper\n";
938     }
939     O << "\n";
940
941     // Output non-lazy-pointers for external and common global variables.
942     if (GVNonLazyPtrs.begin() != GVNonLazyPtrs.end())
943       SwitchToDataSection(".non_lazy_symbol_pointer", 0);
944     for (std::set<std::string>::iterator i = GVNonLazyPtrs.begin(),
945            e = GVNonLazyPtrs.end(); i != e; ++i) {
946       O << "L" << *i << "$non_lazy_ptr:\n";
947       O << "\t.indirect_symbol " << *i << "\n";
948       O << "\t.long\t0\n";
949     }
950
951     // Emit initial debug information.
952     DW.EndModule();
953
954     // Funny Darwin hack: This flag tells the linker that no global symbols
955     // contain code that falls through to other global symbols (e.g. the obvious
956     // implementation of multiple entry points).  If this doesn't occur, the
957     // linker can safely perform dead code stripping.  Since LLVM never
958     // generates code that does this, it is always safe to set.
959     O << "\t.subsections_via_symbols\n";
960   }
961
962   AsmPrinter::doFinalization(M);
963   return false; // success
964 }