ARMAsmPrinter.cpp revision 6c6005eccd76a66ed897310fccf8aa1b90f2937b
1//===-- ARMAsmPrinter.cpp - Print machine code to an ARM .s file ----------===//
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 "ARMBuildAttrs.h"
18#include "ARMAddressingModes.h"
19#include "ARMConstantPoolValue.h"
20#include "AsmPrinter/ARMInstPrinter.h"
21#include "ARMMachineFunctionInfo.h"
22#include "ARMMCInstLower.h"
23#include "ARMTargetMachine.h"
24#include "llvm/Analysis/DebugInfo.h"
25#include "llvm/Constants.h"
26#include "llvm/Module.h"
27#include "llvm/Type.h"
28#include "llvm/Assembly/Writer.h"
29#include "llvm/CodeGen/AsmPrinter.h"
30#include "llvm/CodeGen/MachineModuleInfoImpls.h"
31#include "llvm/CodeGen/MachineFunctionPass.h"
32#include "llvm/CodeGen/MachineJumpTableInfo.h"
33#include "llvm/CodeGen/TargetLoweringObjectFileImpl.h"
34#include "llvm/MC/MCAsmInfo.h"
35#include "llvm/MC/MCContext.h"
36#include "llvm/MC/MCExpr.h"
37#include "llvm/MC/MCInst.h"
38#include "llvm/MC/MCSectionMachO.h"
39#include "llvm/MC/MCStreamer.h"
40#include "llvm/MC/MCSymbol.h"
41#include "llvm/Target/Mangler.h"
42#include "llvm/Target/TargetData.h"
43#include "llvm/Target/TargetMachine.h"
44#include "llvm/Target/TargetOptions.h"
45#include "llvm/Target/TargetRegistry.h"
46#include "llvm/ADT/SmallPtrSet.h"
47#include "llvm/ADT/SmallString.h"
48#include "llvm/ADT/StringExtras.h"
49#include "llvm/Support/CommandLine.h"
50#include "llvm/Support/Debug.h"
51#include "llvm/Support/ErrorHandling.h"
52#include "llvm/Support/raw_ostream.h"
53#include <cctype>
54using namespace llvm;
55
56namespace llvm {
57  namespace ARM {
58    enum DW_ISA {
59      DW_ISA_ARM_thumb = 1,
60      DW_ISA_ARM_arm = 2
61    };
62  }
63}
64
65namespace {
66  class ARMAsmPrinter : public AsmPrinter {
67
68    /// Subtarget - Keep a pointer to the ARMSubtarget around so that we can
69    /// make the right decision when printing asm code for different targets.
70    const ARMSubtarget *Subtarget;
71
72    /// AFI - Keep a pointer to ARMFunctionInfo for the current
73    /// MachineFunction.
74    ARMFunctionInfo *AFI;
75
76    /// MCP - Keep a pointer to constantpool entries of the current
77    /// MachineFunction.
78    const MachineConstantPool *MCP;
79
80  public:
81    explicit ARMAsmPrinter(TargetMachine &TM, MCStreamer &Streamer)
82      : AsmPrinter(TM, Streamer), AFI(NULL), MCP(NULL) {
83      Subtarget = &TM.getSubtarget<ARMSubtarget>();
84    }
85
86    virtual const char *getPassName() const {
87      return "ARM Assembly Printer";
88    }
89
90    void EmitJumpTable(const MachineInstr *MI);
91    void EmitJump2Table(const MachineInstr *MI);
92
93    void printOperand(const MachineInstr *MI, int OpNum, raw_ostream &O,
94                      const char *Modifier = 0);
95    void printSOImmOperand(const MachineInstr *MI, int OpNum, raw_ostream &O);
96    void printSOImm2PartOperand(const MachineInstr *MI, int OpNum,
97                                raw_ostream &O);
98    void printSORegOperand(const MachineInstr *MI, int OpNum,
99                           raw_ostream &O);
100    void printAddrMode2Operand(const MachineInstr *MI, int OpNum,
101                               raw_ostream &O);
102    void printAddrMode2OffsetOperand(const MachineInstr *MI, int OpNum,
103                                     raw_ostream &O);
104    void printAddrMode3Operand(const MachineInstr *MI, int OpNum,
105                               raw_ostream &O);
106    void printAddrMode3OffsetOperand(const MachineInstr *MI, int OpNum,
107                                     raw_ostream &O);
108    void printAddrMode4Operand(const MachineInstr *MI, int OpNum,raw_ostream &O,
109                               const char *Modifier = 0);
110    void printAddrMode5Operand(const MachineInstr *MI, int OpNum,raw_ostream &O,
111                               const char *Modifier = 0);
112    void printAddrMode6Operand(const MachineInstr *MI, int OpNum,
113                               raw_ostream &O);
114    void printAddrMode6OffsetOperand(const MachineInstr *MI, int OpNum,
115                                     raw_ostream &O);
116    void printAddrModePCOperand(const MachineInstr *MI, int OpNum,
117                                raw_ostream &O,
118                                const char *Modifier = 0);
119    void printBitfieldInvMaskImmOperand(const MachineInstr *MI, int OpNum,
120                                        raw_ostream &O);
121    void printMemBOption(const MachineInstr *MI, int OpNum,
122                         raw_ostream &O);
123    void printShiftImmOperand(const MachineInstr *MI, int OpNum,
124                              raw_ostream &O);
125
126    void printThumbS4ImmOperand(const MachineInstr *MI, int OpNum,
127                                raw_ostream &O);
128    void printThumbITMask(const MachineInstr *MI, int OpNum, raw_ostream &O);
129    void printThumbAddrModeRROperand(const MachineInstr *MI, int OpNum,
130                                     raw_ostream &O);
131    void printThumbAddrModeRI5Operand(const MachineInstr *MI, int OpNum,
132                                      raw_ostream &O,
133                                      unsigned Scale);
134    void printThumbAddrModeS1Operand(const MachineInstr *MI, int OpNum,
135                                     raw_ostream &O);
136    void printThumbAddrModeS2Operand(const MachineInstr *MI, int OpNum,
137                                     raw_ostream &O);
138    void printThumbAddrModeS4Operand(const MachineInstr *MI, int OpNum,
139                                     raw_ostream &O);
140    void printThumbAddrModeSPOperand(const MachineInstr *MI, int OpNum,
141                                     raw_ostream &O);
142
143    void printT2SOOperand(const MachineInstr *MI, int OpNum, raw_ostream &O);
144    void printT2AddrModeImm12Operand(const MachineInstr *MI, int OpNum,
145                                     raw_ostream &O);
146    void printT2AddrModeImm8Operand(const MachineInstr *MI, int OpNum,
147                                    raw_ostream &O);
148    void printT2AddrModeImm8s4Operand(const MachineInstr *MI, int OpNum,
149                                      raw_ostream &O);
150    void printT2AddrModeImm8OffsetOperand(const MachineInstr *MI, int OpNum,
151                                          raw_ostream &O);
152    void printT2AddrModeImm8s4OffsetOperand(const MachineInstr *MI, int OpNum,
153                                            raw_ostream &O) {}
154    void printT2AddrModeSoRegOperand(const MachineInstr *MI, int OpNum,
155                                     raw_ostream &O);
156
157    void printCPSOptionOperand(const MachineInstr *MI, int OpNum,
158                               raw_ostream &O) {}
159    void printMSRMaskOperand(const MachineInstr *MI, int OpNum,
160                             raw_ostream &O) {}
161    void printNegZeroOperand(const MachineInstr *MI, int OpNum,
162                             raw_ostream &O) {}
163    void printPredicateOperand(const MachineInstr *MI, int OpNum,
164                               raw_ostream &O);
165    void printMandatoryPredicateOperand(const MachineInstr *MI, int OpNum,
166                                        raw_ostream &O);
167    void printSBitModifierOperand(const MachineInstr *MI, int OpNum,
168                                  raw_ostream &O);
169    void printPCLabel(const MachineInstr *MI, int OpNum,
170                      raw_ostream &O);
171    void printRegisterList(const MachineInstr *MI, int OpNum,
172                           raw_ostream &O);
173    void printCPInstOperand(const MachineInstr *MI, int OpNum,
174                            raw_ostream &O,
175                            const char *Modifier);
176    void printJTBlockOperand(const MachineInstr *MI, int OpNum,
177                             raw_ostream &O);
178    void printJT2BlockOperand(const MachineInstr *MI, int OpNum,
179                              raw_ostream &O);
180    void printTBAddrMode(const MachineInstr *MI, int OpNum,
181                         raw_ostream &O);
182    void printNoHashImmediate(const MachineInstr *MI, int OpNum,
183                              raw_ostream &O);
184    void printVFPf32ImmOperand(const MachineInstr *MI, int OpNum,
185                               raw_ostream &O);
186    void printVFPf64ImmOperand(const MachineInstr *MI, int OpNum,
187                               raw_ostream &O);
188    void printNEONModImmOperand(const MachineInstr *MI, int OpNum,
189                                raw_ostream &O);
190
191    virtual bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNum,
192                                 unsigned AsmVariant, const char *ExtraCode,
193                                 raw_ostream &O);
194    virtual bool PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNum,
195                                       unsigned AsmVariant,
196                                       const char *ExtraCode, raw_ostream &O);
197
198    void printInstruction(const MachineInstr *MI, raw_ostream &O); // autogen
199    static const char *getRegisterName(unsigned RegNo);
200
201    virtual void EmitInstruction(const MachineInstr *MI);
202    bool runOnMachineFunction(MachineFunction &F);
203
204    virtual void EmitConstantPool() {} // we emit constant pools customly!
205    virtual void EmitFunctionEntryLabel();
206    void EmitStartOfAsmFile(Module &M);
207    void EmitEndOfAsmFile(Module &M);
208
209    void PrintDebugValueComment(const MachineInstr *MI, raw_ostream &OS);
210
211    MachineLocation getDebugValueLocation(const MachineInstr *MI) const {
212      MachineLocation Location;
213      assert (MI->getNumOperands() == 4 && "Invalid no. of machine operands!");
214      // Frame address.  Currently handles register +- offset only.
215      if (MI->getOperand(0).isReg() && MI->getOperand(1).isImm())
216        Location.set(MI->getOperand(0).getReg(), MI->getOperand(1).getImm());
217      else {
218        DEBUG(dbgs() << "DBG_VALUE instruction ignored! " << *MI << "\n");
219      }
220      return Location;
221    }
222
223    virtual unsigned getISAEncoding() {
224      // ARM/Darwin adds ISA to the DWARF info for each function.
225      if (!Subtarget->isTargetDarwin())
226        return 0;
227      return Subtarget->isThumb() ?
228        llvm::ARM::DW_ISA_ARM_thumb : llvm::ARM::DW_ISA_ARM_arm;
229    }
230
231    MCSymbol *GetARMSetPICJumpTableLabel2(unsigned uid, unsigned uid2,
232                                          const MachineBasicBlock *MBB) const;
233    MCSymbol *GetARMJTIPICJumpTableLabel2(unsigned uid, unsigned uid2) const;
234
235    MCSymbol *GetARMSJLJEHLabel(void) const;
236
237    /// EmitMachineConstantPoolValue - Print a machine constantpool value to
238    /// the .s file.
239    virtual void EmitMachineConstantPoolValue(MachineConstantPoolValue *MCPV) {
240      SmallString<128> Str;
241      raw_svector_ostream OS(Str);
242      EmitMachineConstantPoolValue(MCPV, OS);
243      OutStreamer.EmitRawText(OS.str());
244    }
245
246    void EmitMachineConstantPoolValue(MachineConstantPoolValue *MCPV,
247                                      raw_ostream &O) {
248      switch (TM.getTargetData()->getTypeAllocSize(MCPV->getType())) {
249      case 1: O << MAI->getData8bitsDirective(0); break;
250      case 2: O << MAI->getData16bitsDirective(0); break;
251      case 4: O << MAI->getData32bitsDirective(0); break;
252      default: assert(0 && "Unknown CPV size");
253      }
254
255      ARMConstantPoolValue *ACPV = static_cast<ARMConstantPoolValue*>(MCPV);
256
257      if (ACPV->isLSDA()) {
258        O << MAI->getPrivateGlobalPrefix() << "_LSDA_" << getFunctionNumber();
259      } else if (ACPV->isBlockAddress()) {
260        O << *GetBlockAddressSymbol(ACPV->getBlockAddress());
261      } else if (ACPV->isGlobalValue()) {
262        const GlobalValue *GV = ACPV->getGV();
263        bool isIndirect = Subtarget->isTargetDarwin() &&
264          Subtarget->GVIsIndirectSymbol(GV, TM.getRelocationModel());
265        if (!isIndirect)
266          O << *Mang->getSymbol(GV);
267        else {
268          // FIXME: Remove this when Darwin transition to @GOT like syntax.
269          MCSymbol *Sym = GetSymbolWithGlobalValueBase(GV, "$non_lazy_ptr");
270          O << *Sym;
271
272          MachineModuleInfoMachO &MMIMachO =
273            MMI->getObjFileInfo<MachineModuleInfoMachO>();
274          MachineModuleInfoImpl::StubValueTy &StubSym =
275            GV->hasHiddenVisibility() ? MMIMachO.getHiddenGVStubEntry(Sym) :
276                                        MMIMachO.getGVStubEntry(Sym);
277          if (StubSym.getPointer() == 0)
278            StubSym = MachineModuleInfoImpl::
279              StubValueTy(Mang->getSymbol(GV), !GV->hasInternalLinkage());
280        }
281      } else {
282        assert(ACPV->isExtSymbol() && "unrecognized constant pool value");
283        O << *GetExternalSymbolSymbol(ACPV->getSymbol());
284      }
285
286      if (ACPV->hasModifier()) O << "(" << ACPV->getModifier() << ")";
287      if (ACPV->getPCAdjustment() != 0) {
288        O << "-(" << MAI->getPrivateGlobalPrefix() << "PC"
289          << getFunctionNumber() << "_"  << ACPV->getLabelId()
290          << "+" << (unsigned)ACPV->getPCAdjustment();
291         if (ACPV->mustAddCurrentAddress())
292           O << "-.";
293         O << ')';
294      }
295    }
296  };
297} // end of anonymous namespace
298
299#include "ARMGenAsmWriter.inc"
300
301void ARMAsmPrinter::EmitFunctionEntryLabel() {
302  if (AFI->isThumbFunction()) {
303    OutStreamer.EmitRawText(StringRef("\t.code\t16"));
304    if (!Subtarget->isTargetDarwin())
305      OutStreamer.EmitRawText(StringRef("\t.thumb_func"));
306    else {
307      // This needs to emit to a temporary string to get properly quoted
308      // MCSymbols when they have spaces in them.
309      SmallString<128> Tmp;
310      raw_svector_ostream OS(Tmp);
311      OS << "\t.thumb_func\t" << *CurrentFnSym;
312      OutStreamer.EmitRawText(OS.str());
313    }
314  }
315
316  OutStreamer.EmitLabel(CurrentFnSym);
317}
318
319/// runOnMachineFunction - This uses the printInstruction()
320/// method to print assembly for each instruction.
321///
322bool ARMAsmPrinter::runOnMachineFunction(MachineFunction &MF) {
323  AFI = MF.getInfo<ARMFunctionInfo>();
324  MCP = MF.getConstantPool();
325
326  return AsmPrinter::runOnMachineFunction(MF);
327}
328
329void ARMAsmPrinter::printOperand(const MachineInstr *MI, int OpNum,
330                                 raw_ostream &O, const char *Modifier) {
331  const MachineOperand &MO = MI->getOperand(OpNum);
332  unsigned TF = MO.getTargetFlags();
333
334  switch (MO.getType()) {
335  default:
336    assert(0 && "<unknown operand type>");
337  case MachineOperand::MO_Register: {
338    unsigned Reg = MO.getReg();
339    assert(TargetRegisterInfo::isPhysicalRegister(Reg));
340    if (Modifier && strcmp(Modifier, "lane") == 0) {
341      unsigned RegNum = getARMRegisterNumbering(Reg);
342      unsigned DReg =
343        TM.getRegisterInfo()->getMatchingSuperReg(Reg,
344          RegNum & 1 ? ARM::ssub_1 : ARM::ssub_0, &ARM::DPR_VFP2RegClass);
345      O << getRegisterName(DReg) << '[' << (RegNum & 1) << ']';
346    } else {
347      assert(!MO.getSubReg() && "Subregs should be eliminated!");
348      O << getRegisterName(Reg);
349    }
350    break;
351  }
352  case MachineOperand::MO_Immediate: {
353    int64_t Imm = MO.getImm();
354    O << '#';
355    if ((Modifier && strcmp(Modifier, "lo16") == 0) ||
356        (TF & ARMII::MO_LO16))
357      O << ":lower16:";
358    else if ((Modifier && strcmp(Modifier, "hi16") == 0) ||
359             (TF & ARMII::MO_HI16))
360      O << ":upper16:";
361    O << Imm;
362    break;
363  }
364  case MachineOperand::MO_MachineBasicBlock:
365    O << *MO.getMBB()->getSymbol();
366    return;
367  case MachineOperand::MO_GlobalAddress: {
368    bool isCallOp = Modifier && !strcmp(Modifier, "call");
369    const GlobalValue *GV = MO.getGlobal();
370
371    if ((Modifier && strcmp(Modifier, "lo16") == 0) ||
372        (TF & ARMII::MO_LO16))
373      O << ":lower16:";
374    else if ((Modifier && strcmp(Modifier, "hi16") == 0) ||
375             (TF & ARMII::MO_HI16))
376      O << ":upper16:";
377    O << *Mang->getSymbol(GV);
378
379    printOffset(MO.getOffset(), O);
380
381    if (isCallOp && Subtarget->isTargetELF() &&
382        TM.getRelocationModel() == Reloc::PIC_)
383      O << "(PLT)";
384    break;
385  }
386  case MachineOperand::MO_ExternalSymbol: {
387    bool isCallOp = Modifier && !strcmp(Modifier, "call");
388    O << *GetExternalSymbolSymbol(MO.getSymbolName());
389
390    if (isCallOp && Subtarget->isTargetELF() &&
391        TM.getRelocationModel() == Reloc::PIC_)
392      O << "(PLT)";
393    break;
394  }
395  case MachineOperand::MO_ConstantPoolIndex:
396    O << *GetCPISymbol(MO.getIndex());
397    break;
398  case MachineOperand::MO_JumpTableIndex:
399    O << *GetJTISymbol(MO.getIndex());
400    break;
401  }
402}
403
404static void printSOImm(raw_ostream &O, int64_t V, bool VerboseAsm,
405                       const MCAsmInfo *MAI) {
406  // Break it up into two parts that make up a shifter immediate.
407  V = ARM_AM::getSOImmVal(V);
408  assert(V != -1 && "Not a valid so_imm value!");
409
410  unsigned Imm = ARM_AM::getSOImmValImm(V);
411  unsigned Rot = ARM_AM::getSOImmValRot(V);
412
413  // Print low-level immediate formation info, per
414  // A5.1.3: "Data-processing operands - Immediate".
415  if (Rot) {
416    O << "#" << Imm << ", " << Rot;
417    // Pretty printed version.
418    if (VerboseAsm) {
419      O << "\t" << MAI->getCommentString() << ' ';
420      O << (int)ARM_AM::rotr32(Imm, Rot);
421    }
422  } else {
423    O << "#" << Imm;
424  }
425}
426
427/// printSOImmOperand - SOImm is 4-bit rotate amount in bits 8-11 with 8-bit
428/// immediate in bits 0-7.
429void ARMAsmPrinter::printSOImmOperand(const MachineInstr *MI, int OpNum,
430                                      raw_ostream &O) {
431  const MachineOperand &MO = MI->getOperand(OpNum);
432  assert(MO.isImm() && "Not a valid so_imm value!");
433  printSOImm(O, MO.getImm(), isVerbose(), MAI);
434}
435
436/// printSOImm2PartOperand - SOImm is broken into two pieces using a 'mov'
437/// followed by an 'orr' to materialize.
438void ARMAsmPrinter::printSOImm2PartOperand(const MachineInstr *MI, int OpNum,
439                                           raw_ostream &O) {
440  const MachineOperand &MO = MI->getOperand(OpNum);
441  assert(MO.isImm() && "Not a valid so_imm value!");
442  unsigned V1 = ARM_AM::getSOImmTwoPartFirst(MO.getImm());
443  unsigned V2 = ARM_AM::getSOImmTwoPartSecond(MO.getImm());
444  printSOImm(O, V1, isVerbose(), MAI);
445  O << "\n\torr";
446  printPredicateOperand(MI, 2, O);
447  O << "\t";
448  printOperand(MI, 0, O);
449  O << ", ";
450  printOperand(MI, 0, O);
451  O << ", ";
452  printSOImm(O, V2, isVerbose(), MAI);
453}
454
455// so_reg is a 4-operand unit corresponding to register forms of the A5.1
456// "Addressing Mode 1 - Data-processing operands" forms.  This includes:
457//    REG 0   0           - e.g. R5
458//    REG REG 0,SH_OPC    - e.g. R5, ROR R3
459//    REG 0   IMM,SH_OPC  - e.g. R5, LSL #3
460void ARMAsmPrinter::printSORegOperand(const MachineInstr *MI, int Op,
461                                      raw_ostream &O) {
462  const MachineOperand &MO1 = MI->getOperand(Op);
463  const MachineOperand &MO2 = MI->getOperand(Op+1);
464  const MachineOperand &MO3 = MI->getOperand(Op+2);
465
466  O << getRegisterName(MO1.getReg());
467
468  // Print the shift opc.
469  ARM_AM::ShiftOpc ShOpc = ARM_AM::getSORegShOp(MO3.getImm());
470  O << ", " << ARM_AM::getShiftOpcStr(ShOpc);
471  if (MO2.getReg()) {
472    O << ' ' << getRegisterName(MO2.getReg());
473    assert(ARM_AM::getSORegOffset(MO3.getImm()) == 0);
474  } else if (ShOpc != ARM_AM::rrx) {
475    O << " #" << ARM_AM::getSORegOffset(MO3.getImm());
476  }
477}
478
479void ARMAsmPrinter::printAddrMode2Operand(const MachineInstr *MI, int Op,
480                                          raw_ostream &O) {
481  const MachineOperand &MO1 = MI->getOperand(Op);
482  const MachineOperand &MO2 = MI->getOperand(Op+1);
483  const MachineOperand &MO3 = MI->getOperand(Op+2);
484
485  if (!MO1.isReg()) {   // FIXME: This is for CP entries, but isn't right.
486    printOperand(MI, Op, O);
487    return;
488  }
489
490  O << "[" << getRegisterName(MO1.getReg());
491
492  if (!MO2.getReg()) {
493    if (ARM_AM::getAM2Offset(MO3.getImm())) // Don't print +0.
494      O << ", #"
495        << ARM_AM::getAddrOpcStr(ARM_AM::getAM2Op(MO3.getImm()))
496        << ARM_AM::getAM2Offset(MO3.getImm());
497    O << "]";
498    return;
499  }
500
501  O << ", "
502    << ARM_AM::getAddrOpcStr(ARM_AM::getAM2Op(MO3.getImm()))
503    << getRegisterName(MO2.getReg());
504
505  if (unsigned ShImm = ARM_AM::getAM2Offset(MO3.getImm()))
506    O << ", "
507      << ARM_AM::getShiftOpcStr(ARM_AM::getAM2ShiftOpc(MO3.getImm()))
508      << " #" << ShImm;
509  O << "]";
510}
511
512void ARMAsmPrinter::printAddrMode2OffsetOperand(const MachineInstr *MI, int Op,
513                                                raw_ostream &O) {
514  const MachineOperand &MO1 = MI->getOperand(Op);
515  const MachineOperand &MO2 = MI->getOperand(Op+1);
516
517  if (!MO1.getReg()) {
518    unsigned ImmOffs = ARM_AM::getAM2Offset(MO2.getImm());
519    O << "#"
520      << ARM_AM::getAddrOpcStr(ARM_AM::getAM2Op(MO2.getImm()))
521      << ImmOffs;
522    return;
523  }
524
525  O << ARM_AM::getAddrOpcStr(ARM_AM::getAM2Op(MO2.getImm()))
526    << getRegisterName(MO1.getReg());
527
528  if (unsigned ShImm = ARM_AM::getAM2Offset(MO2.getImm()))
529    O << ", "
530      << ARM_AM::getShiftOpcStr(ARM_AM::getAM2ShiftOpc(MO2.getImm()))
531      << " #" << ShImm;
532}
533
534void ARMAsmPrinter::printAddrMode3Operand(const MachineInstr *MI, int Op,
535                                          raw_ostream &O) {
536  const MachineOperand &MO1 = MI->getOperand(Op);
537  const MachineOperand &MO2 = MI->getOperand(Op+1);
538  const MachineOperand &MO3 = MI->getOperand(Op+2);
539
540  assert(TargetRegisterInfo::isPhysicalRegister(MO1.getReg()));
541  O << "[" << getRegisterName(MO1.getReg());
542
543  if (MO2.getReg()) {
544    O << ", "
545      << (char)ARM_AM::getAM3Op(MO3.getImm())
546      << getRegisterName(MO2.getReg())
547      << "]";
548    return;
549  }
550
551  if (unsigned ImmOffs = ARM_AM::getAM3Offset(MO3.getImm()))
552    O << ", #"
553      << ARM_AM::getAddrOpcStr(ARM_AM::getAM3Op(MO3.getImm()))
554      << ImmOffs;
555  O << "]";
556}
557
558void ARMAsmPrinter::printAddrMode3OffsetOperand(const MachineInstr *MI, int Op,
559                                                raw_ostream &O){
560  const MachineOperand &MO1 = MI->getOperand(Op);
561  const MachineOperand &MO2 = MI->getOperand(Op+1);
562
563  if (MO1.getReg()) {
564    O << (char)ARM_AM::getAM3Op(MO2.getImm())
565      << getRegisterName(MO1.getReg());
566    return;
567  }
568
569  unsigned ImmOffs = ARM_AM::getAM3Offset(MO2.getImm());
570  O << "#"
571    << ARM_AM::getAddrOpcStr(ARM_AM::getAM3Op(MO2.getImm()))
572    << ImmOffs;
573}
574
575void ARMAsmPrinter::printAddrMode4Operand(const MachineInstr *MI, int Op,
576                                          raw_ostream &O,
577                                          const char *Modifier) {
578  const MachineOperand &MO2 = MI->getOperand(Op+1);
579  ARM_AM::AMSubMode Mode = ARM_AM::getAM4SubMode(MO2.getImm());
580  if (Modifier && strcmp(Modifier, "submode") == 0) {
581    O << ARM_AM::getAMSubModeStr(Mode);
582  } else if (Modifier && strcmp(Modifier, "wide") == 0) {
583    ARM_AM::AMSubMode Mode = ARM_AM::getAM4SubMode(MO2.getImm());
584    if (Mode == ARM_AM::ia)
585      O << ".w";
586  } else {
587    printOperand(MI, Op, O);
588  }
589}
590
591void ARMAsmPrinter::printAddrMode5Operand(const MachineInstr *MI, int Op,
592                                          raw_ostream &O,
593                                          const char *Modifier) {
594  const MachineOperand &MO1 = MI->getOperand(Op);
595  const MachineOperand &MO2 = MI->getOperand(Op+1);
596
597  if (!MO1.isReg()) {   // FIXME: This is for CP entries, but isn't right.
598    printOperand(MI, Op, O);
599    return;
600  }
601
602  assert(TargetRegisterInfo::isPhysicalRegister(MO1.getReg()));
603
604  O << "[" << getRegisterName(MO1.getReg());
605
606  if (unsigned ImmOffs = ARM_AM::getAM5Offset(MO2.getImm())) {
607    O << ", #"
608      << ARM_AM::getAddrOpcStr(ARM_AM::getAM5Op(MO2.getImm()))
609      << ImmOffs*4;
610  }
611  O << "]";
612}
613
614void ARMAsmPrinter::printAddrMode6Operand(const MachineInstr *MI, int Op,
615                                          raw_ostream &O) {
616  const MachineOperand &MO1 = MI->getOperand(Op);
617  const MachineOperand &MO2 = MI->getOperand(Op+1);
618
619  O << "[" << getRegisterName(MO1.getReg());
620  if (MO2.getImm()) {
621    // FIXME: Both darwin as and GNU as violate ARM docs here.
622    O << ", :" << (MO2.getImm() << 3);
623  }
624  O << "]";
625}
626
627void ARMAsmPrinter::printAddrMode6OffsetOperand(const MachineInstr *MI, int Op,
628                                                raw_ostream &O){
629  const MachineOperand &MO = MI->getOperand(Op);
630  if (MO.getReg() == 0)
631    O << "!";
632  else
633    O << ", " << getRegisterName(MO.getReg());
634}
635
636void ARMAsmPrinter::printAddrModePCOperand(const MachineInstr *MI, int Op,
637                                           raw_ostream &O,
638                                           const char *Modifier) {
639  if (Modifier && strcmp(Modifier, "label") == 0) {
640    printPCLabel(MI, Op+1, O);
641    return;
642  }
643
644  const MachineOperand &MO1 = MI->getOperand(Op);
645  assert(TargetRegisterInfo::isPhysicalRegister(MO1.getReg()));
646  O << "[pc, " << getRegisterName(MO1.getReg()) << "]";
647}
648
649void
650ARMAsmPrinter::printBitfieldInvMaskImmOperand(const MachineInstr *MI, int Op,
651                                              raw_ostream &O) {
652  const MachineOperand &MO = MI->getOperand(Op);
653  uint32_t v = ~MO.getImm();
654  int32_t lsb = CountTrailingZeros_32(v);
655  int32_t width = (32 - CountLeadingZeros_32 (v)) - lsb;
656  assert(MO.isImm() && "Not a valid bf_inv_mask_imm value!");
657  O << "#" << lsb << ", #" << width;
658}
659
660void
661ARMAsmPrinter::printMemBOption(const MachineInstr *MI, int OpNum,
662                               raw_ostream &O) {
663  unsigned val = MI->getOperand(OpNum).getImm();
664  O << ARM_MB::MemBOptToString(val);
665}
666
667void ARMAsmPrinter::printShiftImmOperand(const MachineInstr *MI, int OpNum,
668                                         raw_ostream &O) {
669  unsigned ShiftOp = MI->getOperand(OpNum).getImm();
670  ARM_AM::ShiftOpc Opc = ARM_AM::getSORegShOp(ShiftOp);
671  switch (Opc) {
672  case ARM_AM::no_shift:
673    return;
674  case ARM_AM::lsl:
675    O << ", lsl #";
676    break;
677  case ARM_AM::asr:
678    O << ", asr #";
679    break;
680  default:
681    assert(0 && "unexpected shift opcode for shift immediate operand");
682  }
683  O << ARM_AM::getSORegOffset(ShiftOp);
684}
685
686//===--------------------------------------------------------------------===//
687
688void ARMAsmPrinter::printThumbS4ImmOperand(const MachineInstr *MI, int Op,
689                                           raw_ostream &O) {
690  O << "#" <<  MI->getOperand(Op).getImm() * 4;
691}
692
693void
694ARMAsmPrinter::printThumbITMask(const MachineInstr *MI, int Op,
695                                raw_ostream &O) {
696  // (3 - the number of trailing zeros) is the number of then / else.
697  unsigned Mask = MI->getOperand(Op).getImm();
698  unsigned CondBit0 = Mask >> 4 & 1;
699  unsigned NumTZ = CountTrailingZeros_32(Mask);
700  assert(NumTZ <= 3 && "Invalid IT mask!");
701  for (unsigned Pos = 3, e = NumTZ; Pos > e; --Pos) {
702    bool T = ((Mask >> Pos) & 1) == CondBit0;
703    if (T)
704      O << 't';
705    else
706      O << 'e';
707  }
708}
709
710void
711ARMAsmPrinter::printThumbAddrModeRROperand(const MachineInstr *MI, int Op,
712                                           raw_ostream &O) {
713  const MachineOperand &MO1 = MI->getOperand(Op);
714  const MachineOperand &MO2 = MI->getOperand(Op+1);
715  O << "[" << getRegisterName(MO1.getReg());
716  O << ", " << getRegisterName(MO2.getReg()) << "]";
717}
718
719void
720ARMAsmPrinter::printThumbAddrModeRI5Operand(const MachineInstr *MI, int Op,
721                                            raw_ostream &O,
722                                            unsigned Scale) {
723  const MachineOperand &MO1 = MI->getOperand(Op);
724  const MachineOperand &MO2 = MI->getOperand(Op+1);
725  const MachineOperand &MO3 = MI->getOperand(Op+2);
726
727  if (!MO1.isReg()) {   // FIXME: This is for CP entries, but isn't right.
728    printOperand(MI, Op, O);
729    return;
730  }
731
732  O << "[" << getRegisterName(MO1.getReg());
733  if (MO3.getReg())
734    O << ", " << getRegisterName(MO3.getReg());
735  else if (unsigned ImmOffs = MO2.getImm())
736    O << ", #" << ImmOffs * Scale;
737  O << "]";
738}
739
740void
741ARMAsmPrinter::printThumbAddrModeS1Operand(const MachineInstr *MI, int Op,
742                                           raw_ostream &O) {
743  printThumbAddrModeRI5Operand(MI, Op, O, 1);
744}
745void
746ARMAsmPrinter::printThumbAddrModeS2Operand(const MachineInstr *MI, int Op,
747                                           raw_ostream &O) {
748  printThumbAddrModeRI5Operand(MI, Op, O, 2);
749}
750void
751ARMAsmPrinter::printThumbAddrModeS4Operand(const MachineInstr *MI, int Op,
752                                           raw_ostream &O) {
753  printThumbAddrModeRI5Operand(MI, Op, O, 4);
754}
755
756void ARMAsmPrinter::printThumbAddrModeSPOperand(const MachineInstr *MI,int Op,
757                                                raw_ostream &O) {
758  const MachineOperand &MO1 = MI->getOperand(Op);
759  const MachineOperand &MO2 = MI->getOperand(Op+1);
760  O << "[" << getRegisterName(MO1.getReg());
761  if (unsigned ImmOffs = MO2.getImm())
762    O << ", #" << ImmOffs*4;
763  O << "]";
764}
765
766//===--------------------------------------------------------------------===//
767
768// Constant shifts t2_so_reg is a 2-operand unit corresponding to the Thumb2
769// register with shift forms.
770// REG 0   0           - e.g. R5
771// REG IMM, SH_OPC     - e.g. R5, LSL #3
772void ARMAsmPrinter::printT2SOOperand(const MachineInstr *MI, int OpNum,
773                                     raw_ostream &O) {
774  const MachineOperand &MO1 = MI->getOperand(OpNum);
775  const MachineOperand &MO2 = MI->getOperand(OpNum+1);
776
777  unsigned Reg = MO1.getReg();
778  assert(TargetRegisterInfo::isPhysicalRegister(Reg));
779  O << getRegisterName(Reg);
780
781  // Print the shift opc.
782  assert(MO2.isImm() && "Not a valid t2_so_reg value!");
783  ARM_AM::ShiftOpc ShOpc = ARM_AM::getSORegShOp(MO2.getImm());
784  O << ", " << ARM_AM::getShiftOpcStr(ShOpc);
785  if (ShOpc != ARM_AM::rrx)
786    O << " #" << ARM_AM::getSORegOffset(MO2.getImm());
787}
788
789void ARMAsmPrinter::printT2AddrModeImm12Operand(const MachineInstr *MI,
790                                                int OpNum,
791                                                raw_ostream &O) {
792  const MachineOperand &MO1 = MI->getOperand(OpNum);
793  const MachineOperand &MO2 = MI->getOperand(OpNum+1);
794
795  O << "[" << getRegisterName(MO1.getReg());
796
797  unsigned OffImm = MO2.getImm();
798  if (OffImm)  // Don't print +0.
799    O << ", #" << OffImm;
800  O << "]";
801}
802
803void ARMAsmPrinter::printT2AddrModeImm8Operand(const MachineInstr *MI,
804                                               int OpNum,
805                                               raw_ostream &O) {
806  const MachineOperand &MO1 = MI->getOperand(OpNum);
807  const MachineOperand &MO2 = MI->getOperand(OpNum+1);
808
809  O << "[" << getRegisterName(MO1.getReg());
810
811  int32_t OffImm = (int32_t)MO2.getImm();
812  // Don't print +0.
813  if (OffImm < 0)
814    O << ", #-" << -OffImm;
815  else if (OffImm > 0)
816    O << ", #" << OffImm;
817  O << "]";
818}
819
820void ARMAsmPrinter::printT2AddrModeImm8s4Operand(const MachineInstr *MI,
821                                                 int OpNum,
822                                                 raw_ostream &O) {
823  const MachineOperand &MO1 = MI->getOperand(OpNum);
824  const MachineOperand &MO2 = MI->getOperand(OpNum+1);
825
826  O << "[" << getRegisterName(MO1.getReg());
827
828  int32_t OffImm = (int32_t)MO2.getImm() / 4;
829  // Don't print +0.
830  if (OffImm < 0)
831    O << ", #-" << -OffImm * 4;
832  else if (OffImm > 0)
833    O << ", #" << OffImm * 4;
834  O << "]";
835}
836
837void ARMAsmPrinter::printT2AddrModeImm8OffsetOperand(const MachineInstr *MI,
838                                                     int OpNum,
839                                                     raw_ostream &O) {
840  const MachineOperand &MO1 = MI->getOperand(OpNum);
841  int32_t OffImm = (int32_t)MO1.getImm();
842  // Don't print +0.
843  if (OffImm < 0)
844    O << "#-" << -OffImm;
845  else if (OffImm > 0)
846    O << "#" << OffImm;
847}
848
849void ARMAsmPrinter::printT2AddrModeSoRegOperand(const MachineInstr *MI,
850                                                int OpNum,
851                                                raw_ostream &O) {
852  const MachineOperand &MO1 = MI->getOperand(OpNum);
853  const MachineOperand &MO2 = MI->getOperand(OpNum+1);
854  const MachineOperand &MO3 = MI->getOperand(OpNum+2);
855
856  O << "[" << getRegisterName(MO1.getReg());
857
858  assert(MO2.getReg() && "Invalid so_reg load / store address!");
859  O << ", " << getRegisterName(MO2.getReg());
860
861  unsigned ShAmt = MO3.getImm();
862  if (ShAmt) {
863    assert(ShAmt <= 3 && "Not a valid Thumb2 addressing mode!");
864    O << ", lsl #" << ShAmt;
865  }
866  O << "]";
867}
868
869
870//===--------------------------------------------------------------------===//
871
872void ARMAsmPrinter::printPredicateOperand(const MachineInstr *MI, int OpNum,
873                                          raw_ostream &O) {
874  ARMCC::CondCodes CC = (ARMCC::CondCodes)MI->getOperand(OpNum).getImm();
875  if (CC != ARMCC::AL)
876    O << ARMCondCodeToString(CC);
877}
878
879void ARMAsmPrinter::printMandatoryPredicateOperand(const MachineInstr *MI,
880                                                   int OpNum,
881                                                   raw_ostream &O) {
882  ARMCC::CondCodes CC = (ARMCC::CondCodes)MI->getOperand(OpNum).getImm();
883  O << ARMCondCodeToString(CC);
884}
885
886void ARMAsmPrinter::printSBitModifierOperand(const MachineInstr *MI, int OpNum,
887                                             raw_ostream &O){
888  unsigned Reg = MI->getOperand(OpNum).getReg();
889  if (Reg) {
890    assert(Reg == ARM::CPSR && "Expect ARM CPSR register!");
891    O << 's';
892  }
893}
894
895void ARMAsmPrinter::printPCLabel(const MachineInstr *MI, int OpNum,
896                                 raw_ostream &O) {
897  int Id = (int)MI->getOperand(OpNum).getImm();
898  O << MAI->getPrivateGlobalPrefix()
899    << "PC" << getFunctionNumber() << "_" << Id;
900}
901
902void ARMAsmPrinter::printRegisterList(const MachineInstr *MI, int OpNum,
903                                      raw_ostream &O) {
904  O << "{";
905  for (unsigned i = OpNum, e = MI->getNumOperands(); i != e; ++i) {
906    if (MI->getOperand(i).isImplicit())
907      continue;
908    if ((int)i != OpNum) O << ", ";
909    printOperand(MI, i, O);
910  }
911  O << "}";
912}
913
914void ARMAsmPrinter::printCPInstOperand(const MachineInstr *MI, int OpNum,
915                                       raw_ostream &O, const char *Modifier) {
916  assert(Modifier && "This operand only works with a modifier!");
917  // There are two aspects to a CONSTANTPOOL_ENTRY operand, the label and the
918  // data itself.
919  if (!strcmp(Modifier, "label")) {
920    unsigned ID = MI->getOperand(OpNum).getImm();
921    OutStreamer.EmitLabel(GetCPISymbol(ID));
922  } else {
923    assert(!strcmp(Modifier, "cpentry") && "Unknown modifier for CPE");
924    unsigned CPI = MI->getOperand(OpNum).getIndex();
925
926    const MachineConstantPoolEntry &MCPE = MCP->getConstants()[CPI];
927
928    if (MCPE.isMachineConstantPoolEntry()) {
929      EmitMachineConstantPoolValue(MCPE.Val.MachineCPVal);
930    } else {
931      EmitGlobalConstant(MCPE.Val.ConstVal);
932    }
933  }
934}
935
936MCSymbol *ARMAsmPrinter::
937GetARMSetPICJumpTableLabel2(unsigned uid, unsigned uid2,
938                            const MachineBasicBlock *MBB) const {
939  SmallString<60> Name;
940  raw_svector_ostream(Name) << MAI->getPrivateGlobalPrefix()
941    << getFunctionNumber() << '_' << uid << '_' << uid2
942    << "_set_" << MBB->getNumber();
943  return OutContext.GetOrCreateSymbol(Name.str());
944}
945
946MCSymbol *ARMAsmPrinter::
947GetARMJTIPICJumpTableLabel2(unsigned uid, unsigned uid2) const {
948  SmallString<60> Name;
949  raw_svector_ostream(Name) << MAI->getPrivateGlobalPrefix() << "JTI"
950    << getFunctionNumber() << '_' << uid << '_' << uid2;
951  return OutContext.GetOrCreateSymbol(Name.str());
952}
953
954
955MCSymbol *ARMAsmPrinter::GetARMSJLJEHLabel(void) const {
956  SmallString<60> Name;
957  raw_svector_ostream(Name) << MAI->getPrivateGlobalPrefix() << "SJLJEH"
958    << getFunctionNumber();
959  return OutContext.GetOrCreateSymbol(Name.str());
960}
961
962void ARMAsmPrinter::printJTBlockOperand(const MachineInstr *MI, int OpNum,
963                                        raw_ostream &O) {
964  assert(!Subtarget->isThumb2() && "Thumb2 should use double-jump jumptables!");
965
966  const MachineOperand &MO1 = MI->getOperand(OpNum);
967  const MachineOperand &MO2 = MI->getOperand(OpNum+1); // Unique Id
968
969  unsigned JTI = MO1.getIndex();
970  MCSymbol *JTISymbol = GetARMJTIPICJumpTableLabel2(JTI, MO2.getImm());
971  // Can't use EmitLabel until instprinter happens, label comes out in the wrong
972  // order.
973  O << "\n" << *JTISymbol << ":\n";
974
975  const char *JTEntryDirective = MAI->getData32bitsDirective();
976
977  const MachineJumpTableInfo *MJTI = MF->getJumpTableInfo();
978  const std::vector<MachineJumpTableEntry> &JT = MJTI->getJumpTables();
979  const std::vector<MachineBasicBlock*> &JTBBs = JT[JTI].MBBs;
980  bool UseSet= MAI->hasSetDirective() && TM.getRelocationModel() == Reloc::PIC_;
981  SmallPtrSet<MachineBasicBlock*, 8> JTSets;
982  for (unsigned i = 0, e = JTBBs.size(); i != e; ++i) {
983    MachineBasicBlock *MBB = JTBBs[i];
984    bool isNew = JTSets.insert(MBB);
985
986    if (UseSet && isNew) {
987      O << "\t.set\t"
988        << *GetARMSetPICJumpTableLabel2(JTI, MO2.getImm(), MBB) << ','
989        << *MBB->getSymbol() << '-' << *JTISymbol << '\n';
990    }
991
992    O << JTEntryDirective << ' ';
993    if (UseSet)
994      O << *GetARMSetPICJumpTableLabel2(JTI, MO2.getImm(), MBB);
995    else if (TM.getRelocationModel() == Reloc::PIC_)
996      O << *MBB->getSymbol() << '-' << *JTISymbol;
997    else
998      O << *MBB->getSymbol();
999
1000    if (i != e-1)
1001      O << '\n';
1002  }
1003}
1004
1005void ARMAsmPrinter::printJT2BlockOperand(const MachineInstr *MI, int OpNum,
1006                                         raw_ostream &O) {
1007  const MachineOperand &MO1 = MI->getOperand(OpNum);
1008  const MachineOperand &MO2 = MI->getOperand(OpNum+1); // Unique Id
1009  unsigned JTI = MO1.getIndex();
1010
1011  MCSymbol *JTISymbol = GetARMJTIPICJumpTableLabel2(JTI, MO2.getImm());
1012
1013  // Can't use EmitLabel until instprinter happens, label comes out in the wrong
1014  // order.
1015  O << "\n" << *JTISymbol << ":\n";
1016
1017  const MachineJumpTableInfo *MJTI = MF->getJumpTableInfo();
1018  const std::vector<MachineJumpTableEntry> &JT = MJTI->getJumpTables();
1019  const std::vector<MachineBasicBlock*> &JTBBs = JT[JTI].MBBs;
1020  bool ByteOffset = false, HalfWordOffset = false;
1021  if (MI->getOpcode() == ARM::t2TBB)
1022    ByteOffset = true;
1023  else if (MI->getOpcode() == ARM::t2TBH)
1024    HalfWordOffset = true;
1025
1026  for (unsigned i = 0, e = JTBBs.size(); i != e; ++i) {
1027    MachineBasicBlock *MBB = JTBBs[i];
1028    if (ByteOffset)
1029      O << MAI->getData8bitsDirective();
1030    else if (HalfWordOffset)
1031      O << MAI->getData16bitsDirective();
1032
1033    if (ByteOffset || HalfWordOffset)
1034      O << '(' << *MBB->getSymbol() << "-" << *JTISymbol << ")/2";
1035    else
1036      O << "\tb.w " << *MBB->getSymbol();
1037
1038    if (i != e-1)
1039      O << '\n';
1040  }
1041}
1042
1043void ARMAsmPrinter::printTBAddrMode(const MachineInstr *MI, int OpNum,
1044                                    raw_ostream &O) {
1045  O << "[pc, " << getRegisterName(MI->getOperand(OpNum).getReg());
1046  if (MI->getOpcode() == ARM::t2TBH)
1047    O << ", lsl #1";
1048  O << ']';
1049}
1050
1051void ARMAsmPrinter::printNoHashImmediate(const MachineInstr *MI, int OpNum,
1052                                         raw_ostream &O) {
1053  O << MI->getOperand(OpNum).getImm();
1054}
1055
1056void ARMAsmPrinter::printVFPf32ImmOperand(const MachineInstr *MI, int OpNum,
1057                                          raw_ostream &O) {
1058  const ConstantFP *FP = MI->getOperand(OpNum).getFPImm();
1059  O << '#' << FP->getValueAPF().convertToFloat();
1060  if (isVerbose()) {
1061    O << "\t\t" << MAI->getCommentString() << ' ';
1062    WriteAsOperand(O, FP, /*PrintType=*/false);
1063  }
1064}
1065
1066void ARMAsmPrinter::printVFPf64ImmOperand(const MachineInstr *MI, int OpNum,
1067                                          raw_ostream &O) {
1068  const ConstantFP *FP = MI->getOperand(OpNum).getFPImm();
1069  O << '#' << FP->getValueAPF().convertToDouble();
1070  if (isVerbose()) {
1071    O << "\t\t" << MAI->getCommentString() << ' ';
1072    WriteAsOperand(O, FP, /*PrintType=*/false);
1073  }
1074}
1075
1076void ARMAsmPrinter::printNEONModImmOperand(const MachineInstr *MI, int OpNum,
1077                                           raw_ostream &O) {
1078  unsigned EncodedImm = MI->getOperand(OpNum).getImm();
1079  unsigned EltBits;
1080  uint64_t Val = ARM_AM::decodeNEONModImm(EncodedImm, EltBits);
1081  O << "#0x" << utohexstr(Val);
1082}
1083
1084bool ARMAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNum,
1085                                    unsigned AsmVariant, const char *ExtraCode,
1086                                    raw_ostream &O) {
1087  // Does this asm operand have a single letter operand modifier?
1088  if (ExtraCode && ExtraCode[0]) {
1089    if (ExtraCode[1] != 0) return true; // Unknown modifier.
1090
1091    switch (ExtraCode[0]) {
1092    default: return true;  // Unknown modifier.
1093    case 'a': // Print as a memory address.
1094      if (MI->getOperand(OpNum).isReg()) {
1095        O << "[" << getRegisterName(MI->getOperand(OpNum).getReg()) << "]";
1096        return false;
1097      }
1098      // Fallthrough
1099    case 'c': // Don't print "#" before an immediate operand.
1100      if (!MI->getOperand(OpNum).isImm())
1101        return true;
1102      printNoHashImmediate(MI, OpNum, O);
1103      return false;
1104    case 'P': // Print a VFP double precision register.
1105    case 'q': // Print a NEON quad precision register.
1106      printOperand(MI, OpNum, O);
1107      return false;
1108    case 'Q':
1109    case 'R':
1110    case 'H':
1111      report_fatal_error("llvm does not support 'Q', 'R', and 'H' modifiers!");
1112      return true;
1113    }
1114  }
1115
1116  printOperand(MI, OpNum, O);
1117  return false;
1118}
1119
1120bool ARMAsmPrinter::PrintAsmMemoryOperand(const MachineInstr *MI,
1121                                          unsigned OpNum, unsigned AsmVariant,
1122                                          const char *ExtraCode,
1123                                          raw_ostream &O) {
1124  if (ExtraCode && ExtraCode[0])
1125    return true; // Unknown modifier.
1126
1127  const MachineOperand &MO = MI->getOperand(OpNum);
1128  assert(MO.isReg() && "unexpected inline asm memory operand");
1129  O << "[" << getRegisterName(MO.getReg()) << "]";
1130  return false;
1131}
1132
1133void ARMAsmPrinter::EmitStartOfAsmFile(Module &M) {
1134  if (Subtarget->isTargetDarwin()) {
1135    Reloc::Model RelocM = TM.getRelocationModel();
1136    if (RelocM == Reloc::PIC_ || RelocM == Reloc::DynamicNoPIC) {
1137      // Declare all the text sections up front (before the DWARF sections
1138      // emitted by AsmPrinter::doInitialization) so the assembler will keep
1139      // them together at the beginning of the object file.  This helps
1140      // avoid out-of-range branches that are due a fundamental limitation of
1141      // the way symbol offsets are encoded with the current Darwin ARM
1142      // relocations.
1143      const TargetLoweringObjectFileMachO &TLOFMacho =
1144        static_cast<const TargetLoweringObjectFileMachO &>(
1145          getObjFileLowering());
1146      OutStreamer.SwitchSection(TLOFMacho.getTextSection());
1147      OutStreamer.SwitchSection(TLOFMacho.getTextCoalSection());
1148      OutStreamer.SwitchSection(TLOFMacho.getConstTextCoalSection());
1149      if (RelocM == Reloc::DynamicNoPIC) {
1150        const MCSection *sect =
1151          OutContext.getMachOSection("__TEXT", "__symbol_stub4",
1152                                     MCSectionMachO::S_SYMBOL_STUBS,
1153                                     12, SectionKind::getText());
1154        OutStreamer.SwitchSection(sect);
1155      } else {
1156        const MCSection *sect =
1157          OutContext.getMachOSection("__TEXT", "__picsymbolstub4",
1158                                     MCSectionMachO::S_SYMBOL_STUBS,
1159                                     16, SectionKind::getText());
1160        OutStreamer.SwitchSection(sect);
1161      }
1162      const MCSection *StaticInitSect =
1163        OutContext.getMachOSection("__TEXT", "__StaticInit",
1164                                   MCSectionMachO::S_REGULAR |
1165                                   MCSectionMachO::S_ATTR_PURE_INSTRUCTIONS,
1166                                   SectionKind::getText());
1167      OutStreamer.SwitchSection(StaticInitSect);
1168    }
1169  }
1170
1171  // Use unified assembler syntax.
1172  OutStreamer.EmitRawText(StringRef("\t.syntax unified"));
1173
1174  // Emit ARM Build Attributes
1175  if (Subtarget->isTargetELF()) {
1176    // CPU Type
1177    std::string CPUString = Subtarget->getCPUString();
1178    if (CPUString != "generic")
1179      OutStreamer.EmitRawText("\t.cpu " + Twine(CPUString));
1180
1181    // FIXME: Emit FPU type
1182    if (Subtarget->hasVFP2())
1183      OutStreamer.EmitRawText("\t.eabi_attribute " +
1184                              Twine(ARMBuildAttrs::VFP_arch) + ", 2");
1185
1186    // Signal various FP modes.
1187    if (!UnsafeFPMath) {
1188      OutStreamer.EmitRawText("\t.eabi_attribute " +
1189                              Twine(ARMBuildAttrs::ABI_FP_denormal) + ", 1");
1190      OutStreamer.EmitRawText("\t.eabi_attribute " +
1191                              Twine(ARMBuildAttrs::ABI_FP_exceptions) + ", 1");
1192    }
1193
1194    if (NoInfsFPMath && NoNaNsFPMath)
1195      OutStreamer.EmitRawText("\t.eabi_attribute " +
1196                              Twine(ARMBuildAttrs::ABI_FP_number_model)+ ", 1");
1197    else
1198      OutStreamer.EmitRawText("\t.eabi_attribute " +
1199                              Twine(ARMBuildAttrs::ABI_FP_number_model)+ ", 3");
1200
1201    // 8-bytes alignment stuff.
1202    OutStreamer.EmitRawText("\t.eabi_attribute " +
1203                            Twine(ARMBuildAttrs::ABI_align8_needed) + ", 1");
1204    OutStreamer.EmitRawText("\t.eabi_attribute " +
1205                            Twine(ARMBuildAttrs::ABI_align8_preserved) + ", 1");
1206
1207    // Hard float.  Use both S and D registers and conform to AAPCS-VFP.
1208    if (Subtarget->isAAPCS_ABI() && FloatABIType == FloatABI::Hard) {
1209      OutStreamer.EmitRawText("\t.eabi_attribute " +
1210                              Twine(ARMBuildAttrs::ABI_HardFP_use) + ", 3");
1211      OutStreamer.EmitRawText("\t.eabi_attribute " +
1212                              Twine(ARMBuildAttrs::ABI_VFP_args) + ", 1");
1213    }
1214    // FIXME: Should we signal R9 usage?
1215  }
1216}
1217
1218
1219void ARMAsmPrinter::EmitEndOfAsmFile(Module &M) {
1220  if (Subtarget->isTargetDarwin()) {
1221    // All darwin targets use mach-o.
1222    const TargetLoweringObjectFileMachO &TLOFMacho =
1223      static_cast<const TargetLoweringObjectFileMachO &>(getObjFileLowering());
1224    MachineModuleInfoMachO &MMIMacho =
1225      MMI->getObjFileInfo<MachineModuleInfoMachO>();
1226
1227    // Output non-lazy-pointers for external and common global variables.
1228    MachineModuleInfoMachO::SymbolListTy Stubs = MMIMacho.GetGVStubList();
1229
1230    if (!Stubs.empty()) {
1231      // Switch with ".non_lazy_symbol_pointer" directive.
1232      OutStreamer.SwitchSection(TLOFMacho.getNonLazySymbolPointerSection());
1233      EmitAlignment(2);
1234      for (unsigned i = 0, e = Stubs.size(); i != e; ++i) {
1235        // L_foo$stub:
1236        OutStreamer.EmitLabel(Stubs[i].first);
1237        //   .indirect_symbol _foo
1238        MachineModuleInfoImpl::StubValueTy &MCSym = Stubs[i].second;
1239        OutStreamer.EmitSymbolAttribute(MCSym.getPointer(),MCSA_IndirectSymbol);
1240
1241        if (MCSym.getInt())
1242          // External to current translation unit.
1243          OutStreamer.EmitIntValue(0, 4/*size*/, 0/*addrspace*/);
1244        else
1245          // Internal to current translation unit.
1246          //
1247          // When we place the LSDA into the TEXT section, the type info
1248          // pointers need to be indirect and pc-rel. We accomplish this by
1249          // using NLPs; however, sometimes the types are local to the file.
1250          // We need to fill in the value for the NLP in those cases.
1251          OutStreamer.EmitValue(MCSymbolRefExpr::Create(MCSym.getPointer(),
1252                                                        OutContext),
1253                                4/*size*/, 0/*addrspace*/);
1254      }
1255
1256      Stubs.clear();
1257      OutStreamer.AddBlankLine();
1258    }
1259
1260    Stubs = MMIMacho.GetHiddenGVStubList();
1261    if (!Stubs.empty()) {
1262      OutStreamer.SwitchSection(getObjFileLowering().getDataSection());
1263      EmitAlignment(2);
1264      for (unsigned i = 0, e = Stubs.size(); i != e; ++i) {
1265        // L_foo$stub:
1266        OutStreamer.EmitLabel(Stubs[i].first);
1267        //   .long _foo
1268        OutStreamer.EmitValue(MCSymbolRefExpr::
1269                              Create(Stubs[i].second.getPointer(),
1270                                     OutContext),
1271                              4/*size*/, 0/*addrspace*/);
1272      }
1273
1274      Stubs.clear();
1275      OutStreamer.AddBlankLine();
1276    }
1277
1278    // Funny Darwin hack: This flag tells the linker that no global symbols
1279    // contain code that falls through to other global symbols (e.g. the obvious
1280    // implementation of multiple entry points).  If this doesn't occur, the
1281    // linker can safely perform dead code stripping.  Since LLVM never
1282    // generates code that does this, it is always safe to set.
1283    OutStreamer.EmitAssemblerFlag(MCAF_SubsectionsViaSymbols);
1284  }
1285}
1286
1287//===----------------------------------------------------------------------===//
1288
1289static MCSymbol *getPICLabel(const char *Prefix, unsigned FunctionNumber,
1290                             unsigned LabelId, MCContext &Ctx) {
1291
1292  MCSymbol *Label = Ctx.GetOrCreateSymbol(Twine(Prefix)
1293                       + "PC" + Twine(FunctionNumber) + "_" + Twine(LabelId));
1294  return Label;
1295}
1296
1297void ARMAsmPrinter::EmitJumpTable(const MachineInstr *MI) {
1298  unsigned Opcode = MI->getOpcode();
1299  int OpNum = 1;
1300  if (Opcode == ARM::BR_JTadd)
1301    OpNum = 2;
1302  else if (Opcode == ARM::BR_JTm)
1303    OpNum = 3;
1304
1305  const MachineOperand &MO1 = MI->getOperand(OpNum);
1306  const MachineOperand &MO2 = MI->getOperand(OpNum+1); // Unique Id
1307  unsigned JTI = MO1.getIndex();
1308
1309  // Emit a label for the jump table.
1310  MCSymbol *JTISymbol = GetARMJTIPICJumpTableLabel2(JTI, MO2.getImm());
1311  OutStreamer.EmitLabel(JTISymbol);
1312
1313  // Emit each entry of the table.
1314  const MachineJumpTableInfo *MJTI = MF->getJumpTableInfo();
1315  const std::vector<MachineJumpTableEntry> &JT = MJTI->getJumpTables();
1316  const std::vector<MachineBasicBlock*> &JTBBs = JT[JTI].MBBs;
1317
1318  for (unsigned i = 0, e = JTBBs.size(); i != e; ++i) {
1319    MachineBasicBlock *MBB = JTBBs[i];
1320    // Construct an MCExpr for the entry. We want a value of the form:
1321    // (BasicBlockAddr - TableBeginAddr)
1322    //
1323    // For example, a table with entries jumping to basic blocks BB0 and BB1
1324    // would look like:
1325    // LJTI_0_0:
1326    //    .word (LBB0 - LJTI_0_0)
1327    //    .word (LBB1 - LJTI_0_0)
1328    const MCExpr *Expr = MCSymbolRefExpr::Create(MBB->getSymbol(), OutContext);
1329
1330    if (TM.getRelocationModel() == Reloc::PIC_)
1331      Expr = MCBinaryExpr::CreateSub(Expr, MCSymbolRefExpr::Create(JTISymbol,
1332                                                                   OutContext),
1333                                     OutContext);
1334    OutStreamer.EmitValue(Expr, 4);
1335  }
1336}
1337
1338void ARMAsmPrinter::EmitJump2Table(const MachineInstr *MI) {
1339  unsigned Opcode = MI->getOpcode();
1340  int OpNum = (Opcode == ARM::t2BR_JT) ? 2 : 1;
1341  const MachineOperand &MO1 = MI->getOperand(OpNum);
1342  const MachineOperand &MO2 = MI->getOperand(OpNum+1); // Unique Id
1343  unsigned JTI = MO1.getIndex();
1344
1345  // Emit a label for the jump table.
1346  MCSymbol *JTISymbol = GetARMJTIPICJumpTableLabel2(JTI, MO2.getImm());
1347  OutStreamer.EmitLabel(JTISymbol);
1348
1349  // Emit each entry of the table.
1350  const MachineJumpTableInfo *MJTI = MF->getJumpTableInfo();
1351  const std::vector<MachineJumpTableEntry> &JT = MJTI->getJumpTables();
1352  const std::vector<MachineBasicBlock*> &JTBBs = JT[JTI].MBBs;
1353  unsigned OffsetWidth = 4;
1354  if (MI->getOpcode() == ARM::t2TBB)
1355    OffsetWidth = 1;
1356  else if (MI->getOpcode() == ARM::t2TBH)
1357    OffsetWidth = 2;
1358
1359  for (unsigned i = 0, e = JTBBs.size(); i != e; ++i) {
1360    MachineBasicBlock *MBB = JTBBs[i];
1361    const MCExpr *MBBSymbolExpr = MCSymbolRefExpr::Create(MBB->getSymbol(),
1362                                                      OutContext);
1363    // If this isn't a TBB or TBH, the entries are direct branch instructions.
1364    if (OffsetWidth == 4) {
1365      MCInst BrInst;
1366      BrInst.setOpcode(ARM::t2B);
1367      BrInst.addOperand(MCOperand::CreateExpr(MBBSymbolExpr));
1368      OutStreamer.EmitInstruction(BrInst);
1369      continue;
1370    }
1371    // Otherwise it's an offset from the dispatch instruction. Construct an
1372    // MCExpr for the entry. We want a value of the form:
1373    // (BasicBlockAddr - TableBeginAddr) / 2
1374    //
1375    // For example, a TBB table with entries jumping to basic blocks BB0 and BB1
1376    // would look like:
1377    // LJTI_0_0:
1378    //    .byte (LBB0 - LJTI_0_0) / 2
1379    //    .byte (LBB1 - LJTI_0_0) / 2
1380    const MCExpr *Expr =
1381      MCBinaryExpr::CreateSub(MBBSymbolExpr,
1382                              MCSymbolRefExpr::Create(JTISymbol, OutContext),
1383                              OutContext);
1384    Expr = MCBinaryExpr::CreateDiv(Expr, MCConstantExpr::Create(2, OutContext),
1385                                   OutContext);
1386    OutStreamer.EmitValue(Expr, OffsetWidth);
1387  }
1388
1389  // Make sure the instruction that follows TBB is 2-byte aligned.
1390  // FIXME: Constant island pass should insert an "ALIGN" instruction instead.
1391  if (MI->getOpcode() == ARM::t2TBB)
1392    EmitAlignment(1);
1393}
1394
1395void ARMAsmPrinter::PrintDebugValueComment(const MachineInstr *MI,
1396                                           raw_ostream &OS) {
1397  unsigned NOps = MI->getNumOperands();
1398  assert(NOps==4);
1399  OS << '\t' << MAI->getCommentString() << "DEBUG_VALUE: ";
1400  // cast away const; DIetc do not take const operands for some reason.
1401  DIVariable V(const_cast<MDNode *>(MI->getOperand(NOps-1).getMetadata()));
1402  OS << V.getName();
1403  OS << " <- ";
1404  // Frame address.  Currently handles register +- offset only.
1405  assert(MI->getOperand(0).isReg() && MI->getOperand(1).isImm());
1406  OS << '['; printOperand(MI, 0, OS); OS << '+'; printOperand(MI, 1, OS);
1407  OS << ']';
1408  OS << "+";
1409  printOperand(MI, NOps-2, OS);
1410}
1411
1412void ARMAsmPrinter::EmitInstruction(const MachineInstr *MI) {
1413  ARMMCInstLower MCInstLowering(OutContext, *Mang, *this);
1414  switch (MI->getOpcode()) {
1415  case ARM::t2MOVi32imm:
1416    assert(0 && "Should be lowered by thumb2it pass");
1417  default: break;
1418  case ARM::DBG_VALUE: {
1419    if (isVerbose() && OutStreamer.hasRawTextSupport()) {
1420      SmallString<128> TmpStr;
1421      raw_svector_ostream OS(TmpStr);
1422      PrintDebugValueComment(MI, OS);
1423      OutStreamer.EmitRawText(StringRef(OS.str()));
1424    }
1425    return;
1426  }
1427  case ARM::tPICADD: {
1428    // This is a pseudo op for a label + instruction sequence, which looks like:
1429    // LPC0:
1430    //     add r0, pc
1431    // This adds the address of LPC0 to r0.
1432
1433    // Emit the label.
1434    OutStreamer.EmitLabel(getPICLabel(MAI->getPrivateGlobalPrefix(),
1435                          getFunctionNumber(), MI->getOperand(2).getImm(),
1436                          OutContext));
1437
1438    // Form and emit the add.
1439    MCInst AddInst;
1440    AddInst.setOpcode(ARM::tADDhirr);
1441    AddInst.addOperand(MCOperand::CreateReg(MI->getOperand(0).getReg()));
1442    AddInst.addOperand(MCOperand::CreateReg(MI->getOperand(0).getReg()));
1443    AddInst.addOperand(MCOperand::CreateReg(ARM::PC));
1444    // Add predicate operands.
1445    AddInst.addOperand(MCOperand::CreateImm(ARMCC::AL));
1446    AddInst.addOperand(MCOperand::CreateReg(0));
1447    OutStreamer.EmitInstruction(AddInst);
1448    return;
1449  }
1450  case ARM::PICADD: { // FIXME: Remove asm string from td file.
1451    // This is a pseudo op for a label + instruction sequence, which looks like:
1452    // LPC0:
1453    //     add r0, pc, r0
1454    // This adds the address of LPC0 to r0.
1455
1456    // Emit the label.
1457    OutStreamer.EmitLabel(getPICLabel(MAI->getPrivateGlobalPrefix(),
1458                          getFunctionNumber(), MI->getOperand(2).getImm(),
1459                          OutContext));
1460
1461    // Form and emit the add.
1462    MCInst AddInst;
1463    AddInst.setOpcode(ARM::ADDrr);
1464    AddInst.addOperand(MCOperand::CreateReg(MI->getOperand(0).getReg()));
1465    AddInst.addOperand(MCOperand::CreateReg(ARM::PC));
1466    AddInst.addOperand(MCOperand::CreateReg(MI->getOperand(1).getReg()));
1467    // Add predicate operands.
1468    AddInst.addOperand(MCOperand::CreateImm(MI->getOperand(3).getImm()));
1469    AddInst.addOperand(MCOperand::CreateReg(MI->getOperand(4).getReg()));
1470    // Add 's' bit operand (always reg0 for this)
1471    AddInst.addOperand(MCOperand::CreateReg(0));
1472    OutStreamer.EmitInstruction(AddInst);
1473    return;
1474  }
1475  case ARM::PICSTR:
1476  case ARM::PICSTRB:
1477  case ARM::PICSTRH:
1478  case ARM::PICLDR:
1479  case ARM::PICLDRB:
1480  case ARM::PICLDRH:
1481  case ARM::PICLDRSB:
1482  case ARM::PICLDRSH: {
1483    // This is a pseudo op for a label + instruction sequence, which looks like:
1484    // LPC0:
1485    //     OP r0, [pc, r0]
1486    // The LCP0 label is referenced by a constant pool entry in order to get
1487    // a PC-relative address at the ldr instruction.
1488
1489    // Emit the label.
1490    OutStreamer.EmitLabel(getPICLabel(MAI->getPrivateGlobalPrefix(),
1491                          getFunctionNumber(), MI->getOperand(2).getImm(),
1492                          OutContext));
1493
1494    // Form and emit the load
1495    unsigned Opcode;
1496    switch (MI->getOpcode()) {
1497    default:
1498      llvm_unreachable("Unexpected opcode!");
1499    case ARM::PICSTR:   Opcode = ARM::STR; break;
1500    case ARM::PICSTRB:  Opcode = ARM::STRB; break;
1501    case ARM::PICSTRH:  Opcode = ARM::STRH; break;
1502    case ARM::PICLDR:   Opcode = ARM::LDR; break;
1503    case ARM::PICLDRB:  Opcode = ARM::LDRB; break;
1504    case ARM::PICLDRH:  Opcode = ARM::LDRH; break;
1505    case ARM::PICLDRSB: Opcode = ARM::LDRSB; break;
1506    case ARM::PICLDRSH: Opcode = ARM::LDRSH; break;
1507    }
1508    MCInst LdStInst;
1509    LdStInst.setOpcode(Opcode);
1510    LdStInst.addOperand(MCOperand::CreateReg(MI->getOperand(0).getReg()));
1511    LdStInst.addOperand(MCOperand::CreateReg(ARM::PC));
1512    LdStInst.addOperand(MCOperand::CreateReg(MI->getOperand(1).getReg()));
1513    LdStInst.addOperand(MCOperand::CreateImm(0));
1514    // Add predicate operands.
1515    LdStInst.addOperand(MCOperand::CreateImm(MI->getOperand(3).getImm()));
1516    LdStInst.addOperand(MCOperand::CreateReg(MI->getOperand(4).getReg()));
1517    OutStreamer.EmitInstruction(LdStInst);
1518
1519    return;
1520  }
1521  case ARM::CONSTPOOL_ENTRY: { // FIXME: Remove asm string from td file.
1522    /// CONSTPOOL_ENTRY - This instruction represents a floating constant pool
1523    /// in the function.  The first operand is the ID# for this instruction, the
1524    /// second is the index into the MachineConstantPool that this is, the third
1525    /// is the size in bytes of this constant pool entry.
1526    unsigned LabelId = (unsigned)MI->getOperand(0).getImm();
1527    unsigned CPIdx   = (unsigned)MI->getOperand(1).getIndex();
1528
1529    EmitAlignment(2);
1530    OutStreamer.EmitLabel(GetCPISymbol(LabelId));
1531
1532    const MachineConstantPoolEntry &MCPE = MCP->getConstants()[CPIdx];
1533    if (MCPE.isMachineConstantPoolEntry())
1534      EmitMachineConstantPoolValue(MCPE.Val.MachineCPVal);
1535    else
1536      EmitGlobalConstant(MCPE.Val.ConstVal);
1537
1538    return;
1539  }
1540  case ARM::MOVi2pieces: { // FIXME: Remove asmstring from td file.
1541    // This is a hack that lowers as a two instruction sequence.
1542    unsigned DstReg = MI->getOperand(0).getReg();
1543    unsigned ImmVal = (unsigned)MI->getOperand(1).getImm();
1544
1545    unsigned SOImmValV1 = ARM_AM::getSOImmTwoPartFirst(ImmVal);
1546    unsigned SOImmValV2 = ARM_AM::getSOImmTwoPartSecond(ImmVal);
1547
1548    {
1549      MCInst TmpInst;
1550      TmpInst.setOpcode(ARM::MOVi);
1551      TmpInst.addOperand(MCOperand::CreateReg(DstReg));
1552      TmpInst.addOperand(MCOperand::CreateImm(SOImmValV1));
1553
1554      // Predicate.
1555      TmpInst.addOperand(MCOperand::CreateImm(MI->getOperand(2).getImm()));
1556      TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(3).getReg()));
1557
1558      TmpInst.addOperand(MCOperand::CreateReg(0));          // cc_out
1559      OutStreamer.EmitInstruction(TmpInst);
1560    }
1561
1562    {
1563      MCInst TmpInst;
1564      TmpInst.setOpcode(ARM::ORRri);
1565      TmpInst.addOperand(MCOperand::CreateReg(DstReg));     // dstreg
1566      TmpInst.addOperand(MCOperand::CreateReg(DstReg));     // inreg
1567      TmpInst.addOperand(MCOperand::CreateImm(SOImmValV2)); // so_imm
1568      // Predicate.
1569      TmpInst.addOperand(MCOperand::CreateImm(MI->getOperand(2).getImm()));
1570      TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(3).getReg()));
1571
1572      TmpInst.addOperand(MCOperand::CreateReg(0));          // cc_out
1573      OutStreamer.EmitInstruction(TmpInst);
1574    }
1575    return;
1576  }
1577  case ARM::MOVi32imm: { // FIXME: Remove asmstring from td file.
1578    // This is a hack that lowers as a two instruction sequence.
1579    unsigned DstReg = MI->getOperand(0).getReg();
1580    const MachineOperand &MO = MI->getOperand(1);
1581    MCOperand V1, V2;
1582    if (MO.isImm()) {
1583      unsigned ImmVal = (unsigned)MI->getOperand(1).getImm();
1584      V1 = MCOperand::CreateImm(ImmVal & 65535);
1585      V2 = MCOperand::CreateImm(ImmVal >> 16);
1586    } else if (MO.isGlobal()) {
1587      MCSymbol *Symbol = MCInstLowering.GetGlobalAddressSymbol(MO.getGlobal());
1588      const MCSymbolRefExpr *SymRef1 =
1589        MCSymbolRefExpr::Create(Symbol,
1590                                MCSymbolRefExpr::VK_ARM_LO16, OutContext);
1591      const MCSymbolRefExpr *SymRef2 =
1592        MCSymbolRefExpr::Create(Symbol,
1593                                MCSymbolRefExpr::VK_ARM_HI16, OutContext);
1594      V1 = MCOperand::CreateExpr(SymRef1);
1595      V2 = MCOperand::CreateExpr(SymRef2);
1596    } else {
1597      // FIXME: External symbol?
1598      MI->dump();
1599      llvm_unreachable("cannot handle this operand");
1600    }
1601
1602    {
1603      MCInst TmpInst;
1604      TmpInst.setOpcode(ARM::MOVi16);
1605      TmpInst.addOperand(MCOperand::CreateReg(DstReg));         // dstreg
1606      TmpInst.addOperand(V1); // lower16(imm)
1607
1608      // Predicate.
1609      TmpInst.addOperand(MCOperand::CreateImm(MI->getOperand(2).getImm()));
1610      TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(3).getReg()));
1611
1612      OutStreamer.EmitInstruction(TmpInst);
1613    }
1614
1615    {
1616      MCInst TmpInst;
1617      TmpInst.setOpcode(ARM::MOVTi16);
1618      TmpInst.addOperand(MCOperand::CreateReg(DstReg));         // dstreg
1619      TmpInst.addOperand(MCOperand::CreateReg(DstReg));         // srcreg
1620      TmpInst.addOperand(V2);   // upper16(imm)
1621
1622      // Predicate.
1623      TmpInst.addOperand(MCOperand::CreateImm(MI->getOperand(2).getImm()));
1624      TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(3).getReg()));
1625
1626      OutStreamer.EmitInstruction(TmpInst);
1627    }
1628
1629    return;
1630  }
1631  case ARM::t2TBB:
1632  case ARM::t2TBH:
1633  case ARM::t2BR_JT: {
1634    // Lower and emit the instruction itself, then the jump table following it.
1635    MCInst TmpInst;
1636    MCInstLowering.Lower(MI, TmpInst);
1637    OutStreamer.EmitInstruction(TmpInst);
1638    EmitJump2Table(MI);
1639    return;
1640  }
1641  case ARM::tBR_JTr:
1642  case ARM::BR_JTr:
1643  case ARM::BR_JTm:
1644  case ARM::BR_JTadd: {
1645    // Lower and emit the instruction itself, then the jump table following it.
1646    MCInst TmpInst;
1647    MCInstLowering.Lower(MI, TmpInst);
1648    OutStreamer.EmitInstruction(TmpInst);
1649    EmitJumpTable(MI);
1650    return;
1651  }
1652  case ARM::TRAP: {
1653    // Non-Darwin binutils don't yet support the "trap" mnemonic.
1654    // FIXME: Remove this special case when they do.
1655    if (!Subtarget->isTargetDarwin()) {
1656      //.long 0xe7ffdefe ${:comment} trap
1657      uint32_t Val = 0xe7ffdefeUL;
1658      OutStreamer.AddComment("trap");
1659      OutStreamer.EmitIntValue(Val, 4);
1660      return;
1661    }
1662    break;
1663  }
1664  case ARM::tTRAP: {
1665    // Non-Darwin binutils don't yet support the "trap" mnemonic.
1666    // FIXME: Remove this special case when they do.
1667    if (!Subtarget->isTargetDarwin()) {
1668      //.short 57086 ${:comment} trap
1669      uint16_t Val = 0xdefe;
1670      OutStreamer.AddComment("trap");
1671      OutStreamer.EmitIntValue(Val, 2);
1672      return;
1673    }
1674    break;
1675  }
1676  case ARM::t2Int_eh_sjlj_setjmp:
1677  case ARM::t2Int_eh_sjlj_setjmp_nofp:
1678  case ARM::tInt_eh_sjlj_setjmp: { // FIXME: Remove asmstring from td file.
1679    // Two incoming args: GPR:$src, GPR:$val
1680    // mov $val, pc
1681    // adds $val, #7
1682    // str $val, [$src, #4]
1683    // movs r0, #0
1684    // b 1f
1685    // movs r0, #1
1686    // 1:
1687    unsigned SrcReg = MI->getOperand(0).getReg();
1688    unsigned ValReg = MI->getOperand(1).getReg();
1689    MCSymbol *Label = GetARMSJLJEHLabel();
1690    {
1691      MCInst TmpInst;
1692      TmpInst.setOpcode(ARM::tMOVgpr2tgpr);
1693      TmpInst.addOperand(MCOperand::CreateReg(ValReg));
1694      TmpInst.addOperand(MCOperand::CreateReg(ARM::PC));
1695      // 's' bit operand
1696      TmpInst.addOperand(MCOperand::CreateReg(ARM::CPSR));
1697      OutStreamer.AddComment("eh_setjmp begin");
1698      OutStreamer.EmitInstruction(TmpInst);
1699    }
1700    {
1701      MCInst TmpInst;
1702      TmpInst.setOpcode(ARM::tADDi3);
1703      TmpInst.addOperand(MCOperand::CreateReg(ValReg));
1704      // 's' bit operand
1705      TmpInst.addOperand(MCOperand::CreateReg(ARM::CPSR));
1706      TmpInst.addOperand(MCOperand::CreateReg(ValReg));
1707      TmpInst.addOperand(MCOperand::CreateImm(7));
1708      // Predicate.
1709      TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL));
1710      TmpInst.addOperand(MCOperand::CreateReg(0));
1711      OutStreamer.EmitInstruction(TmpInst);
1712    }
1713    {
1714      MCInst TmpInst;
1715      TmpInst.setOpcode(ARM::tSTR);
1716      TmpInst.addOperand(MCOperand::CreateReg(ValReg));
1717      TmpInst.addOperand(MCOperand::CreateReg(SrcReg));
1718      // The offset immediate is #4. The operand value is scaled by 4 for the
1719      // tSTR instruction.
1720      TmpInst.addOperand(MCOperand::CreateImm(1));
1721      TmpInst.addOperand(MCOperand::CreateReg(0));
1722      // Predicate.
1723      TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL));
1724      TmpInst.addOperand(MCOperand::CreateReg(0));
1725      OutStreamer.EmitInstruction(TmpInst);
1726    }
1727    {
1728      MCInst TmpInst;
1729      TmpInst.setOpcode(ARM::tMOVi8);
1730      TmpInst.addOperand(MCOperand::CreateReg(ARM::R0));
1731      TmpInst.addOperand(MCOperand::CreateReg(ARM::CPSR));
1732      TmpInst.addOperand(MCOperand::CreateImm(0));
1733      // Predicate.
1734      TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL));
1735      TmpInst.addOperand(MCOperand::CreateReg(0));
1736      OutStreamer.EmitInstruction(TmpInst);
1737    }
1738    {
1739      const MCExpr *SymbolExpr = MCSymbolRefExpr::Create(Label, OutContext);
1740      MCInst TmpInst;
1741      TmpInst.setOpcode(ARM::tB);
1742      TmpInst.addOperand(MCOperand::CreateExpr(SymbolExpr));
1743      OutStreamer.EmitInstruction(TmpInst);
1744    }
1745    {
1746      MCInst TmpInst;
1747      TmpInst.setOpcode(ARM::tMOVi8);
1748      TmpInst.addOperand(MCOperand::CreateReg(ARM::R0));
1749      TmpInst.addOperand(MCOperand::CreateReg(ARM::CPSR));
1750      TmpInst.addOperand(MCOperand::CreateImm(1));
1751      // Predicate.
1752      TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL));
1753      TmpInst.addOperand(MCOperand::CreateReg(0));
1754      OutStreamer.AddComment("eh_setjmp end");
1755      OutStreamer.EmitInstruction(TmpInst);
1756    }
1757    OutStreamer.EmitLabel(Label);
1758    return;
1759  }
1760
1761  case ARM::Int_eh_sjlj_setjmp_nofp:
1762  case ARM::Int_eh_sjlj_setjmp: { // FIXME: Remove asmstring from td file.
1763    // Two incoming args: GPR:$src, GPR:$val
1764    // add $val, pc, #8
1765    // str $val, [$src, #+4]
1766    // mov r0, #0
1767    // add pc, pc, #0
1768    // mov r0, #1
1769    unsigned SrcReg = MI->getOperand(0).getReg();
1770    unsigned ValReg = MI->getOperand(1).getReg();
1771
1772    {
1773      MCInst TmpInst;
1774      TmpInst.setOpcode(ARM::ADDri);
1775      TmpInst.addOperand(MCOperand::CreateReg(ValReg));
1776      TmpInst.addOperand(MCOperand::CreateReg(ARM::PC));
1777      TmpInst.addOperand(MCOperand::CreateImm(8));
1778      // Predicate.
1779      TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL));
1780      TmpInst.addOperand(MCOperand::CreateReg(0));
1781      // 's' bit operand (always reg0 for this).
1782      TmpInst.addOperand(MCOperand::CreateReg(0));
1783      OutStreamer.AddComment("eh_setjmp begin");
1784      OutStreamer.EmitInstruction(TmpInst);
1785    }
1786    {
1787      MCInst TmpInst;
1788      TmpInst.setOpcode(ARM::STR);
1789      TmpInst.addOperand(MCOperand::CreateReg(ValReg));
1790      TmpInst.addOperand(MCOperand::CreateReg(SrcReg));
1791      TmpInst.addOperand(MCOperand::CreateReg(0));
1792      TmpInst.addOperand(MCOperand::CreateImm(4));
1793      // Predicate.
1794      TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL));
1795      TmpInst.addOperand(MCOperand::CreateReg(0));
1796      OutStreamer.EmitInstruction(TmpInst);
1797    }
1798    {
1799      MCInst TmpInst;
1800      TmpInst.setOpcode(ARM::MOVi);
1801      TmpInst.addOperand(MCOperand::CreateReg(ARM::R0));
1802      TmpInst.addOperand(MCOperand::CreateImm(0));
1803      // Predicate.
1804      TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL));
1805      TmpInst.addOperand(MCOperand::CreateReg(0));
1806      // 's' bit operand (always reg0 for this).
1807      TmpInst.addOperand(MCOperand::CreateReg(0));
1808      OutStreamer.EmitInstruction(TmpInst);
1809    }
1810    {
1811      MCInst TmpInst;
1812      TmpInst.setOpcode(ARM::ADDri);
1813      TmpInst.addOperand(MCOperand::CreateReg(ARM::PC));
1814      TmpInst.addOperand(MCOperand::CreateReg(ARM::PC));
1815      TmpInst.addOperand(MCOperand::CreateImm(0));
1816      // Predicate.
1817      TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL));
1818      TmpInst.addOperand(MCOperand::CreateReg(0));
1819      // 's' bit operand (always reg0 for this).
1820      TmpInst.addOperand(MCOperand::CreateReg(0));
1821      OutStreamer.EmitInstruction(TmpInst);
1822    }
1823    {
1824      MCInst TmpInst;
1825      TmpInst.setOpcode(ARM::MOVi);
1826      TmpInst.addOperand(MCOperand::CreateReg(ARM::R0));
1827      TmpInst.addOperand(MCOperand::CreateImm(1));
1828      // Predicate.
1829      TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL));
1830      TmpInst.addOperand(MCOperand::CreateReg(0));
1831      // 's' bit operand (always reg0 for this).
1832      TmpInst.addOperand(MCOperand::CreateReg(0));
1833      OutStreamer.AddComment("eh_setjmp end");
1834      OutStreamer.EmitInstruction(TmpInst);
1835    }
1836    return;
1837  }
1838  case ARM::Int_eh_sjlj_longjmp: {
1839    // ldr sp, [$src, #8]
1840    // ldr $scratch, [$src, #4]
1841    // ldr r7, [$src]
1842    // bx $scratch
1843    unsigned SrcReg = MI->getOperand(0).getReg();
1844    unsigned ScratchReg = MI->getOperand(1).getReg();
1845    {
1846      MCInst TmpInst;
1847      TmpInst.setOpcode(ARM::LDR);
1848      TmpInst.addOperand(MCOperand::CreateReg(ARM::SP));
1849      TmpInst.addOperand(MCOperand::CreateReg(SrcReg));
1850      TmpInst.addOperand(MCOperand::CreateReg(0));
1851      TmpInst.addOperand(MCOperand::CreateImm(8));
1852      // Predicate.
1853      TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL));
1854      TmpInst.addOperand(MCOperand::CreateReg(0));
1855      OutStreamer.EmitInstruction(TmpInst);
1856    }
1857    {
1858      MCInst TmpInst;
1859      TmpInst.setOpcode(ARM::LDR);
1860      TmpInst.addOperand(MCOperand::CreateReg(ScratchReg));
1861      TmpInst.addOperand(MCOperand::CreateReg(SrcReg));
1862      TmpInst.addOperand(MCOperand::CreateReg(0));
1863      TmpInst.addOperand(MCOperand::CreateImm(4));
1864      // Predicate.
1865      TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL));
1866      TmpInst.addOperand(MCOperand::CreateReg(0));
1867      OutStreamer.EmitInstruction(TmpInst);
1868    }
1869    {
1870      MCInst TmpInst;
1871      TmpInst.setOpcode(ARM::LDR);
1872      TmpInst.addOperand(MCOperand::CreateReg(ARM::R7));
1873      TmpInst.addOperand(MCOperand::CreateReg(SrcReg));
1874      TmpInst.addOperand(MCOperand::CreateReg(0));
1875      TmpInst.addOperand(MCOperand::CreateImm(0));
1876      // Predicate.
1877      TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL));
1878      TmpInst.addOperand(MCOperand::CreateReg(0));
1879      OutStreamer.EmitInstruction(TmpInst);
1880    }
1881    {
1882      MCInst TmpInst;
1883      TmpInst.setOpcode(ARM::BRIND);
1884      TmpInst.addOperand(MCOperand::CreateReg(ScratchReg));
1885      // Predicate.
1886      TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL));
1887      TmpInst.addOperand(MCOperand::CreateReg(0));
1888      OutStreamer.EmitInstruction(TmpInst);
1889    }
1890    return;
1891  }
1892  case ARM::tInt_eh_sjlj_longjmp: {
1893    // ldr $scratch, [$src, #8]
1894    // mov sp, $scratch
1895    // ldr $scratch, [$src, #4]
1896    // ldr r7, [$src]
1897    // bx $scratch
1898    unsigned SrcReg = MI->getOperand(0).getReg();
1899    unsigned ScratchReg = MI->getOperand(1).getReg();
1900    {
1901      MCInst TmpInst;
1902      TmpInst.setOpcode(ARM::tLDR);
1903      TmpInst.addOperand(MCOperand::CreateReg(ScratchReg));
1904      TmpInst.addOperand(MCOperand::CreateReg(SrcReg));
1905      // The offset immediate is #8. The operand value is scaled by 4 for the
1906      // tSTR instruction.
1907      TmpInst.addOperand(MCOperand::CreateImm(2));
1908      TmpInst.addOperand(MCOperand::CreateReg(0));
1909      // Predicate.
1910      TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL));
1911      TmpInst.addOperand(MCOperand::CreateReg(0));
1912      OutStreamer.EmitInstruction(TmpInst);
1913    }
1914    {
1915      MCInst TmpInst;
1916      TmpInst.setOpcode(ARM::tMOVtgpr2gpr);
1917      TmpInst.addOperand(MCOperand::CreateReg(ARM::SP));
1918      TmpInst.addOperand(MCOperand::CreateReg(ScratchReg));
1919      // Predicate.
1920      TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL));
1921      TmpInst.addOperand(MCOperand::CreateReg(0));
1922      OutStreamer.EmitInstruction(TmpInst);
1923    }
1924    {
1925      MCInst TmpInst;
1926      TmpInst.setOpcode(ARM::tLDR);
1927      TmpInst.addOperand(MCOperand::CreateReg(ScratchReg));
1928      TmpInst.addOperand(MCOperand::CreateReg(SrcReg));
1929      TmpInst.addOperand(MCOperand::CreateImm(1));
1930      TmpInst.addOperand(MCOperand::CreateReg(0));
1931      // Predicate.
1932      TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL));
1933      TmpInst.addOperand(MCOperand::CreateReg(0));
1934      OutStreamer.EmitInstruction(TmpInst);
1935    }
1936    {
1937      MCInst TmpInst;
1938      TmpInst.setOpcode(ARM::tLDR);
1939      TmpInst.addOperand(MCOperand::CreateReg(ARM::R7));
1940      TmpInst.addOperand(MCOperand::CreateReg(SrcReg));
1941      TmpInst.addOperand(MCOperand::CreateImm(0));
1942      TmpInst.addOperand(MCOperand::CreateReg(0));
1943      // Predicate.
1944      TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL));
1945      TmpInst.addOperand(MCOperand::CreateReg(0));
1946      OutStreamer.EmitInstruction(TmpInst);
1947    }
1948    {
1949      MCInst TmpInst;
1950      TmpInst.setOpcode(ARM::tBX_RET_vararg);
1951      TmpInst.addOperand(MCOperand::CreateReg(ScratchReg));
1952      // Predicate.
1953      TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL));
1954      TmpInst.addOperand(MCOperand::CreateReg(0));
1955      OutStreamer.EmitInstruction(TmpInst);
1956    }
1957    return;
1958  }
1959  }
1960
1961  MCInst TmpInst;
1962  MCInstLowering.Lower(MI, TmpInst);
1963  OutStreamer.EmitInstruction(TmpInst);
1964}
1965
1966//===----------------------------------------------------------------------===//
1967// Target Registry Stuff
1968//===----------------------------------------------------------------------===//
1969
1970static MCInstPrinter *createARMMCInstPrinter(const Target &T,
1971                                             unsigned SyntaxVariant,
1972                                             const MCAsmInfo &MAI) {
1973  if (SyntaxVariant == 0)
1974    return new ARMInstPrinter(MAI);
1975  return 0;
1976}
1977
1978// Force static initialization.
1979extern "C" void LLVMInitializeARMAsmPrinter() {
1980  RegisterAsmPrinter<ARMAsmPrinter> X(TheARMTarget);
1981  RegisterAsmPrinter<ARMAsmPrinter> Y(TheThumbTarget);
1982
1983  TargetRegistry::RegisterMCInstPrinter(TheARMTarget, createARMMCInstPrinter);
1984  TargetRegistry::RegisterMCInstPrinter(TheThumbTarget, createARMMCInstPrinter);
1985}
1986
1987