ARMMCCodeEmitter.cpp revision 54fea632b161f98e96ec7275922e35102bcecc5d
1568eeedea72c274abbba1310c18a31eef78e14a4Jim Grosbach//===-- ARM/ARMMCCodeEmitter.cpp - Convert ARM code to machine code -------===//
2568eeedea72c274abbba1310c18a31eef78e14a4Jim Grosbach//
3568eeedea72c274abbba1310c18a31eef78e14a4Jim Grosbach//                     The LLVM Compiler Infrastructure
4568eeedea72c274abbba1310c18a31eef78e14a4Jim Grosbach//
5568eeedea72c274abbba1310c18a31eef78e14a4Jim Grosbach// This file is distributed under the University of Illinois Open Source
6568eeedea72c274abbba1310c18a31eef78e14a4Jim Grosbach// License. See LICENSE.TXT for details.
7568eeedea72c274abbba1310c18a31eef78e14a4Jim Grosbach//
8568eeedea72c274abbba1310c18a31eef78e14a4Jim Grosbach//===----------------------------------------------------------------------===//
9568eeedea72c274abbba1310c18a31eef78e14a4Jim Grosbach//
10568eeedea72c274abbba1310c18a31eef78e14a4Jim Grosbach// This file implements the ARMMCCodeEmitter class.
11568eeedea72c274abbba1310c18a31eef78e14a4Jim Grosbach//
12568eeedea72c274abbba1310c18a31eef78e14a4Jim Grosbach//===----------------------------------------------------------------------===//
13568eeedea72c274abbba1310c18a31eef78e14a4Jim Grosbach
14568eeedea72c274abbba1310c18a31eef78e14a4Jim Grosbach#define DEBUG_TYPE "arm-emitter"
15568eeedea72c274abbba1310c18a31eef78e14a4Jim Grosbach#include "ARM.h"
1642fac8ee3bc02e18a5887800e812af762b45b9ebJim Grosbach#include "ARMAddressingModes.h"
1770933266ae73c891d9d1c2f0de72ecd1db8f86dfJim Grosbach#include "ARMFixupKinds.h"
18d6d4b42ba473657b6d30242962f0d0fb23fe126eJim Grosbach#include "ARMInstrInfo.h"
19568eeedea72c274abbba1310c18a31eef78e14a4Jim Grosbach#include "llvm/MC/MCCodeEmitter.h"
20568eeedea72c274abbba1310c18a31eef78e14a4Jim Grosbach#include "llvm/MC/MCExpr.h"
21568eeedea72c274abbba1310c18a31eef78e14a4Jim Grosbach#include "llvm/MC/MCInst.h"
22d6d4b42ba473657b6d30242962f0d0fb23fe126eJim Grosbach#include "llvm/ADT/Statistic.h"
23568eeedea72c274abbba1310c18a31eef78e14a4Jim Grosbach#include "llvm/Support/raw_ostream.h"
24568eeedea72c274abbba1310c18a31eef78e14a4Jim Grosbachusing namespace llvm;
25568eeedea72c274abbba1310c18a31eef78e14a4Jim Grosbach
2670933266ae73c891d9d1c2f0de72ecd1db8f86dfJim GrosbachSTATISTIC(MCNumEmitted, "Number of MC instructions emitted.");
2770933266ae73c891d9d1c2f0de72ecd1db8f86dfJim GrosbachSTATISTIC(MCNumCPRelocations, "Number of constant pool relocations created.");
28d6d4b42ba473657b6d30242962f0d0fb23fe126eJim Grosbach
29568eeedea72c274abbba1310c18a31eef78e14a4Jim Grosbachnamespace {
30568eeedea72c274abbba1310c18a31eef78e14a4Jim Grosbachclass ARMMCCodeEmitter : public MCCodeEmitter {
31568eeedea72c274abbba1310c18a31eef78e14a4Jim Grosbach  ARMMCCodeEmitter(const ARMMCCodeEmitter &); // DO NOT IMPLEMENT
32568eeedea72c274abbba1310c18a31eef78e14a4Jim Grosbach  void operator=(const ARMMCCodeEmitter &); // DO NOT IMPLEMENT
33568eeedea72c274abbba1310c18a31eef78e14a4Jim Grosbach  const TargetMachine &TM;
34568eeedea72c274abbba1310c18a31eef78e14a4Jim Grosbach  const TargetInstrInfo &TII;
35568eeedea72c274abbba1310c18a31eef78e14a4Jim Grosbach  MCContext &Ctx;
36568eeedea72c274abbba1310c18a31eef78e14a4Jim Grosbach
37568eeedea72c274abbba1310c18a31eef78e14a4Jim Grosbachpublic:
38568eeedea72c274abbba1310c18a31eef78e14a4Jim Grosbach  ARMMCCodeEmitter(TargetMachine &tm, MCContext &ctx)
39568eeedea72c274abbba1310c18a31eef78e14a4Jim Grosbach    : TM(tm), TII(*TM.getInstrInfo()), Ctx(ctx) {
40568eeedea72c274abbba1310c18a31eef78e14a4Jim Grosbach  }
41568eeedea72c274abbba1310c18a31eef78e14a4Jim Grosbach
42568eeedea72c274abbba1310c18a31eef78e14a4Jim Grosbach  ~ARMMCCodeEmitter() {}
43568eeedea72c274abbba1310c18a31eef78e14a4Jim Grosbach
4470933266ae73c891d9d1c2f0de72ecd1db8f86dfJim Grosbach  unsigned getNumFixupKinds() const { return 2; }
4570933266ae73c891d9d1c2f0de72ecd1db8f86dfJim Grosbach
4670933266ae73c891d9d1c2f0de72ecd1db8f86dfJim Grosbach  const MCFixupKindInfo &getFixupKindInfo(MCFixupKind Kind) const {
4770933266ae73c891d9d1c2f0de72ecd1db8f86dfJim Grosbach    const static MCFixupKindInfo Infos[] = {
4870933266ae73c891d9d1c2f0de72ecd1db8f86dfJim Grosbach      { "fixup_arm_pcrel_12", 2, 12, MCFixupKindInfo::FKF_IsPCRel },
4970933266ae73c891d9d1c2f0de72ecd1db8f86dfJim Grosbach      { "fixup_arm_vfp_pcrel_12", 3, 8, MCFixupKindInfo::FKF_IsPCRel },
5070933266ae73c891d9d1c2f0de72ecd1db8f86dfJim Grosbach    };
5170933266ae73c891d9d1c2f0de72ecd1db8f86dfJim Grosbach
5270933266ae73c891d9d1c2f0de72ecd1db8f86dfJim Grosbach    if (Kind < FirstTargetFixupKind)
5370933266ae73c891d9d1c2f0de72ecd1db8f86dfJim Grosbach      return MCCodeEmitter::getFixupKindInfo(Kind);
5470933266ae73c891d9d1c2f0de72ecd1db8f86dfJim Grosbach
5570933266ae73c891d9d1c2f0de72ecd1db8f86dfJim Grosbach    assert(unsigned(Kind - FirstTargetFixupKind) < getNumFixupKinds() &&
5670933266ae73c891d9d1c2f0de72ecd1db8f86dfJim Grosbach           "Invalid kind!");
5770933266ae73c891d9d1c2f0de72ecd1db8f86dfJim Grosbach    return Infos[Kind - FirstTargetFixupKind];
5870933266ae73c891d9d1c2f0de72ecd1db8f86dfJim Grosbach  }
590de6ab3c43ed2143d661115dddf1480545236c91Jim Grosbach  unsigned getMachineSoImmOpValue(unsigned SoImm) const;
600de6ab3c43ed2143d661115dddf1480545236c91Jim Grosbach
619af82ba42b53905f580f8c4270626946e3548654Jim Grosbach  // getBinaryCodeForInstr - TableGen'erated function for getting the
629af82ba42b53905f580f8c4270626946e3548654Jim Grosbach  // binary encoding for an instruction.
63806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbach  unsigned getBinaryCodeForInstr(const MCInst &MI,
64806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbach                                 SmallVectorImpl<MCFixup> &Fixups) const;
659af82ba42b53905f580f8c4270626946e3548654Jim Grosbach
669af82ba42b53905f580f8c4270626946e3548654Jim Grosbach  /// getMachineOpValue - Return binary encoding of operand. If the machine
679af82ba42b53905f580f8c4270626946e3548654Jim Grosbach  /// operand requires relocation, record the relocation and return zero.
68806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbach  unsigned getMachineOpValue(const MCInst &MI,const MCOperand &MO,
69806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbach                             SmallVectorImpl<MCFixup> &Fixups) const;
709af82ba42b53905f580f8c4270626946e3548654Jim Grosbach
7192b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling  bool EncodeAddrModeOpValues(const MCInst &MI, unsigned OpIdx,
72806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbach                              unsigned &Reg, unsigned &Imm,
73806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbach                              SmallVectorImpl<MCFixup> &Fixups) const;
7492b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling
7592b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling  /// getAddrModeImm12OpValue - Return encoding info for 'reg +/- imm12'
7692b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling  /// operand.
77806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbach  uint32_t getAddrModeImm12OpValue(const MCInst &MI, unsigned OpIdx,
78806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbach                                   SmallVectorImpl<MCFixup> &Fixups) const;
7992b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling
8054fea632b161f98e96ec7275922e35102bcecc5dJim Grosbach  /// getLdStSORegOpValue - Return encoding info for 'reg +/- reg shop imm'
8154fea632b161f98e96ec7275922e35102bcecc5dJim Grosbach  /// operand as needed by load/store instructions.
8254fea632b161f98e96ec7275922e35102bcecc5dJim Grosbach  uint32_t getLdStSORegOpValue(const MCInst &MI, unsigned OpIdx,
8354fea632b161f98e96ec7275922e35102bcecc5dJim Grosbach                               SmallVectorImpl<MCFixup> &Fixups) const;
8454fea632b161f98e96ec7275922e35102bcecc5dJim Grosbach
8592b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling  /// getAddrMode5OpValue - Return encoding info for 'reg +/- imm8' operand.
86806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbach  uint32_t getAddrMode5OpValue(const MCInst &MI, unsigned OpIdx,
87806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbach                               SmallVectorImpl<MCFixup> &Fixups) const;
883e5561247202bae994dd259a2d8dc4eff8f799f3Jim Grosbach
8908bd54987f4ae482de13436e7254ff08b23f825fJim Grosbach  /// getCCOutOpValue - Return encoding of the 's' bit.
90806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbach  unsigned getCCOutOpValue(const MCInst &MI, unsigned Op,
91806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbach                           SmallVectorImpl<MCFixup> &Fixups) const {
9208bd54987f4ae482de13436e7254ff08b23f825fJim Grosbach    // The operand is either reg0 or CPSR. The 's' bit is encoded as '0' or
9308bd54987f4ae482de13436e7254ff08b23f825fJim Grosbach    // '1' respectively.
9408bd54987f4ae482de13436e7254ff08b23f825fJim Grosbach    return MI.getOperand(Op).getReg() == ARM::CPSR;
9508bd54987f4ae482de13436e7254ff08b23f825fJim Grosbach  }
96ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach
972a6a93d5425b38546de2b6674719d52f565171d8Jim Grosbach  /// getSOImmOpValue - Return an encoded 12-bit shifted-immediate value.
98806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbach  unsigned getSOImmOpValue(const MCInst &MI, unsigned Op,
99806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbach                           SmallVectorImpl<MCFixup> &Fixups) const {
1002a6a93d5425b38546de2b6674719d52f565171d8Jim Grosbach    unsigned SoImm = MI.getOperand(Op).getImm();
1012a6a93d5425b38546de2b6674719d52f565171d8Jim Grosbach    int SoImmVal = ARM_AM::getSOImmVal(SoImm);
1022a6a93d5425b38546de2b6674719d52f565171d8Jim Grosbach    assert(SoImmVal != -1 && "Not a valid so_imm value!");
1032a6a93d5425b38546de2b6674719d52f565171d8Jim Grosbach
1042a6a93d5425b38546de2b6674719d52f565171d8Jim Grosbach    // Encode rotate_imm.
1052a6a93d5425b38546de2b6674719d52f565171d8Jim Grosbach    unsigned Binary = (ARM_AM::getSOImmValRot((unsigned)SoImmVal) >> 1)
1062a6a93d5425b38546de2b6674719d52f565171d8Jim Grosbach      << ARMII::SoRotImmShift;
1072a6a93d5425b38546de2b6674719d52f565171d8Jim Grosbach
1082a6a93d5425b38546de2b6674719d52f565171d8Jim Grosbach    // Encode immed_8.
1092a6a93d5425b38546de2b6674719d52f565171d8Jim Grosbach    Binary |= ARM_AM::getSOImmValImm((unsigned)SoImmVal);
1102a6a93d5425b38546de2b6674719d52f565171d8Jim Grosbach    return Binary;
1112a6a93d5425b38546de2b6674719d52f565171d8Jim Grosbach  }
11208bd54987f4ae482de13436e7254ff08b23f825fJim Grosbach
113ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach  /// getSORegOpValue - Return an encoded so_reg shifted register value.
114806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbach  unsigned getSORegOpValue(const MCInst &MI, unsigned Op,
115806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbach                           SmallVectorImpl<MCFixup> &Fixups) const;
116ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach
117806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbach  unsigned getRotImmOpValue(const MCInst &MI, unsigned Op,
118806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbach                            SmallVectorImpl<MCFixup> &Fixups) const {
119b35ad41fef5d1edd9495f708fb7eae1a0a94ef9dJim Grosbach    switch (MI.getOperand(Op).getImm()) {
120b35ad41fef5d1edd9495f708fb7eae1a0a94ef9dJim Grosbach    default: assert (0 && "Not a valid rot_imm value!");
121b35ad41fef5d1edd9495f708fb7eae1a0a94ef9dJim Grosbach    case 0:  return 0;
122b35ad41fef5d1edd9495f708fb7eae1a0a94ef9dJim Grosbach    case 8:  return 1;
123b35ad41fef5d1edd9495f708fb7eae1a0a94ef9dJim Grosbach    case 16: return 2;
124b35ad41fef5d1edd9495f708fb7eae1a0a94ef9dJim Grosbach    case 24: return 3;
125b35ad41fef5d1edd9495f708fb7eae1a0a94ef9dJim Grosbach    }
126b35ad41fef5d1edd9495f708fb7eae1a0a94ef9dJim Grosbach  }
127b35ad41fef5d1edd9495f708fb7eae1a0a94ef9dJim Grosbach
128806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbach  unsigned getImmMinusOneOpValue(const MCInst &MI, unsigned Op,
129806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbach                                 SmallVectorImpl<MCFixup> &Fixups) const {
1308abe32af38b66bf4577526b23b6af6ec7eb6c155Jim Grosbach    return MI.getOperand(Op).getImm() - 1;
1318abe32af38b66bf4577526b23b6af6ec7eb6c155Jim Grosbach  }
132d8a11c25fa64c152628cfcf5f9d36eb60242b302Jim Grosbach
133806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbach  unsigned getNEONVcvtImm32OpValue(const MCInst &MI, unsigned Op,
134806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbach                                   SmallVectorImpl<MCFixup> &Fixups) const {
135498ec20703c89d0c2890b0967791f0f5f2b59a2fOwen Anderson    return 64 - MI.getOperand(Op).getImm();
136498ec20703c89d0c2890b0967791f0f5f2b59a2fOwen Anderson  }
1378abe32af38b66bf4577526b23b6af6ec7eb6c155Jim Grosbach
138806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbach  unsigned getBitfieldInvertedMaskOpValue(const MCInst &MI, unsigned Op,
139806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbach                                      SmallVectorImpl<MCFixup> &Fixups) const;
1403fea19105d4929ad694f0b6272de31924c9f9f09Jim Grosbach
141806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbach  unsigned getRegisterListOpValue(const MCInst &MI, unsigned Op,
142806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbach                                  SmallVectorImpl<MCFixup> &Fixups) const;
143806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbach  unsigned getAddrMode6AddressOpValue(const MCInst &MI, unsigned Op,
144806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbach                                      SmallVectorImpl<MCFixup> &Fixups) const;
145806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbach  unsigned getAddrMode6OffsetOpValue(const MCInst &MI, unsigned Op,
146806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbach                                     SmallVectorImpl<MCFixup> &Fixups) const;
1476b5252db2db5eeeadec4602329ac56beb6dea54aJim Grosbach
14870933266ae73c891d9d1c2f0de72ecd1db8f86dfJim Grosbach  void EmitByte(unsigned char C, raw_ostream &OS) const {
149568eeedea72c274abbba1310c18a31eef78e14a4Jim Grosbach    OS << (char)C;
150568eeedea72c274abbba1310c18a31eef78e14a4Jim Grosbach  }
151568eeedea72c274abbba1310c18a31eef78e14a4Jim Grosbach
15270933266ae73c891d9d1c2f0de72ecd1db8f86dfJim Grosbach  void EmitConstant(uint64_t Val, unsigned Size, raw_ostream &OS) const {
153568eeedea72c274abbba1310c18a31eef78e14a4Jim Grosbach    // Output the constant in little endian byte order.
154568eeedea72c274abbba1310c18a31eef78e14a4Jim Grosbach    for (unsigned i = 0; i != Size; ++i) {
15570933266ae73c891d9d1c2f0de72ecd1db8f86dfJim Grosbach      EmitByte(Val & 255, OS);
156568eeedea72c274abbba1310c18a31eef78e14a4Jim Grosbach      Val >>= 8;
157568eeedea72c274abbba1310c18a31eef78e14a4Jim Grosbach    }
158568eeedea72c274abbba1310c18a31eef78e14a4Jim Grosbach  }
159568eeedea72c274abbba1310c18a31eef78e14a4Jim Grosbach
160568eeedea72c274abbba1310c18a31eef78e14a4Jim Grosbach  void EncodeInstruction(const MCInst &MI, raw_ostream &OS,
161568eeedea72c274abbba1310c18a31eef78e14a4Jim Grosbach                         SmallVectorImpl<MCFixup> &Fixups) const;
162568eeedea72c274abbba1310c18a31eef78e14a4Jim Grosbach};
163568eeedea72c274abbba1310c18a31eef78e14a4Jim Grosbach
164568eeedea72c274abbba1310c18a31eef78e14a4Jim Grosbach} // end anonymous namespace
165568eeedea72c274abbba1310c18a31eef78e14a4Jim Grosbach
1660800ce71896ccd7f49b37861a8cfbc21b6b10022Bill WendlingMCCodeEmitter *llvm::createARMMCCodeEmitter(const Target &, TargetMachine &TM,
1670800ce71896ccd7f49b37861a8cfbc21b6b10022Bill Wendling                                            MCContext &Ctx) {
168568eeedea72c274abbba1310c18a31eef78e14a4Jim Grosbach  return new ARMMCCodeEmitter(TM, Ctx);
169568eeedea72c274abbba1310c18a31eef78e14a4Jim Grosbach}
170568eeedea72c274abbba1310c18a31eef78e14a4Jim Grosbach
17156ac907c57fcfddfd650238f03c856a9d55987e5Jim Grosbach/// getMachineOpValue - Return binary encoding of operand. If the machine
17256ac907c57fcfddfd650238f03c856a9d55987e5Jim Grosbach/// operand requires relocation, record the relocation and return zero.
173806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbachunsigned ARMMCCodeEmitter::
174806e80ef42bdb416f409142a1ff1d4e8752baac8Jim GrosbachgetMachineOpValue(const MCInst &MI, const MCOperand &MO,
175806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbach                  SmallVectorImpl<MCFixup> &Fixups) const {
176bbbdcd453d22258cb4dd217eddf016668fcebf84Bill Wendling  if (MO.isReg()) {
1770800ce71896ccd7f49b37861a8cfbc21b6b10022Bill Wendling    unsigned Reg = MO.getReg();
1780800ce71896ccd7f49b37861a8cfbc21b6b10022Bill Wendling    unsigned RegNo = getARMRegisterNumbering(Reg);
179d8a11c25fa64c152628cfcf5f9d36eb60242b302Jim Grosbach
18090d4cf931477b497553a9f2d0ed53377dd5dd88cOwen Anderson    // Q registers are encodes as 2x their register number.
1810800ce71896ccd7f49b37861a8cfbc21b6b10022Bill Wendling    switch (Reg) {
1820800ce71896ccd7f49b37861a8cfbc21b6b10022Bill Wendling    default:
1830800ce71896ccd7f49b37861a8cfbc21b6b10022Bill Wendling      return RegNo;
1840800ce71896ccd7f49b37861a8cfbc21b6b10022Bill Wendling    case ARM::Q0:  case ARM::Q1:  case ARM::Q2:  case ARM::Q3:
1850800ce71896ccd7f49b37861a8cfbc21b6b10022Bill Wendling    case ARM::Q4:  case ARM::Q5:  case ARM::Q6:  case ARM::Q7:
1860800ce71896ccd7f49b37861a8cfbc21b6b10022Bill Wendling    case ARM::Q8:  case ARM::Q9:  case ARM::Q10: case ARM::Q11:
1870800ce71896ccd7f49b37861a8cfbc21b6b10022Bill Wendling    case ARM::Q12: case ARM::Q13: case ARM::Q14: case ARM::Q15:
1880800ce71896ccd7f49b37861a8cfbc21b6b10022Bill Wendling      return 2 * RegNo;
18990d4cf931477b497553a9f2d0ed53377dd5dd88cOwen Anderson    }
190bbbdcd453d22258cb4dd217eddf016668fcebf84Bill Wendling  } else if (MO.isImm()) {
19156ac907c57fcfddfd650238f03c856a9d55987e5Jim Grosbach    return static_cast<unsigned>(MO.getImm());
192bbbdcd453d22258cb4dd217eddf016668fcebf84Bill Wendling  } else if (MO.isFPImm()) {
193bbbdcd453d22258cb4dd217eddf016668fcebf84Bill Wendling    return static_cast<unsigned>(APFloat(MO.getFPImm())
194bbbdcd453d22258cb4dd217eddf016668fcebf84Bill Wendling                     .bitcastToAPInt().getHiBits(32).getLimitedValue());
1950800ce71896ccd7f49b37861a8cfbc21b6b10022Bill Wendling  }
1960800ce71896ccd7f49b37861a8cfbc21b6b10022Bill Wendling
19756ac907c57fcfddfd650238f03c856a9d55987e5Jim Grosbach#ifndef NDEBUG
1980800ce71896ccd7f49b37861a8cfbc21b6b10022Bill Wendling  errs() << MO;
19956ac907c57fcfddfd650238f03c856a9d55987e5Jim Grosbach#endif
2000800ce71896ccd7f49b37861a8cfbc21b6b10022Bill Wendling  llvm_unreachable(0);
20156ac907c57fcfddfd650238f03c856a9d55987e5Jim Grosbach  return 0;
20256ac907c57fcfddfd650238f03c856a9d55987e5Jim Grosbach}
20356ac907c57fcfddfd650238f03c856a9d55987e5Jim Grosbach
2045df0e0a61d6ac0e8dcf1a600bdc28d3e4a8db0adBill Wendling/// getAddrModeImmOpValue - Return encoding info for 'reg +/- imm' operand.
205806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbachbool ARMMCCodeEmitter::
206806e80ef42bdb416f409142a1ff1d4e8752baac8Jim GrosbachEncodeAddrModeOpValues(const MCInst &MI, unsigned OpIdx, unsigned &Reg,
207806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbach                       unsigned &Imm, SmallVectorImpl<MCFixup> &Fixups) const {
2083e5561247202bae994dd259a2d8dc4eff8f799f3Jim Grosbach  const MCOperand &MO  = MI.getOperand(OpIdx);
2093e5561247202bae994dd259a2d8dc4eff8f799f3Jim Grosbach  const MCOperand &MO1 = MI.getOperand(OpIdx + 1);
2109af3d1c0dc2250793ada1ca6cfa98e9f1253f7f9Jim Grosbach
21192b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling  Reg = getARMRegisterNumbering(MO.getReg());
21292b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling
21392b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling  int32_t SImm = MO1.getImm();
21492b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling  bool isAdd = true;
2155df0e0a61d6ac0e8dcf1a600bdc28d3e4a8db0adBill Wendling
216ab682a2090f795d0b67f29889622da0a74cd97c3Jim Grosbach  // Special value for #-0
21792b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling  if (SImm == INT32_MIN)
21892b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling    SImm = 0;
2195df0e0a61d6ac0e8dcf1a600bdc28d3e4a8db0adBill Wendling
220ab682a2090f795d0b67f29889622da0a74cd97c3Jim Grosbach  // Immediate is always encoded as positive. The 'U' bit controls add vs sub.
22192b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling  if (SImm < 0) {
22292b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling    SImm = -SImm;
22392b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling    isAdd = false;
22492b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling  }
22592b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling
22692b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling  Imm = SImm;
22792b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling  return isAdd;
22892b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling}
2295df0e0a61d6ac0e8dcf1a600bdc28d3e4a8db0adBill Wendling
23092b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling/// getAddrModeImm12OpValue - Return encoding info for 'reg +/- imm12' operand.
231806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbachuint32_t ARMMCCodeEmitter::
232806e80ef42bdb416f409142a1ff1d4e8752baac8Jim GrosbachgetAddrModeImm12OpValue(const MCInst &MI, unsigned OpIdx,
233806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbach                        SmallVectorImpl<MCFixup> &Fixups) const {
23492b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling  // {17-13} = reg
23592b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling  // {12}    = (U)nsigned (add == '1', sub == '0')
23692b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling  // {11-0}  = imm12
23792b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling  unsigned Reg, Imm12;
23870933266ae73c891d9d1c2f0de72ecd1db8f86dfJim Grosbach  bool isAdd = true;
23970933266ae73c891d9d1c2f0de72ecd1db8f86dfJim Grosbach  // If The first operand isn't a register, we have a label reference.
24070933266ae73c891d9d1c2f0de72ecd1db8f86dfJim Grosbach  const MCOperand &MO = MI.getOperand(OpIdx);
24170933266ae73c891d9d1c2f0de72ecd1db8f86dfJim Grosbach  if (!MO.isReg()) {
242679cbd3b215b1769a6035e334f9009aeeb940dddJim Grosbach    Reg = getARMRegisterNumbering(ARM::PC);   // Rn is PC.
24370933266ae73c891d9d1c2f0de72ecd1db8f86dfJim Grosbach    Imm12 = 0;
24470933266ae73c891d9d1c2f0de72ecd1db8f86dfJim Grosbach
24570933266ae73c891d9d1c2f0de72ecd1db8f86dfJim Grosbach    assert(MO.isExpr() && "Unexpected machine operand type!");
24670933266ae73c891d9d1c2f0de72ecd1db8f86dfJim Grosbach    const MCExpr *Expr = MO.getExpr();
24770933266ae73c891d9d1c2f0de72ecd1db8f86dfJim Grosbach    MCFixupKind Kind = MCFixupKind(ARM::fixup_arm_pcrel_12);
24870933266ae73c891d9d1c2f0de72ecd1db8f86dfJim Grosbach    Fixups.push_back(MCFixup::Create(0, Expr, Kind));
24970933266ae73c891d9d1c2f0de72ecd1db8f86dfJim Grosbach
25070933266ae73c891d9d1c2f0de72ecd1db8f86dfJim Grosbach    ++MCNumCPRelocations;
25170933266ae73c891d9d1c2f0de72ecd1db8f86dfJim Grosbach  } else
25270933266ae73c891d9d1c2f0de72ecd1db8f86dfJim Grosbach    isAdd = EncodeAddrModeOpValues(MI, OpIdx, Reg, Imm12, Fixups);
25392b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling
25492b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling  uint32_t Binary = Imm12 & 0xfff;
25592b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling  // Immediate is always encoded as positive. The 'U' bit controls add vs sub.
256ab682a2090f795d0b67f29889622da0a74cd97c3Jim Grosbach  if (isAdd)
25792b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling    Binary |= (1 << 12);
25892b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling  Binary |= (Reg << 13);
25992b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling  return Binary;
26092b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling}
26192b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling
26254fea632b161f98e96ec7275922e35102bcecc5dJim Grosbachuint32_t ARMMCCodeEmitter::
26354fea632b161f98e96ec7275922e35102bcecc5dJim GrosbachgetLdStSORegOpValue(const MCInst &MI, unsigned OpIdx,
26454fea632b161f98e96ec7275922e35102bcecc5dJim Grosbach                    SmallVectorImpl<MCFixup> &Fixups) const {
26554fea632b161f98e96ec7275922e35102bcecc5dJim Grosbach  const MCOperand &MO = MI.getOperand(OpIdx);
26654fea632b161f98e96ec7275922e35102bcecc5dJim Grosbach  const MCOperand &MO1 = MI.getOperand(OpIdx+1);
26754fea632b161f98e96ec7275922e35102bcecc5dJim Grosbach  const MCOperand &MO2 = MI.getOperand(OpIdx+2);
26854fea632b161f98e96ec7275922e35102bcecc5dJim Grosbach  unsigned Rn = getARMRegisterNumbering(MO.getReg());
26954fea632b161f98e96ec7275922e35102bcecc5dJim Grosbach  unsigned Rm = getARMRegisterNumbering(MO1.getReg());
27054fea632b161f98e96ec7275922e35102bcecc5dJim Grosbach  ARM_AM::ShiftOpc ShOp = ARM_AM::getAM2ShiftOpc(MO2.getImm());
27154fea632b161f98e96ec7275922e35102bcecc5dJim Grosbach  unsigned ShImm = ARM_AM::getAM2Offset(MO2.getImm());
27254fea632b161f98e96ec7275922e35102bcecc5dJim Grosbach  bool isAdd = ARM_AM::getAM2Op(MO2.getImm()) == ARM_AM::add;
27354fea632b161f98e96ec7275922e35102bcecc5dJim Grosbach  unsigned SBits;
27454fea632b161f98e96ec7275922e35102bcecc5dJim Grosbach  // LSL - 00
27554fea632b161f98e96ec7275922e35102bcecc5dJim Grosbach  // LSR - 01
27654fea632b161f98e96ec7275922e35102bcecc5dJim Grosbach  // ASR - 10
27754fea632b161f98e96ec7275922e35102bcecc5dJim Grosbach  // ROR - 11
27854fea632b161f98e96ec7275922e35102bcecc5dJim Grosbach  switch (ShOp) {
27954fea632b161f98e96ec7275922e35102bcecc5dJim Grosbach  default: llvm_unreachable("Unknown shift opc!");
28054fea632b161f98e96ec7275922e35102bcecc5dJim Grosbach  case ARM_AM::lsl: SBits = 0x0; break;
28154fea632b161f98e96ec7275922e35102bcecc5dJim Grosbach  case ARM_AM::lsr: SBits = 0x1; break;
28254fea632b161f98e96ec7275922e35102bcecc5dJim Grosbach  case ARM_AM::asr: SBits = 0x2; break;
28354fea632b161f98e96ec7275922e35102bcecc5dJim Grosbach  case ARM_AM::ror: SBits = 0x3; break;
28454fea632b161f98e96ec7275922e35102bcecc5dJim Grosbach  }
28554fea632b161f98e96ec7275922e35102bcecc5dJim Grosbach
28654fea632b161f98e96ec7275922e35102bcecc5dJim Grosbach  // {16-13} = Rn
28754fea632b161f98e96ec7275922e35102bcecc5dJim Grosbach  // {12}    = isAdd
28854fea632b161f98e96ec7275922e35102bcecc5dJim Grosbach  // {11-0}  = shifter
28954fea632b161f98e96ec7275922e35102bcecc5dJim Grosbach  //  {3-0}  = Rm
29054fea632b161f98e96ec7275922e35102bcecc5dJim Grosbach  //  {4}    = 0
29154fea632b161f98e96ec7275922e35102bcecc5dJim Grosbach  //  {6-5}  = type
29254fea632b161f98e96ec7275922e35102bcecc5dJim Grosbach  //  {11-7} = imm
29354fea632b161f98e96ec7275922e35102bcecc5dJim Grosbach  int64_t Binary = Rm;
29454fea632b161f98e96ec7275922e35102bcecc5dJim Grosbach  Binary |= Rn << 13;
29554fea632b161f98e96ec7275922e35102bcecc5dJim Grosbach  Binary |= SBits << 5;
29654fea632b161f98e96ec7275922e35102bcecc5dJim Grosbach  Binary |= ShImm << 7;
29754fea632b161f98e96ec7275922e35102bcecc5dJim Grosbach  if (isAdd)
29854fea632b161f98e96ec7275922e35102bcecc5dJim Grosbach    Binary |= 1 << 12;
29954fea632b161f98e96ec7275922e35102bcecc5dJim Grosbach  return Binary;
30054fea632b161f98e96ec7275922e35102bcecc5dJim Grosbach}
30154fea632b161f98e96ec7275922e35102bcecc5dJim Grosbach
30292b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling/// getAddrMode5OpValue - Return encoding info for 'reg +/- imm12' operand.
303806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbachuint32_t ARMMCCodeEmitter::
304806e80ef42bdb416f409142a1ff1d4e8752baac8Jim GrosbachgetAddrMode5OpValue(const MCInst &MI, unsigned OpIdx,
305806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbach                    SmallVectorImpl<MCFixup> &Fixups) const {
30692b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling  // {12-9} = reg
30792b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling  // {8}    = (U)nsigned (add == '1', sub == '0')
30892b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling  // {7-0}  = imm8
30992b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling  unsigned Reg, Imm8;
31070933266ae73c891d9d1c2f0de72ecd1db8f86dfJim Grosbach  // If The first operand isn't a register, we have a label reference.
31170933266ae73c891d9d1c2f0de72ecd1db8f86dfJim Grosbach  const MCOperand &MO = MI.getOperand(OpIdx);
31270933266ae73c891d9d1c2f0de72ecd1db8f86dfJim Grosbach  if (!MO.isReg()) {
313679cbd3b215b1769a6035e334f9009aeeb940dddJim Grosbach    Reg = getARMRegisterNumbering(ARM::PC);   // Rn is PC.
31470933266ae73c891d9d1c2f0de72ecd1db8f86dfJim Grosbach    Imm8 = 0;
31570933266ae73c891d9d1c2f0de72ecd1db8f86dfJim Grosbach
31670933266ae73c891d9d1c2f0de72ecd1db8f86dfJim Grosbach    assert(MO.isExpr() && "Unexpected machine operand type!");
31770933266ae73c891d9d1c2f0de72ecd1db8f86dfJim Grosbach    const MCExpr *Expr = MO.getExpr();
31870933266ae73c891d9d1c2f0de72ecd1db8f86dfJim Grosbach    MCFixupKind Kind = MCFixupKind(ARM::fixup_arm_vfp_pcrel_12);
31970933266ae73c891d9d1c2f0de72ecd1db8f86dfJim Grosbach    Fixups.push_back(MCFixup::Create(0, Expr, Kind));
32070933266ae73c891d9d1c2f0de72ecd1db8f86dfJim Grosbach
32170933266ae73c891d9d1c2f0de72ecd1db8f86dfJim Grosbach    ++MCNumCPRelocations;
32270933266ae73c891d9d1c2f0de72ecd1db8f86dfJim Grosbach  } else
32370933266ae73c891d9d1c2f0de72ecd1db8f86dfJim Grosbach    EncodeAddrModeOpValues(MI, OpIdx, Reg, Imm8, Fixups);
32492b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling
32592b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling  uint32_t Binary = ARM_AM::getAM5Offset(Imm8);
32692b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling  // Immediate is always encoded as positive. The 'U' bit controls add vs sub.
32792b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling  if (ARM_AM::getAM5Op(Imm8) == ARM_AM::add)
32892b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling    Binary |= (1 << 8);
32992b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling  Binary |= (Reg << 9);
3303e5561247202bae994dd259a2d8dc4eff8f799f3Jim Grosbach  return Binary;
3313e5561247202bae994dd259a2d8dc4eff8f799f3Jim Grosbach}
3323e5561247202bae994dd259a2d8dc4eff8f799f3Jim Grosbach
333806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbachunsigned ARMMCCodeEmitter::
334806e80ef42bdb416f409142a1ff1d4e8752baac8Jim GrosbachgetSORegOpValue(const MCInst &MI, unsigned OpIdx,
335806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbach                SmallVectorImpl<MCFixup> &Fixups) const {
3360800ce71896ccd7f49b37861a8cfbc21b6b10022Bill Wendling  // Sub-operands are [reg, reg, imm]. The first register is Rm, the reg to be
3370800ce71896ccd7f49b37861a8cfbc21b6b10022Bill Wendling  // shifted. The second is either Rs, the amount to shift by, or reg0 in which
3380800ce71896ccd7f49b37861a8cfbc21b6b10022Bill Wendling  // case the imm contains the amount to shift by.
33935b2de012d9404e3e9e4373e45f41711f752dd3aJim Grosbach  //
340ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach  // {3-0} = Rm.
3410800ce71896ccd7f49b37861a8cfbc21b6b10022Bill Wendling  // {4}   = 1 if reg shift, 0 if imm shift
342ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach  // {6-5} = type
343ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach  //    If reg shift:
344ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach  //      {11-8} = Rs
3450800ce71896ccd7f49b37861a8cfbc21b6b10022Bill Wendling  //      {7}    = 0
346ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach  //    else (imm shift)
347ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach  //      {11-7} = imm
348ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach
349ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach  const MCOperand &MO  = MI.getOperand(OpIdx);
350ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach  const MCOperand &MO1 = MI.getOperand(OpIdx + 1);
351ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach  const MCOperand &MO2 = MI.getOperand(OpIdx + 2);
352ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach  ARM_AM::ShiftOpc SOpc = ARM_AM::getSORegShOp(MO2.getImm());
353ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach
354ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach  // Encode Rm.
355ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach  unsigned Binary = getARMRegisterNumbering(MO.getReg());
356ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach
357ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach  // Encode the shift opcode.
358ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach  unsigned SBits = 0;
359ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach  unsigned Rs = MO1.getReg();
360ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach  if (Rs) {
361ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach    // Set shift operand (bit[7:4]).
362ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach    // LSL - 0001
363ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach    // LSR - 0011
364ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach    // ASR - 0101
365ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach    // ROR - 0111
366ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach    // RRX - 0110 and bit[11:8] clear.
367ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach    switch (SOpc) {
368ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach    default: llvm_unreachable("Unknown shift opc!");
369ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach    case ARM_AM::lsl: SBits = 0x1; break;
370ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach    case ARM_AM::lsr: SBits = 0x3; break;
371ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach    case ARM_AM::asr: SBits = 0x5; break;
372ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach    case ARM_AM::ror: SBits = 0x7; break;
373ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach    case ARM_AM::rrx: SBits = 0x6; break;
374ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach    }
375ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach  } else {
376ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach    // Set shift operand (bit[6:4]).
377ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach    // LSL - 000
378ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach    // LSR - 010
379ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach    // ASR - 100
380ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach    // ROR - 110
381ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach    switch (SOpc) {
382ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach    default: llvm_unreachable("Unknown shift opc!");
383ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach    case ARM_AM::lsl: SBits = 0x0; break;
384ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach    case ARM_AM::lsr: SBits = 0x2; break;
385ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach    case ARM_AM::asr: SBits = 0x4; break;
386ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach    case ARM_AM::ror: SBits = 0x6; break;
387ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach    }
388ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach  }
3890800ce71896ccd7f49b37861a8cfbc21b6b10022Bill Wendling
390ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach  Binary |= SBits << 4;
391ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach  if (SOpc == ARM_AM::rrx)
392ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach    return Binary;
393ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach
394ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach  // Encode the shift operation Rs or shift_imm (except rrx).
395ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach  if (Rs) {
396ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach    // Encode Rs bit[11:8].
397ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach    assert(ARM_AM::getSORegOffset(MO2.getImm()) == 0);
398ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach    return Binary | (getARMRegisterNumbering(Rs) << ARMII::RegRsShift);
399ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach  }
400ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach
401ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach  // Encode shift_imm bit[11:7].
402ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach  return Binary | ARM_AM::getSORegOffset(MO2.getImm()) << 7;
403ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach}
404ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach
405806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbachunsigned ARMMCCodeEmitter::
406806e80ef42bdb416f409142a1ff1d4e8752baac8Jim GrosbachgetBitfieldInvertedMaskOpValue(const MCInst &MI, unsigned Op,
407806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbach                               SmallVectorImpl<MCFixup> &Fixups) const {
4083fea19105d4929ad694f0b6272de31924c9f9f09Jim Grosbach  // 10 bits. lower 5 bits are are the lsb of the mask, high five bits are the
4093fea19105d4929ad694f0b6272de31924c9f9f09Jim Grosbach  // msb of the mask.
4103fea19105d4929ad694f0b6272de31924c9f9f09Jim Grosbach  const MCOperand &MO = MI.getOperand(Op);
4113fea19105d4929ad694f0b6272de31924c9f9f09Jim Grosbach  uint32_t v = ~MO.getImm();
4123fea19105d4929ad694f0b6272de31924c9f9f09Jim Grosbach  uint32_t lsb = CountTrailingZeros_32(v);
4133fea19105d4929ad694f0b6272de31924c9f9f09Jim Grosbach  uint32_t msb = (32 - CountLeadingZeros_32 (v)) - 1;
4143fea19105d4929ad694f0b6272de31924c9f9f09Jim Grosbach  assert (v != 0 && lsb < 32 && msb < 32 && "Illegal bitfield mask!");
4153fea19105d4929ad694f0b6272de31924c9f9f09Jim Grosbach  return lsb | (msb << 5);
4163fea19105d4929ad694f0b6272de31924c9f9f09Jim Grosbach}
4173fea19105d4929ad694f0b6272de31924c9f9f09Jim Grosbach
418806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbachunsigned ARMMCCodeEmitter::
419806e80ef42bdb416f409142a1ff1d4e8752baac8Jim GrosbachgetRegisterListOpValue(const MCInst &MI, unsigned Op,
4205e559a22c18166508a01fbd65471ec4e752726f9Bill Wendling                       SmallVectorImpl<MCFixup> &Fixups) const {
4215e559a22c18166508a01fbd65471ec4e752726f9Bill Wendling  // Convert a list of GPRs into a bitfield (R0 -> bit 0). For each
4225e559a22c18166508a01fbd65471ec4e752726f9Bill Wendling  // register in the list, set the corresponding bit.
4235e559a22c18166508a01fbd65471ec4e752726f9Bill Wendling  unsigned Binary = 0;
4245e559a22c18166508a01fbd65471ec4e752726f9Bill Wendling  for (unsigned i = Op, e = MI.getNumOperands(); i < e; ++i) {
4255e559a22c18166508a01fbd65471ec4e752726f9Bill Wendling    unsigned regno = getARMRegisterNumbering(MI.getOperand(i).getReg());
4265e559a22c18166508a01fbd65471ec4e752726f9Bill Wendling    Binary |= 1 << regno;
4275e559a22c18166508a01fbd65471ec4e752726f9Bill Wendling  }
4286b5252db2db5eeeadec4602329ac56beb6dea54aJim Grosbach  return Binary;
4296b5252db2db5eeeadec4602329ac56beb6dea54aJim Grosbach}
4306b5252db2db5eeeadec4602329ac56beb6dea54aJim Grosbach
431806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbachunsigned ARMMCCodeEmitter::
432806e80ef42bdb416f409142a1ff1d4e8752baac8Jim GrosbachgetAddrMode6AddressOpValue(const MCInst &MI, unsigned Op,
433806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbach                           SmallVectorImpl<MCFixup> &Fixups) const {
434d9aa7d30aa277fba319ee4bcdb862cd79f1aabe5Owen Anderson  const MCOperand &Reg = MI.getOperand(Op);
4350800ce71896ccd7f49b37861a8cfbc21b6b10022Bill Wendling  const MCOperand &Imm = MI.getOperand(Op + 1);
43635b2de012d9404e3e9e4373e45f41711f752dd3aJim Grosbach
437d9aa7d30aa277fba319ee4bcdb862cd79f1aabe5Owen Anderson  unsigned RegNo = getARMRegisterNumbering(Reg.getReg());
4380800ce71896ccd7f49b37861a8cfbc21b6b10022Bill Wendling  unsigned Align = 0;
4390800ce71896ccd7f49b37861a8cfbc21b6b10022Bill Wendling
4400800ce71896ccd7f49b37861a8cfbc21b6b10022Bill Wendling  switch (Imm.getImm()) {
4410800ce71896ccd7f49b37861a8cfbc21b6b10022Bill Wendling  default: break;
4420800ce71896ccd7f49b37861a8cfbc21b6b10022Bill Wendling  case 2:
4430800ce71896ccd7f49b37861a8cfbc21b6b10022Bill Wendling  case 4:
4440800ce71896ccd7f49b37861a8cfbc21b6b10022Bill Wendling  case 8:  Align = 0x01; break;
4450800ce71896ccd7f49b37861a8cfbc21b6b10022Bill Wendling  case 16: Align = 0x02; break;
4460800ce71896ccd7f49b37861a8cfbc21b6b10022Bill Wendling  case 32: Align = 0x03; break;
447d9aa7d30aa277fba319ee4bcdb862cd79f1aabe5Owen Anderson  }
4480800ce71896ccd7f49b37861a8cfbc21b6b10022Bill Wendling
449d9aa7d30aa277fba319ee4bcdb862cd79f1aabe5Owen Anderson  return RegNo | (Align << 4);
450d9aa7d30aa277fba319ee4bcdb862cd79f1aabe5Owen Anderson}
451d9aa7d30aa277fba319ee4bcdb862cd79f1aabe5Owen Anderson
452806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbachunsigned ARMMCCodeEmitter::
453806e80ef42bdb416f409142a1ff1d4e8752baac8Jim GrosbachgetAddrMode6OffsetOpValue(const MCInst &MI, unsigned Op,
454806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbach                          SmallVectorImpl<MCFixup> &Fixups) const {
4550800ce71896ccd7f49b37861a8cfbc21b6b10022Bill Wendling  const MCOperand &MO = MI.getOperand(Op);
4560800ce71896ccd7f49b37861a8cfbc21b6b10022Bill Wendling  if (MO.getReg() == 0) return 0x0D;
4570800ce71896ccd7f49b37861a8cfbc21b6b10022Bill Wendling  return MO.getReg();
458cf667be17b479fe276fd606b8fd72ccfa3065bb8Owen Anderson}
459cf667be17b479fe276fd606b8fd72ccfa3065bb8Owen Anderson
460568eeedea72c274abbba1310c18a31eef78e14a4Jim Grosbachvoid ARMMCCodeEmitter::
461568eeedea72c274abbba1310c18a31eef78e14a4Jim GrosbachEncodeInstruction(const MCInst &MI, raw_ostream &OS,
462806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbach                  SmallVectorImpl<MCFixup> &Fixups) const {
463d6d4b42ba473657b6d30242962f0d0fb23fe126eJim Grosbach  // Pseudo instructions don't get encoded.
4647292e0a6564bb24707eff1c49da9044dd5eaec78Bill Wendling  const TargetInstrDesc &Desc = TII.get(MI.getOpcode());
4657292e0a6564bb24707eff1c49da9044dd5eaec78Bill Wendling  if ((Desc.TSFlags & ARMII::FormMask) == ARMII::Pseudo)
466d6d4b42ba473657b6d30242962f0d0fb23fe126eJim Grosbach    return;
467d6d4b42ba473657b6d30242962f0d0fb23fe126eJim Grosbach
46870933266ae73c891d9d1c2f0de72ecd1db8f86dfJim Grosbach  EmitConstant(getBinaryCodeForInstr(MI, Fixups), 4, OS);
4697292e0a6564bb24707eff1c49da9044dd5eaec78Bill Wendling  ++MCNumEmitted;  // Keep track of the # of mi's emitted.
470568eeedea72c274abbba1310c18a31eef78e14a4Jim Grosbach}
4719af82ba42b53905f580f8c4270626946e3548654Jim Grosbach
472806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbach#include "ARMGenMCCodeEmitter.inc"
473