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