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