ARMAsmPrinter.cpp revision e8e5495474d67cd5151bd88e502be3f46ace7a85
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>
39using namespace llvm;
40
41STATISTIC(EmittedInsts, "Number of machine instrs printed");
42
43namespace {
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///
167FunctionPass *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///
175bool 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
259void 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
332static 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.
350void 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.
358void 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
377void 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
399void 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
431void 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
452void 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
475void 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
491void 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
510void 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
549void 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
561void
562ARMAsmPrinter::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
569void
570ARMAsmPrinter::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
592void
593ARMAsmPrinter::printThumbAddrModeS1Operand(const MachineInstr *MI, int Op) {
594  printThumbAddrModeRI5Operand(MI, Op, 1);
595}
596void
597ARMAsmPrinter::printThumbAddrModeS2Operand(const MachineInstr *MI, int Op) {
598  printThumbAddrModeRI5Operand(MI, Op, 2);
599}
600void
601ARMAsmPrinter::printThumbAddrModeS4Operand(const MachineInstr *MI, int Op) {
602  printThumbAddrModeRI5Operand(MI, Op, 4);
603}
604
605void 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
614void ARMAsmPrinter::printCCOperand(const MachineInstr *MI, int opNum) {
615  int CC = (int)MI->getOperand(opNum).getImmedValue();
616  O << ARMCondCodeToString((ARMCC::CondCodes)CC);
617}
618
619void ARMAsmPrinter::printPCLabel(const MachineInstr *MI, int opNum) {
620  int Id = (int)MI->getOperand(opNum).getImmedValue();
621  O << TAI->getPrivateGlobalPrefix() << "PC" << Id;
622}
623
624void 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
633void 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
661void 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
702bool 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
736void 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
765bool ARMAsmPrinter::doInitialization(Module &M) {
766  // Emit initial debug information.
767  DW.BeginModule(&M);
768
769  return AsmPrinter::doInitialization(M);
770}
771
772bool 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}
1001