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