1212793Sdim//===-- ARMAsmPrinter.cpp - Print machine code to an ARM .s file ----------===//
2212793Sdim//
3212793Sdim//                     The LLVM Compiler Infrastructure
4212793Sdim//
5212793Sdim// This file is distributed under the University of Illinois Open Source
6212793Sdim// License. See LICENSE.TXT for details.
7212793Sdim//
8212793Sdim//===----------------------------------------------------------------------===//
9212793Sdim//
10212793Sdim// This file contains a printer that converts from our internal representation
11212793Sdim// of machine-dependent LLVM code to GAS-format ARM assembly language.
12212793Sdim//
13212793Sdim//===----------------------------------------------------------------------===//
14212793Sdim
15212793Sdim#define DEBUG_TYPE "asm-printer"
16234353Sdim#include "ARMAsmPrinter.h"
17212793Sdim#include "ARM.h"
18212793Sdim#include "ARMBuildAttrs.h"
19212793Sdim#include "ARMConstantPoolValue.h"
20212793Sdim#include "ARMMachineFunctionInfo.h"
21212793Sdim#include "ARMTargetMachine.h"
22218893Sdim#include "ARMTargetObjectFile.h"
23218893Sdim#include "InstPrinter/ARMInstPrinter.h"
24226633Sdim#include "MCTargetDesc/ARMAddressingModes.h"
25226633Sdim#include "MCTargetDesc/ARMMCExpr.h"
26243830Sdim#include "llvm/ADT/SetVector.h"
27243830Sdim#include "llvm/ADT/SmallString.h"
28212793Sdim#include "llvm/Assembly/Writer.h"
29212793Sdim#include "llvm/CodeGen/MachineFunctionPass.h"
30212793Sdim#include "llvm/CodeGen/MachineJumpTableInfo.h"
31249423Sdim#include "llvm/CodeGen/MachineModuleInfoImpls.h"
32249423Sdim#include "llvm/DebugInfo.h"
33249423Sdim#include "llvm/IR/Constants.h"
34249423Sdim#include "llvm/IR/DataLayout.h"
35249423Sdim#include "llvm/IR/Module.h"
36249423Sdim#include "llvm/IR/Type.h"
37212793Sdim#include "llvm/MC/MCAsmInfo.h"
38218893Sdim#include "llvm/MC/MCAssembler.h"
39212793Sdim#include "llvm/MC/MCContext.h"
40249423Sdim#include "llvm/MC/MCELFStreamer.h"
41212793Sdim#include "llvm/MC/MCInst.h"
42249423Sdim#include "llvm/MC/MCInstBuilder.h"
43249423Sdim#include "llvm/MC/MCObjectStreamer.h"
44212793Sdim#include "llvm/MC/MCSectionMachO.h"
45212793Sdim#include "llvm/MC/MCStreamer.h"
46212793Sdim#include "llvm/MC/MCSymbol.h"
47212793Sdim#include "llvm/Support/CommandLine.h"
48212793Sdim#include "llvm/Support/Debug.h"
49249423Sdim#include "llvm/Support/ELF.h"
50212793Sdim#include "llvm/Support/ErrorHandling.h"
51226633Sdim#include "llvm/Support/TargetRegistry.h"
52212793Sdim#include "llvm/Support/raw_ostream.h"
53249423Sdim#include "llvm/Target/Mangler.h"
54249423Sdim#include "llvm/Target/TargetMachine.h"
55212793Sdim#include <cctype>
56212793Sdimusing namespace llvm;
57212793Sdim
58212793Sdimnamespace {
59212793Sdim
60218893Sdim  // Per section and per symbol attributes are not supported.
61218893Sdim  // To implement them we would need the ability to delay this emission
62218893Sdim  // until the assembly file is fully parsed/generated as only then do we
63218893Sdim  // know the symbol and section numbers.
64218893Sdim  class AttributeEmitter {
65218893Sdim  public:
66218893Sdim    virtual void MaybeSwitchVendor(StringRef Vendor) = 0;
67218893Sdim    virtual void EmitAttribute(unsigned Attribute, unsigned Value) = 0;
68218893Sdim    virtual void EmitTextAttribute(unsigned Attribute, StringRef String) = 0;
69218893Sdim    virtual void Finish() = 0;
70218893Sdim    virtual ~AttributeEmitter() {}
71218893Sdim  };
72212793Sdim
73218893Sdim  class AsmAttributeEmitter : public AttributeEmitter {
74218893Sdim    MCStreamer &Streamer;
75212793Sdim
76218893Sdim  public:
77218893Sdim    AsmAttributeEmitter(MCStreamer &Streamer_) : Streamer(Streamer_) {}
78218893Sdim    void MaybeSwitchVendor(StringRef Vendor) { }
79212793Sdim
80218893Sdim    void EmitAttribute(unsigned Attribute, unsigned Value) {
81218893Sdim      Streamer.EmitRawText("\t.eabi_attribute " +
82218893Sdim                           Twine(Attribute) + ", " + Twine(Value));
83212793Sdim    }
84212793Sdim
85218893Sdim    void EmitTextAttribute(unsigned Attribute, StringRef String) {
86218893Sdim      switch (Attribute) {
87234353Sdim      default: llvm_unreachable("Unsupported Text attribute in ASM Mode");
88218893Sdim      case ARMBuildAttrs::CPU_name:
89234353Sdim        Streamer.EmitRawText(StringRef("\t.cpu ") + String.lower());
90218893Sdim        break;
91221345Sdim      /* GAS requires .fpu to be emitted regardless of EABI attribute */
92221345Sdim      case ARMBuildAttrs::Advanced_SIMD_arch:
93221345Sdim      case ARMBuildAttrs::VFP_arch:
94234353Sdim        Streamer.EmitRawText(StringRef("\t.fpu ") + String.lower());
95226633Sdim        break;
96218893Sdim      }
97212793Sdim    }
98218893Sdim    void Finish() { }
99218893Sdim  };
100212793Sdim
101218893Sdim  class ObjectAttributeEmitter : public AttributeEmitter {
102226633Sdim    // This structure holds all attributes, accounting for
103226633Sdim    // their string/numeric value, so we can later emmit them
104226633Sdim    // in declaration order, keeping all in the same vector
105226633Sdim    struct AttributeItemType {
106226633Sdim      enum {
107226633Sdim        HiddenAttribute = 0,
108226633Sdim        NumericAttribute,
109226633Sdim        TextAttribute
110226633Sdim      } Type;
111226633Sdim      unsigned Tag;
112226633Sdim      unsigned IntValue;
113226633Sdim      StringRef StringValue;
114226633Sdim    } AttributeItem;
115226633Sdim
116218893Sdim    MCObjectStreamer &Streamer;
117218893Sdim    StringRef CurrentVendor;
118226633Sdim    SmallVector<AttributeItemType, 64> Contents;
119212793Sdim
120226633Sdim    // Account for the ULEB/String size of each item,
121226633Sdim    // not just the number of items
122226633Sdim    size_t ContentsSize;
123226633Sdim    // FIXME: this should be in a more generic place, but
124226633Sdim    // getULEBSize() is in MCAsmInfo and will be moved to MCDwarf
125226633Sdim    size_t getULEBSize(int Value) {
126226633Sdim      size_t Size = 0;
127226633Sdim      do {
128226633Sdim        Value >>= 7;
129226633Sdim        Size += sizeof(int8_t); // Is this really necessary?
130226633Sdim      } while (Value);
131226633Sdim      return Size;
132226633Sdim    }
133226633Sdim
134218893Sdim  public:
135218893Sdim    ObjectAttributeEmitter(MCObjectStreamer &Streamer_) :
136226633Sdim      Streamer(Streamer_), CurrentVendor(""), ContentsSize(0) { }
137212793Sdim
138218893Sdim    void MaybeSwitchVendor(StringRef Vendor) {
139218893Sdim      assert(!Vendor.empty() && "Vendor cannot be empty.");
140212793Sdim
141218893Sdim      if (CurrentVendor.empty())
142218893Sdim        CurrentVendor = Vendor;
143218893Sdim      else if (CurrentVendor == Vendor)
144218893Sdim        return;
145218893Sdim      else
146218893Sdim        Finish();
147212793Sdim
148218893Sdim      CurrentVendor = Vendor;
149212793Sdim
150218893Sdim      assert(Contents.size() == 0);
151218893Sdim    }
152212793Sdim
153218893Sdim    void EmitAttribute(unsigned Attribute, unsigned Value) {
154226633Sdim      AttributeItemType attr = {
155226633Sdim        AttributeItemType::NumericAttribute,
156226633Sdim        Attribute,
157226633Sdim        Value,
158226633Sdim        StringRef("")
159226633Sdim      };
160226633Sdim      ContentsSize += getULEBSize(Attribute);
161226633Sdim      ContentsSize += getULEBSize(Value);
162226633Sdim      Contents.push_back(attr);
163212793Sdim    }
164212793Sdim
165218893Sdim    void EmitTextAttribute(unsigned Attribute, StringRef String) {
166226633Sdim      AttributeItemType attr = {
167226633Sdim        AttributeItemType::TextAttribute,
168226633Sdim        Attribute,
169226633Sdim        0,
170226633Sdim        String
171226633Sdim      };
172226633Sdim      ContentsSize += getULEBSize(Attribute);
173226633Sdim      // String + \0
174226633Sdim      ContentsSize += String.size()+1;
175226633Sdim
176226633Sdim      Contents.push_back(attr);
177212793Sdim    }
178212793Sdim
179218893Sdim    void Finish() {
180218893Sdim      // Vendor size + Vendor name + '\0'
181218893Sdim      const size_t VendorHeaderSize = 4 + CurrentVendor.size() + 1;
182212793Sdim
183218893Sdim      // Tag + Tag Size
184218893Sdim      const size_t TagHeaderSize = 1 + 4;
185212793Sdim
186218893Sdim      Streamer.EmitIntValue(VendorHeaderSize + TagHeaderSize + ContentsSize, 4);
187249423Sdim      Streamer.EmitBytes(CurrentVendor);
188218893Sdim      Streamer.EmitIntValue(0, 1); // '\0'
189212793Sdim
190218893Sdim      Streamer.EmitIntValue(ARMBuildAttrs::File, 1);
191218893Sdim      Streamer.EmitIntValue(TagHeaderSize + ContentsSize, 4);
192212793Sdim
193226633Sdim      // Size should have been accounted for already, now
194226633Sdim      // emit each field as its type (ULEB or String)
195226633Sdim      for (unsigned int i=0; i<Contents.size(); ++i) {
196226633Sdim        AttributeItemType item = Contents[i];
197249423Sdim        Streamer.EmitULEB128IntValue(item.Tag);
198226633Sdim        switch (item.Type) {
199234353Sdim        default: llvm_unreachable("Invalid attribute type");
200226633Sdim        case AttributeItemType::NumericAttribute:
201249423Sdim          Streamer.EmitULEB128IntValue(item.IntValue);
202226633Sdim          break;
203226633Sdim        case AttributeItemType::TextAttribute:
204249423Sdim          Streamer.EmitBytes(item.StringValue.upper());
205226633Sdim          Streamer.EmitIntValue(0, 1); // '\0'
206226633Sdim          break;
207226633Sdim        }
208226633Sdim      }
209212793Sdim
210218893Sdim      Contents.clear();
211212793Sdim    }
212212793Sdim  };
213218893Sdim
214212793Sdim} // end of anonymous namespace
215212793Sdim
216218893SdimMachineLocation ARMAsmPrinter::
217218893SdimgetDebugValueLocation(const MachineInstr *MI) const {
218218893Sdim  MachineLocation Location;
219218893Sdim  assert(MI->getNumOperands() == 4 && "Invalid no. of machine operands!");
220218893Sdim  // Frame address.  Currently handles register +- offset only.
221218893Sdim  if (MI->getOperand(0).isReg() && MI->getOperand(1).isImm())
222218893Sdim    Location.set(MI->getOperand(0).getReg(), MI->getOperand(1).getImm());
223218893Sdim  else {
224218893Sdim    DEBUG(dbgs() << "DBG_VALUE instruction ignored! " << *MI << "\n");
225218893Sdim  }
226218893Sdim  return Location;
227218893Sdim}
228212793Sdim
229221345Sdim/// EmitDwarfRegOp - Emit dwarf register operation.
230221345Sdimvoid ARMAsmPrinter::EmitDwarfRegOp(const MachineLocation &MLoc) const {
231221345Sdim  const TargetRegisterInfo *RI = TM.getRegisterInfo();
232221345Sdim  if (RI->getDwarfRegNum(MLoc.getReg(), false) != -1)
233221345Sdim    AsmPrinter::EmitDwarfRegOp(MLoc);
234221345Sdim  else {
235221345Sdim    unsigned Reg = MLoc.getReg();
236221345Sdim    if (Reg >= ARM::S0 && Reg <= ARM::S31) {
237221345Sdim      assert(ARM::S0 + 31 == ARM::S31 && "Unexpected ARM S register numbering");
238221345Sdim      // S registers are described as bit-pieces of a register
239221345Sdim      // S[2x] = DW_OP_regx(256 + (x>>1)) DW_OP_bit_piece(32, 0)
240221345Sdim      // S[2x+1] = DW_OP_regx(256 + (x>>1)) DW_OP_bit_piece(32, 32)
241226633Sdim
242221345Sdim      unsigned SReg = Reg - ARM::S0;
243221345Sdim      bool odd = SReg & 0x1;
244221345Sdim      unsigned Rx = 256 + (SReg >> 1);
245221345Sdim
246221345Sdim      OutStreamer.AddComment("DW_OP_regx for S register");
247221345Sdim      EmitInt8(dwarf::DW_OP_regx);
248221345Sdim
249221345Sdim      OutStreamer.AddComment(Twine(SReg));
250221345Sdim      EmitULEB128(Rx);
251221345Sdim
252221345Sdim      if (odd) {
253221345Sdim        OutStreamer.AddComment("DW_OP_bit_piece 32 32");
254221345Sdim        EmitInt8(dwarf::DW_OP_bit_piece);
255221345Sdim        EmitULEB128(32);
256221345Sdim        EmitULEB128(32);
257221345Sdim      } else {
258221345Sdim        OutStreamer.AddComment("DW_OP_bit_piece 32 0");
259221345Sdim        EmitInt8(dwarf::DW_OP_bit_piece);
260221345Sdim        EmitULEB128(32);
261221345Sdim        EmitULEB128(0);
262221345Sdim      }
263221345Sdim    } else if (Reg >= ARM::Q0 && Reg <= ARM::Q15) {
264221345Sdim      assert(ARM::Q0 + 15 == ARM::Q15 && "Unexpected ARM Q register numbering");
265221345Sdim      // Q registers Q0-Q15 are described by composing two D registers together.
266226633Sdim      // Qx = DW_OP_regx(256+2x) DW_OP_piece(8) DW_OP_regx(256+2x+1)
267226633Sdim      // DW_OP_piece(8)
268221345Sdim
269221345Sdim      unsigned QReg = Reg - ARM::Q0;
270221345Sdim      unsigned D1 = 256 + 2 * QReg;
271221345Sdim      unsigned D2 = D1 + 1;
272226633Sdim
273221345Sdim      OutStreamer.AddComment("DW_OP_regx for Q register: D1");
274221345Sdim      EmitInt8(dwarf::DW_OP_regx);
275221345Sdim      EmitULEB128(D1);
276221345Sdim      OutStreamer.AddComment("DW_OP_piece 8");
277221345Sdim      EmitInt8(dwarf::DW_OP_piece);
278221345Sdim      EmitULEB128(8);
279221345Sdim
280221345Sdim      OutStreamer.AddComment("DW_OP_regx for Q register: D2");
281221345Sdim      EmitInt8(dwarf::DW_OP_regx);
282221345Sdim      EmitULEB128(D2);
283221345Sdim      OutStreamer.AddComment("DW_OP_piece 8");
284221345Sdim      EmitInt8(dwarf::DW_OP_piece);
285221345Sdim      EmitULEB128(8);
286221345Sdim    }
287221345Sdim  }
288221345Sdim}
289221345Sdim
290239462Sdimvoid ARMAsmPrinter::EmitFunctionBodyEnd() {
291239462Sdim  // Make sure to terminate any constant pools that were at the end
292239462Sdim  // of the function.
293239462Sdim  if (!InConstantPool)
294239462Sdim    return;
295239462Sdim  InConstantPool = false;
296239462Sdim  OutStreamer.EmitDataRegion(MCDR_DataRegionEnd);
297239462Sdim}
298239462Sdim
299212793Sdimvoid ARMAsmPrinter::EmitFunctionEntryLabel() {
300212793Sdim  if (AFI->isThumbFunction()) {
301218893Sdim    OutStreamer.EmitAssemblerFlag(MCAF_Code16);
302223017Sdim    OutStreamer.EmitThumbFunc(CurrentFnSym);
303212793Sdim  }
304212793Sdim
305212793Sdim  OutStreamer.EmitLabel(CurrentFnSym);
306212793Sdim}
307212793Sdim
308234353Sdimvoid ARMAsmPrinter::EmitXXStructor(const Constant *CV) {
309243830Sdim  uint64_t Size = TM.getDataLayout()->getTypeAllocSize(CV->getType());
310234353Sdim  assert(Size && "C++ constructor pointer had zero size!");
311234353Sdim
312234353Sdim  const GlobalValue *GV = dyn_cast<GlobalValue>(CV->stripPointerCasts());
313234353Sdim  assert(GV && "C++ constructor pointer was not a GlobalValue!");
314234353Sdim
315234353Sdim  const MCExpr *E = MCSymbolRefExpr::Create(Mang->getSymbol(GV),
316234353Sdim                                            (Subtarget->isTargetDarwin()
317234353Sdim                                             ? MCSymbolRefExpr::VK_None
318234353Sdim                                             : MCSymbolRefExpr::VK_ARM_TARGET1),
319234353Sdim                                            OutContext);
320234353Sdim
321234353Sdim  OutStreamer.EmitValue(E, Size);
322234353Sdim}
323234353Sdim
324218893Sdim/// runOnMachineFunction - This uses the EmitInstruction()
325212793Sdim/// method to print assembly for each instruction.
326212793Sdim///
327212793Sdimbool ARMAsmPrinter::runOnMachineFunction(MachineFunction &MF) {
328212793Sdim  AFI = MF.getInfo<ARMFunctionInfo>();
329212793Sdim  MCP = MF.getConstantPool();
330212793Sdim
331212793Sdim  return AsmPrinter::runOnMachineFunction(MF);
332212793Sdim}
333212793Sdim
334212793Sdimvoid ARMAsmPrinter::printOperand(const MachineInstr *MI, int OpNum,
335212793Sdim                                 raw_ostream &O, const char *Modifier) {
336212793Sdim  const MachineOperand &MO = MI->getOperand(OpNum);
337212793Sdim  unsigned TF = MO.getTargetFlags();
338212793Sdim
339212793Sdim  switch (MO.getType()) {
340234353Sdim  default: llvm_unreachable("<unknown operand type>");
341212793Sdim  case MachineOperand::MO_Register: {
342212793Sdim    unsigned Reg = MO.getReg();
343212793Sdim    assert(TargetRegisterInfo::isPhysicalRegister(Reg));
344218893Sdim    assert(!MO.getSubReg() && "Subregs should be eliminated!");
345249423Sdim    if(ARM::GPRPairRegClass.contains(Reg)) {
346249423Sdim      const MachineFunction &MF = *MI->getParent()->getParent();
347249423Sdim      const TargetRegisterInfo *TRI = MF.getTarget().getRegisterInfo();
348249423Sdim      Reg = TRI->getSubReg(Reg, ARM::gsub_0);
349249423Sdim    }
350218893Sdim    O << ARMInstPrinter::getRegisterName(Reg);
351212793Sdim    break;
352212793Sdim  }
353212793Sdim  case MachineOperand::MO_Immediate: {
354212793Sdim    int64_t Imm = MO.getImm();
355212793Sdim    O << '#';
356212793Sdim    if ((Modifier && strcmp(Modifier, "lo16") == 0) ||
357218893Sdim        (TF == ARMII::MO_LO16))
358212793Sdim      O << ":lower16:";
359212793Sdim    else if ((Modifier && strcmp(Modifier, "hi16") == 0) ||
360218893Sdim             (TF == ARMII::MO_HI16))
361212793Sdim      O << ":upper16:";
362212793Sdim    O << Imm;
363212793Sdim    break;
364212793Sdim  }
365212793Sdim  case MachineOperand::MO_MachineBasicBlock:
366212793Sdim    O << *MO.getMBB()->getSymbol();
367212793Sdim    return;
368212793Sdim  case MachineOperand::MO_GlobalAddress: {
369212793Sdim    const GlobalValue *GV = MO.getGlobal();
370212793Sdim    if ((Modifier && strcmp(Modifier, "lo16") == 0) ||
371212793Sdim        (TF & ARMII::MO_LO16))
372212793Sdim      O << ":lower16:";
373212793Sdim    else if ((Modifier && strcmp(Modifier, "hi16") == 0) ||
374212793Sdim             (TF & ARMII::MO_HI16))
375212793Sdim      O << ":upper16:";
376212793Sdim    O << *Mang->getSymbol(GV);
377212793Sdim
378212793Sdim    printOffset(MO.getOffset(), O);
379218893Sdim    if (TF == ARMII::MO_PLT)
380212793Sdim      O << "(PLT)";
381212793Sdim    break;
382212793Sdim  }
383212793Sdim  case MachineOperand::MO_ExternalSymbol: {
384212793Sdim    O << *GetExternalSymbolSymbol(MO.getSymbolName());
385218893Sdim    if (TF == ARMII::MO_PLT)
386212793Sdim      O << "(PLT)";
387212793Sdim    break;
388212793Sdim  }
389212793Sdim  case MachineOperand::MO_ConstantPoolIndex:
390212793Sdim    O << *GetCPISymbol(MO.getIndex());
391212793Sdim    break;
392212793Sdim  case MachineOperand::MO_JumpTableIndex:
393212793Sdim    O << *GetJTISymbol(MO.getIndex());
394212793Sdim    break;
395212793Sdim  }
396212793Sdim}
397212793Sdim
398212793Sdim//===--------------------------------------------------------------------===//
399212793Sdim
400212793SdimMCSymbol *ARMAsmPrinter::
401212793SdimGetARMJTIPICJumpTableLabel2(unsigned uid, unsigned uid2) const {
402212793Sdim  SmallString<60> Name;
403212793Sdim  raw_svector_ostream(Name) << MAI->getPrivateGlobalPrefix() << "JTI"
404212793Sdim    << getFunctionNumber() << '_' << uid << '_' << uid2;
405212793Sdim  return OutContext.GetOrCreateSymbol(Name.str());
406212793Sdim}
407212793Sdim
408212793Sdim
409249423SdimMCSymbol *ARMAsmPrinter::GetARMSJLJEHLabel() const {
410218893Sdim  SmallString<60> Name;
411218893Sdim  raw_svector_ostream(Name) << MAI->getPrivateGlobalPrefix() << "SJLJEH"
412218893Sdim    << getFunctionNumber();
413218893Sdim  return OutContext.GetOrCreateSymbol(Name.str());
414212793Sdim}
415212793Sdim
416212793Sdimbool ARMAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNum,
417212793Sdim                                    unsigned AsmVariant, const char *ExtraCode,
418212793Sdim                                    raw_ostream &O) {
419212793Sdim  // Does this asm operand have a single letter operand modifier?
420212793Sdim  if (ExtraCode && ExtraCode[0]) {
421212793Sdim    if (ExtraCode[1] != 0) return true; // Unknown modifier.
422212793Sdim
423212793Sdim    switch (ExtraCode[0]) {
424239462Sdim    default:
425239462Sdim      // See if this is a generic print operand
426239462Sdim      return AsmPrinter::PrintAsmOperand(MI, OpNum, AsmVariant, ExtraCode, O);
427212793Sdim    case 'a': // Print as a memory address.
428212793Sdim      if (MI->getOperand(OpNum).isReg()) {
429218893Sdim        O << "["
430218893Sdim          << ARMInstPrinter::getRegisterName(MI->getOperand(OpNum).getReg())
431218893Sdim          << "]";
432212793Sdim        return false;
433212793Sdim      }
434212793Sdim      // Fallthrough
435212793Sdim    case 'c': // Don't print "#" before an immediate operand.
436212793Sdim      if (!MI->getOperand(OpNum).isImm())
437212793Sdim        return true;
438218893Sdim      O << MI->getOperand(OpNum).getImm();
439212793Sdim      return false;
440212793Sdim    case 'P': // Print a VFP double precision register.
441212793Sdim    case 'q': // Print a NEON quad precision register.
442212793Sdim      printOperand(MI, OpNum, O);
443212793Sdim      return false;
444223017Sdim    case 'y': // Print a VFP single precision register as indexed double.
445223017Sdim      if (MI->getOperand(OpNum).isReg()) {
446223017Sdim        unsigned Reg = MI->getOperand(OpNum).getReg();
447223017Sdim        const TargetRegisterInfo *TRI = MF->getTarget().getRegisterInfo();
448239462Sdim        // Find the 'd' register that has this 's' register as a sub-register,
449239462Sdim        // and determine the lane number.
450239462Sdim        for (MCSuperRegIterator SR(Reg, TRI); SR.isValid(); ++SR) {
451239462Sdim          if (!ARM::DPRRegClass.contains(*SR))
452239462Sdim            continue;
453239462Sdim          bool Lane0 = TRI->getSubReg(*SR, ARM::ssub_0) == Reg;
454239462Sdim          O << ARMInstPrinter::getRegisterName(*SR) << (Lane0 ? "[0]" : "[1]");
455239462Sdim          return false;
456239462Sdim        }
457223017Sdim      }
458212793Sdim      return true;
459223017Sdim    case 'B': // Bitwise inverse of integer or symbol without a preceding #.
460223017Sdim      if (!MI->getOperand(OpNum).isImm())
461223017Sdim        return true;
462223017Sdim      O << ~(MI->getOperand(OpNum).getImm());
463223017Sdim      return false;
464223017Sdim    case 'L': // The low 16 bits of an immediate constant.
465223017Sdim      if (!MI->getOperand(OpNum).isImm())
466223017Sdim        return true;
467223017Sdim      O << (MI->getOperand(OpNum).getImm() & 0xffff);
468223017Sdim      return false;
469223017Sdim    case 'M': { // A register range suitable for LDM/STM.
470223017Sdim      if (!MI->getOperand(OpNum).isReg())
471223017Sdim        return true;
472223017Sdim      const MachineOperand &MO = MI->getOperand(OpNum);
473223017Sdim      unsigned RegBegin = MO.getReg();
474223017Sdim      // This takes advantage of the 2 operand-ness of ldm/stm and that we've
475223017Sdim      // already got the operands in registers that are operands to the
476223017Sdim      // inline asm statement.
477226633Sdim
478223017Sdim      O << "{" << ARMInstPrinter::getRegisterName(RegBegin);
479226633Sdim
480223017Sdim      // FIXME: The register allocator not only may not have given us the
481223017Sdim      // registers in sequence, but may not be in ascending registers. This
482223017Sdim      // will require changes in the register allocator that'll need to be
483223017Sdim      // propagated down here if the operands change.
484223017Sdim      unsigned RegOps = OpNum + 1;
485223017Sdim      while (MI->getOperand(RegOps).isReg()) {
486226633Sdim        O << ", "
487223017Sdim          << ARMInstPrinter::getRegisterName(MI->getOperand(RegOps).getReg());
488223017Sdim        RegOps++;
489223017Sdim      }
490223017Sdim
491223017Sdim      O << "}";
492223017Sdim
493223017Sdim      return false;
494212793Sdim    }
495226633Sdim    case 'R': // The most significant register of a pair.
496226633Sdim    case 'Q': { // The least significant register of a pair.
497226633Sdim      if (OpNum == 0)
498226633Sdim        return true;
499226633Sdim      const MachineOperand &FlagsOP = MI->getOperand(OpNum - 1);
500226633Sdim      if (!FlagsOP.isImm())
501226633Sdim        return true;
502226633Sdim      unsigned Flags = FlagsOP.getImm();
503226633Sdim      unsigned NumVals = InlineAsm::getNumOperandRegisters(Flags);
504226633Sdim      if (NumVals != 2)
505226633Sdim        return true;
506226633Sdim      unsigned RegOp = ExtraCode[0] == 'Q' ? OpNum : OpNum + 1;
507226633Sdim      if (RegOp >= MI->getNumOperands())
508226633Sdim        return true;
509226633Sdim      const MachineOperand &MO = MI->getOperand(RegOp);
510226633Sdim      if (!MO.isReg())
511226633Sdim        return true;
512226633Sdim      unsigned Reg = MO.getReg();
513226633Sdim      O << ARMInstPrinter::getRegisterName(Reg);
514226633Sdim      return false;
515226633Sdim    }
516226633Sdim
517234353Sdim    case 'e': // The low doubleword register of a NEON quad register.
518234353Sdim    case 'f': { // The high doubleword register of a NEON quad register.
519234353Sdim      if (!MI->getOperand(OpNum).isReg())
520234353Sdim        return true;
521234353Sdim      unsigned Reg = MI->getOperand(OpNum).getReg();
522234353Sdim      if (!ARM::QPRRegClass.contains(Reg))
523234353Sdim        return true;
524234353Sdim      const TargetRegisterInfo *TRI = MF->getTarget().getRegisterInfo();
525234353Sdim      unsigned SubReg = TRI->getSubReg(Reg, ExtraCode[0] == 'e' ?
526234353Sdim                                       ARM::dsub_0 : ARM::dsub_1);
527234353Sdim      O << ARMInstPrinter::getRegisterName(SubReg);
528234353Sdim      return false;
529234353Sdim    }
530234353Sdim
531239462Sdim    // This modifier is not yet supported.
532223017Sdim    case 'h': // A range of VFP/NEON registers suitable for VLD1/VST1.
533223017Sdim      return true;
534239462Sdim    case 'H': { // The highest-numbered register of a pair.
535239462Sdim      const MachineOperand &MO = MI->getOperand(OpNum);
536239462Sdim      if (!MO.isReg())
537239462Sdim        return true;
538239462Sdim      const MachineFunction &MF = *MI->getParent()->getParent();
539239462Sdim      const TargetRegisterInfo *TRI = MF.getTarget().getRegisterInfo();
540249423Sdim      unsigned Reg = MO.getReg();
541249423Sdim      if(!ARM::GPRPairRegClass.contains(Reg))
542249423Sdim        return false;
543249423Sdim      Reg = TRI->getSubReg(Reg, ARM::gsub_1);
544239462Sdim      O << ARMInstPrinter::getRegisterName(Reg);
545239462Sdim      return false;
546223017Sdim    }
547239462Sdim    }
548212793Sdim  }
549212793Sdim
550212793Sdim  printOperand(MI, OpNum, O);
551212793Sdim  return false;
552212793Sdim}
553212793Sdim
554212793Sdimbool ARMAsmPrinter::PrintAsmMemoryOperand(const MachineInstr *MI,
555212793Sdim                                          unsigned OpNum, unsigned AsmVariant,
556212793Sdim                                          const char *ExtraCode,
557212793Sdim                                          raw_ostream &O) {
558223017Sdim  // Does this asm operand have a single letter operand modifier?
559223017Sdim  if (ExtraCode && ExtraCode[0]) {
560223017Sdim    if (ExtraCode[1] != 0) return true; // Unknown modifier.
561226633Sdim
562223017Sdim    switch (ExtraCode[0]) {
563223017Sdim      case 'A': // A memory operand for a VLD1/VST1 instruction.
564223017Sdim      default: return true;  // Unknown modifier.
565223017Sdim      case 'm': // The base register of a memory operand.
566223017Sdim        if (!MI->getOperand(OpNum).isReg())
567223017Sdim          return true;
568223017Sdim        O << ARMInstPrinter::getRegisterName(MI->getOperand(OpNum).getReg());
569223017Sdim        return false;
570223017Sdim    }
571223017Sdim  }
572226633Sdim
573212793Sdim  const MachineOperand &MO = MI->getOperand(OpNum);
574212793Sdim  assert(MO.isReg() && "unexpected inline asm memory operand");
575218893Sdim  O << "[" << ARMInstPrinter::getRegisterName(MO.getReg()) << "]";
576212793Sdim  return false;
577212793Sdim}
578212793Sdim
579212793Sdimvoid ARMAsmPrinter::EmitStartOfAsmFile(Module &M) {
580212793Sdim  if (Subtarget->isTargetDarwin()) {
581212793Sdim    Reloc::Model RelocM = TM.getRelocationModel();
582212793Sdim    if (RelocM == Reloc::PIC_ || RelocM == Reloc::DynamicNoPIC) {
583212793Sdim      // Declare all the text sections up front (before the DWARF sections
584212793Sdim      // emitted by AsmPrinter::doInitialization) so the assembler will keep
585212793Sdim      // them together at the beginning of the object file.  This helps
586212793Sdim      // avoid out-of-range branches that are due a fundamental limitation of
587212793Sdim      // the way symbol offsets are encoded with the current Darwin ARM
588212793Sdim      // relocations.
589212793Sdim      const TargetLoweringObjectFileMachO &TLOFMacho =
590212793Sdim        static_cast<const TargetLoweringObjectFileMachO &>(
591212793Sdim          getObjFileLowering());
592243830Sdim
593243830Sdim      // Collect the set of sections our functions will go into.
594243830Sdim      SetVector<const MCSection *, SmallVector<const MCSection *, 8>,
595243830Sdim        SmallPtrSet<const MCSection *, 8> > TextSections;
596243830Sdim      // Default text section comes first.
597243830Sdim      TextSections.insert(TLOFMacho.getTextSection());
598243830Sdim      // Now any user defined text sections from function attributes.
599243830Sdim      for (Module::iterator F = M.begin(), e = M.end(); F != e; ++F)
600243830Sdim        if (!F->isDeclaration() && !F->hasAvailableExternallyLinkage())
601243830Sdim          TextSections.insert(TLOFMacho.SectionForGlobal(F, Mang, TM));
602243830Sdim      // Now the coalescable sections.
603243830Sdim      TextSections.insert(TLOFMacho.getTextCoalSection());
604243830Sdim      TextSections.insert(TLOFMacho.getConstTextCoalSection());
605243830Sdim
606243830Sdim      // Emit the sections in the .s file header to fix the order.
607243830Sdim      for (unsigned i = 0, e = TextSections.size(); i != e; ++i)
608243830Sdim        OutStreamer.SwitchSection(TextSections[i]);
609243830Sdim
610212793Sdim      if (RelocM == Reloc::DynamicNoPIC) {
611212793Sdim        const MCSection *sect =
612212793Sdim          OutContext.getMachOSection("__TEXT", "__symbol_stub4",
613212793Sdim                                     MCSectionMachO::S_SYMBOL_STUBS,
614212793Sdim                                     12, SectionKind::getText());
615212793Sdim        OutStreamer.SwitchSection(sect);
616212793Sdim      } else {
617212793Sdim        const MCSection *sect =
618212793Sdim          OutContext.getMachOSection("__TEXT", "__picsymbolstub4",
619212793Sdim                                     MCSectionMachO::S_SYMBOL_STUBS,
620212793Sdim                                     16, SectionKind::getText());
621212793Sdim        OutStreamer.SwitchSection(sect);
622212793Sdim      }
623212793Sdim      const MCSection *StaticInitSect =
624212793Sdim        OutContext.getMachOSection("__TEXT", "__StaticInit",
625212793Sdim                                   MCSectionMachO::S_REGULAR |
626212793Sdim                                   MCSectionMachO::S_ATTR_PURE_INSTRUCTIONS,
627212793Sdim                                   SectionKind::getText());
628212793Sdim      OutStreamer.SwitchSection(StaticInitSect);
629212793Sdim    }
630212793Sdim  }
631212793Sdim
632212793Sdim  // Use unified assembler syntax.
633218893Sdim  OutStreamer.EmitAssemblerFlag(MCAF_SyntaxUnified);
634212793Sdim
635212793Sdim  // Emit ARM Build Attributes
636234353Sdim  if (Subtarget->isTargetELF())
637218893Sdim    emitAttributes();
638212793Sdim}
639212793Sdim
640212793Sdim
641212793Sdimvoid ARMAsmPrinter::EmitEndOfAsmFile(Module &M) {
642212793Sdim  if (Subtarget->isTargetDarwin()) {
643212793Sdim    // All darwin targets use mach-o.
644212793Sdim    const TargetLoweringObjectFileMachO &TLOFMacho =
645212793Sdim      static_cast<const TargetLoweringObjectFileMachO &>(getObjFileLowering());
646212793Sdim    MachineModuleInfoMachO &MMIMacho =
647212793Sdim      MMI->getObjFileInfo<MachineModuleInfoMachO>();
648212793Sdim
649212793Sdim    // Output non-lazy-pointers for external and common global variables.
650212793Sdim    MachineModuleInfoMachO::SymbolListTy Stubs = MMIMacho.GetGVStubList();
651212793Sdim
652212793Sdim    if (!Stubs.empty()) {
653212793Sdim      // Switch with ".non_lazy_symbol_pointer" directive.
654212793Sdim      OutStreamer.SwitchSection(TLOFMacho.getNonLazySymbolPointerSection());
655212793Sdim      EmitAlignment(2);
656212793Sdim      for (unsigned i = 0, e = Stubs.size(); i != e; ++i) {
657212793Sdim        // L_foo$stub:
658212793Sdim        OutStreamer.EmitLabel(Stubs[i].first);
659212793Sdim        //   .indirect_symbol _foo
660212793Sdim        MachineModuleInfoImpl::StubValueTy &MCSym = Stubs[i].second;
661212793Sdim        OutStreamer.EmitSymbolAttribute(MCSym.getPointer(),MCSA_IndirectSymbol);
662212793Sdim
663212793Sdim        if (MCSym.getInt())
664212793Sdim          // External to current translation unit.
665249423Sdim          OutStreamer.EmitIntValue(0, 4/*size*/);
666212793Sdim        else
667212793Sdim          // Internal to current translation unit.
668212793Sdim          //
669218893Sdim          // When we place the LSDA into the TEXT section, the type info
670218893Sdim          // pointers need to be indirect and pc-rel. We accomplish this by
671218893Sdim          // using NLPs; however, sometimes the types are local to the file.
672218893Sdim          // We need to fill in the value for the NLP in those cases.
673212793Sdim          OutStreamer.EmitValue(MCSymbolRefExpr::Create(MCSym.getPointer(),
674212793Sdim                                                        OutContext),
675249423Sdim                                4/*size*/);
676212793Sdim      }
677212793Sdim
678212793Sdim      Stubs.clear();
679212793Sdim      OutStreamer.AddBlankLine();
680212793Sdim    }
681212793Sdim
682212793Sdim    Stubs = MMIMacho.GetHiddenGVStubList();
683212793Sdim    if (!Stubs.empty()) {
684212793Sdim      OutStreamer.SwitchSection(getObjFileLowering().getDataSection());
685212793Sdim      EmitAlignment(2);
686212793Sdim      for (unsigned i = 0, e = Stubs.size(); i != e; ++i) {
687212793Sdim        // L_foo$stub:
688212793Sdim        OutStreamer.EmitLabel(Stubs[i].first);
689212793Sdim        //   .long _foo
690212793Sdim        OutStreamer.EmitValue(MCSymbolRefExpr::
691212793Sdim                              Create(Stubs[i].second.getPointer(),
692212793Sdim                                     OutContext),
693249423Sdim                              4/*size*/);
694212793Sdim      }
695212793Sdim
696212793Sdim      Stubs.clear();
697212793Sdim      OutStreamer.AddBlankLine();
698212793Sdim    }
699212793Sdim
700212793Sdim    // Funny Darwin hack: This flag tells the linker that no global symbols
701212793Sdim    // contain code that falls through to other global symbols (e.g. the obvious
702212793Sdim    // implementation of multiple entry points).  If this doesn't occur, the
703212793Sdim    // linker can safely perform dead code stripping.  Since LLVM never
704212793Sdim    // generates code that does this, it is always safe to set.
705212793Sdim    OutStreamer.EmitAssemblerFlag(MCAF_SubsectionsViaSymbols);
706212793Sdim  }
707249423Sdim  // FIXME: This should eventually end up somewhere else where more
708249423Sdim  // intelligent flag decisions can be made. For now we are just maintaining
709249423Sdim  // the status quo for ARM and setting EF_ARM_EABI_VER5 as the default.
710249423Sdim  if (MCELFStreamer *MES = dyn_cast<MCELFStreamer>(&OutStreamer))
711249423Sdim    MES->getAssembler().setELFHeaderEFlags(ELF::EF_ARM_EABI_VER5);
712212793Sdim}
713212793Sdim
714212793Sdim//===----------------------------------------------------------------------===//
715218893Sdim// Helper routines for EmitStartOfAsmFile() and EmitEndOfAsmFile()
716218893Sdim// FIXME:
717218893Sdim// The following seem like one-off assembler flags, but they actually need
718218893Sdim// to appear in the .ARM.attributes section in ELF.
719218893Sdim// Instead of subclassing the MCELFStreamer, we do the work here.
720212793Sdim
721218893Sdimvoid ARMAsmPrinter::emitAttributes() {
722218893Sdim
723218893Sdim  emitARMAttributeSection();
724218893Sdim
725221345Sdim  /* GAS expect .fpu to be emitted, regardless of VFP build attribute */
726221345Sdim  bool emitFPU = false;
727218893Sdim  AttributeEmitter *AttrEmitter;
728221345Sdim  if (OutStreamer.hasRawTextSupport()) {
729218893Sdim    AttrEmitter = new AsmAttributeEmitter(OutStreamer);
730221345Sdim    emitFPU = true;
731221345Sdim  } else {
732218893Sdim    MCObjectStreamer &O = static_cast<MCObjectStreamer&>(OutStreamer);
733218893Sdim    AttrEmitter = new ObjectAttributeEmitter(O);
734218893Sdim  }
735218893Sdim
736218893Sdim  AttrEmitter->MaybeSwitchVendor("aeabi");
737218893Sdim
738218893Sdim  std::string CPUString = Subtarget->getCPUString();
739218893Sdim
740218893Sdim  if (CPUString == "cortex-a8" ||
741218893Sdim      Subtarget->isCortexA8()) {
742218893Sdim    AttrEmitter->EmitTextAttribute(ARMBuildAttrs::CPU_name, "cortex-a8");
743218893Sdim    AttrEmitter->EmitAttribute(ARMBuildAttrs::CPU_arch, ARMBuildAttrs::v7);
744218893Sdim    AttrEmitter->EmitAttribute(ARMBuildAttrs::CPU_arch_profile,
745218893Sdim                               ARMBuildAttrs::ApplicationProfile);
746218893Sdim    AttrEmitter->EmitAttribute(ARMBuildAttrs::ARM_ISA_use,
747218893Sdim                               ARMBuildAttrs::Allowed);
748218893Sdim    AttrEmitter->EmitAttribute(ARMBuildAttrs::THUMB_ISA_use,
749218893Sdim                               ARMBuildAttrs::AllowThumb32);
750218893Sdim    // Fixme: figure out when this is emitted.
751218893Sdim    //AttrEmitter->EmitAttribute(ARMBuildAttrs::WMMX_arch,
752218893Sdim    //                           ARMBuildAttrs::AllowWMMXv1);
753218893Sdim    //
754218893Sdim
755218893Sdim    /// ADD additional Else-cases here!
756223017Sdim  } else if (CPUString == "xscale") {
757223017Sdim    AttrEmitter->EmitAttribute(ARMBuildAttrs::CPU_arch, ARMBuildAttrs::v5TEJ);
758223017Sdim    AttrEmitter->EmitAttribute(ARMBuildAttrs::ARM_ISA_use,
759223017Sdim                               ARMBuildAttrs::Allowed);
760223017Sdim    AttrEmitter->EmitAttribute(ARMBuildAttrs::THUMB_ISA_use,
761223017Sdim                               ARMBuildAttrs::Allowed);
762218893Sdim  } else if (CPUString == "generic") {
763243830Sdim    // For a generic CPU, we assume a standard v7a architecture in Subtarget.
764243830Sdim    AttrEmitter->EmitAttribute(ARMBuildAttrs::CPU_arch, ARMBuildAttrs::v7);
765243830Sdim    AttrEmitter->EmitAttribute(ARMBuildAttrs::CPU_arch_profile,
766243830Sdim                               ARMBuildAttrs::ApplicationProfile);
767218893Sdim    AttrEmitter->EmitAttribute(ARMBuildAttrs::ARM_ISA_use,
768218893Sdim                               ARMBuildAttrs::Allowed);
769218893Sdim    AttrEmitter->EmitAttribute(ARMBuildAttrs::THUMB_ISA_use,
770243830Sdim                               ARMBuildAttrs::AllowThumb32);
771243830Sdim  } else if (Subtarget->hasV7Ops()) {
772243830Sdim    AttrEmitter->EmitAttribute(ARMBuildAttrs::CPU_arch, ARMBuildAttrs::v7);
773243830Sdim    AttrEmitter->EmitAttribute(ARMBuildAttrs::THUMB_ISA_use,
774243830Sdim                               ARMBuildAttrs::AllowThumb32);
775243830Sdim  } else if (Subtarget->hasV6T2Ops())
776243830Sdim    AttrEmitter->EmitAttribute(ARMBuildAttrs::CPU_arch, ARMBuildAttrs::v6T2);
777243830Sdim  else if (Subtarget->hasV6Ops())
778243830Sdim    AttrEmitter->EmitAttribute(ARMBuildAttrs::CPU_arch, ARMBuildAttrs::v6);
779243830Sdim  else if (Subtarget->hasV5TEOps())
780243830Sdim    AttrEmitter->EmitAttribute(ARMBuildAttrs::CPU_arch, ARMBuildAttrs::v5TE);
781243830Sdim  else if (Subtarget->hasV5TOps())
782243830Sdim    AttrEmitter->EmitAttribute(ARMBuildAttrs::CPU_arch, ARMBuildAttrs::v5T);
783243830Sdim  else if (Subtarget->hasV4TOps())
784243830Sdim    AttrEmitter->EmitAttribute(ARMBuildAttrs::CPU_arch, ARMBuildAttrs::v4T);
785218893Sdim
786221345Sdim  if (Subtarget->hasNEON() && emitFPU) {
787221345Sdim    /* NEON is not exactly a VFP architecture, but GAS emit one of
788234353Sdim     * neon/neon-vfpv4/vfpv3/vfpv2 for .fpu parameters */
789234353Sdim    if (Subtarget->hasVFP4())
790234353Sdim      AttrEmitter->EmitTextAttribute(ARMBuildAttrs::Advanced_SIMD_arch,
791234353Sdim                                     "neon-vfpv4");
792234353Sdim    else
793234353Sdim      AttrEmitter->EmitTextAttribute(ARMBuildAttrs::Advanced_SIMD_arch, "neon");
794221345Sdim    /* If emitted for NEON, omit from VFP below, since you can have both
795221345Sdim     * NEON and VFP in build attributes but only one .fpu */
796221345Sdim    emitFPU = false;
797221345Sdim  }
798221345Sdim
799234353Sdim  /* VFPv4 + .fpu */
800234353Sdim  if (Subtarget->hasVFP4()) {
801234353Sdim    AttrEmitter->EmitAttribute(ARMBuildAttrs::VFP_arch,
802234353Sdim                               ARMBuildAttrs::AllowFPv4A);
803234353Sdim    if (emitFPU)
804234353Sdim      AttrEmitter->EmitTextAttribute(ARMBuildAttrs::VFP_arch, "vfpv4");
805234353Sdim
806221345Sdim  /* VFPv3 + .fpu */
807234353Sdim  } else if (Subtarget->hasVFP3()) {
808218893Sdim    AttrEmitter->EmitAttribute(ARMBuildAttrs::VFP_arch,
809221345Sdim                               ARMBuildAttrs::AllowFPv3A);
810221345Sdim    if (emitFPU)
811221345Sdim      AttrEmitter->EmitTextAttribute(ARMBuildAttrs::VFP_arch, "vfpv3");
812221345Sdim
813221345Sdim  /* VFPv2 + .fpu */
814221345Sdim  } else if (Subtarget->hasVFP2()) {
815221345Sdim    AttrEmitter->EmitAttribute(ARMBuildAttrs::VFP_arch,
816218893Sdim                               ARMBuildAttrs::AllowFPv2);
817221345Sdim    if (emitFPU)
818221345Sdim      AttrEmitter->EmitTextAttribute(ARMBuildAttrs::VFP_arch, "vfpv2");
819221345Sdim  }
820218893Sdim
821221345Sdim  /* TODO: ARMBuildAttrs::Allowed is not completely accurate,
822224145Sdim   * since NEON can have 1 (allowed) or 2 (MAC operations) */
823221345Sdim  if (Subtarget->hasNEON()) {
824221345Sdim    AttrEmitter->EmitAttribute(ARMBuildAttrs::Advanced_SIMD_arch,
825221345Sdim                               ARMBuildAttrs::Allowed);
826221345Sdim  }
827221345Sdim
828218893Sdim  // Signal various FP modes.
829234353Sdim  if (!TM.Options.UnsafeFPMath) {
830218893Sdim    AttrEmitter->EmitAttribute(ARMBuildAttrs::ABI_FP_denormal,
831218893Sdim                               ARMBuildAttrs::Allowed);
832218893Sdim    AttrEmitter->EmitAttribute(ARMBuildAttrs::ABI_FP_exceptions,
833218893Sdim                               ARMBuildAttrs::Allowed);
834218893Sdim  }
835218893Sdim
836234353Sdim  if (TM.Options.NoInfsFPMath && TM.Options.NoNaNsFPMath)
837218893Sdim    AttrEmitter->EmitAttribute(ARMBuildAttrs::ABI_FP_number_model,
838218893Sdim                               ARMBuildAttrs::Allowed);
839218893Sdim  else
840218893Sdim    AttrEmitter->EmitAttribute(ARMBuildAttrs::ABI_FP_number_model,
841218893Sdim                               ARMBuildAttrs::AllowIEE754);
842218893Sdim
843218893Sdim  // FIXME: add more flags to ARMBuildAttrs.h
844218893Sdim  // 8-bytes alignment stuff.
845218893Sdim  AttrEmitter->EmitAttribute(ARMBuildAttrs::ABI_align8_needed, 1);
846218893Sdim  AttrEmitter->EmitAttribute(ARMBuildAttrs::ABI_align8_preserved, 1);
847218893Sdim
848218893Sdim  // Hard float.  Use both S and D registers and conform to AAPCS-VFP.
849234353Sdim  if (Subtarget->isAAPCS_ABI() && TM.Options.FloatABIType == FloatABI::Hard) {
850218893Sdim    AttrEmitter->EmitAttribute(ARMBuildAttrs::ABI_HardFP_use, 3);
851218893Sdim    AttrEmitter->EmitAttribute(ARMBuildAttrs::ABI_VFP_args, 1);
852218893Sdim  }
853218893Sdim  // FIXME: Should we signal R9 usage?
854218893Sdim
855218893Sdim  if (Subtarget->hasDivide())
856218893Sdim    AttrEmitter->EmitAttribute(ARMBuildAttrs::DIV_use, 1);
857218893Sdim
858218893Sdim  AttrEmitter->Finish();
859218893Sdim  delete AttrEmitter;
860218893Sdim}
861218893Sdim
862218893Sdimvoid ARMAsmPrinter::emitARMAttributeSection() {
863218893Sdim  // <format-version>
864218893Sdim  // [ <section-length> "vendor-name"
865218893Sdim  // [ <file-tag> <size> <attribute>*
866218893Sdim  //   | <section-tag> <size> <section-number>* 0 <attribute>*
867218893Sdim  //   | <symbol-tag> <size> <symbol-number>* 0 <attribute>*
868218893Sdim  //   ]+
869218893Sdim  // ]*
870218893Sdim
871218893Sdim  if (OutStreamer.hasRawTextSupport())
872218893Sdim    return;
873218893Sdim
874218893Sdim  const ARMElfTargetObjectFile &TLOFELF =
875218893Sdim    static_cast<const ARMElfTargetObjectFile &>
876218893Sdim    (getObjFileLowering());
877218893Sdim
878218893Sdim  OutStreamer.SwitchSection(TLOFELF.getAttributesSection());
879218893Sdim
880218893Sdim  // Format version
881218893Sdim  OutStreamer.EmitIntValue(0x41, 1);
882218893Sdim}
883218893Sdim
884218893Sdim//===----------------------------------------------------------------------===//
885218893Sdim
886218893Sdimstatic MCSymbol *getPICLabel(const char *Prefix, unsigned FunctionNumber,
887218893Sdim                             unsigned LabelId, MCContext &Ctx) {
888218893Sdim
889218893Sdim  MCSymbol *Label = Ctx.GetOrCreateSymbol(Twine(Prefix)
890218893Sdim                       + "PC" + Twine(FunctionNumber) + "_" + Twine(LabelId));
891218893Sdim  return Label;
892218893Sdim}
893218893Sdim
894218893Sdimstatic MCSymbolRefExpr::VariantKind
895218893SdimgetModifierVariantKind(ARMCP::ARMCPModifier Modifier) {
896218893Sdim  switch (Modifier) {
897218893Sdim  case ARMCP::no_modifier: return MCSymbolRefExpr::VK_None;
898218893Sdim  case ARMCP::TLSGD:       return MCSymbolRefExpr::VK_ARM_TLSGD;
899218893Sdim  case ARMCP::TPOFF:       return MCSymbolRefExpr::VK_ARM_TPOFF;
900218893Sdim  case ARMCP::GOTTPOFF:    return MCSymbolRefExpr::VK_ARM_GOTTPOFF;
901218893Sdim  case ARMCP::GOT:         return MCSymbolRefExpr::VK_ARM_GOT;
902218893Sdim  case ARMCP::GOTOFF:      return MCSymbolRefExpr::VK_ARM_GOTOFF;
903218893Sdim  }
904234353Sdim  llvm_unreachable("Invalid ARMCPModifier!");
905218893Sdim}
906218893Sdim
907218893SdimMCSymbol *ARMAsmPrinter::GetARMGVSymbol(const GlobalValue *GV) {
908218893Sdim  bool isIndirect = Subtarget->isTargetDarwin() &&
909218893Sdim    Subtarget->GVIsIndirectSymbol(GV, TM.getRelocationModel());
910218893Sdim  if (!isIndirect)
911218893Sdim    return Mang->getSymbol(GV);
912218893Sdim
913218893Sdim  // FIXME: Remove this when Darwin transition to @GOT like syntax.
914218893Sdim  MCSymbol *MCSym = GetSymbolWithGlobalValueBase(GV, "$non_lazy_ptr");
915218893Sdim  MachineModuleInfoMachO &MMIMachO =
916218893Sdim    MMI->getObjFileInfo<MachineModuleInfoMachO>();
917218893Sdim  MachineModuleInfoImpl::StubValueTy &StubSym =
918218893Sdim    GV->hasHiddenVisibility() ? MMIMachO.getHiddenGVStubEntry(MCSym) :
919218893Sdim    MMIMachO.getGVStubEntry(MCSym);
920218893Sdim  if (StubSym.getPointer() == 0)
921218893Sdim    StubSym = MachineModuleInfoImpl::
922218893Sdim      StubValueTy(Mang->getSymbol(GV), !GV->hasInternalLinkage());
923218893Sdim  return MCSym;
924218893Sdim}
925218893Sdim
926218893Sdimvoid ARMAsmPrinter::
927218893SdimEmitMachineConstantPoolValue(MachineConstantPoolValue *MCPV) {
928243830Sdim  int Size = TM.getDataLayout()->getTypeAllocSize(MCPV->getType());
929218893Sdim
930218893Sdim  ARMConstantPoolValue *ACPV = static_cast<ARMConstantPoolValue*>(MCPV);
931218893Sdim
932218893Sdim  MCSymbol *MCSym;
933218893Sdim  if (ACPV->isLSDA()) {
934218893Sdim    SmallString<128> Str;
935218893Sdim    raw_svector_ostream OS(Str);
936218893Sdim    OS << MAI->getPrivateGlobalPrefix() << "_LSDA_" << getFunctionNumber();
937218893Sdim    MCSym = OutContext.GetOrCreateSymbol(OS.str());
938218893Sdim  } else if (ACPV->isBlockAddress()) {
939226633Sdim    const BlockAddress *BA =
940226633Sdim      cast<ARMConstantPoolConstant>(ACPV)->getBlockAddress();
941226633Sdim    MCSym = GetBlockAddressSymbol(BA);
942218893Sdim  } else if (ACPV->isGlobalValue()) {
943226633Sdim    const GlobalValue *GV = cast<ARMConstantPoolConstant>(ACPV)->getGV();
944218893Sdim    MCSym = GetARMGVSymbol(GV);
945226633Sdim  } else if (ACPV->isMachineBasicBlock()) {
946226633Sdim    const MachineBasicBlock *MBB = cast<ARMConstantPoolMBB>(ACPV)->getMBB();
947226633Sdim    MCSym = MBB->getSymbol();
948218893Sdim  } else {
949218893Sdim    assert(ACPV->isExtSymbol() && "unrecognized constant pool value");
950226633Sdim    const char *Sym = cast<ARMConstantPoolSymbol>(ACPV)->getSymbol();
951226633Sdim    MCSym = GetExternalSymbolSymbol(Sym);
952218893Sdim  }
953218893Sdim
954218893Sdim  // Create an MCSymbol for the reference.
955218893Sdim  const MCExpr *Expr =
956218893Sdim    MCSymbolRefExpr::Create(MCSym, getModifierVariantKind(ACPV->getModifier()),
957218893Sdim                            OutContext);
958218893Sdim
959218893Sdim  if (ACPV->getPCAdjustment()) {
960218893Sdim    MCSymbol *PCLabel = getPICLabel(MAI->getPrivateGlobalPrefix(),
961218893Sdim                                    getFunctionNumber(),
962218893Sdim                                    ACPV->getLabelId(),
963218893Sdim                                    OutContext);
964218893Sdim    const MCExpr *PCRelExpr = MCSymbolRefExpr::Create(PCLabel, OutContext);
965218893Sdim    PCRelExpr =
966218893Sdim      MCBinaryExpr::CreateAdd(PCRelExpr,
967218893Sdim                              MCConstantExpr::Create(ACPV->getPCAdjustment(),
968218893Sdim                                                     OutContext),
969218893Sdim                              OutContext);
970218893Sdim    if (ACPV->mustAddCurrentAddress()) {
971218893Sdim      // We want "(<expr> - .)", but MC doesn't have a concept of the '.'
972218893Sdim      // label, so just emit a local label end reference that instead.
973218893Sdim      MCSymbol *DotSym = OutContext.CreateTempSymbol();
974218893Sdim      OutStreamer.EmitLabel(DotSym);
975218893Sdim      const MCExpr *DotExpr = MCSymbolRefExpr::Create(DotSym, OutContext);
976218893Sdim      PCRelExpr = MCBinaryExpr::CreateSub(PCRelExpr, DotExpr, OutContext);
977218893Sdim    }
978218893Sdim    Expr = MCBinaryExpr::CreateSub(Expr, PCRelExpr, OutContext);
979218893Sdim  }
980218893Sdim  OutStreamer.EmitValue(Expr, Size);
981218893Sdim}
982218893Sdim
983218893Sdimvoid ARMAsmPrinter::EmitJumpTable(const MachineInstr *MI) {
984218893Sdim  unsigned Opcode = MI->getOpcode();
985218893Sdim  int OpNum = 1;
986218893Sdim  if (Opcode == ARM::BR_JTadd)
987218893Sdim    OpNum = 2;
988218893Sdim  else if (Opcode == ARM::BR_JTm)
989218893Sdim    OpNum = 3;
990218893Sdim
991218893Sdim  const MachineOperand &MO1 = MI->getOperand(OpNum);
992218893Sdim  const MachineOperand &MO2 = MI->getOperand(OpNum+1); // Unique Id
993218893Sdim  unsigned JTI = MO1.getIndex();
994218893Sdim
995218893Sdim  // Emit a label for the jump table.
996218893Sdim  MCSymbol *JTISymbol = GetARMJTIPICJumpTableLabel2(JTI, MO2.getImm());
997218893Sdim  OutStreamer.EmitLabel(JTISymbol);
998218893Sdim
999239462Sdim  // Mark the jump table as data-in-code.
1000239462Sdim  OutStreamer.EmitDataRegion(MCDR_DataRegionJT32);
1001239462Sdim
1002218893Sdim  // Emit each entry of the table.
1003218893Sdim  const MachineJumpTableInfo *MJTI = MF->getJumpTableInfo();
1004218893Sdim  const std::vector<MachineJumpTableEntry> &JT = MJTI->getJumpTables();
1005218893Sdim  const std::vector<MachineBasicBlock*> &JTBBs = JT[JTI].MBBs;
1006218893Sdim
1007218893Sdim  for (unsigned i = 0, e = JTBBs.size(); i != e; ++i) {
1008218893Sdim    MachineBasicBlock *MBB = JTBBs[i];
1009218893Sdim    // Construct an MCExpr for the entry. We want a value of the form:
1010218893Sdim    // (BasicBlockAddr - TableBeginAddr)
1011218893Sdim    //
1012218893Sdim    // For example, a table with entries jumping to basic blocks BB0 and BB1
1013218893Sdim    // would look like:
1014218893Sdim    // LJTI_0_0:
1015218893Sdim    //    .word (LBB0 - LJTI_0_0)
1016218893Sdim    //    .word (LBB1 - LJTI_0_0)
1017218893Sdim    const MCExpr *Expr = MCSymbolRefExpr::Create(MBB->getSymbol(), OutContext);
1018218893Sdim
1019218893Sdim    if (TM.getRelocationModel() == Reloc::PIC_)
1020218893Sdim      Expr = MCBinaryExpr::CreateSub(Expr, MCSymbolRefExpr::Create(JTISymbol,
1021218893Sdim                                                                   OutContext),
1022218893Sdim                                     OutContext);
1023226633Sdim    // If we're generating a table of Thumb addresses in static relocation
1024226633Sdim    // model, we need to add one to keep interworking correctly.
1025226633Sdim    else if (AFI->isThumbFunction())
1026226633Sdim      Expr = MCBinaryExpr::CreateAdd(Expr, MCConstantExpr::Create(1,OutContext),
1027226633Sdim                                     OutContext);
1028218893Sdim    OutStreamer.EmitValue(Expr, 4);
1029218893Sdim  }
1030239462Sdim  // Mark the end of jump table data-in-code region.
1031239462Sdim  OutStreamer.EmitDataRegion(MCDR_DataRegionEnd);
1032218893Sdim}
1033218893Sdim
1034218893Sdimvoid ARMAsmPrinter::EmitJump2Table(const MachineInstr *MI) {
1035218893Sdim  unsigned Opcode = MI->getOpcode();
1036218893Sdim  int OpNum = (Opcode == ARM::t2BR_JT) ? 2 : 1;
1037218893Sdim  const MachineOperand &MO1 = MI->getOperand(OpNum);
1038218893Sdim  const MachineOperand &MO2 = MI->getOperand(OpNum+1); // Unique Id
1039218893Sdim  unsigned JTI = MO1.getIndex();
1040218893Sdim
1041218893Sdim  MCSymbol *JTISymbol = GetARMJTIPICJumpTableLabel2(JTI, MO2.getImm());
1042218893Sdim  OutStreamer.EmitLabel(JTISymbol);
1043218893Sdim
1044218893Sdim  // Emit each entry of the table.
1045218893Sdim  const MachineJumpTableInfo *MJTI = MF->getJumpTableInfo();
1046218893Sdim  const std::vector<MachineJumpTableEntry> &JT = MJTI->getJumpTables();
1047218893Sdim  const std::vector<MachineBasicBlock*> &JTBBs = JT[JTI].MBBs;
1048218893Sdim  unsigned OffsetWidth = 4;
1049239462Sdim  if (MI->getOpcode() == ARM::t2TBB_JT) {
1050218893Sdim    OffsetWidth = 1;
1051239462Sdim    // Mark the jump table as data-in-code.
1052239462Sdim    OutStreamer.EmitDataRegion(MCDR_DataRegionJT8);
1053239462Sdim  } else if (MI->getOpcode() == ARM::t2TBH_JT) {
1054218893Sdim    OffsetWidth = 2;
1055239462Sdim    // Mark the jump table as data-in-code.
1056239462Sdim    OutStreamer.EmitDataRegion(MCDR_DataRegionJT16);
1057239462Sdim  }
1058218893Sdim
1059218893Sdim  for (unsigned i = 0, e = JTBBs.size(); i != e; ++i) {
1060218893Sdim    MachineBasicBlock *MBB = JTBBs[i];
1061218893Sdim    const MCExpr *MBBSymbolExpr = MCSymbolRefExpr::Create(MBB->getSymbol(),
1062218893Sdim                                                      OutContext);
1063218893Sdim    // If this isn't a TBB or TBH, the entries are direct branch instructions.
1064218893Sdim    if (OffsetWidth == 4) {
1065249423Sdim      OutStreamer.EmitInstruction(MCInstBuilder(ARM::t2B)
1066249423Sdim        .addExpr(MBBSymbolExpr)
1067249423Sdim        .addImm(ARMCC::AL)
1068249423Sdim        .addReg(0));
1069218893Sdim      continue;
1070218893Sdim    }
1071218893Sdim    // Otherwise it's an offset from the dispatch instruction. Construct an
1072218893Sdim    // MCExpr for the entry. We want a value of the form:
1073218893Sdim    // (BasicBlockAddr - TableBeginAddr) / 2
1074218893Sdim    //
1075218893Sdim    // For example, a TBB table with entries jumping to basic blocks BB0 and BB1
1076218893Sdim    // would look like:
1077218893Sdim    // LJTI_0_0:
1078218893Sdim    //    .byte (LBB0 - LJTI_0_0) / 2
1079218893Sdim    //    .byte (LBB1 - LJTI_0_0) / 2
1080218893Sdim    const MCExpr *Expr =
1081218893Sdim      MCBinaryExpr::CreateSub(MBBSymbolExpr,
1082218893Sdim                              MCSymbolRefExpr::Create(JTISymbol, OutContext),
1083218893Sdim                              OutContext);
1084218893Sdim    Expr = MCBinaryExpr::CreateDiv(Expr, MCConstantExpr::Create(2, OutContext),
1085218893Sdim                                   OutContext);
1086218893Sdim    OutStreamer.EmitValue(Expr, OffsetWidth);
1087218893Sdim  }
1088239462Sdim  // Mark the end of jump table data-in-code region. 32-bit offsets use
1089239462Sdim  // actual branch instructions here, so we don't mark those as a data-region
1090239462Sdim  // at all.
1091239462Sdim  if (OffsetWidth != 4)
1092239462Sdim    OutStreamer.EmitDataRegion(MCDR_DataRegionEnd);
1093218893Sdim}
1094218893Sdim
1095218893Sdimvoid ARMAsmPrinter::PrintDebugValueComment(const MachineInstr *MI,
1096218893Sdim                                           raw_ostream &OS) {
1097218893Sdim  unsigned NOps = MI->getNumOperands();
1098218893Sdim  assert(NOps==4);
1099218893Sdim  OS << '\t' << MAI->getCommentString() << "DEBUG_VALUE: ";
1100218893Sdim  // cast away const; DIetc do not take const operands for some reason.
1101218893Sdim  DIVariable V(const_cast<MDNode *>(MI->getOperand(NOps-1).getMetadata()));
1102218893Sdim  OS << V.getName();
1103218893Sdim  OS << " <- ";
1104218893Sdim  // Frame address.  Currently handles register +- offset only.
1105218893Sdim  assert(MI->getOperand(0).isReg() && MI->getOperand(1).isImm());
1106218893Sdim  OS << '['; printOperand(MI, 0, OS); OS << '+'; printOperand(MI, 1, OS);
1107218893Sdim  OS << ']';
1108218893Sdim  OS << "+";
1109218893Sdim  printOperand(MI, NOps-2, OS);
1110218893Sdim}
1111218893Sdim
1112221345Sdimvoid ARMAsmPrinter::EmitUnwindingInstruction(const MachineInstr *MI) {
1113221345Sdim  assert(MI->getFlag(MachineInstr::FrameSetup) &&
1114221345Sdim      "Only instruction which are involved into frame setup code are allowed");
1115221345Sdim
1116221345Sdim  const MachineFunction &MF = *MI->getParent()->getParent();
1117221345Sdim  const TargetRegisterInfo *RegInfo = MF.getTarget().getRegisterInfo();
1118221345Sdim  const ARMFunctionInfo &AFI = *MF.getInfo<ARMFunctionInfo>();
1119221345Sdim
1120221345Sdim  unsigned FramePtr = RegInfo->getFrameRegister(MF);
1121221345Sdim  unsigned Opc = MI->getOpcode();
1122221345Sdim  unsigned SrcReg, DstReg;
1123221345Sdim
1124221345Sdim  if (Opc == ARM::tPUSH || Opc == ARM::tLDRpci) {
1125221345Sdim    // Two special cases:
1126221345Sdim    // 1) tPUSH does not have src/dst regs.
1127221345Sdim    // 2) for Thumb1 code we sometimes materialize the constant via constpool
1128221345Sdim    // load. Yes, this is pretty fragile, but for now I don't see better
1129221345Sdim    // way... :(
1130221345Sdim    SrcReg = DstReg = ARM::SP;
1131221345Sdim  } else {
1132221345Sdim    SrcReg = MI->getOperand(1).getReg();
1133221345Sdim    DstReg = MI->getOperand(0).getReg();
1134221345Sdim  }
1135221345Sdim
1136221345Sdim  // Try to figure out the unwinding opcode out of src / dst regs.
1137234353Sdim  if (MI->mayStore()) {
1138221345Sdim    // Register saves.
1139221345Sdim    assert(DstReg == ARM::SP &&
1140221345Sdim           "Only stack pointer as a destination reg is supported");
1141221345Sdim
1142221345Sdim    SmallVector<unsigned, 4> RegList;
1143221345Sdim    // Skip src & dst reg, and pred ops.
1144221345Sdim    unsigned StartOp = 2 + 2;
1145221345Sdim    // Use all the operands.
1146221345Sdim    unsigned NumOffset = 0;
1147221345Sdim
1148221345Sdim    switch (Opc) {
1149221345Sdim    default:
1150221345Sdim      MI->dump();
1151234353Sdim      llvm_unreachable("Unsupported opcode for unwinding information");
1152221345Sdim    case ARM::tPUSH:
1153221345Sdim      // Special case here: no src & dst reg, but two extra imp ops.
1154221345Sdim      StartOp = 2; NumOffset = 2;
1155221345Sdim    case ARM::STMDB_UPD:
1156221345Sdim    case ARM::t2STMDB_UPD:
1157221345Sdim    case ARM::VSTMDDB_UPD:
1158221345Sdim      assert(SrcReg == ARM::SP &&
1159221345Sdim             "Only stack pointer as a source reg is supported");
1160221345Sdim      for (unsigned i = StartOp, NumOps = MI->getNumOperands() - NumOffset;
1161239462Sdim           i != NumOps; ++i) {
1162239462Sdim        const MachineOperand &MO = MI->getOperand(i);
1163239462Sdim        // Actually, there should never be any impdef stuff here. Skip it
1164239462Sdim        // temporary to workaround PR11902.
1165239462Sdim        if (MO.isImplicit())
1166239462Sdim          continue;
1167239462Sdim        RegList.push_back(MO.getReg());
1168239462Sdim      }
1169221345Sdim      break;
1170226633Sdim    case ARM::STR_PRE_IMM:
1171226633Sdim    case ARM::STR_PRE_REG:
1172234353Sdim    case ARM::t2STR_PRE:
1173221345Sdim      assert(MI->getOperand(2).getReg() == ARM::SP &&
1174221345Sdim             "Only stack pointer as a source reg is supported");
1175221345Sdim      RegList.push_back(SrcReg);
1176221345Sdim      break;
1177221345Sdim    }
1178221345Sdim    OutStreamer.EmitRegSave(RegList, Opc == ARM::VSTMDDB_UPD);
1179221345Sdim  } else {
1180221345Sdim    // Changes of stack / frame pointer.
1181221345Sdim    if (SrcReg == ARM::SP) {
1182221345Sdim      int64_t Offset = 0;
1183221345Sdim      switch (Opc) {
1184221345Sdim      default:
1185221345Sdim        MI->dump();
1186234353Sdim        llvm_unreachable("Unsupported opcode for unwinding information");
1187221345Sdim      case ARM::MOVr:
1188234353Sdim      case ARM::tMOVr:
1189221345Sdim        Offset = 0;
1190221345Sdim        break;
1191221345Sdim      case ARM::ADDri:
1192221345Sdim        Offset = -MI->getOperand(2).getImm();
1193221345Sdim        break;
1194221345Sdim      case ARM::SUBri:
1195234353Sdim      case ARM::t2SUBri:
1196224145Sdim        Offset = MI->getOperand(2).getImm();
1197221345Sdim        break;
1198221345Sdim      case ARM::tSUBspi:
1199224145Sdim        Offset = MI->getOperand(2).getImm()*4;
1200221345Sdim        break;
1201221345Sdim      case ARM::tADDspi:
1202221345Sdim      case ARM::tADDrSPi:
1203221345Sdim        Offset = -MI->getOperand(2).getImm()*4;
1204221345Sdim        break;
1205221345Sdim      case ARM::tLDRpci: {
1206221345Sdim        // Grab the constpool index and check, whether it corresponds to
1207221345Sdim        // original or cloned constpool entry.
1208221345Sdim        unsigned CPI = MI->getOperand(1).getIndex();
1209221345Sdim        const MachineConstantPool *MCP = MF.getConstantPool();
1210221345Sdim        if (CPI >= MCP->getConstants().size())
1211221345Sdim          CPI = AFI.getOriginalCPIdx(CPI);
1212221345Sdim        assert(CPI != -1U && "Invalid constpool index");
1213221345Sdim
1214221345Sdim        // Derive the actual offset.
1215221345Sdim        const MachineConstantPoolEntry &CPE = MCP->getConstants()[CPI];
1216221345Sdim        assert(!CPE.isMachineConstantPoolEntry() && "Invalid constpool entry");
1217221345Sdim        // FIXME: Check for user, it should be "add" instruction!
1218221345Sdim        Offset = -cast<ConstantInt>(CPE.Val.ConstVal)->getSExtValue();
1219221345Sdim        break;
1220221345Sdim      }
1221221345Sdim      }
1222221345Sdim
1223221345Sdim      if (DstReg == FramePtr && FramePtr != ARM::SP)
1224221345Sdim        // Set-up of the frame pointer. Positive values correspond to "add"
1225221345Sdim        // instruction.
1226221345Sdim        OutStreamer.EmitSetFP(FramePtr, ARM::SP, -Offset);
1227221345Sdim      else if (DstReg == ARM::SP) {
1228221345Sdim        // Change of SP by an offset. Positive values correspond to "sub"
1229221345Sdim        // instruction.
1230221345Sdim        OutStreamer.EmitPad(Offset);
1231221345Sdim      } else {
1232221345Sdim        MI->dump();
1233234353Sdim        llvm_unreachable("Unsupported opcode for unwinding information");
1234221345Sdim      }
1235221345Sdim    } else if (DstReg == ARM::SP) {
1236221345Sdim      // FIXME: .movsp goes here
1237221345Sdim      MI->dump();
1238234353Sdim      llvm_unreachable("Unsupported opcode for unwinding information");
1239221345Sdim    }
1240221345Sdim    else {
1241221345Sdim      MI->dump();
1242234353Sdim      llvm_unreachable("Unsupported opcode for unwinding information");
1243221345Sdim    }
1244221345Sdim  }
1245221345Sdim}
1246221345Sdim
1247221345Sdimextern cl::opt<bool> EnableARMEHABI;
1248221345Sdim
1249224145Sdim// Simple pseudo-instructions have their lowering (with expansion to real
1250224145Sdim// instructions) auto-generated.
1251224145Sdim#include "ARMGenMCPseudoLowering.inc"
1252224145Sdim
1253218893Sdimvoid ARMAsmPrinter::EmitInstruction(const MachineInstr *MI) {
1254239462Sdim  // If we just ended a constant pool, mark it as such.
1255239462Sdim  if (InConstantPool && MI->getOpcode() != ARM::CONSTPOOL_ENTRY) {
1256239462Sdim    OutStreamer.EmitDataRegion(MCDR_DataRegionEnd);
1257239462Sdim    InConstantPool = false;
1258239462Sdim  }
1259226633Sdim
1260226633Sdim  // Emit unwinding stuff for frame-related instructions
1261226633Sdim  if (EnableARMEHABI && MI->getFlag(MachineInstr::FrameSetup))
1262226633Sdim    EmitUnwindingInstruction(MI);
1263226633Sdim
1264224145Sdim  // Do any auto-generated pseudo lowerings.
1265224145Sdim  if (emitPseudoExpansionLowering(OutStreamer, MI))
1266224145Sdim    return;
1267224145Sdim
1268226633Sdim  assert(!convertAddSubFlagsOpcode(MI->getOpcode()) &&
1269226633Sdim         "Pseudo flag setting opcode should be expanded early");
1270226633Sdim
1271224145Sdim  // Check for manual lowerings.
1272218893Sdim  unsigned Opc = MI->getOpcode();
1273218893Sdim  switch (Opc) {
1274234353Sdim  case ARM::t2MOVi32imm: llvm_unreachable("Should be lowered by thumb2it pass");
1275218893Sdim  case ARM::DBG_VALUE: {
1276218893Sdim    if (isVerbose() && OutStreamer.hasRawTextSupport()) {
1277218893Sdim      SmallString<128> TmpStr;
1278218893Sdim      raw_svector_ostream OS(TmpStr);
1279218893Sdim      PrintDebugValueComment(MI, OS);
1280218893Sdim      OutStreamer.EmitRawText(StringRef(OS.str()));
1281218893Sdim    }
1282218893Sdim    return;
1283218893Sdim  }
1284218893Sdim  case ARM::LEApcrel:
1285218893Sdim  case ARM::tLEApcrel:
1286218893Sdim  case ARM::t2LEApcrel: {
1287218893Sdim    // FIXME: Need to also handle globals and externals
1288249423Sdim    MCSymbol *CPISymbol = GetCPISymbol(MI->getOperand(1).getIndex());
1289249423Sdim    OutStreamer.EmitInstruction(MCInstBuilder(MI->getOpcode() ==
1290249423Sdim                                              ARM::t2LEApcrel ? ARM::t2ADR
1291249423Sdim                  : (MI->getOpcode() == ARM::tLEApcrel ? ARM::tADR
1292249423Sdim                     : ARM::ADR))
1293249423Sdim      .addReg(MI->getOperand(0).getReg())
1294249423Sdim      .addExpr(MCSymbolRefExpr::Create(CPISymbol, OutContext))
1295249423Sdim      // Add predicate operands.
1296249423Sdim      .addImm(MI->getOperand(2).getImm())
1297249423Sdim      .addReg(MI->getOperand(3).getReg()));
1298218893Sdim    return;
1299218893Sdim  }
1300218893Sdim  case ARM::LEApcrelJT:
1301218893Sdim  case ARM::tLEApcrelJT:
1302218893Sdim  case ARM::t2LEApcrelJT: {
1303249423Sdim    MCSymbol *JTIPICSymbol =
1304249423Sdim      GetARMJTIPICJumpTableLabel2(MI->getOperand(1).getIndex(),
1305249423Sdim                                  MI->getOperand(2).getImm());
1306249423Sdim    OutStreamer.EmitInstruction(MCInstBuilder(MI->getOpcode() ==
1307249423Sdim                                              ARM::t2LEApcrelJT ? ARM::t2ADR
1308249423Sdim                  : (MI->getOpcode() == ARM::tLEApcrelJT ? ARM::tADR
1309249423Sdim                     : ARM::ADR))
1310249423Sdim      .addReg(MI->getOperand(0).getReg())
1311249423Sdim      .addExpr(MCSymbolRefExpr::Create(JTIPICSymbol, OutContext))
1312249423Sdim      // Add predicate operands.
1313249423Sdim      .addImm(MI->getOperand(3).getImm())
1314249423Sdim      .addReg(MI->getOperand(4).getReg()));
1315218893Sdim    return;
1316218893Sdim  }
1317221345Sdim  // Darwin call instructions are just normal call instructions with different
1318221345Sdim  // clobber semantics (they clobber R9).
1319218893Sdim  case ARM::BX_CALL: {
1320249423Sdim    OutStreamer.EmitInstruction(MCInstBuilder(ARM::MOVr)
1321249423Sdim      .addReg(ARM::LR)
1322249423Sdim      .addReg(ARM::PC)
1323218893Sdim      // Add predicate operands.
1324249423Sdim      .addImm(ARMCC::AL)
1325249423Sdim      .addReg(0)
1326218893Sdim      // Add 's' bit operand (always reg0 for this)
1327249423Sdim      .addReg(0));
1328249423Sdim
1329249423Sdim    OutStreamer.EmitInstruction(MCInstBuilder(ARM::BX)
1330249423Sdim      .addReg(MI->getOperand(0).getReg()));
1331218893Sdim    return;
1332218893Sdim  }
1333223017Sdim  case ARM::tBX_CALL: {
1334249423Sdim    OutStreamer.EmitInstruction(MCInstBuilder(ARM::tMOVr)
1335249423Sdim      .addReg(ARM::LR)
1336249423Sdim      .addReg(ARM::PC)
1337224145Sdim      // Add predicate operands.
1338249423Sdim      .addImm(ARMCC::AL)
1339249423Sdim      .addReg(0));
1340249423Sdim
1341249423Sdim    OutStreamer.EmitInstruction(MCInstBuilder(ARM::tBX)
1342249423Sdim      .addReg(MI->getOperand(0).getReg())
1343223017Sdim      // Add predicate operands.
1344249423Sdim      .addImm(ARMCC::AL)
1345249423Sdim      .addReg(0));
1346223017Sdim    return;
1347223017Sdim  }
1348218893Sdim  case ARM::BMOVPCRX_CALL: {
1349249423Sdim    OutStreamer.EmitInstruction(MCInstBuilder(ARM::MOVr)
1350249423Sdim      .addReg(ARM::LR)
1351249423Sdim      .addReg(ARM::PC)
1352218893Sdim      // Add predicate operands.
1353249423Sdim      .addImm(ARMCC::AL)
1354249423Sdim      .addReg(0)
1355218893Sdim      // Add 's' bit operand (always reg0 for this)
1356249423Sdim      .addReg(0));
1357249423Sdim
1358249423Sdim    OutStreamer.EmitInstruction(MCInstBuilder(ARM::MOVr)
1359249423Sdim      .addReg(ARM::PC)
1360249423Sdim      .addReg(MI->getOperand(0).getReg())
1361218893Sdim      // Add predicate operands.
1362249423Sdim      .addImm(ARMCC::AL)
1363249423Sdim      .addReg(0)
1364218893Sdim      // Add 's' bit operand (always reg0 for this)
1365249423Sdim      .addReg(0));
1366218893Sdim    return;
1367218893Sdim  }
1368234353Sdim  case ARM::BMOVPCB_CALL: {
1369249423Sdim    OutStreamer.EmitInstruction(MCInstBuilder(ARM::MOVr)
1370249423Sdim      .addReg(ARM::LR)
1371249423Sdim      .addReg(ARM::PC)
1372234353Sdim      // Add predicate operands.
1373249423Sdim      .addImm(ARMCC::AL)
1374249423Sdim      .addReg(0)
1375234353Sdim      // Add 's' bit operand (always reg0 for this)
1376249423Sdim      .addReg(0));
1377249423Sdim
1378249423Sdim    const GlobalValue *GV = MI->getOperand(0).getGlobal();
1379249423Sdim    MCSymbol *GVSym = Mang->getSymbol(GV);
1380249423Sdim    const MCExpr *GVSymExpr = MCSymbolRefExpr::Create(GVSym, OutContext);
1381249423Sdim    OutStreamer.EmitInstruction(MCInstBuilder(ARM::Bcc)
1382249423Sdim      .addExpr(GVSymExpr)
1383234353Sdim      // Add predicate operands.
1384249423Sdim      .addImm(ARMCC::AL)
1385249423Sdim      .addReg(0));
1386234353Sdim    return;
1387234353Sdim  }
1388218893Sdim  case ARM::MOVi16_ga_pcrel:
1389218893Sdim  case ARM::t2MOVi16_ga_pcrel: {
1390218893Sdim    MCInst TmpInst;
1391218893Sdim    TmpInst.setOpcode(Opc == ARM::MOVi16_ga_pcrel? ARM::MOVi16 : ARM::t2MOVi16);
1392218893Sdim    TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(0).getReg()));
1393218893Sdim
1394218893Sdim    unsigned TF = MI->getOperand(1).getTargetFlags();
1395218893Sdim    bool isPIC = TF == ARMII::MO_LO16_NONLAZY_PIC;
1396218893Sdim    const GlobalValue *GV = MI->getOperand(1).getGlobal();
1397218893Sdim    MCSymbol *GVSym = GetARMGVSymbol(GV);
1398218893Sdim    const MCExpr *GVSymExpr = MCSymbolRefExpr::Create(GVSym, OutContext);
1399218893Sdim    if (isPIC) {
1400218893Sdim      MCSymbol *LabelSym = getPICLabel(MAI->getPrivateGlobalPrefix(),
1401218893Sdim                                       getFunctionNumber(),
1402218893Sdim                                       MI->getOperand(2).getImm(), OutContext);
1403218893Sdim      const MCExpr *LabelSymExpr= MCSymbolRefExpr::Create(LabelSym, OutContext);
1404218893Sdim      unsigned PCAdj = (Opc == ARM::MOVi16_ga_pcrel) ? 8 : 4;
1405218893Sdim      const MCExpr *PCRelExpr =
1406218893Sdim        ARMMCExpr::CreateLower16(MCBinaryExpr::CreateSub(GVSymExpr,
1407218893Sdim                                  MCBinaryExpr::CreateAdd(LabelSymExpr,
1408218893Sdim                                      MCConstantExpr::Create(PCAdj, OutContext),
1409218893Sdim                                          OutContext), OutContext), OutContext);
1410218893Sdim      TmpInst.addOperand(MCOperand::CreateExpr(PCRelExpr));
1411218893Sdim    } else {
1412218893Sdim      const MCExpr *RefExpr= ARMMCExpr::CreateLower16(GVSymExpr, OutContext);
1413218893Sdim      TmpInst.addOperand(MCOperand::CreateExpr(RefExpr));
1414218893Sdim    }
1415218893Sdim
1416218893Sdim    // Add predicate operands.
1417218893Sdim    TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL));
1418218893Sdim    TmpInst.addOperand(MCOperand::CreateReg(0));
1419218893Sdim    // Add 's' bit operand (always reg0 for this)
1420218893Sdim    TmpInst.addOperand(MCOperand::CreateReg(0));
1421218893Sdim    OutStreamer.EmitInstruction(TmpInst);
1422218893Sdim    return;
1423218893Sdim  }
1424218893Sdim  case ARM::MOVTi16_ga_pcrel:
1425218893Sdim  case ARM::t2MOVTi16_ga_pcrel: {
1426218893Sdim    MCInst TmpInst;
1427218893Sdim    TmpInst.setOpcode(Opc == ARM::MOVTi16_ga_pcrel
1428218893Sdim                      ? ARM::MOVTi16 : ARM::t2MOVTi16);
1429218893Sdim    TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(0).getReg()));
1430218893Sdim    TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(1).getReg()));
1431218893Sdim
1432218893Sdim    unsigned TF = MI->getOperand(2).getTargetFlags();
1433218893Sdim    bool isPIC = TF == ARMII::MO_HI16_NONLAZY_PIC;
1434218893Sdim    const GlobalValue *GV = MI->getOperand(2).getGlobal();
1435218893Sdim    MCSymbol *GVSym = GetARMGVSymbol(GV);
1436218893Sdim    const MCExpr *GVSymExpr = MCSymbolRefExpr::Create(GVSym, OutContext);
1437218893Sdim    if (isPIC) {
1438218893Sdim      MCSymbol *LabelSym = getPICLabel(MAI->getPrivateGlobalPrefix(),
1439218893Sdim                                       getFunctionNumber(),
1440218893Sdim                                       MI->getOperand(3).getImm(), OutContext);
1441218893Sdim      const MCExpr *LabelSymExpr= MCSymbolRefExpr::Create(LabelSym, OutContext);
1442218893Sdim      unsigned PCAdj = (Opc == ARM::MOVTi16_ga_pcrel) ? 8 : 4;
1443218893Sdim      const MCExpr *PCRelExpr =
1444218893Sdim        ARMMCExpr::CreateUpper16(MCBinaryExpr::CreateSub(GVSymExpr,
1445218893Sdim                                   MCBinaryExpr::CreateAdd(LabelSymExpr,
1446218893Sdim                                      MCConstantExpr::Create(PCAdj, OutContext),
1447218893Sdim                                          OutContext), OutContext), OutContext);
1448218893Sdim      TmpInst.addOperand(MCOperand::CreateExpr(PCRelExpr));
1449218893Sdim    } else {
1450218893Sdim      const MCExpr *RefExpr= ARMMCExpr::CreateUpper16(GVSymExpr, OutContext);
1451218893Sdim      TmpInst.addOperand(MCOperand::CreateExpr(RefExpr));
1452218893Sdim    }
1453218893Sdim    // Add predicate operands.
1454218893Sdim    TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL));
1455218893Sdim    TmpInst.addOperand(MCOperand::CreateReg(0));
1456218893Sdim    // Add 's' bit operand (always reg0 for this)
1457218893Sdim    TmpInst.addOperand(MCOperand::CreateReg(0));
1458218893Sdim    OutStreamer.EmitInstruction(TmpInst);
1459218893Sdim    return;
1460218893Sdim  }
1461218893Sdim  case ARM::tPICADD: {
1462212793Sdim    // This is a pseudo op for a label + instruction sequence, which looks like:
1463212793Sdim    // LPC0:
1464218893Sdim    //     add r0, pc
1465218893Sdim    // This adds the address of LPC0 to r0.
1466218893Sdim
1467218893Sdim    // Emit the label.
1468218893Sdim    OutStreamer.EmitLabel(getPICLabel(MAI->getPrivateGlobalPrefix(),
1469218893Sdim                          getFunctionNumber(), MI->getOperand(2).getImm(),
1470218893Sdim                          OutContext));
1471218893Sdim
1472218893Sdim    // Form and emit the add.
1473249423Sdim    OutStreamer.EmitInstruction(MCInstBuilder(ARM::tADDhirr)
1474249423Sdim      .addReg(MI->getOperand(0).getReg())
1475249423Sdim      .addReg(MI->getOperand(0).getReg())
1476249423Sdim      .addReg(ARM::PC)
1477249423Sdim      // Add predicate operands.
1478249423Sdim      .addImm(ARMCC::AL)
1479249423Sdim      .addReg(0));
1480218893Sdim    return;
1481218893Sdim  }
1482218893Sdim  case ARM::PICADD: {
1483218893Sdim    // This is a pseudo op for a label + instruction sequence, which looks like:
1484218893Sdim    // LPC0:
1485212793Sdim    //     add r0, pc, r0
1486212793Sdim    // This adds the address of LPC0 to r0.
1487212793Sdim
1488212793Sdim    // Emit the label.
1489218893Sdim    OutStreamer.EmitLabel(getPICLabel(MAI->getPrivateGlobalPrefix(),
1490218893Sdim                          getFunctionNumber(), MI->getOperand(2).getImm(),
1491218893Sdim                          OutContext));
1492212793Sdim
1493218893Sdim    // Form and emit the add.
1494249423Sdim    OutStreamer.EmitInstruction(MCInstBuilder(ARM::ADDrr)
1495249423Sdim      .addReg(MI->getOperand(0).getReg())
1496249423Sdim      .addReg(ARM::PC)
1497249423Sdim      .addReg(MI->getOperand(1).getReg())
1498249423Sdim      // Add predicate operands.
1499249423Sdim      .addImm(MI->getOperand(3).getImm())
1500249423Sdim      .addReg(MI->getOperand(4).getReg())
1501249423Sdim      // Add 's' bit operand (always reg0 for this)
1502249423Sdim      .addReg(0));
1503212793Sdim    return;
1504212793Sdim  }
1505218893Sdim  case ARM::PICSTR:
1506218893Sdim  case ARM::PICSTRB:
1507218893Sdim  case ARM::PICSTRH:
1508218893Sdim  case ARM::PICLDR:
1509218893Sdim  case ARM::PICLDRB:
1510218893Sdim  case ARM::PICLDRH:
1511218893Sdim  case ARM::PICLDRSB:
1512218893Sdim  case ARM::PICLDRSH: {
1513218893Sdim    // This is a pseudo op for a label + instruction sequence, which looks like:
1514218893Sdim    // LPC0:
1515218893Sdim    //     OP r0, [pc, r0]
1516218893Sdim    // The LCP0 label is referenced by a constant pool entry in order to get
1517218893Sdim    // a PC-relative address at the ldr instruction.
1518218893Sdim
1519218893Sdim    // Emit the label.
1520218893Sdim    OutStreamer.EmitLabel(getPICLabel(MAI->getPrivateGlobalPrefix(),
1521218893Sdim                          getFunctionNumber(), MI->getOperand(2).getImm(),
1522218893Sdim                          OutContext));
1523218893Sdim
1524218893Sdim    // Form and emit the load
1525218893Sdim    unsigned Opcode;
1526218893Sdim    switch (MI->getOpcode()) {
1527218893Sdim    default:
1528218893Sdim      llvm_unreachable("Unexpected opcode!");
1529218893Sdim    case ARM::PICSTR:   Opcode = ARM::STRrs; break;
1530218893Sdim    case ARM::PICSTRB:  Opcode = ARM::STRBrs; break;
1531218893Sdim    case ARM::PICSTRH:  Opcode = ARM::STRH; break;
1532218893Sdim    case ARM::PICLDR:   Opcode = ARM::LDRrs; break;
1533218893Sdim    case ARM::PICLDRB:  Opcode = ARM::LDRBrs; break;
1534218893Sdim    case ARM::PICLDRH:  Opcode = ARM::LDRH; break;
1535218893Sdim    case ARM::PICLDRSB: Opcode = ARM::LDRSB; break;
1536218893Sdim    case ARM::PICLDRSH: Opcode = ARM::LDRSH; break;
1537218893Sdim    }
1538249423Sdim    OutStreamer.EmitInstruction(MCInstBuilder(Opcode)
1539249423Sdim      .addReg(MI->getOperand(0).getReg())
1540249423Sdim      .addReg(ARM::PC)
1541249423Sdim      .addReg(MI->getOperand(1).getReg())
1542249423Sdim      .addImm(0)
1543249423Sdim      // Add predicate operands.
1544249423Sdim      .addImm(MI->getOperand(3).getImm())
1545249423Sdim      .addReg(MI->getOperand(4).getReg()));
1546218893Sdim
1547218893Sdim    return;
1548218893Sdim  }
1549218893Sdim  case ARM::CONSTPOOL_ENTRY: {
1550212793Sdim    /// CONSTPOOL_ENTRY - This instruction represents a floating constant pool
1551212793Sdim    /// in the function.  The first operand is the ID# for this instruction, the
1552212793Sdim    /// second is the index into the MachineConstantPool that this is, the third
1553212793Sdim    /// is the size in bytes of this constant pool entry.
1554234353Sdim    /// The required alignment is specified on the basic block holding this MI.
1555212793Sdim    unsigned LabelId = (unsigned)MI->getOperand(0).getImm();
1556212793Sdim    unsigned CPIdx   = (unsigned)MI->getOperand(1).getIndex();
1557212793Sdim
1558239462Sdim    // If this is the first entry of the pool, mark it.
1559239462Sdim    if (!InConstantPool) {
1560239462Sdim      OutStreamer.EmitDataRegion(MCDR_DataRegion);
1561239462Sdim      InConstantPool = true;
1562239462Sdim    }
1563239462Sdim
1564212793Sdim    OutStreamer.EmitLabel(GetCPISymbol(LabelId));
1565212793Sdim
1566212793Sdim    const MachineConstantPoolEntry &MCPE = MCP->getConstants()[CPIdx];
1567212793Sdim    if (MCPE.isMachineConstantPoolEntry())
1568212793Sdim      EmitMachineConstantPoolValue(MCPE.Val.MachineCPVal);
1569212793Sdim    else
1570212793Sdim      EmitGlobalConstant(MCPE.Val.ConstVal);
1571212793Sdim    return;
1572212793Sdim  }
1573218893Sdim  case ARM::t2BR_JT: {
1574218893Sdim    // Lower and emit the instruction itself, then the jump table following it.
1575249423Sdim    OutStreamer.EmitInstruction(MCInstBuilder(ARM::tMOVr)
1576249423Sdim      .addReg(ARM::PC)
1577249423Sdim      .addReg(MI->getOperand(0).getReg())
1578249423Sdim      // Add predicate operands.
1579249423Sdim      .addImm(ARMCC::AL)
1580249423Sdim      .addReg(0));
1581249423Sdim
1582218893Sdim    // Output the data for the jump table itself
1583218893Sdim    EmitJump2Table(MI);
1584218893Sdim    return;
1585218893Sdim  }
1586218893Sdim  case ARM::t2TBB_JT: {
1587218893Sdim    // Lower and emit the instruction itself, then the jump table following it.
1588249423Sdim    OutStreamer.EmitInstruction(MCInstBuilder(ARM::t2TBB)
1589249423Sdim      .addReg(ARM::PC)
1590249423Sdim      .addReg(MI->getOperand(0).getReg())
1591249423Sdim      // Add predicate operands.
1592249423Sdim      .addImm(ARMCC::AL)
1593249423Sdim      .addReg(0));
1594212793Sdim
1595218893Sdim    // Output the data for the jump table itself
1596218893Sdim    EmitJump2Table(MI);
1597218893Sdim    // Make sure the next instruction is 2-byte aligned.
1598218893Sdim    EmitAlignment(1);
1599218893Sdim    return;
1600218893Sdim  }
1601218893Sdim  case ARM::t2TBH_JT: {
1602218893Sdim    // Lower and emit the instruction itself, then the jump table following it.
1603249423Sdim    OutStreamer.EmitInstruction(MCInstBuilder(ARM::t2TBH)
1604249423Sdim      .addReg(ARM::PC)
1605249423Sdim      .addReg(MI->getOperand(0).getReg())
1606249423Sdim      // Add predicate operands.
1607249423Sdim      .addImm(ARMCC::AL)
1608249423Sdim      .addReg(0));
1609212793Sdim
1610218893Sdim    // Output the data for the jump table itself
1611218893Sdim    EmitJump2Table(MI);
1612218893Sdim    return;
1613218893Sdim  }
1614218893Sdim  case ARM::tBR_JTr:
1615218893Sdim  case ARM::BR_JTr: {
1616218893Sdim    // Lower and emit the instruction itself, then the jump table following it.
1617218893Sdim    // mov pc, target
1618218893Sdim    MCInst TmpInst;
1619218893Sdim    unsigned Opc = MI->getOpcode() == ARM::BR_JTr ?
1620224145Sdim      ARM::MOVr : ARM::tMOVr;
1621218893Sdim    TmpInst.setOpcode(Opc);
1622218893Sdim    TmpInst.addOperand(MCOperand::CreateReg(ARM::PC));
1623218893Sdim    TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(0).getReg()));
1624218893Sdim    // Add predicate operands.
1625218893Sdim    TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL));
1626218893Sdim    TmpInst.addOperand(MCOperand::CreateReg(0));
1627218893Sdim    // Add 's' bit operand (always reg0 for this)
1628218893Sdim    if (Opc == ARM::MOVr)
1629218893Sdim      TmpInst.addOperand(MCOperand::CreateReg(0));
1630218893Sdim    OutStreamer.EmitInstruction(TmpInst);
1631212793Sdim
1632218893Sdim    // Make sure the Thumb jump table is 4-byte aligned.
1633224145Sdim    if (Opc == ARM::tMOVr)
1634218893Sdim      EmitAlignment(2);
1635218893Sdim
1636218893Sdim    // Output the data for the jump table itself
1637218893Sdim    EmitJumpTable(MI);
1638218893Sdim    return;
1639218893Sdim  }
1640218893Sdim  case ARM::BR_JTm: {
1641218893Sdim    // Lower and emit the instruction itself, then the jump table following it.
1642218893Sdim    // ldr pc, target
1643218893Sdim    MCInst TmpInst;
1644218893Sdim    if (MI->getOperand(1).getReg() == 0) {
1645218893Sdim      // literal offset
1646218893Sdim      TmpInst.setOpcode(ARM::LDRi12);
1647218893Sdim      TmpInst.addOperand(MCOperand::CreateReg(ARM::PC));
1648218893Sdim      TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(0).getReg()));
1649212793Sdim      TmpInst.addOperand(MCOperand::CreateImm(MI->getOperand(2).getImm()));
1650218893Sdim    } else {
1651218893Sdim      TmpInst.setOpcode(ARM::LDRrs);
1652218893Sdim      TmpInst.addOperand(MCOperand::CreateReg(ARM::PC));
1653218893Sdim      TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(0).getReg()));
1654218893Sdim      TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(1).getReg()));
1655218893Sdim      TmpInst.addOperand(MCOperand::CreateImm(0));
1656218893Sdim    }
1657218893Sdim    // Add predicate operands.
1658218893Sdim    TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL));
1659218893Sdim    TmpInst.addOperand(MCOperand::CreateReg(0));
1660218893Sdim    OutStreamer.EmitInstruction(TmpInst);
1661212793Sdim
1662218893Sdim    // Output the data for the jump table itself
1663218893Sdim    EmitJumpTable(MI);
1664218893Sdim    return;
1665218893Sdim  }
1666218893Sdim  case ARM::BR_JTadd: {
1667218893Sdim    // Lower and emit the instruction itself, then the jump table following it.
1668218893Sdim    // add pc, target, idx
1669249423Sdim    OutStreamer.EmitInstruction(MCInstBuilder(ARM::ADDrr)
1670249423Sdim      .addReg(ARM::PC)
1671249423Sdim      .addReg(MI->getOperand(0).getReg())
1672249423Sdim      .addReg(MI->getOperand(1).getReg())
1673249423Sdim      // Add predicate operands.
1674249423Sdim      .addImm(ARMCC::AL)
1675249423Sdim      .addReg(0)
1676249423Sdim      // Add 's' bit operand (always reg0 for this)
1677249423Sdim      .addReg(0));
1678218893Sdim
1679218893Sdim    // Output the data for the jump table itself
1680218893Sdim    EmitJumpTable(MI);
1681218893Sdim    return;
1682218893Sdim  }
1683218893Sdim  case ARM::TRAP: {
1684218893Sdim    // Non-Darwin binutils don't yet support the "trap" mnemonic.
1685218893Sdim    // FIXME: Remove this special case when they do.
1686218893Sdim    if (!Subtarget->isTargetDarwin()) {
1687218893Sdim      //.long 0xe7ffdefe @ trap
1688218893Sdim      uint32_t Val = 0xe7ffdefeUL;
1689218893Sdim      OutStreamer.AddComment("trap");
1690218893Sdim      OutStreamer.EmitIntValue(Val, 4);
1691218893Sdim      return;
1692218893Sdim    }
1693218893Sdim    break;
1694218893Sdim  }
1695249423Sdim  case ARM::TRAPNaCl: {
1696249423Sdim    //.long 0xe7fedef0 @ trap
1697249423Sdim    uint32_t Val = 0xe7fedef0UL;
1698249423Sdim    OutStreamer.AddComment("trap");
1699249423Sdim    OutStreamer.EmitIntValue(Val, 4);
1700249423Sdim    return;
1701249423Sdim  }
1702218893Sdim  case ARM::tTRAP: {
1703218893Sdim    // Non-Darwin binutils don't yet support the "trap" mnemonic.
1704218893Sdim    // FIXME: Remove this special case when they do.
1705218893Sdim    if (!Subtarget->isTargetDarwin()) {
1706218893Sdim      //.short 57086 @ trap
1707218893Sdim      uint16_t Val = 0xdefe;
1708218893Sdim      OutStreamer.AddComment("trap");
1709218893Sdim      OutStreamer.EmitIntValue(Val, 2);
1710218893Sdim      return;
1711218893Sdim    }
1712218893Sdim    break;
1713218893Sdim  }
1714218893Sdim  case ARM::t2Int_eh_sjlj_setjmp:
1715218893Sdim  case ARM::t2Int_eh_sjlj_setjmp_nofp:
1716218893Sdim  case ARM::tInt_eh_sjlj_setjmp: {
1717218893Sdim    // Two incoming args: GPR:$src, GPR:$val
1718218893Sdim    // mov $val, pc
1719218893Sdim    // adds $val, #7
1720218893Sdim    // str $val, [$src, #4]
1721218893Sdim    // movs r0, #0
1722218893Sdim    // b 1f
1723218893Sdim    // movs r0, #1
1724218893Sdim    // 1:
1725218893Sdim    unsigned SrcReg = MI->getOperand(0).getReg();
1726218893Sdim    unsigned ValReg = MI->getOperand(1).getReg();
1727218893Sdim    MCSymbol *Label = GetARMSJLJEHLabel();
1728249423Sdim    OutStreamer.AddComment("eh_setjmp begin");
1729249423Sdim    OutStreamer.EmitInstruction(MCInstBuilder(ARM::tMOVr)
1730249423Sdim      .addReg(ValReg)
1731249423Sdim      .addReg(ARM::PC)
1732224145Sdim      // Predicate.
1733249423Sdim      .addImm(ARMCC::AL)
1734249423Sdim      .addReg(0));
1735249423Sdim
1736249423Sdim    OutStreamer.EmitInstruction(MCInstBuilder(ARM::tADDi3)
1737249423Sdim      .addReg(ValReg)
1738218893Sdim      // 's' bit operand
1739249423Sdim      .addReg(ARM::CPSR)
1740249423Sdim      .addReg(ValReg)
1741249423Sdim      .addImm(7)
1742218893Sdim      // Predicate.
1743249423Sdim      .addImm(ARMCC::AL)
1744249423Sdim      .addReg(0));
1745249423Sdim
1746249423Sdim    OutStreamer.EmitInstruction(MCInstBuilder(ARM::tSTRi)
1747249423Sdim      .addReg(ValReg)
1748249423Sdim      .addReg(SrcReg)
1749218893Sdim      // The offset immediate is #4. The operand value is scaled by 4 for the
1750218893Sdim      // tSTR instruction.
1751249423Sdim      .addImm(1)
1752218893Sdim      // Predicate.
1753249423Sdim      .addImm(ARMCC::AL)
1754249423Sdim      .addReg(0));
1755249423Sdim
1756249423Sdim    OutStreamer.EmitInstruction(MCInstBuilder(ARM::tMOVi8)
1757249423Sdim      .addReg(ARM::R0)
1758249423Sdim      .addReg(ARM::CPSR)
1759249423Sdim      .addImm(0)
1760218893Sdim      // Predicate.
1761249423Sdim      .addImm(ARMCC::AL)
1762249423Sdim      .addReg(0));
1763249423Sdim
1764249423Sdim    const MCExpr *SymbolExpr = MCSymbolRefExpr::Create(Label, OutContext);
1765249423Sdim    OutStreamer.EmitInstruction(MCInstBuilder(ARM::tB)
1766249423Sdim      .addExpr(SymbolExpr)
1767249423Sdim      .addImm(ARMCC::AL)
1768249423Sdim      .addReg(0));
1769249423Sdim
1770249423Sdim    OutStreamer.AddComment("eh_setjmp end");
1771249423Sdim    OutStreamer.EmitInstruction(MCInstBuilder(ARM::tMOVi8)
1772249423Sdim      .addReg(ARM::R0)
1773249423Sdim      .addReg(ARM::CPSR)
1774249423Sdim      .addImm(1)
1775218893Sdim      // Predicate.
1776249423Sdim      .addImm(ARMCC::AL)
1777249423Sdim      .addReg(0));
1778249423Sdim
1779218893Sdim    OutStreamer.EmitLabel(Label);
1780218893Sdim    return;
1781218893Sdim  }
1782212793Sdim
1783218893Sdim  case ARM::Int_eh_sjlj_setjmp_nofp:
1784218893Sdim  case ARM::Int_eh_sjlj_setjmp: {
1785218893Sdim    // Two incoming args: GPR:$src, GPR:$val
1786218893Sdim    // add $val, pc, #8
1787218893Sdim    // str $val, [$src, #+4]
1788218893Sdim    // mov r0, #0
1789218893Sdim    // add pc, pc, #0
1790218893Sdim    // mov r0, #1
1791218893Sdim    unsigned SrcReg = MI->getOperand(0).getReg();
1792218893Sdim    unsigned ValReg = MI->getOperand(1).getReg();
1793218893Sdim
1794249423Sdim    OutStreamer.AddComment("eh_setjmp begin");
1795249423Sdim    OutStreamer.EmitInstruction(MCInstBuilder(ARM::ADDri)
1796249423Sdim      .addReg(ValReg)
1797249423Sdim      .addReg(ARM::PC)
1798249423Sdim      .addImm(8)
1799212793Sdim      // Predicate.
1800249423Sdim      .addImm(ARMCC::AL)
1801249423Sdim      .addReg(0)
1802218893Sdim      // 's' bit operand (always reg0 for this).
1803249423Sdim      .addReg(0));
1804249423Sdim
1805249423Sdim    OutStreamer.EmitInstruction(MCInstBuilder(ARM::STRi12)
1806249423Sdim      .addReg(ValReg)
1807249423Sdim      .addReg(SrcReg)
1808249423Sdim      .addImm(4)
1809218893Sdim      // Predicate.
1810249423Sdim      .addImm(ARMCC::AL)
1811249423Sdim      .addReg(0));
1812249423Sdim
1813249423Sdim    OutStreamer.EmitInstruction(MCInstBuilder(ARM::MOVi)
1814249423Sdim      .addReg(ARM::R0)
1815249423Sdim      .addImm(0)
1816218893Sdim      // Predicate.
1817249423Sdim      .addImm(ARMCC::AL)
1818249423Sdim      .addReg(0)
1819218893Sdim      // 's' bit operand (always reg0 for this).
1820249423Sdim      .addReg(0));
1821249423Sdim
1822249423Sdim    OutStreamer.EmitInstruction(MCInstBuilder(ARM::ADDri)
1823249423Sdim      .addReg(ARM::PC)
1824249423Sdim      .addReg(ARM::PC)
1825249423Sdim      .addImm(0)
1826218893Sdim      // Predicate.
1827249423Sdim      .addImm(ARMCC::AL)
1828249423Sdim      .addReg(0)
1829218893Sdim      // 's' bit operand (always reg0 for this).
1830249423Sdim      .addReg(0));
1831249423Sdim
1832249423Sdim    OutStreamer.AddComment("eh_setjmp end");
1833249423Sdim    OutStreamer.EmitInstruction(MCInstBuilder(ARM::MOVi)
1834249423Sdim      .addReg(ARM::R0)
1835249423Sdim      .addImm(1)
1836218893Sdim      // Predicate.
1837249423Sdim      .addImm(ARMCC::AL)
1838249423Sdim      .addReg(0)
1839218893Sdim      // 's' bit operand (always reg0 for this).
1840249423Sdim      .addReg(0));
1841212793Sdim    return;
1842212793Sdim  }
1843218893Sdim  case ARM::Int_eh_sjlj_longjmp: {
1844218893Sdim    // ldr sp, [$src, #8]
1845218893Sdim    // ldr $scratch, [$src, #4]
1846218893Sdim    // ldr r7, [$src]
1847218893Sdim    // bx $scratch
1848218893Sdim    unsigned SrcReg = MI->getOperand(0).getReg();
1849218893Sdim    unsigned ScratchReg = MI->getOperand(1).getReg();
1850249423Sdim    OutStreamer.EmitInstruction(MCInstBuilder(ARM::LDRi12)
1851249423Sdim      .addReg(ARM::SP)
1852249423Sdim      .addReg(SrcReg)
1853249423Sdim      .addImm(8)
1854218893Sdim      // Predicate.
1855249423Sdim      .addImm(ARMCC::AL)
1856249423Sdim      .addReg(0));
1857249423Sdim
1858249423Sdim    OutStreamer.EmitInstruction(MCInstBuilder(ARM::LDRi12)
1859249423Sdim      .addReg(ScratchReg)
1860249423Sdim      .addReg(SrcReg)
1861249423Sdim      .addImm(4)
1862212793Sdim      // Predicate.
1863249423Sdim      .addImm(ARMCC::AL)
1864249423Sdim      .addReg(0));
1865249423Sdim
1866249423Sdim    OutStreamer.EmitInstruction(MCInstBuilder(ARM::LDRi12)
1867249423Sdim      .addReg(ARM::R7)
1868249423Sdim      .addReg(SrcReg)
1869249423Sdim      .addImm(0)
1870212793Sdim      // Predicate.
1871249423Sdim      .addImm(ARMCC::AL)
1872249423Sdim      .addReg(0));
1873249423Sdim
1874249423Sdim    OutStreamer.EmitInstruction(MCInstBuilder(ARM::BX)
1875249423Sdim      .addReg(ScratchReg)
1876218893Sdim      // Predicate.
1877249423Sdim      .addImm(ARMCC::AL)
1878249423Sdim      .addReg(0));
1879212793Sdim    return;
1880212793Sdim  }
1881218893Sdim  case ARM::tInt_eh_sjlj_longjmp: {
1882218893Sdim    // ldr $scratch, [$src, #8]
1883218893Sdim    // mov sp, $scratch
1884218893Sdim    // ldr $scratch, [$src, #4]
1885218893Sdim    // ldr r7, [$src]
1886218893Sdim    // bx $scratch
1887218893Sdim    unsigned SrcReg = MI->getOperand(0).getReg();
1888218893Sdim    unsigned ScratchReg = MI->getOperand(1).getReg();
1889249423Sdim    OutStreamer.EmitInstruction(MCInstBuilder(ARM::tLDRi)
1890249423Sdim      .addReg(ScratchReg)
1891249423Sdim      .addReg(SrcReg)
1892218893Sdim      // The offset immediate is #8. The operand value is scaled by 4 for the
1893218893Sdim      // tLDR instruction.
1894249423Sdim      .addImm(2)
1895218893Sdim      // Predicate.
1896249423Sdim      .addImm(ARMCC::AL)
1897249423Sdim      .addReg(0));
1898249423Sdim
1899249423Sdim    OutStreamer.EmitInstruction(MCInstBuilder(ARM::tMOVr)
1900249423Sdim      .addReg(ARM::SP)
1901249423Sdim      .addReg(ScratchReg)
1902218893Sdim      // Predicate.
1903249423Sdim      .addImm(ARMCC::AL)
1904249423Sdim      .addReg(0));
1905249423Sdim
1906249423Sdim    OutStreamer.EmitInstruction(MCInstBuilder(ARM::tLDRi)
1907249423Sdim      .addReg(ScratchReg)
1908249423Sdim      .addReg(SrcReg)
1909249423Sdim      .addImm(1)
1910218893Sdim      // Predicate.
1911249423Sdim      .addImm(ARMCC::AL)
1912249423Sdim      .addReg(0));
1913249423Sdim
1914249423Sdim    OutStreamer.EmitInstruction(MCInstBuilder(ARM::tLDRi)
1915249423Sdim      .addReg(ARM::R7)
1916249423Sdim      .addReg(SrcReg)
1917249423Sdim      .addImm(0)
1918218893Sdim      // Predicate.
1919249423Sdim      .addImm(ARMCC::AL)
1920249423Sdim      .addReg(0));
1921249423Sdim
1922249423Sdim    OutStreamer.EmitInstruction(MCInstBuilder(ARM::tBX)
1923249423Sdim      .addReg(ScratchReg)
1924218893Sdim      // Predicate.
1925249423Sdim      .addImm(ARMCC::AL)
1926249423Sdim      .addReg(0));
1927218893Sdim    return;
1928212793Sdim  }
1929221345Sdim  }
1930221345Sdim
1931212793Sdim  MCInst TmpInst;
1932218893Sdim  LowerARMMachineInstrToMCInst(MI, TmpInst, *this);
1933221345Sdim
1934212793Sdim  OutStreamer.EmitInstruction(TmpInst);
1935212793Sdim}
1936212793Sdim
1937212793Sdim//===----------------------------------------------------------------------===//
1938212793Sdim// Target Registry Stuff
1939212793Sdim//===----------------------------------------------------------------------===//
1940212793Sdim
1941212793Sdim// Force static initialization.
1942212793Sdimextern "C" void LLVMInitializeARMAsmPrinter() {
1943212793Sdim  RegisterAsmPrinter<ARMAsmPrinter> X(TheARMTarget);
1944212793Sdim  RegisterAsmPrinter<ARMAsmPrinter> Y(TheThumbTarget);
1945212793Sdim}
1946