ARMMCCodeEmitter.cpp revision 2f196747f15240691bd4e622f7995edfedf90f61
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 142ac190238e88b21e716e2853900b5076c9013410Chris Lattner#define DEBUG_TYPE "mccodeemitter" 15ee04a6d3a40c3017124e3fd89a0db473a2824498Evan Cheng#include "MCTargetDesc/ARMAddressingModes.h" 16be74029f44c32efc09274a16cbff588ad10dc5eaEvan Cheng#include "MCTargetDesc/ARMBaseInfo.h" 17be74029f44c32efc09274a16cbff588ad10dc5eaEvan Cheng#include "MCTargetDesc/ARMFixupKinds.h" 18ee04a6d3a40c3017124e3fd89a0db473a2824498Evan Cheng#include "MCTargetDesc/ARMMCExpr.h" 19be74029f44c32efc09274a16cbff588ad10dc5eaEvan Cheng#include "MCTargetDesc/ARMMCTargetDesc.h" 20568eeedea72c274abbba1310c18a31eef78e14a4Jim Grosbach#include "llvm/MC/MCCodeEmitter.h" 21568eeedea72c274abbba1310c18a31eef78e14a4Jim Grosbach#include "llvm/MC/MCExpr.h" 22568eeedea72c274abbba1310c18a31eef78e14a4Jim Grosbach#include "llvm/MC/MCInst.h" 2359ee62d2418df8db499eca1ae17f5900dc2dcbbaEvan Cheng#include "llvm/MC/MCInstrInfo.h" 24be74029f44c32efc09274a16cbff588ad10dc5eaEvan Cheng#include "llvm/MC/MCRegisterInfo.h" 2559ee62d2418df8db499eca1ae17f5900dc2dcbbaEvan Cheng#include "llvm/MC/MCSubtargetInfo.h" 26ee04a6d3a40c3017124e3fd89a0db473a2824498Evan Cheng#include "llvm/ADT/APFloat.h" 27d6d4b42ba473657b6d30242962f0d0fb23fe126eJim Grosbach#include "llvm/ADT/Statistic.h" 28568eeedea72c274abbba1310c18a31eef78e14a4Jim Grosbach#include "llvm/Support/raw_ostream.h" 2959ee62d2418df8db499eca1ae17f5900dc2dcbbaEvan Cheng 30568eeedea72c274abbba1310c18a31eef78e14a4Jim Grosbachusing namespace llvm; 31568eeedea72c274abbba1310c18a31eef78e14a4Jim Grosbach 3270933266ae73c891d9d1c2f0de72ecd1db8f86dfJim GrosbachSTATISTIC(MCNumEmitted, "Number of MC instructions emitted."); 3370933266ae73c891d9d1c2f0de72ecd1db8f86dfJim GrosbachSTATISTIC(MCNumCPRelocations, "Number of constant pool relocations created."); 34d6d4b42ba473657b6d30242962f0d0fb23fe126eJim Grosbach 35568eeedea72c274abbba1310c18a31eef78e14a4Jim Grosbachnamespace { 36568eeedea72c274abbba1310c18a31eef78e14a4Jim Grosbachclass ARMMCCodeEmitter : public MCCodeEmitter { 37568eeedea72c274abbba1310c18a31eef78e14a4Jim Grosbach ARMMCCodeEmitter(const ARMMCCodeEmitter &); // DO NOT IMPLEMENT 38568eeedea72c274abbba1310c18a31eef78e14a4Jim Grosbach void operator=(const ARMMCCodeEmitter &); // DO NOT IMPLEMENT 3959ee62d2418df8db499eca1ae17f5900dc2dcbbaEvan Cheng const MCInstrInfo &MCII; 4059ee62d2418df8db499eca1ae17f5900dc2dcbbaEvan Cheng const MCSubtargetInfo &STI; 41568eeedea72c274abbba1310c18a31eef78e14a4Jim Grosbach 42568eeedea72c274abbba1310c18a31eef78e14a4Jim Grosbachpublic: 4359ee62d2418df8db499eca1ae17f5900dc2dcbbaEvan Cheng ARMMCCodeEmitter(const MCInstrInfo &mcii, const MCSubtargetInfo &sti, 4459ee62d2418df8db499eca1ae17f5900dc2dcbbaEvan Cheng MCContext &ctx) 45af0a2e6730ffb59405352269e1500b6e83e42d6aEvan Cheng : MCII(mcii), STI(sti) { 46568eeedea72c274abbba1310c18a31eef78e14a4Jim Grosbach } 47568eeedea72c274abbba1310c18a31eef78e14a4Jim Grosbach 48568eeedea72c274abbba1310c18a31eef78e14a4Jim Grosbach ~ARMMCCodeEmitter() {} 49568eeedea72c274abbba1310c18a31eef78e14a4Jim Grosbach 5059ee62d2418df8db499eca1ae17f5900dc2dcbbaEvan Cheng bool isThumb() const { 5159ee62d2418df8db499eca1ae17f5900dc2dcbbaEvan Cheng // FIXME: Can tablegen auto-generate this? 5259ee62d2418df8db499eca1ae17f5900dc2dcbbaEvan Cheng return (STI.getFeatureBits() & ARM::ModeThumb) != 0; 5359ee62d2418df8db499eca1ae17f5900dc2dcbbaEvan Cheng } 5459ee62d2418df8db499eca1ae17f5900dc2dcbbaEvan Cheng bool isThumb2() const { 5559ee62d2418df8db499eca1ae17f5900dc2dcbbaEvan Cheng return isThumb() && (STI.getFeatureBits() & ARM::FeatureThumb2) != 0; 5659ee62d2418df8db499eca1ae17f5900dc2dcbbaEvan Cheng } 5759ee62d2418df8db499eca1ae17f5900dc2dcbbaEvan Cheng bool isTargetDarwin() const { 5859ee62d2418df8db499eca1ae17f5900dc2dcbbaEvan Cheng Triple TT(STI.getTargetTriple()); 5959ee62d2418df8db499eca1ae17f5900dc2dcbbaEvan Cheng Triple::OSType OS = TT.getOS(); 6059ee62d2418df8db499eca1ae17f5900dc2dcbbaEvan Cheng return OS == Triple::Darwin || OS == Triple::MacOSX || OS == Triple::IOS; 6159ee62d2418df8db499eca1ae17f5900dc2dcbbaEvan Cheng } 6259ee62d2418df8db499eca1ae17f5900dc2dcbbaEvan Cheng 630de6ab3c43ed2143d661115dddf1480545236c91Jim Grosbach unsigned getMachineSoImmOpValue(unsigned SoImm) const; 640de6ab3c43ed2143d661115dddf1480545236c91Jim Grosbach 659af82ba42b53905f580f8c4270626946e3548654Jim Grosbach // getBinaryCodeForInstr - TableGen'erated function for getting the 669af82ba42b53905f580f8c4270626946e3548654Jim Grosbach // binary encoding for an instruction. 67806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbach unsigned getBinaryCodeForInstr(const MCInst &MI, 68806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbach SmallVectorImpl<MCFixup> &Fixups) const; 699af82ba42b53905f580f8c4270626946e3548654Jim Grosbach 709af82ba42b53905f580f8c4270626946e3548654Jim Grosbach /// getMachineOpValue - Return binary encoding of operand. If the machine 719af82ba42b53905f580f8c4270626946e3548654Jim Grosbach /// operand requires relocation, record the relocation and return zero. 72806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbach unsigned getMachineOpValue(const MCInst &MI,const MCOperand &MO, 73806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbach SmallVectorImpl<MCFixup> &Fixups) const; 749af82ba42b53905f580f8c4270626946e3548654Jim Grosbach 757597212abced110723f2fee985a7d60557c092ecEvan Cheng /// getHiLo16ImmOpValue - Return the encoding for the hi / low 16-bit of 76971b83b67a9812556cdb97bb58aa96fb37af458dOwen Anderson /// the specified operand. This is used for operands with :lower16: and 777597212abced110723f2fee985a7d60557c092ecEvan Cheng /// :upper16: prefixes. 787597212abced110723f2fee985a7d60557c092ecEvan Cheng uint32_t getHiLo16ImmOpValue(const MCInst &MI, unsigned OpIdx, 797597212abced110723f2fee985a7d60557c092ecEvan Cheng SmallVectorImpl<MCFixup> &Fixups) const; 80837caa9313e1f9480721f232f89f5c7b1b9c9d09Jason W Kim 8192b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling bool EncodeAddrModeOpValues(const MCInst &MI, unsigned OpIdx, 82806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbach unsigned &Reg, unsigned &Imm, 83806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbach SmallVectorImpl<MCFixup> &Fixups) const; 8492b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling 85662a816e89a9d77bf75e1328b09cf9235b4682aaJim Grosbach /// getThumbBLTargetOpValue - Return encoding info for Thumb immediate 8609aa3f0ef35d9241c92439d74b8d5e9a81d814c2Bill Wendling /// BL branch target. 87662a816e89a9d77bf75e1328b09cf9235b4682aaJim Grosbach uint32_t getThumbBLTargetOpValue(const MCInst &MI, unsigned OpIdx, 88662a816e89a9d77bf75e1328b09cf9235b4682aaJim Grosbach SmallVectorImpl<MCFixup> &Fixups) const; 89662a816e89a9d77bf75e1328b09cf9235b4682aaJim Grosbach 9009aa3f0ef35d9241c92439d74b8d5e9a81d814c2Bill Wendling /// getThumbBLXTargetOpValue - Return encoding info for Thumb immediate 9109aa3f0ef35d9241c92439d74b8d5e9a81d814c2Bill Wendling /// BLX branch target. 9209aa3f0ef35d9241c92439d74b8d5e9a81d814c2Bill Wendling uint32_t getThumbBLXTargetOpValue(const MCInst &MI, unsigned OpIdx, 9309aa3f0ef35d9241c92439d74b8d5e9a81d814c2Bill Wendling SmallVectorImpl<MCFixup> &Fixups) const; 9409aa3f0ef35d9241c92439d74b8d5e9a81d814c2Bill Wendling 95e246717c3a36a913fd4200776ed621649bb2b624Jim Grosbach /// getThumbBRTargetOpValue - Return encoding info for Thumb branch target. 96e246717c3a36a913fd4200776ed621649bb2b624Jim Grosbach uint32_t getThumbBRTargetOpValue(const MCInst &MI, unsigned OpIdx, 97e246717c3a36a913fd4200776ed621649bb2b624Jim Grosbach SmallVectorImpl<MCFixup> &Fixups) const; 98e246717c3a36a913fd4200776ed621649bb2b624Jim Grosbach 9901086451393ef33e82b6fad623989dd97dd70edfJim Grosbach /// getThumbBCCTargetOpValue - Return encoding info for Thumb branch target. 10001086451393ef33e82b6fad623989dd97dd70edfJim Grosbach uint32_t getThumbBCCTargetOpValue(const MCInst &MI, unsigned OpIdx, 10101086451393ef33e82b6fad623989dd97dd70edfJim Grosbach SmallVectorImpl<MCFixup> &Fixups) const; 10201086451393ef33e82b6fad623989dd97dd70edfJim Grosbach 103027d6e8d1ca04e4096fb3a27579b861d861466c5Jim Grosbach /// getThumbCBTargetOpValue - Return encoding info for Thumb branch target. 104027d6e8d1ca04e4096fb3a27579b861d861466c5Jim Grosbach uint32_t getThumbCBTargetOpValue(const MCInst &MI, unsigned OpIdx, 105dff2f7151f695b86db8c4b0c6604463bdb8a63eaBill Wendling SmallVectorImpl<MCFixup> &Fixups) const; 106dff2f7151f695b86db8c4b0c6604463bdb8a63eaBill Wendling 107c466b937dbdbaabeef0097fe340de1b8f49a3508Jim Grosbach /// getBranchTargetOpValue - Return encoding info for 24-bit immediate 108c466b937dbdbaabeef0097fe340de1b8f49a3508Jim Grosbach /// branch target. 109c466b937dbdbaabeef0097fe340de1b8f49a3508Jim Grosbach uint32_t getBranchTargetOpValue(const MCInst &MI, unsigned OpIdx, 110c466b937dbdbaabeef0097fe340de1b8f49a3508Jim Grosbach SmallVectorImpl<MCFixup> &Fixups) const; 111c466b937dbdbaabeef0097fe340de1b8f49a3508Jim Grosbach 112c266600bec4b5ba0ee93ffdfeaafcab8f1295145Owen Anderson /// getUnconditionalBranchTargetOpValue - Return encoding info for 24-bit 113c266600bec4b5ba0ee93ffdfeaafcab8f1295145Owen Anderson /// immediate Thumb2 direct branch target. 114c266600bec4b5ba0ee93ffdfeaafcab8f1295145Owen Anderson uint32_t getUnconditionalBranchTargetOpValue(const MCInst &MI, unsigned OpIdx, 115c266600bec4b5ba0ee93ffdfeaafcab8f1295145Owen Anderson SmallVectorImpl<MCFixup> &Fixups) const; 11610096dbdef22a10a6a4444437c935ab428545525Owen Anderson 117685c350ae76b588e1f00c01a511fe8bd57f18394Jason W Kim /// getARMBranchTargetOpValue - Return encoding info for 24-bit immediate 118685c350ae76b588e1f00c01a511fe8bd57f18394Jason W Kim /// branch target. 119685c350ae76b588e1f00c01a511fe8bd57f18394Jason W Kim uint32_t getARMBranchTargetOpValue(const MCInst &MI, unsigned OpIdx, 120685c350ae76b588e1f00c01a511fe8bd57f18394Jason W Kim SmallVectorImpl<MCFixup> &Fixups) const; 121f1eab597b2316c6cfcabfcee98895fedb2071722Owen Anderson uint32_t getARMBLXTargetOpValue(const MCInst &MI, unsigned OpIdx, 122f1eab597b2316c6cfcabfcee98895fedb2071722Owen Anderson SmallVectorImpl<MCFixup> &Fixups) const; 123c266600bec4b5ba0ee93ffdfeaafcab8f1295145Owen Anderson 1245d14f9be7ba64162c7b996f36d419b11d8cdbe9aJim Grosbach /// getAdrLabelOpValue - Return encoding info for 12-bit immediate 1255d14f9be7ba64162c7b996f36d419b11d8cdbe9aJim Grosbach /// ADR label target. 1265d14f9be7ba64162c7b996f36d419b11d8cdbe9aJim Grosbach uint32_t getAdrLabelOpValue(const MCInst &MI, unsigned OpIdx, 1275d14f9be7ba64162c7b996f36d419b11d8cdbe9aJim Grosbach SmallVectorImpl<MCFixup> &Fixups) const; 128d40963c4065432ec7e47879d3ca665a54ee903b6Jim Grosbach uint32_t getThumbAdrLabelOpValue(const MCInst &MI, unsigned OpIdx, 129d40963c4065432ec7e47879d3ca665a54ee903b6Jim Grosbach SmallVectorImpl<MCFixup> &Fixups) const; 130a838a25d59838adfa91463f6a918ae3adeb352c1Owen Anderson uint32_t getT2AdrLabelOpValue(const MCInst &MI, unsigned OpIdx, 131a838a25d59838adfa91463f6a918ae3adeb352c1Owen Anderson SmallVectorImpl<MCFixup> &Fixups) const; 132971b83b67a9812556cdb97bb58aa96fb37af458dOwen Anderson 1335d14f9be7ba64162c7b996f36d419b11d8cdbe9aJim Grosbach 13492b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling /// getAddrModeImm12OpValue - Return encoding info for 'reg +/- imm12' 13592b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling /// operand. 136806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbach uint32_t getAddrModeImm12OpValue(const MCInst &MI, unsigned OpIdx, 137806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbach SmallVectorImpl<MCFixup> &Fixups) const; 13892b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling 139f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling /// getThumbAddrModeRegRegOpValue - Return encoding for 'reg + reg' operand. 140f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling uint32_t getThumbAddrModeRegRegOpValue(const MCInst &MI, unsigned OpIdx, 141f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling SmallVectorImpl<MCFixup> &Fixups)const; 1420f4b60d43a289671082deee3bd56a3a055afb16aOwen Anderson 1439d63d90de5e57ad96f467b270544443a9284eb2bOwen Anderson /// getT2AddrModeImm8s4OpValue - Return encoding info for 'reg +/- imm8<<2' 1449d63d90de5e57ad96f467b270544443a9284eb2bOwen Anderson /// operand. 1459d63d90de5e57ad96f467b270544443a9284eb2bOwen Anderson uint32_t getT2AddrModeImm8s4OpValue(const MCInst &MI, unsigned OpIdx, 1469d63d90de5e57ad96f467b270544443a9284eb2bOwen Anderson SmallVectorImpl<MCFixup> &Fixups) const; 147b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach 148b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach /// getT2AddrModeImm0_1020s4OpValue - Return encoding info for 'reg + imm8<<2' 149b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach /// operand. 150b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach uint32_t getT2AddrModeImm0_1020s4OpValue(const MCInst &MI, unsigned OpIdx, 151b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach SmallVectorImpl<MCFixup> &Fixups) const; 152b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach 153a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach /// getT2Imm8s4OpValue - Return encoding info for '+/- imm8<<2' 154a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach /// operand. 155a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach uint32_t getT2Imm8s4OpValue(const MCInst &MI, unsigned OpIdx, 156a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach SmallVectorImpl<MCFixup> &Fixups) const; 1579d63d90de5e57ad96f467b270544443a9284eb2bOwen Anderson 1589d63d90de5e57ad96f467b270544443a9284eb2bOwen Anderson 15954fea632b161f98e96ec7275922e35102bcecc5dJim Grosbach /// getLdStSORegOpValue - Return encoding info for 'reg +/- reg shop imm' 16054fea632b161f98e96ec7275922e35102bcecc5dJim Grosbach /// operand as needed by load/store instructions. 16154fea632b161f98e96ec7275922e35102bcecc5dJim Grosbach uint32_t getLdStSORegOpValue(const MCInst &MI, unsigned OpIdx, 16254fea632b161f98e96ec7275922e35102bcecc5dJim Grosbach SmallVectorImpl<MCFixup> &Fixups) const; 16354fea632b161f98e96ec7275922e35102bcecc5dJim Grosbach 1645d5eb9e3817a2765297e6dd5649ecb9b8b03e334Jim Grosbach /// getLdStmModeOpValue - Return encoding for load/store multiple mode. 1655d5eb9e3817a2765297e6dd5649ecb9b8b03e334Jim Grosbach uint32_t getLdStmModeOpValue(const MCInst &MI, unsigned OpIdx, 1665d5eb9e3817a2765297e6dd5649ecb9b8b03e334Jim Grosbach SmallVectorImpl<MCFixup> &Fixups) const { 1675d5eb9e3817a2765297e6dd5649ecb9b8b03e334Jim Grosbach ARM_AM::AMSubMode Mode = (ARM_AM::AMSubMode)MI.getOperand(OpIdx).getImm(); 1685d5eb9e3817a2765297e6dd5649ecb9b8b03e334Jim Grosbach switch (Mode) { 1695f8a917b6558f8fdf31b4a6fa591b396e16b9ff2Matt Beaumont-Gay default: assert(0 && "Unknown addressing sub-mode!"); 1705d5eb9e3817a2765297e6dd5649ecb9b8b03e334Jim Grosbach case ARM_AM::da: return 0; 1715d5eb9e3817a2765297e6dd5649ecb9b8b03e334Jim Grosbach case ARM_AM::ia: return 1; 1725d5eb9e3817a2765297e6dd5649ecb9b8b03e334Jim Grosbach case ARM_AM::db: return 2; 1735d5eb9e3817a2765297e6dd5649ecb9b8b03e334Jim Grosbach case ARM_AM::ib: return 3; 1745d5eb9e3817a2765297e6dd5649ecb9b8b03e334Jim Grosbach } 1755d5eb9e3817a2765297e6dd5649ecb9b8b03e334Jim Grosbach } 17699f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach /// getShiftOp - Return the shift opcode (bit[6:5]) of the immediate value. 17799f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach /// 17899f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach unsigned getShiftOp(ARM_AM::ShiftOpc ShOpc) const { 17999f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach switch (ShOpc) { 18099f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach default: llvm_unreachable("Unknown shift opc!"); 18199f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach case ARM_AM::no_shift: 18299f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach case ARM_AM::lsl: return 0; 18399f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach case ARM_AM::lsr: return 1; 18499f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach case ARM_AM::asr: return 2; 18599f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach case ARM_AM::ror: 18699f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach case ARM_AM::rrx: return 3; 18799f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach } 18899f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach return 0; 18999f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach } 19099f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach 19199f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach /// getAddrMode2OpValue - Return encoding for addrmode2 operands. 19299f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach uint32_t getAddrMode2OpValue(const MCInst &MI, unsigned OpIdx, 19399f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach SmallVectorImpl<MCFixup> &Fixups) const; 19499f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach 19599f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach /// getAddrMode2OffsetOpValue - Return encoding for am2offset operands. 19699f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach uint32_t getAddrMode2OffsetOpValue(const MCInst &MI, unsigned OpIdx, 19799f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach SmallVectorImpl<MCFixup> &Fixups) const; 19899f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach 1997ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach /// getPostIdxRegOpValue - Return encoding for postidx_reg operands. 2007ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach uint32_t getPostIdxRegOpValue(const MCInst &MI, unsigned OpIdx, 2017ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach SmallVectorImpl<MCFixup> &Fixups) const; 2027ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach 2037eab97f260ba0f56d1d4a82f3a4eb2c979452011Jim Grosbach /// getAddrMode3OffsetOpValue - Return encoding for am3offset operands. 2047eab97f260ba0f56d1d4a82f3a4eb2c979452011Jim Grosbach uint32_t getAddrMode3OffsetOpValue(const MCInst &MI, unsigned OpIdx, 2057eab97f260ba0f56d1d4a82f3a4eb2c979452011Jim Grosbach SmallVectorImpl<MCFixup> &Fixups) const; 2067eab97f260ba0f56d1d4a82f3a4eb2c979452011Jim Grosbach 207570a9226913ebe1af04832b8fb3273c70b4ee152Jim Grosbach /// getAddrMode3OpValue - Return encoding for addrmode3 operands. 208570a9226913ebe1af04832b8fb3273c70b4ee152Jim Grosbach uint32_t getAddrMode3OpValue(const MCInst &MI, unsigned OpIdx, 209570a9226913ebe1af04832b8fb3273c70b4ee152Jim Grosbach SmallVectorImpl<MCFixup> &Fixups) const; 2105d5eb9e3817a2765297e6dd5649ecb9b8b03e334Jim Grosbach 211d967cd096ae87accf2f1df86b2dfac969d9c9da2Jim Grosbach /// getAddrModeThumbSPOpValue - Return encoding info for 'reg +/- imm12' 212d967cd096ae87accf2f1df86b2dfac969d9c9da2Jim Grosbach /// operand. 213d967cd096ae87accf2f1df86b2dfac969d9c9da2Jim Grosbach uint32_t getAddrModeThumbSPOpValue(const MCInst &MI, unsigned OpIdx, 214d967cd096ae87accf2f1df86b2dfac969d9c9da2Jim Grosbach SmallVectorImpl<MCFixup> &Fixups) const; 215d967cd096ae87accf2f1df86b2dfac969d9c9da2Jim Grosbach 216f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling /// getAddrModeISOpValue - Encode the t_addrmode_is# operands. 217f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling uint32_t getAddrModeISOpValue(const MCInst &MI, unsigned OpIdx, 21822447ae54bcb8ca94ed994cad103074a24e66781Bill Wendling SmallVectorImpl<MCFixup> &Fixups) const; 2191fd374e9c1c074c1681336bef31e65f0170b0f7eBill Wendling 220b8958b031ec5163261f490f131780c5dc3d823d6Bill Wendling /// getAddrModePCOpValue - Return encoding for t_addrmode_pc operands. 221b8958b031ec5163261f490f131780c5dc3d823d6Bill Wendling uint32_t getAddrModePCOpValue(const MCInst &MI, unsigned OpIdx, 222b8958b031ec5163261f490f131780c5dc3d823d6Bill Wendling SmallVectorImpl<MCFixup> &Fixups) const; 223b8958b031ec5163261f490f131780c5dc3d823d6Bill Wendling 22492b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling /// getAddrMode5OpValue - Return encoding info for 'reg +/- imm8' operand. 225806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbach uint32_t getAddrMode5OpValue(const MCInst &MI, unsigned OpIdx, 226806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbach SmallVectorImpl<MCFixup> &Fixups) const; 2273e5561247202bae994dd259a2d8dc4eff8f799f3Jim Grosbach 22808bd54987f4ae482de13436e7254ff08b23f825fJim Grosbach /// getCCOutOpValue - Return encoding of the 's' bit. 229806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbach unsigned getCCOutOpValue(const MCInst &MI, unsigned Op, 230806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbach SmallVectorImpl<MCFixup> &Fixups) const { 23108bd54987f4ae482de13436e7254ff08b23f825fJim Grosbach // The operand is either reg0 or CPSR. The 's' bit is encoded as '0' or 23208bd54987f4ae482de13436e7254ff08b23f825fJim Grosbach // '1' respectively. 23308bd54987f4ae482de13436e7254ff08b23f825fJim Grosbach return MI.getOperand(Op).getReg() == ARM::CPSR; 23408bd54987f4ae482de13436e7254ff08b23f825fJim Grosbach } 235ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach 2362a6a93d5425b38546de2b6674719d52f565171d8Jim Grosbach /// getSOImmOpValue - Return an encoded 12-bit shifted-immediate value. 237806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbach unsigned getSOImmOpValue(const MCInst &MI, unsigned Op, 238806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbach SmallVectorImpl<MCFixup> &Fixups) const { 2392a6a93d5425b38546de2b6674719d52f565171d8Jim Grosbach unsigned SoImm = MI.getOperand(Op).getImm(); 2402a6a93d5425b38546de2b6674719d52f565171d8Jim Grosbach int SoImmVal = ARM_AM::getSOImmVal(SoImm); 2412a6a93d5425b38546de2b6674719d52f565171d8Jim Grosbach assert(SoImmVal != -1 && "Not a valid so_imm value!"); 2422a6a93d5425b38546de2b6674719d52f565171d8Jim Grosbach 2432a6a93d5425b38546de2b6674719d52f565171d8Jim Grosbach // Encode rotate_imm. 2442a6a93d5425b38546de2b6674719d52f565171d8Jim Grosbach unsigned Binary = (ARM_AM::getSOImmValRot((unsigned)SoImmVal) >> 1) 2452a6a93d5425b38546de2b6674719d52f565171d8Jim Grosbach << ARMII::SoRotImmShift; 2462a6a93d5425b38546de2b6674719d52f565171d8Jim Grosbach 2472a6a93d5425b38546de2b6674719d52f565171d8Jim Grosbach // Encode immed_8. 2482a6a93d5425b38546de2b6674719d52f565171d8Jim Grosbach Binary |= ARM_AM::getSOImmValImm((unsigned)SoImmVal); 2492a6a93d5425b38546de2b6674719d52f565171d8Jim Grosbach return Binary; 2502a6a93d5425b38546de2b6674719d52f565171d8Jim Grosbach } 2517bf4c02789f97e32225fc248dff6622b994a15eeJim Grosbach 2525de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson /// getT2SOImmOpValue - Return an encoded 12-bit shifted-immediate value. 2535de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson unsigned getT2SOImmOpValue(const MCInst &MI, unsigned Op, 2545de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson SmallVectorImpl<MCFixup> &Fixups) const { 2555de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson unsigned SoImm = MI.getOperand(Op).getImm(); 2565de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson unsigned Encoded = ARM_AM::getT2SOImmVal(SoImm); 2575de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson assert(Encoded != ~0U && "Not a Thumb2 so_imm value?"); 2585de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson return Encoded; 2595de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson } 26008bd54987f4ae482de13436e7254ff08b23f825fJim Grosbach 26175579f739fbc99a92a15f3ce75bbd7628ba00f8cOwen Anderson unsigned getT2AddrModeSORegOpValue(const MCInst &MI, unsigned OpNum, 26275579f739fbc99a92a15f3ce75bbd7628ba00f8cOwen Anderson SmallVectorImpl<MCFixup> &Fixups) const; 26375579f739fbc99a92a15f3ce75bbd7628ba00f8cOwen Anderson unsigned getT2AddrModeImm8OpValue(const MCInst &MI, unsigned OpNum, 26475579f739fbc99a92a15f3ce75bbd7628ba00f8cOwen Anderson SmallVectorImpl<MCFixup> &Fixups) const; 2656af50f7dd12d82f0a80f3158102180eee4c921aaOwen Anderson unsigned getT2AddrModeImm8OffsetOpValue(const MCInst &MI, unsigned OpNum, 2666af50f7dd12d82f0a80f3158102180eee4c921aaOwen Anderson SmallVectorImpl<MCFixup> &Fixups) const; 2670e1bcdf4f7547bb5f47ed5ff5f2409a8f72f3609Owen Anderson unsigned getT2AddrModeImm12OffsetOpValue(const MCInst &MI, unsigned OpNum, 2680e1bcdf4f7547bb5f47ed5ff5f2409a8f72f3609Owen Anderson SmallVectorImpl<MCFixup> &Fixups) const; 26975579f739fbc99a92a15f3ce75bbd7628ba00f8cOwen Anderson 270ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach /// getSORegOpValue - Return an encoded so_reg shifted register value. 271152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson unsigned getSORegRegOpValue(const MCInst &MI, unsigned Op, 272152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson SmallVectorImpl<MCFixup> &Fixups) const; 273152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson unsigned getSORegImmOpValue(const MCInst &MI, unsigned Op, 274806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbach SmallVectorImpl<MCFixup> &Fixups) const; 2755de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson unsigned getT2SORegOpValue(const MCInst &MI, unsigned Op, 2765de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson SmallVectorImpl<MCFixup> &Fixups) const; 277ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach 278806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbach unsigned getNEONVcvtImm32OpValue(const MCInst &MI, unsigned Op, 279806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbach SmallVectorImpl<MCFixup> &Fixups) const { 280498ec20703c89d0c2890b0967791f0f5f2b59a2fOwen Anderson return 64 - MI.getOperand(Op).getImm(); 281498ec20703c89d0c2890b0967791f0f5f2b59a2fOwen Anderson } 2828abe32af38b66bf4577526b23b6af6ec7eb6c155Jim Grosbach 283806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbach unsigned getBitfieldInvertedMaskOpValue(const MCInst &MI, unsigned Op, 284806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbach SmallVectorImpl<MCFixup> &Fixups) const; 2853fea19105d4929ad694f0b6272de31924c9f9f09Jim Grosbach 286806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbach unsigned getRegisterListOpValue(const MCInst &MI, unsigned Op, 287806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbach SmallVectorImpl<MCFixup> &Fixups) const; 288806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbach unsigned getAddrMode6AddressOpValue(const MCInst &MI, unsigned Op, 289806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbach SmallVectorImpl<MCFixup> &Fixups) const; 290183c627d89be5d0e8f3255ab7f6d1204c2fabedfMon P Wang unsigned getAddrMode6OneLane32AddressOpValue(const MCInst &MI, unsigned Op, 291183c627d89be5d0e8f3255ab7f6d1204c2fabedfMon P Wang SmallVectorImpl<MCFixup> &Fixups) const; 2928e0c7b52877983b4838e54e233449912fc1a2325Bob Wilson unsigned getAddrMode6DupAddressOpValue(const MCInst &MI, unsigned Op, 2938e0c7b52877983b4838e54e233449912fc1a2325Bob Wilson SmallVectorImpl<MCFixup> &Fixups) const; 294806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbach unsigned getAddrMode6OffsetOpValue(const MCInst &MI, unsigned Op, 295806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbach SmallVectorImpl<MCFixup> &Fixups) const; 2966b5252db2db5eeeadec4602329ac56beb6dea54aJim Grosbach 2973116dce33840a115130c5f8ffcb9679d023496d6Bill Wendling unsigned getShiftRight8Imm(const MCInst &MI, unsigned Op, 2983116dce33840a115130c5f8ffcb9679d023496d6Bill Wendling SmallVectorImpl<MCFixup> &Fixups) const; 2993116dce33840a115130c5f8ffcb9679d023496d6Bill Wendling unsigned getShiftRight16Imm(const MCInst &MI, unsigned Op, 3003116dce33840a115130c5f8ffcb9679d023496d6Bill Wendling SmallVectorImpl<MCFixup> &Fixups) const; 3013116dce33840a115130c5f8ffcb9679d023496d6Bill Wendling unsigned getShiftRight32Imm(const MCInst &MI, unsigned Op, 3023116dce33840a115130c5f8ffcb9679d023496d6Bill Wendling SmallVectorImpl<MCFixup> &Fixups) const; 3033116dce33840a115130c5f8ffcb9679d023496d6Bill Wendling unsigned getShiftRight64Imm(const MCInst &MI, unsigned Op, 3043116dce33840a115130c5f8ffcb9679d023496d6Bill Wendling SmallVectorImpl<MCFixup> &Fixups) const; 305a656b63ee4d5b0e3f4d26a55dd4cc69795746684Bill Wendling 3066d74631062e4464326eb5c680a4d62d340fa42ebOwen Anderson unsigned getThumbSRImmOpValue(const MCInst &MI, unsigned Op, 3076d74631062e4464326eb5c680a4d62d340fa42ebOwen Anderson SmallVectorImpl<MCFixup> &Fixups) const; 3086d74631062e4464326eb5c680a4d62d340fa42ebOwen Anderson 309c7139a6f0d3acd198ab9eb536ea1ec52e61ff130Owen Anderson unsigned NEONThumb2DataIPostEncoder(const MCInst &MI, 310c7139a6f0d3acd198ab9eb536ea1ec52e61ff130Owen Anderson unsigned EncodedValue) const; 31157dac88f775c1191a98cff89abd1f7ad33df5e29Owen Anderson unsigned NEONThumb2LoadStorePostEncoder(const MCInst &MI, 312cf590263cd5c24ccf1d08cef612738d99cd980d9Bill Wendling unsigned EncodedValue) const; 3138f143913141991baaa535ca0da7c8a81606d6392Owen Anderson unsigned NEONThumb2DupPostEncoder(const MCInst &MI, 314cf590263cd5c24ccf1d08cef612738d99cd980d9Bill Wendling unsigned EncodedValue) const; 315cf590263cd5c24ccf1d08cef612738d99cd980d9Bill Wendling 316cf590263cd5c24ccf1d08cef612738d99cd980d9Bill Wendling unsigned VFPThumb2PostEncoder(const MCInst &MI, 317cf590263cd5c24ccf1d08cef612738d99cd980d9Bill Wendling unsigned EncodedValue) const; 318c7139a6f0d3acd198ab9eb536ea1ec52e61ff130Owen Anderson 31970933266ae73c891d9d1c2f0de72ecd1db8f86dfJim Grosbach void EmitByte(unsigned char C, raw_ostream &OS) const { 320568eeedea72c274abbba1310c18a31eef78e14a4Jim Grosbach OS << (char)C; 321568eeedea72c274abbba1310c18a31eef78e14a4Jim Grosbach } 322568eeedea72c274abbba1310c18a31eef78e14a4Jim Grosbach 32370933266ae73c891d9d1c2f0de72ecd1db8f86dfJim Grosbach void EmitConstant(uint64_t Val, unsigned Size, raw_ostream &OS) const { 324568eeedea72c274abbba1310c18a31eef78e14a4Jim Grosbach // Output the constant in little endian byte order. 325568eeedea72c274abbba1310c18a31eef78e14a4Jim Grosbach for (unsigned i = 0; i != Size; ++i) { 32670933266ae73c891d9d1c2f0de72ecd1db8f86dfJim Grosbach EmitByte(Val & 255, OS); 327568eeedea72c274abbba1310c18a31eef78e14a4Jim Grosbach Val >>= 8; 328568eeedea72c274abbba1310c18a31eef78e14a4Jim Grosbach } 329568eeedea72c274abbba1310c18a31eef78e14a4Jim Grosbach } 330568eeedea72c274abbba1310c18a31eef78e14a4Jim Grosbach 331568eeedea72c274abbba1310c18a31eef78e14a4Jim Grosbach void EncodeInstruction(const MCInst &MI, raw_ostream &OS, 332568eeedea72c274abbba1310c18a31eef78e14a4Jim Grosbach SmallVectorImpl<MCFixup> &Fixups) const; 333568eeedea72c274abbba1310c18a31eef78e14a4Jim Grosbach}; 334568eeedea72c274abbba1310c18a31eef78e14a4Jim Grosbach 335568eeedea72c274abbba1310c18a31eef78e14a4Jim Grosbach} // end anonymous namespace 336568eeedea72c274abbba1310c18a31eef78e14a4Jim Grosbach 33759ee62d2418df8db499eca1ae17f5900dc2dcbbaEvan ChengMCCodeEmitter *llvm::createARMMCCodeEmitter(const MCInstrInfo &MCII, 33859ee62d2418df8db499eca1ae17f5900dc2dcbbaEvan Cheng const MCSubtargetInfo &STI, 3390800ce71896ccd7f49b37861a8cfbc21b6b10022Bill Wendling MCContext &Ctx) { 34059ee62d2418df8db499eca1ae17f5900dc2dcbbaEvan Cheng return new ARMMCCodeEmitter(MCII, STI, Ctx); 341568eeedea72c274abbba1310c18a31eef78e14a4Jim Grosbach} 342568eeedea72c274abbba1310c18a31eef78e14a4Jim Grosbach 3437bf4c02789f97e32225fc248dff6622b994a15eeJim Grosbach/// NEONThumb2DataIPostEncoder - Post-process encoded NEON data-processing 3447bf4c02789f97e32225fc248dff6622b994a15eeJim Grosbach/// instructions, and rewrite them to their Thumb2 form if we are currently in 345c7139a6f0d3acd198ab9eb536ea1ec52e61ff130Owen Anderson/// Thumb2 mode. 346c7139a6f0d3acd198ab9eb536ea1ec52e61ff130Owen Andersonunsigned ARMMCCodeEmitter::NEONThumb2DataIPostEncoder(const MCInst &MI, 347c7139a6f0d3acd198ab9eb536ea1ec52e61ff130Owen Anderson unsigned EncodedValue) const { 34859ee62d2418df8db499eca1ae17f5900dc2dcbbaEvan Cheng if (isThumb2()) { 3497bf4c02789f97e32225fc248dff6622b994a15eeJim Grosbach // NEON Thumb2 data-processsing encodings are very simple: bit 24 is moved 350c7139a6f0d3acd198ab9eb536ea1ec52e61ff130Owen Anderson // to bit 12 of the high half-word (i.e. bit 28), and bits 27-24 are 351c7139a6f0d3acd198ab9eb536ea1ec52e61ff130Owen Anderson // set to 1111. 352c7139a6f0d3acd198ab9eb536ea1ec52e61ff130Owen Anderson unsigned Bit24 = EncodedValue & 0x01000000; 353c7139a6f0d3acd198ab9eb536ea1ec52e61ff130Owen Anderson unsigned Bit28 = Bit24 << 4; 354c7139a6f0d3acd198ab9eb536ea1ec52e61ff130Owen Anderson EncodedValue &= 0xEFFFFFFF; 355c7139a6f0d3acd198ab9eb536ea1ec52e61ff130Owen Anderson EncodedValue |= Bit28; 356c7139a6f0d3acd198ab9eb536ea1ec52e61ff130Owen Anderson EncodedValue |= 0x0F000000; 357c7139a6f0d3acd198ab9eb536ea1ec52e61ff130Owen Anderson } 3587bf4c02789f97e32225fc248dff6622b994a15eeJim Grosbach 359c7139a6f0d3acd198ab9eb536ea1ec52e61ff130Owen Anderson return EncodedValue; 360c7139a6f0d3acd198ab9eb536ea1ec52e61ff130Owen Anderson} 361c7139a6f0d3acd198ab9eb536ea1ec52e61ff130Owen Anderson 36257dac88f775c1191a98cff89abd1f7ad33df5e29Owen Anderson/// NEONThumb2LoadStorePostEncoder - Post-process encoded NEON load/store 3637bf4c02789f97e32225fc248dff6622b994a15eeJim Grosbach/// instructions, and rewrite them to their Thumb2 form if we are currently in 36457dac88f775c1191a98cff89abd1f7ad33df5e29Owen Anderson/// Thumb2 mode. 36557dac88f775c1191a98cff89abd1f7ad33df5e29Owen Andersonunsigned ARMMCCodeEmitter::NEONThumb2LoadStorePostEncoder(const MCInst &MI, 36657dac88f775c1191a98cff89abd1f7ad33df5e29Owen Anderson unsigned EncodedValue) const { 36759ee62d2418df8db499eca1ae17f5900dc2dcbbaEvan Cheng if (isThumb2()) { 36857dac88f775c1191a98cff89abd1f7ad33df5e29Owen Anderson EncodedValue &= 0xF0FFFFFF; 36957dac88f775c1191a98cff89abd1f7ad33df5e29Owen Anderson EncodedValue |= 0x09000000; 37057dac88f775c1191a98cff89abd1f7ad33df5e29Owen Anderson } 3717bf4c02789f97e32225fc248dff6622b994a15eeJim Grosbach 37257dac88f775c1191a98cff89abd1f7ad33df5e29Owen Anderson return EncodedValue; 37357dac88f775c1191a98cff89abd1f7ad33df5e29Owen Anderson} 37457dac88f775c1191a98cff89abd1f7ad33df5e29Owen Anderson 3758f143913141991baaa535ca0da7c8a81606d6392Owen Anderson/// NEONThumb2DupPostEncoder - Post-process encoded NEON vdup 3767bf4c02789f97e32225fc248dff6622b994a15eeJim Grosbach/// instructions, and rewrite them to their Thumb2 form if we are currently in 3778f143913141991baaa535ca0da7c8a81606d6392Owen Anderson/// Thumb2 mode. 3788f143913141991baaa535ca0da7c8a81606d6392Owen Andersonunsigned ARMMCCodeEmitter::NEONThumb2DupPostEncoder(const MCInst &MI, 3798f143913141991baaa535ca0da7c8a81606d6392Owen Anderson unsigned EncodedValue) const { 38059ee62d2418df8db499eca1ae17f5900dc2dcbbaEvan Cheng if (isThumb2()) { 3818f143913141991baaa535ca0da7c8a81606d6392Owen Anderson EncodedValue &= 0x00FFFFFF; 3828f143913141991baaa535ca0da7c8a81606d6392Owen Anderson EncodedValue |= 0xEE000000; 3838f143913141991baaa535ca0da7c8a81606d6392Owen Anderson } 3847bf4c02789f97e32225fc248dff6622b994a15eeJim Grosbach 3858f143913141991baaa535ca0da7c8a81606d6392Owen Anderson return EncodedValue; 3868f143913141991baaa535ca0da7c8a81606d6392Owen Anderson} 3878f143913141991baaa535ca0da7c8a81606d6392Owen Anderson 388cf590263cd5c24ccf1d08cef612738d99cd980d9Bill Wendling/// VFPThumb2PostEncoder - Post-process encoded VFP instructions and rewrite 389cf590263cd5c24ccf1d08cef612738d99cd980d9Bill Wendling/// them to their Thumb2 form if we are currently in Thumb2 mode. 390cf590263cd5c24ccf1d08cef612738d99cd980d9Bill Wendlingunsigned ARMMCCodeEmitter:: 391cf590263cd5c24ccf1d08cef612738d99cd980d9Bill WendlingVFPThumb2PostEncoder(const MCInst &MI, unsigned EncodedValue) const { 39259ee62d2418df8db499eca1ae17f5900dc2dcbbaEvan Cheng if (isThumb2()) { 393cf590263cd5c24ccf1d08cef612738d99cd980d9Bill Wendling EncodedValue &= 0x0FFFFFFF; 394cf590263cd5c24ccf1d08cef612738d99cd980d9Bill Wendling EncodedValue |= 0xE0000000; 395cf590263cd5c24ccf1d08cef612738d99cd980d9Bill Wendling } 396cf590263cd5c24ccf1d08cef612738d99cd980d9Bill Wendling return EncodedValue; 397cf590263cd5c24ccf1d08cef612738d99cd980d9Bill Wendling} 39857dac88f775c1191a98cff89abd1f7ad33df5e29Owen Anderson 39956ac907c57fcfddfd650238f03c856a9d55987e5Jim Grosbach/// getMachineOpValue - Return binary encoding of operand. If the machine 40056ac907c57fcfddfd650238f03c856a9d55987e5Jim Grosbach/// operand requires relocation, record the relocation and return zero. 401806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbachunsigned ARMMCCodeEmitter:: 402806e80ef42bdb416f409142a1ff1d4e8752baac8Jim GrosbachgetMachineOpValue(const MCInst &MI, const MCOperand &MO, 403806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbach SmallVectorImpl<MCFixup> &Fixups) const { 404bbbdcd453d22258cb4dd217eddf016668fcebf84Bill Wendling if (MO.isReg()) { 4050800ce71896ccd7f49b37861a8cfbc21b6b10022Bill Wendling unsigned Reg = MO.getReg(); 4060800ce71896ccd7f49b37861a8cfbc21b6b10022Bill Wendling unsigned RegNo = getARMRegisterNumbering(Reg); 407d8a11c25fa64c152628cfcf5f9d36eb60242b302Jim Grosbach 408b0708d292bbe04cfcfe0c5cb5e27d8a872c9839aJim Grosbach // Q registers are encoded as 2x their register number. 4090800ce71896ccd7f49b37861a8cfbc21b6b10022Bill Wendling switch (Reg) { 4100800ce71896ccd7f49b37861a8cfbc21b6b10022Bill Wendling default: 4110800ce71896ccd7f49b37861a8cfbc21b6b10022Bill Wendling return RegNo; 4120800ce71896ccd7f49b37861a8cfbc21b6b10022Bill Wendling case ARM::Q0: case ARM::Q1: case ARM::Q2: case ARM::Q3: 4130800ce71896ccd7f49b37861a8cfbc21b6b10022Bill Wendling case ARM::Q4: case ARM::Q5: case ARM::Q6: case ARM::Q7: 4140800ce71896ccd7f49b37861a8cfbc21b6b10022Bill Wendling case ARM::Q8: case ARM::Q9: case ARM::Q10: case ARM::Q11: 4150800ce71896ccd7f49b37861a8cfbc21b6b10022Bill Wendling case ARM::Q12: case ARM::Q13: case ARM::Q14: case ARM::Q15: 4160800ce71896ccd7f49b37861a8cfbc21b6b10022Bill Wendling return 2 * RegNo; 41790d4cf931477b497553a9f2d0ed53377dd5dd88cOwen Anderson } 418bbbdcd453d22258cb4dd217eddf016668fcebf84Bill Wendling } else if (MO.isImm()) { 41956ac907c57fcfddfd650238f03c856a9d55987e5Jim Grosbach return static_cast<unsigned>(MO.getImm()); 420bbbdcd453d22258cb4dd217eddf016668fcebf84Bill Wendling } else if (MO.isFPImm()) { 421bbbdcd453d22258cb4dd217eddf016668fcebf84Bill Wendling return static_cast<unsigned>(APFloat(MO.getFPImm()) 422bbbdcd453d22258cb4dd217eddf016668fcebf84Bill Wendling .bitcastToAPInt().getHiBits(32).getLimitedValue()); 4230800ce71896ccd7f49b37861a8cfbc21b6b10022Bill Wendling } 4240800ce71896ccd7f49b37861a8cfbc21b6b10022Bill Wendling 425817c1a6dddadb4664738777d224bc7eae6e62cf3Jim Grosbach llvm_unreachable("Unable to encode MCOperand!"); 42656ac907c57fcfddfd650238f03c856a9d55987e5Jim Grosbach return 0; 42756ac907c57fcfddfd650238f03c856a9d55987e5Jim Grosbach} 42856ac907c57fcfddfd650238f03c856a9d55987e5Jim Grosbach 4295df0e0a61d6ac0e8dcf1a600bdc28d3e4a8db0adBill Wendling/// getAddrModeImmOpValue - Return encoding info for 'reg +/- imm' operand. 430806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbachbool ARMMCCodeEmitter:: 431806e80ef42bdb416f409142a1ff1d4e8752baac8Jim GrosbachEncodeAddrModeOpValues(const MCInst &MI, unsigned OpIdx, unsigned &Reg, 432806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbach unsigned &Imm, SmallVectorImpl<MCFixup> &Fixups) const { 4333e5561247202bae994dd259a2d8dc4eff8f799f3Jim Grosbach const MCOperand &MO = MI.getOperand(OpIdx); 4343e5561247202bae994dd259a2d8dc4eff8f799f3Jim Grosbach const MCOperand &MO1 = MI.getOperand(OpIdx + 1); 4359af3d1c0dc2250793ada1ca6cfa98e9f1253f7f9Jim Grosbach 43692b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling Reg = getARMRegisterNumbering(MO.getReg()); 43792b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling 43892b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling int32_t SImm = MO1.getImm(); 43992b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling bool isAdd = true; 4405df0e0a61d6ac0e8dcf1a600bdc28d3e4a8db0adBill Wendling 441ab682a2090f795d0b67f29889622da0a74cd97c3Jim Grosbach // Special value for #-0 4420da10cf44d0f22111dae728bb535ade2283d976bOwen Anderson if (SImm == INT32_MIN) { 44392b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling SImm = 0; 4440da10cf44d0f22111dae728bb535ade2283d976bOwen Anderson isAdd = false; 4450da10cf44d0f22111dae728bb535ade2283d976bOwen Anderson } 4465df0e0a61d6ac0e8dcf1a600bdc28d3e4a8db0adBill Wendling 447ab682a2090f795d0b67f29889622da0a74cd97c3Jim Grosbach // Immediate is always encoded as positive. The 'U' bit controls add vs sub. 44892b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling if (SImm < 0) { 44992b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling SImm = -SImm; 45092b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling isAdd = false; 45192b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling } 45292b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling 45392b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling Imm = SImm; 45492b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling return isAdd; 45592b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling} 4565df0e0a61d6ac0e8dcf1a600bdc28d3e4a8db0adBill Wendling 457dff2f7151f695b86db8c4b0c6604463bdb8a63eaBill Wendling/// getBranchTargetOpValue - Helper function to get the branch target operand, 458dff2f7151f695b86db8c4b0c6604463bdb8a63eaBill Wendling/// which is either an immediate or requires a fixup. 459dff2f7151f695b86db8c4b0c6604463bdb8a63eaBill Wendlingstatic uint32_t getBranchTargetOpValue(const MCInst &MI, unsigned OpIdx, 460dff2f7151f695b86db8c4b0c6604463bdb8a63eaBill Wendling unsigned FixupKind, 461dff2f7151f695b86db8c4b0c6604463bdb8a63eaBill Wendling SmallVectorImpl<MCFixup> &Fixups) { 462662a816e89a9d77bf75e1328b09cf9235b4682aaJim Grosbach const MCOperand &MO = MI.getOperand(OpIdx); 463662a816e89a9d77bf75e1328b09cf9235b4682aaJim Grosbach 464662a816e89a9d77bf75e1328b09cf9235b4682aaJim Grosbach // If the destination is an immediate, we have nothing to do. 465662a816e89a9d77bf75e1328b09cf9235b4682aaJim Grosbach if (MO.isImm()) return MO.getImm(); 466dff2f7151f695b86db8c4b0c6604463bdb8a63eaBill Wendling assert(MO.isExpr() && "Unexpected branch target type!"); 467662a816e89a9d77bf75e1328b09cf9235b4682aaJim Grosbach const MCExpr *Expr = MO.getExpr(); 468dff2f7151f695b86db8c4b0c6604463bdb8a63eaBill Wendling MCFixupKind Kind = MCFixupKind(FixupKind); 469662a816e89a9d77bf75e1328b09cf9235b4682aaJim Grosbach Fixups.push_back(MCFixup::Create(0, Expr, Kind)); 470662a816e89a9d77bf75e1328b09cf9235b4682aaJim Grosbach 471662a816e89a9d77bf75e1328b09cf9235b4682aaJim Grosbach // All of the information is in the fixup. 472662a816e89a9d77bf75e1328b09cf9235b4682aaJim Grosbach return 0; 473662a816e89a9d77bf75e1328b09cf9235b4682aaJim Grosbach} 474662a816e89a9d77bf75e1328b09cf9235b4682aaJim Grosbach 475559c277aa9242dd5b32d2f2ccc353d938f886ee9Owen Anderson// Thumb BL and BLX use a strange offset encoding where bits 22 and 21 are 476559c277aa9242dd5b32d2f2ccc353d938f886ee9Owen Anderson// determined by negating them and XOR'ing them with bit 23. 477559c277aa9242dd5b32d2f2ccc353d938f886ee9Owen Andersonstatic int32_t encodeThumbBLOffset(int32_t offset) { 478559c277aa9242dd5b32d2f2ccc353d938f886ee9Owen Anderson offset >>= 1; 479559c277aa9242dd5b32d2f2ccc353d938f886ee9Owen Anderson uint32_t S = (offset & 0x800000) >> 23; 480559c277aa9242dd5b32d2f2ccc353d938f886ee9Owen Anderson uint32_t J1 = (offset & 0x400000) >> 22; 481559c277aa9242dd5b32d2f2ccc353d938f886ee9Owen Anderson uint32_t J2 = (offset & 0x200000) >> 21; 482559c277aa9242dd5b32d2f2ccc353d938f886ee9Owen Anderson J1 = (~J1 & 0x1); 483559c277aa9242dd5b32d2f2ccc353d938f886ee9Owen Anderson J2 = (~J2 & 0x1); 484559c277aa9242dd5b32d2f2ccc353d938f886ee9Owen Anderson J1 ^= S; 485559c277aa9242dd5b32d2f2ccc353d938f886ee9Owen Anderson J2 ^= S; 486559c277aa9242dd5b32d2f2ccc353d938f886ee9Owen Anderson 487559c277aa9242dd5b32d2f2ccc353d938f886ee9Owen Anderson offset &= ~0x600000; 488559c277aa9242dd5b32d2f2ccc353d938f886ee9Owen Anderson offset |= J1 << 22; 489559c277aa9242dd5b32d2f2ccc353d938f886ee9Owen Anderson offset |= J2 << 21; 490559c277aa9242dd5b32d2f2ccc353d938f886ee9Owen Anderson 491559c277aa9242dd5b32d2f2ccc353d938f886ee9Owen Anderson return offset; 492559c277aa9242dd5b32d2f2ccc353d938f886ee9Owen Anderson} 493559c277aa9242dd5b32d2f2ccc353d938f886ee9Owen Anderson 494dff2f7151f695b86db8c4b0c6604463bdb8a63eaBill Wendling/// getThumbBLTargetOpValue - Return encoding info for immediate branch target. 495c466b937dbdbaabeef0097fe340de1b8f49a3508Jim Grosbachuint32_t ARMMCCodeEmitter:: 496dff2f7151f695b86db8c4b0c6604463bdb8a63eaBill WendlinggetThumbBLTargetOpValue(const MCInst &MI, unsigned OpIdx, 497c466b937dbdbaabeef0097fe340de1b8f49a3508Jim Grosbach SmallVectorImpl<MCFixup> &Fixups) const { 498559c277aa9242dd5b32d2f2ccc353d938f886ee9Owen Anderson const MCOperand MO = MI.getOperand(OpIdx); 499559c277aa9242dd5b32d2f2ccc353d938f886ee9Owen Anderson if (MO.isExpr()) 500559c277aa9242dd5b32d2f2ccc353d938f886ee9Owen Anderson return ::getBranchTargetOpValue(MI, OpIdx, ARM::fixup_arm_thumb_bl, 501559c277aa9242dd5b32d2f2ccc353d938f886ee9Owen Anderson Fixups); 502559c277aa9242dd5b32d2f2ccc353d938f886ee9Owen Anderson return encodeThumbBLOffset(MO.getImm()); 503dff2f7151f695b86db8c4b0c6604463bdb8a63eaBill Wendling} 504c466b937dbdbaabeef0097fe340de1b8f49a3508Jim Grosbach 50509aa3f0ef35d9241c92439d74b8d5e9a81d814c2Bill Wendling/// getThumbBLXTargetOpValue - Return encoding info for Thumb immediate 50609aa3f0ef35d9241c92439d74b8d5e9a81d814c2Bill Wendling/// BLX branch target. 50709aa3f0ef35d9241c92439d74b8d5e9a81d814c2Bill Wendlinguint32_t ARMMCCodeEmitter:: 50809aa3f0ef35d9241c92439d74b8d5e9a81d814c2Bill WendlinggetThumbBLXTargetOpValue(const MCInst &MI, unsigned OpIdx, 50909aa3f0ef35d9241c92439d74b8d5e9a81d814c2Bill Wendling SmallVectorImpl<MCFixup> &Fixups) const { 510559c277aa9242dd5b32d2f2ccc353d938f886ee9Owen Anderson const MCOperand MO = MI.getOperand(OpIdx); 511559c277aa9242dd5b32d2f2ccc353d938f886ee9Owen Anderson if (MO.isExpr()) 512559c277aa9242dd5b32d2f2ccc353d938f886ee9Owen Anderson return ::getBranchTargetOpValue(MI, OpIdx, ARM::fixup_arm_thumb_blx, 513559c277aa9242dd5b32d2f2ccc353d938f886ee9Owen Anderson Fixups); 514559c277aa9242dd5b32d2f2ccc353d938f886ee9Owen Anderson return encodeThumbBLOffset(MO.getImm()); 51509aa3f0ef35d9241c92439d74b8d5e9a81d814c2Bill Wendling} 51609aa3f0ef35d9241c92439d74b8d5e9a81d814c2Bill Wendling 517e246717c3a36a913fd4200776ed621649bb2b624Jim Grosbach/// getThumbBRTargetOpValue - Return encoding info for Thumb branch target. 518e246717c3a36a913fd4200776ed621649bb2b624Jim Grosbachuint32_t ARMMCCodeEmitter:: 519e246717c3a36a913fd4200776ed621649bb2b624Jim GrosbachgetThumbBRTargetOpValue(const MCInst &MI, unsigned OpIdx, 520e246717c3a36a913fd4200776ed621649bb2b624Jim Grosbach SmallVectorImpl<MCFixup> &Fixups) const { 521391ac65377f2ad5e48a796e75120959e22430605Owen Anderson const MCOperand MO = MI.getOperand(OpIdx); 522391ac65377f2ad5e48a796e75120959e22430605Owen Anderson if (MO.isExpr()) 523559c277aa9242dd5b32d2f2ccc353d938f886ee9Owen Anderson return ::getBranchTargetOpValue(MI, OpIdx, ARM::fixup_arm_thumb_br, 524559c277aa9242dd5b32d2f2ccc353d938f886ee9Owen Anderson Fixups); 525391ac65377f2ad5e48a796e75120959e22430605Owen Anderson return (MO.getImm() >> 1); 526e246717c3a36a913fd4200776ed621649bb2b624Jim Grosbach} 527e246717c3a36a913fd4200776ed621649bb2b624Jim Grosbach 52801086451393ef33e82b6fad623989dd97dd70edfJim Grosbach/// getThumbBCCTargetOpValue - Return encoding info for Thumb branch target. 52901086451393ef33e82b6fad623989dd97dd70edfJim Grosbachuint32_t ARMMCCodeEmitter:: 53001086451393ef33e82b6fad623989dd97dd70edfJim GrosbachgetThumbBCCTargetOpValue(const MCInst &MI, unsigned OpIdx, 531e246717c3a36a913fd4200776ed621649bb2b624Jim Grosbach SmallVectorImpl<MCFixup> &Fixups) const { 532721cb1fde07423fd1905338d443172a8028ad634Owen Anderson const MCOperand MO = MI.getOperand(OpIdx); 533721cb1fde07423fd1905338d443172a8028ad634Owen Anderson if (MO.isExpr()) 534721cb1fde07423fd1905338d443172a8028ad634Owen Anderson return ::getBranchTargetOpValue(MI, OpIdx, ARM::fixup_arm_thumb_bcc, 535721cb1fde07423fd1905338d443172a8028ad634Owen Anderson Fixups); 536721cb1fde07423fd1905338d443172a8028ad634Owen Anderson return (MO.getImm() >> 1); 53701086451393ef33e82b6fad623989dd97dd70edfJim Grosbach} 53801086451393ef33e82b6fad623989dd97dd70edfJim Grosbach 539027d6e8d1ca04e4096fb3a27579b861d861466c5Jim Grosbach/// getThumbCBTargetOpValue - Return encoding info for Thumb branch target. 540dff2f7151f695b86db8c4b0c6604463bdb8a63eaBill Wendlinguint32_t ARMMCCodeEmitter:: 541027d6e8d1ca04e4096fb3a27579b861d861466c5Jim GrosbachgetThumbCBTargetOpValue(const MCInst &MI, unsigned OpIdx, 542dff2f7151f695b86db8c4b0c6604463bdb8a63eaBill Wendling SmallVectorImpl<MCFixup> &Fixups) const { 54321df36c57afc588c8073a070a47e3ba45fa87270Owen Anderson const MCOperand MO = MI.getOperand(OpIdx); 54421df36c57afc588c8073a070a47e3ba45fa87270Owen Anderson if (MO.isExpr()) 54521df36c57afc588c8073a070a47e3ba45fa87270Owen Anderson return ::getBranchTargetOpValue(MI, OpIdx, ARM::fixup_arm_thumb_cb, Fixups); 54621df36c57afc588c8073a070a47e3ba45fa87270Owen Anderson return (MO.getImm() >> 1); 547dff2f7151f695b86db8c4b0c6604463bdb8a63eaBill Wendling} 548c466b937dbdbaabeef0097fe340de1b8f49a3508Jim Grosbach 549685c350ae76b588e1f00c01a511fe8bd57f18394Jason W Kim/// Return true if this branch has a non-always predication 550685c350ae76b588e1f00c01a511fe8bd57f18394Jason W Kimstatic bool HasConditionalBranch(const MCInst &MI) { 551685c350ae76b588e1f00c01a511fe8bd57f18394Jason W Kim int NumOp = MI.getNumOperands(); 552685c350ae76b588e1f00c01a511fe8bd57f18394Jason W Kim if (NumOp >= 2) { 553685c350ae76b588e1f00c01a511fe8bd57f18394Jason W Kim for (int i = 0; i < NumOp-1; ++i) { 554685c350ae76b588e1f00c01a511fe8bd57f18394Jason W Kim const MCOperand &MCOp1 = MI.getOperand(i); 555685c350ae76b588e1f00c01a511fe8bd57f18394Jason W Kim const MCOperand &MCOp2 = MI.getOperand(i + 1); 55610096dbdef22a10a6a4444437c935ab428545525Owen Anderson if (MCOp1.isImm() && MCOp2.isReg() && 557685c350ae76b588e1f00c01a511fe8bd57f18394Jason W Kim (MCOp2.getReg() == 0 || MCOp2.getReg() == ARM::CPSR)) { 55810096dbdef22a10a6a4444437c935ab428545525Owen Anderson if (ARMCC::CondCodes(MCOp1.getImm()) != ARMCC::AL) 559685c350ae76b588e1f00c01a511fe8bd57f18394Jason W Kim return true; 560685c350ae76b588e1f00c01a511fe8bd57f18394Jason W Kim } 561685c350ae76b588e1f00c01a511fe8bd57f18394Jason W Kim } 562685c350ae76b588e1f00c01a511fe8bd57f18394Jason W Kim } 563685c350ae76b588e1f00c01a511fe8bd57f18394Jason W Kim return false; 564685c350ae76b588e1f00c01a511fe8bd57f18394Jason W Kim} 565685c350ae76b588e1f00c01a511fe8bd57f18394Jason W Kim 566dff2f7151f695b86db8c4b0c6604463bdb8a63eaBill Wendling/// getBranchTargetOpValue - Return encoding info for 24-bit immediate branch 567dff2f7151f695b86db8c4b0c6604463bdb8a63eaBill Wendling/// target. 568dff2f7151f695b86db8c4b0c6604463bdb8a63eaBill Wendlinguint32_t ARMMCCodeEmitter:: 569dff2f7151f695b86db8c4b0c6604463bdb8a63eaBill WendlinggetBranchTargetOpValue(const MCInst &MI, unsigned OpIdx, 570dff2f7151f695b86db8c4b0c6604463bdb8a63eaBill Wendling SmallVectorImpl<MCFixup> &Fixups) const { 571092e2cd5693114a4f1d93eb5b72f3e194de27236Jim Grosbach // FIXME: This really, really shouldn't use TargetMachine. We don't want 572092e2cd5693114a4f1d93eb5b72f3e194de27236Jim Grosbach // coupling between MC and TM anywhere we can help it. 57359ee62d2418df8db499eca1ae17f5900dc2dcbbaEvan Cheng if (isThumb2()) 574c266600bec4b5ba0ee93ffdfeaafcab8f1295145Owen Anderson return 575c266600bec4b5ba0ee93ffdfeaafcab8f1295145Owen Anderson ::getBranchTargetOpValue(MI, OpIdx, ARM::fixup_t2_condbranch, Fixups); 576685c350ae76b588e1f00c01a511fe8bd57f18394Jason W Kim return getARMBranchTargetOpValue(MI, OpIdx, Fixups); 577685c350ae76b588e1f00c01a511fe8bd57f18394Jason W Kim} 578685c350ae76b588e1f00c01a511fe8bd57f18394Jason W Kim 579685c350ae76b588e1f00c01a511fe8bd57f18394Jason W Kim/// getBranchTargetOpValue - Return encoding info for 24-bit immediate branch 580685c350ae76b588e1f00c01a511fe8bd57f18394Jason W Kim/// target. 581685c350ae76b588e1f00c01a511fe8bd57f18394Jason W Kimuint32_t ARMMCCodeEmitter:: 582685c350ae76b588e1f00c01a511fe8bd57f18394Jason W KimgetARMBranchTargetOpValue(const MCInst &MI, unsigned OpIdx, 583685c350ae76b588e1f00c01a511fe8bd57f18394Jason W Kim SmallVectorImpl<MCFixup> &Fixups) const { 584d7568e1c355f5e364eddafc15c6d5553559f32a5Owen Anderson const MCOperand MO = MI.getOperand(OpIdx); 585d7568e1c355f5e364eddafc15c6d5553559f32a5Owen Anderson if (MO.isExpr()) { 58610096dbdef22a10a6a4444437c935ab428545525Owen Anderson if (HasConditionalBranch(MI)) 587d7568e1c355f5e364eddafc15c6d5553559f32a5Owen Anderson return ::getBranchTargetOpValue(MI, OpIdx, 588d7568e1c355f5e364eddafc15c6d5553559f32a5Owen Anderson ARM::fixup_arm_condbranch, Fixups); 58910096dbdef22a10a6a4444437c935ab428545525Owen Anderson return ::getBranchTargetOpValue(MI, OpIdx, 590d7568e1c355f5e364eddafc15c6d5553559f32a5Owen Anderson ARM::fixup_arm_uncondbranch, Fixups); 591d7568e1c355f5e364eddafc15c6d5553559f32a5Owen Anderson } 592d7568e1c355f5e364eddafc15c6d5553559f32a5Owen Anderson 593d7568e1c355f5e364eddafc15c6d5553559f32a5Owen Anderson return MO.getImm() >> 2; 594c466b937dbdbaabeef0097fe340de1b8f49a3508Jim Grosbach} 595c466b937dbdbaabeef0097fe340de1b8f49a3508Jim Grosbach 596f1eab597b2316c6cfcabfcee98895fedb2071722Owen Andersonuint32_t ARMMCCodeEmitter:: 597f1eab597b2316c6cfcabfcee98895fedb2071722Owen AndersongetARMBLXTargetOpValue(const MCInst &MI, unsigned OpIdx, 598f1eab597b2316c6cfcabfcee98895fedb2071722Owen Anderson SmallVectorImpl<MCFixup> &Fixups) const { 599f1eab597b2316c6cfcabfcee98895fedb2071722Owen Anderson const MCOperand MO = MI.getOperand(OpIdx); 600f1eab597b2316c6cfcabfcee98895fedb2071722Owen Anderson if (MO.isExpr()) { 60110096dbdef22a10a6a4444437c935ab428545525Owen Anderson if (HasConditionalBranch(MI)) 602f1eab597b2316c6cfcabfcee98895fedb2071722Owen Anderson return ::getBranchTargetOpValue(MI, OpIdx, 603f1eab597b2316c6cfcabfcee98895fedb2071722Owen Anderson ARM::fixup_arm_condbranch, Fixups); 60410096dbdef22a10a6a4444437c935ab428545525Owen Anderson return ::getBranchTargetOpValue(MI, OpIdx, 605f1eab597b2316c6cfcabfcee98895fedb2071722Owen Anderson ARM::fixup_arm_uncondbranch, Fixups); 606f1eab597b2316c6cfcabfcee98895fedb2071722Owen Anderson } 607685c350ae76b588e1f00c01a511fe8bd57f18394Jason W Kim 608f1eab597b2316c6cfcabfcee98895fedb2071722Owen Anderson return MO.getImm() >> 1; 609f1eab597b2316c6cfcabfcee98895fedb2071722Owen Anderson} 610685c350ae76b588e1f00c01a511fe8bd57f18394Jason W Kim 611c266600bec4b5ba0ee93ffdfeaafcab8f1295145Owen Anderson/// getUnconditionalBranchTargetOpValue - Return encoding info for 24-bit 612c266600bec4b5ba0ee93ffdfeaafcab8f1295145Owen Anderson/// immediate branch target. 613c266600bec4b5ba0ee93ffdfeaafcab8f1295145Owen Andersonuint32_t ARMMCCodeEmitter:: 614c266600bec4b5ba0ee93ffdfeaafcab8f1295145Owen AndersongetUnconditionalBranchTargetOpValue(const MCInst &MI, unsigned OpIdx, 615c266600bec4b5ba0ee93ffdfeaafcab8f1295145Owen Anderson SmallVectorImpl<MCFixup> &Fixups) const { 616c266600bec4b5ba0ee93ffdfeaafcab8f1295145Owen Anderson unsigned Val = 617c266600bec4b5ba0ee93ffdfeaafcab8f1295145Owen Anderson ::getBranchTargetOpValue(MI, OpIdx, ARM::fixup_t2_uncondbranch, Fixups); 618c266600bec4b5ba0ee93ffdfeaafcab8f1295145Owen Anderson bool I = (Val & 0x800000); 619c266600bec4b5ba0ee93ffdfeaafcab8f1295145Owen Anderson bool J1 = (Val & 0x400000); 620c266600bec4b5ba0ee93ffdfeaafcab8f1295145Owen Anderson bool J2 = (Val & 0x200000); 621c266600bec4b5ba0ee93ffdfeaafcab8f1295145Owen Anderson if (I ^ J1) 622c266600bec4b5ba0ee93ffdfeaafcab8f1295145Owen Anderson Val &= ~0x400000; 623c266600bec4b5ba0ee93ffdfeaafcab8f1295145Owen Anderson else 624c266600bec4b5ba0ee93ffdfeaafcab8f1295145Owen Anderson Val |= 0x400000; 625971b83b67a9812556cdb97bb58aa96fb37af458dOwen Anderson 626c266600bec4b5ba0ee93ffdfeaafcab8f1295145Owen Anderson if (I ^ J2) 627c266600bec4b5ba0ee93ffdfeaafcab8f1295145Owen Anderson Val &= ~0x200000; 628c266600bec4b5ba0ee93ffdfeaafcab8f1295145Owen Anderson else 629c266600bec4b5ba0ee93ffdfeaafcab8f1295145Owen Anderson Val |= 0x200000; 630971b83b67a9812556cdb97bb58aa96fb37af458dOwen Anderson 631c266600bec4b5ba0ee93ffdfeaafcab8f1295145Owen Anderson return Val; 632c266600bec4b5ba0ee93ffdfeaafcab8f1295145Owen Anderson} 633c266600bec4b5ba0ee93ffdfeaafcab8f1295145Owen Anderson 634dff2f7151f695b86db8c4b0c6604463bdb8a63eaBill Wendling/// getAdrLabelOpValue - Return encoding info for 12-bit immediate ADR label 635dff2f7151f695b86db8c4b0c6604463bdb8a63eaBill Wendling/// target. 6365d14f9be7ba64162c7b996f36d419b11d8cdbe9aJim Grosbachuint32_t ARMMCCodeEmitter:: 6375d14f9be7ba64162c7b996f36d419b11d8cdbe9aJim GrosbachgetAdrLabelOpValue(const MCInst &MI, unsigned OpIdx, 6385d14f9be7ba64162c7b996f36d419b11d8cdbe9aJim Grosbach SmallVectorImpl<MCFixup> &Fixups) const { 63996425c846494c1c20a4c931f4783571295ab170cOwen Anderson const MCOperand MO = MI.getOperand(OpIdx); 64096425c846494c1c20a4c931f4783571295ab170cOwen Anderson if (MO.isExpr()) 64196425c846494c1c20a4c931f4783571295ab170cOwen Anderson return ::getBranchTargetOpValue(MI, OpIdx, ARM::fixup_arm_adr_pcrel_12, 64296425c846494c1c20a4c931f4783571295ab170cOwen Anderson Fixups); 64396425c846494c1c20a4c931f4783571295ab170cOwen Anderson int32_t offset = MO.getImm(); 64496425c846494c1c20a4c931f4783571295ab170cOwen Anderson uint32_t Val = 0x2000; 64596425c846494c1c20a4c931f4783571295ab170cOwen Anderson if (offset < 0) { 64696425c846494c1c20a4c931f4783571295ab170cOwen Anderson Val = 0x1000; 64796425c846494c1c20a4c931f4783571295ab170cOwen Anderson offset *= -1; 64896425c846494c1c20a4c931f4783571295ab170cOwen Anderson } 64996425c846494c1c20a4c931f4783571295ab170cOwen Anderson Val |= offset; 65096425c846494c1c20a4c931f4783571295ab170cOwen Anderson return Val; 6515d14f9be7ba64162c7b996f36d419b11d8cdbe9aJim Grosbach} 6525d14f9be7ba64162c7b996f36d419b11d8cdbe9aJim Grosbach 653a838a25d59838adfa91463f6a918ae3adeb352c1Owen Anderson/// getAdrLabelOpValue - Return encoding info for 12-bit immediate ADR label 654a838a25d59838adfa91463f6a918ae3adeb352c1Owen Anderson/// target. 655a838a25d59838adfa91463f6a918ae3adeb352c1Owen Andersonuint32_t ARMMCCodeEmitter:: 656a838a25d59838adfa91463f6a918ae3adeb352c1Owen AndersongetT2AdrLabelOpValue(const MCInst &MI, unsigned OpIdx, 657a838a25d59838adfa91463f6a918ae3adeb352c1Owen Anderson SmallVectorImpl<MCFixup> &Fixups) const { 65896425c846494c1c20a4c931f4783571295ab170cOwen Anderson const MCOperand MO = MI.getOperand(OpIdx); 65996425c846494c1c20a4c931f4783571295ab170cOwen Anderson if (MO.isExpr()) 66096425c846494c1c20a4c931f4783571295ab170cOwen Anderson return ::getBranchTargetOpValue(MI, OpIdx, ARM::fixup_t2_adr_pcrel_12, 66196425c846494c1c20a4c931f4783571295ab170cOwen Anderson Fixups); 66208fef885eb39339a47e3be7f0842b1db33683003Owen Anderson int32_t Val = MO.getImm(); 66308fef885eb39339a47e3be7f0842b1db33683003Owen Anderson if (Val < 0) { 66408fef885eb39339a47e3be7f0842b1db33683003Owen Anderson Val *= -1; 66508fef885eb39339a47e3be7f0842b1db33683003Owen Anderson Val |= 0x1000; 66608fef885eb39339a47e3be7f0842b1db33683003Owen Anderson } 66708fef885eb39339a47e3be7f0842b1db33683003Owen Anderson return Val; 668a838a25d59838adfa91463f6a918ae3adeb352c1Owen Anderson} 669a838a25d59838adfa91463f6a918ae3adeb352c1Owen Anderson 670d40963c4065432ec7e47879d3ca665a54ee903b6Jim Grosbach/// getAdrLabelOpValue - Return encoding info for 8-bit immediate ADR label 671d40963c4065432ec7e47879d3ca665a54ee903b6Jim Grosbach/// target. 672d40963c4065432ec7e47879d3ca665a54ee903b6Jim Grosbachuint32_t ARMMCCodeEmitter:: 673d40963c4065432ec7e47879d3ca665a54ee903b6Jim GrosbachgetThumbAdrLabelOpValue(const MCInst &MI, unsigned OpIdx, 674d40963c4065432ec7e47879d3ca665a54ee903b6Jim Grosbach SmallVectorImpl<MCFixup> &Fixups) const { 67596425c846494c1c20a4c931f4783571295ab170cOwen Anderson const MCOperand MO = MI.getOperand(OpIdx); 67696425c846494c1c20a4c931f4783571295ab170cOwen Anderson if (MO.isExpr()) 67796425c846494c1c20a4c931f4783571295ab170cOwen Anderson return ::getBranchTargetOpValue(MI, OpIdx, ARM::fixup_thumb_adr_pcrel_10, 67896425c846494c1c20a4c931f4783571295ab170cOwen Anderson Fixups); 67996425c846494c1c20a4c931f4783571295ab170cOwen Anderson return MO.getImm(); 680d40963c4065432ec7e47879d3ca665a54ee903b6Jim Grosbach} 681d40963c4065432ec7e47879d3ca665a54ee903b6Jim Grosbach 682f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling/// getThumbAddrModeRegRegOpValue - Return encoding info for 'reg + reg' 683f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling/// operand. 6840f4b60d43a289671082deee3bd56a3a055afb16aOwen Andersonuint32_t ARMMCCodeEmitter:: 685f4caf69720d807573c50d41aa06bcec1c99bdbbdBill WendlinggetThumbAddrModeRegRegOpValue(const MCInst &MI, unsigned OpIdx, 686f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling SmallVectorImpl<MCFixup> &) const { 687f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling // [Rn, Rm] 688f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling // {5-3} = Rm 689f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling // {2-0} = Rn 6900f4b60d43a289671082deee3bd56a3a055afb16aOwen Anderson const MCOperand &MO1 = MI.getOperand(OpIdx); 691f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling const MCOperand &MO2 = MI.getOperand(OpIdx + 1); 6920f4b60d43a289671082deee3bd56a3a055afb16aOwen Anderson unsigned Rn = getARMRegisterNumbering(MO1.getReg()); 6930f4b60d43a289671082deee3bd56a3a055afb16aOwen Anderson unsigned Rm = getARMRegisterNumbering(MO2.getReg()); 6940f4b60d43a289671082deee3bd56a3a055afb16aOwen Anderson return (Rm << 3) | Rn; 6950f4b60d43a289671082deee3bd56a3a055afb16aOwen Anderson} 6960f4b60d43a289671082deee3bd56a3a055afb16aOwen Anderson 69792b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling/// getAddrModeImm12OpValue - Return encoding info for 'reg +/- imm12' operand. 698806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbachuint32_t ARMMCCodeEmitter:: 699806e80ef42bdb416f409142a1ff1d4e8752baac8Jim GrosbachgetAddrModeImm12OpValue(const MCInst &MI, unsigned OpIdx, 700806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbach SmallVectorImpl<MCFixup> &Fixups) const { 70192b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling // {17-13} = reg 70292b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling // {12} = (U)nsigned (add == '1', sub == '0') 70392b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling // {11-0} = imm12 70492b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling unsigned Reg, Imm12; 70570933266ae73c891d9d1c2f0de72ecd1db8f86dfJim Grosbach bool isAdd = true; 70670933266ae73c891d9d1c2f0de72ecd1db8f86dfJim Grosbach // If The first operand isn't a register, we have a label reference. 70770933266ae73c891d9d1c2f0de72ecd1db8f86dfJim Grosbach const MCOperand &MO = MI.getOperand(OpIdx); 708971b83b67a9812556cdb97bb58aa96fb37af458dOwen Anderson if (!MO.isReg()) { 709679cbd3b215b1769a6035e334f9009aeeb940dddJim Grosbach Reg = getARMRegisterNumbering(ARM::PC); // Rn is PC. 71070933266ae73c891d9d1c2f0de72ecd1db8f86dfJim Grosbach Imm12 = 0; 71197dd28fb89dc4c4caa3c60890335dc99489981a6Jim Grosbach isAdd = false ; // 'U' bit is set as part of the fixup. 71270933266ae73c891d9d1c2f0de72ecd1db8f86dfJim Grosbach 713fd92d2e106acfbf13ed29b5d15f3a690cd8699b2Owen Anderson if (MO.isExpr()) { 714fd92d2e106acfbf13ed29b5d15f3a690cd8699b2Owen Anderson const MCExpr *Expr = MO.getExpr(); 715fd92d2e106acfbf13ed29b5d15f3a690cd8699b2Owen Anderson 716fd92d2e106acfbf13ed29b5d15f3a690cd8699b2Owen Anderson MCFixupKind Kind; 717fd92d2e106acfbf13ed29b5d15f3a690cd8699b2Owen Anderson if (isThumb2()) 718fd92d2e106acfbf13ed29b5d15f3a690cd8699b2Owen Anderson Kind = MCFixupKind(ARM::fixup_t2_ldst_pcrel_12); 719fd92d2e106acfbf13ed29b5d15f3a690cd8699b2Owen Anderson else 720fd92d2e106acfbf13ed29b5d15f3a690cd8699b2Owen Anderson Kind = MCFixupKind(ARM::fixup_arm_ldst_pcrel_12); 721fd92d2e106acfbf13ed29b5d15f3a690cd8699b2Owen Anderson Fixups.push_back(MCFixup::Create(0, Expr, Kind)); 722fd92d2e106acfbf13ed29b5d15f3a690cd8699b2Owen Anderson 723fd92d2e106acfbf13ed29b5d15f3a690cd8699b2Owen Anderson ++MCNumCPRelocations; 724fd92d2e106acfbf13ed29b5d15f3a690cd8699b2Owen Anderson } else { 725fd92d2e106acfbf13ed29b5d15f3a690cd8699b2Owen Anderson Reg = ARM::PC; 726fd92d2e106acfbf13ed29b5d15f3a690cd8699b2Owen Anderson int32_t Offset = MO.getImm(); 727fd92d2e106acfbf13ed29b5d15f3a690cd8699b2Owen Anderson if (Offset < 0) { 728fd92d2e106acfbf13ed29b5d15f3a690cd8699b2Owen Anderson Offset *= -1; 729fd92d2e106acfbf13ed29b5d15f3a690cd8699b2Owen Anderson isAdd = false; 730fd92d2e106acfbf13ed29b5d15f3a690cd8699b2Owen Anderson } 731fd92d2e106acfbf13ed29b5d15f3a690cd8699b2Owen Anderson Imm12 = Offset; 732fd92d2e106acfbf13ed29b5d15f3a690cd8699b2Owen Anderson } 73370933266ae73c891d9d1c2f0de72ecd1db8f86dfJim Grosbach } else 73470933266ae73c891d9d1c2f0de72ecd1db8f86dfJim Grosbach isAdd = EncodeAddrModeOpValues(MI, OpIdx, Reg, Imm12, Fixups); 73592b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling 73692b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling uint32_t Binary = Imm12 & 0xfff; 73792b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling // Immediate is always encoded as positive. The 'U' bit controls add vs sub. 738ab682a2090f795d0b67f29889622da0a74cd97c3Jim Grosbach if (isAdd) 73992b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling Binary |= (1 << 12); 74092b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling Binary |= (Reg << 13); 74192b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling return Binary; 74292b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling} 74392b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling 744a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach/// getT2Imm8s4OpValue - Return encoding info for 745a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach/// '+/- imm8<<2' operand. 746a77295db19527503d6b290e4f34f273d0a789365Jim Grosbachuint32_t ARMMCCodeEmitter:: 747a77295db19527503d6b290e4f34f273d0a789365Jim GrosbachgetT2Imm8s4OpValue(const MCInst &MI, unsigned OpIdx, 748a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach SmallVectorImpl<MCFixup> &Fixups) const { 749a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach // FIXME: The immediate operand should have already been encoded like this 750a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach // before ever getting here. The encoder method should just need to combine 751a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach // the MI operands for the register and the offset into a single 752a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach // representation for the complex operand in the .td file. This isn't just 753a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach // style, unfortunately. As-is, we can't represent the distinct encoding 754a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach // for #-0. 755a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach 756a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach // {8} = (U)nsigned (add == '1', sub == '0') 757a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach // {7-0} = imm8 758a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach int32_t Imm8 = MI.getOperand(OpIdx).getImm(); 759a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach bool isAdd = Imm8 >= 0; 760a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach 761a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach // Immediate is always encoded as positive. The 'U' bit controls add vs sub. 762a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach if (Imm8 < 0) 763a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach Imm8 = -Imm8; 764a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach 765a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach // Scaled by 4. 766a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach Imm8 /= 4; 767a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach 768a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach uint32_t Binary = Imm8 & 0xff; 769a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach // Immediate is always encoded as positive. The 'U' bit controls add vs sub. 770a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach if (isAdd) 771a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach Binary |= (1 << 8); 772a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach return Binary; 773a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach} 774a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach 7759d63d90de5e57ad96f467b270544443a9284eb2bOwen Anderson/// getT2AddrModeImm8s4OpValue - Return encoding info for 7769d63d90de5e57ad96f467b270544443a9284eb2bOwen Anderson/// 'reg +/- imm8<<2' operand. 7779d63d90de5e57ad96f467b270544443a9284eb2bOwen Andersonuint32_t ARMMCCodeEmitter:: 7789d63d90de5e57ad96f467b270544443a9284eb2bOwen AndersongetT2AddrModeImm8s4OpValue(const MCInst &MI, unsigned OpIdx, 7799d63d90de5e57ad96f467b270544443a9284eb2bOwen Anderson SmallVectorImpl<MCFixup> &Fixups) const { 78090cc533fda9742f5c67203f97e69e5efd270c676Jim Grosbach // {12-9} = reg 78190cc533fda9742f5c67203f97e69e5efd270c676Jim Grosbach // {8} = (U)nsigned (add == '1', sub == '0') 78290cc533fda9742f5c67203f97e69e5efd270c676Jim Grosbach // {7-0} = imm8 7839d63d90de5e57ad96f467b270544443a9284eb2bOwen Anderson unsigned Reg, Imm8; 7849d63d90de5e57ad96f467b270544443a9284eb2bOwen Anderson bool isAdd = true; 7859d63d90de5e57ad96f467b270544443a9284eb2bOwen Anderson // If The first operand isn't a register, we have a label reference. 7869d63d90de5e57ad96f467b270544443a9284eb2bOwen Anderson const MCOperand &MO = MI.getOperand(OpIdx); 7879d63d90de5e57ad96f467b270544443a9284eb2bOwen Anderson if (!MO.isReg()) { 7889d63d90de5e57ad96f467b270544443a9284eb2bOwen Anderson Reg = getARMRegisterNumbering(ARM::PC); // Rn is PC. 7899d63d90de5e57ad96f467b270544443a9284eb2bOwen Anderson Imm8 = 0; 7909d63d90de5e57ad96f467b270544443a9284eb2bOwen Anderson isAdd = false ; // 'U' bit is set as part of the fixup. 7919d63d90de5e57ad96f467b270544443a9284eb2bOwen Anderson 7929d63d90de5e57ad96f467b270544443a9284eb2bOwen Anderson assert(MO.isExpr() && "Unexpected machine operand type!"); 7939d63d90de5e57ad96f467b270544443a9284eb2bOwen Anderson const MCExpr *Expr = MO.getExpr(); 7942f196747f15240691bd4e622f7995edfedf90f61Jim Grosbach MCFixupKind Kind = MCFixupKind(ARM::fixup_t2_pcrel_10); 7959d63d90de5e57ad96f467b270544443a9284eb2bOwen Anderson Fixups.push_back(MCFixup::Create(0, Expr, Kind)); 7969d63d90de5e57ad96f467b270544443a9284eb2bOwen Anderson 7979d63d90de5e57ad96f467b270544443a9284eb2bOwen Anderson ++MCNumCPRelocations; 7989d63d90de5e57ad96f467b270544443a9284eb2bOwen Anderson } else 7999d63d90de5e57ad96f467b270544443a9284eb2bOwen Anderson isAdd = EncodeAddrModeOpValues(MI, OpIdx, Reg, Imm8, Fixups); 8009d63d90de5e57ad96f467b270544443a9284eb2bOwen Anderson 801a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach // FIXME: The immediate operand should have already been encoded like this 802a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach // before ever getting here. The encoder method should just need to combine 803a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach // the MI operands for the register and the offset into a single 804a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach // representation for the complex operand in the .td file. This isn't just 805a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach // style, unfortunately. As-is, we can't represent the distinct encoding 806a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach // for #-0. 8079d63d90de5e57ad96f467b270544443a9284eb2bOwen Anderson uint32_t Binary = (Imm8 >> 2) & 0xff; 8089d63d90de5e57ad96f467b270544443a9284eb2bOwen Anderson // Immediate is always encoded as positive. The 'U' bit controls add vs sub. 8099d63d90de5e57ad96f467b270544443a9284eb2bOwen Anderson if (isAdd) 81090cc533fda9742f5c67203f97e69e5efd270c676Jim Grosbach Binary |= (1 << 8); 8119d63d90de5e57ad96f467b270544443a9284eb2bOwen Anderson Binary |= (Reg << 9); 8129d63d90de5e57ad96f467b270544443a9284eb2bOwen Anderson return Binary; 8139d63d90de5e57ad96f467b270544443a9284eb2bOwen Anderson} 8149d63d90de5e57ad96f467b270544443a9284eb2bOwen Anderson 815b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach/// getT2AddrModeImm0_1020s4OpValue - Return encoding info for 816b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach/// 'reg + imm8<<2' operand. 817b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbachuint32_t ARMMCCodeEmitter:: 818b6aed508e310e31dcb080e761ca856127cec0773Jim GrosbachgetT2AddrModeImm0_1020s4OpValue(const MCInst &MI, unsigned OpIdx, 819b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach SmallVectorImpl<MCFixup> &Fixups) const { 820b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach // {11-8} = reg 821b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach // {7-0} = imm8 822b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach const MCOperand &MO = MI.getOperand(OpIdx); 823b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach const MCOperand &MO1 = MI.getOperand(OpIdx + 1); 824b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach unsigned Reg = getARMRegisterNumbering(MO.getReg()); 825b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach unsigned Imm8 = MO1.getImm(); 826b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach return (Reg << 8) | Imm8; 827b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach} 828b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach 82986a97f2e4d0cde5e992f52ac287da0de687e0110Jason W Kim// FIXME: This routine assumes that a binary 83086a97f2e4d0cde5e992f52ac287da0de687e0110Jason W Kim// expression will always result in a PCRel expression 83186a97f2e4d0cde5e992f52ac287da0de687e0110Jason W Kim// In reality, its only true if one or more subexpressions 83286a97f2e4d0cde5e992f52ac287da0de687e0110Jason W Kim// is itself a PCRel (i.e. "." in asm or some other pcrel construct) 83386a97f2e4d0cde5e992f52ac287da0de687e0110Jason W Kim// but this is good enough for now. 83486a97f2e4d0cde5e992f52ac287da0de687e0110Jason W Kimstatic bool EvaluateAsPCRel(const MCExpr *Expr) { 83586a97f2e4d0cde5e992f52ac287da0de687e0110Jason W Kim switch (Expr->getKind()) { 8365f8a917b6558f8fdf31b4a6fa591b396e16b9ff2Matt Beaumont-Gay default: assert(0 && "Unexpected expression type"); 83786a97f2e4d0cde5e992f52ac287da0de687e0110Jason W Kim case MCExpr::SymbolRef: return false; 83886a97f2e4d0cde5e992f52ac287da0de687e0110Jason W Kim case MCExpr::Binary: return true; 83986a97f2e4d0cde5e992f52ac287da0de687e0110Jason W Kim } 84086a97f2e4d0cde5e992f52ac287da0de687e0110Jason W Kim} 84186a97f2e4d0cde5e992f52ac287da0de687e0110Jason W Kim 8427597212abced110723f2fee985a7d60557c092ecEvan Chenguint32_t 8437597212abced110723f2fee985a7d60557c092ecEvan ChengARMMCCodeEmitter::getHiLo16ImmOpValue(const MCInst &MI, unsigned OpIdx, 8447597212abced110723f2fee985a7d60557c092ecEvan Cheng SmallVectorImpl<MCFixup> &Fixups) const { 845837caa9313e1f9480721f232f89f5c7b1b9c9d09Jason W Kim // {20-16} = imm{15-12} 846837caa9313e1f9480721f232f89f5c7b1b9c9d09Jason W Kim // {11-0} = imm{11-0} 8477bf4c02789f97e32225fc248dff6622b994a15eeJim Grosbach const MCOperand &MO = MI.getOperand(OpIdx); 8487597212abced110723f2fee985a7d60557c092ecEvan Cheng if (MO.isImm()) 8497597212abced110723f2fee985a7d60557c092ecEvan Cheng // Hi / lo 16 bits already extracted during earlier passes. 850837caa9313e1f9480721f232f89f5c7b1b9c9d09Jason W Kim return static_cast<unsigned>(MO.getImm()); 8517597212abced110723f2fee985a7d60557c092ecEvan Cheng 8527597212abced110723f2fee985a7d60557c092ecEvan Cheng // Handle :upper16: and :lower16: assembly prefixes. 8537597212abced110723f2fee985a7d60557c092ecEvan Cheng const MCExpr *E = MO.getExpr(); 8547597212abced110723f2fee985a7d60557c092ecEvan Cheng if (E->getKind() == MCExpr::Target) { 8557597212abced110723f2fee985a7d60557c092ecEvan Cheng const ARMMCExpr *ARM16Expr = cast<ARMMCExpr>(E); 8567597212abced110723f2fee985a7d60557c092ecEvan Cheng E = ARM16Expr->getSubExpr(); 8577597212abced110723f2fee985a7d60557c092ecEvan Cheng 858837caa9313e1f9480721f232f89f5c7b1b9c9d09Jason W Kim MCFixupKind Kind; 8597597212abced110723f2fee985a7d60557c092ecEvan Cheng switch (ARM16Expr->getKind()) { 8605f8a917b6558f8fdf31b4a6fa591b396e16b9ff2Matt Beaumont-Gay default: assert(0 && "Unsupported ARMFixup"); 8617597212abced110723f2fee985a7d60557c092ecEvan Cheng case ARMMCExpr::VK_ARM_HI16: 86259ee62d2418df8db499eca1ae17f5900dc2dcbbaEvan Cheng if (!isTargetDarwin() && EvaluateAsPCRel(E)) 86359ee62d2418df8db499eca1ae17f5900dc2dcbbaEvan Cheng Kind = MCFixupKind(isThumb2() 864f3eb3bba1614a7935b44fc963a805088d71267f3Evan Cheng ? ARM::fixup_t2_movt_hi16_pcrel 865f3eb3bba1614a7935b44fc963a805088d71267f3Evan Cheng : ARM::fixup_arm_movt_hi16_pcrel); 866f3eb3bba1614a7935b44fc963a805088d71267f3Evan Cheng else 86759ee62d2418df8db499eca1ae17f5900dc2dcbbaEvan Cheng Kind = MCFixupKind(isThumb2() 868f3eb3bba1614a7935b44fc963a805088d71267f3Evan Cheng ? ARM::fixup_t2_movt_hi16 869f3eb3bba1614a7935b44fc963a805088d71267f3Evan Cheng : ARM::fixup_arm_movt_hi16); 870837caa9313e1f9480721f232f89f5c7b1b9c9d09Jason W Kim break; 8717597212abced110723f2fee985a7d60557c092ecEvan Cheng case ARMMCExpr::VK_ARM_LO16: 87259ee62d2418df8db499eca1ae17f5900dc2dcbbaEvan Cheng if (!isTargetDarwin() && EvaluateAsPCRel(E)) 87359ee62d2418df8db499eca1ae17f5900dc2dcbbaEvan Cheng Kind = MCFixupKind(isThumb2() 874f3eb3bba1614a7935b44fc963a805088d71267f3Evan Cheng ? ARM::fixup_t2_movw_lo16_pcrel 875f3eb3bba1614a7935b44fc963a805088d71267f3Evan Cheng : ARM::fixup_arm_movw_lo16_pcrel); 876f3eb3bba1614a7935b44fc963a805088d71267f3Evan Cheng else 87759ee62d2418df8db499eca1ae17f5900dc2dcbbaEvan Cheng Kind = MCFixupKind(isThumb2() 878f3eb3bba1614a7935b44fc963a805088d71267f3Evan Cheng ? ARM::fixup_t2_movw_lo16 879f3eb3bba1614a7935b44fc963a805088d71267f3Evan Cheng : ARM::fixup_arm_movw_lo16); 880837caa9313e1f9480721f232f89f5c7b1b9c9d09Jason W Kim break; 881837caa9313e1f9480721f232f89f5c7b1b9c9d09Jason W Kim } 8827597212abced110723f2fee985a7d60557c092ecEvan Cheng Fixups.push_back(MCFixup::Create(0, E, Kind)); 883837caa9313e1f9480721f232f89f5c7b1b9c9d09Jason W Kim return 0; 884817c1a6dddadb4664738777d224bc7eae6e62cf3Jim Grosbach }; 8857597212abced110723f2fee985a7d60557c092ecEvan Cheng 886817c1a6dddadb4664738777d224bc7eae6e62cf3Jim Grosbach llvm_unreachable("Unsupported MCExpr type in MCOperand!"); 887837caa9313e1f9480721f232f89f5c7b1b9c9d09Jason W Kim return 0; 888837caa9313e1f9480721f232f89f5c7b1b9c9d09Jason W Kim} 889837caa9313e1f9480721f232f89f5c7b1b9c9d09Jason W Kim 890837caa9313e1f9480721f232f89f5c7b1b9c9d09Jason W Kimuint32_t ARMMCCodeEmitter:: 89154fea632b161f98e96ec7275922e35102bcecc5dJim GrosbachgetLdStSORegOpValue(const MCInst &MI, unsigned OpIdx, 89254fea632b161f98e96ec7275922e35102bcecc5dJim Grosbach SmallVectorImpl<MCFixup> &Fixups) const { 89354fea632b161f98e96ec7275922e35102bcecc5dJim Grosbach const MCOperand &MO = MI.getOperand(OpIdx); 89454fea632b161f98e96ec7275922e35102bcecc5dJim Grosbach const MCOperand &MO1 = MI.getOperand(OpIdx+1); 89554fea632b161f98e96ec7275922e35102bcecc5dJim Grosbach const MCOperand &MO2 = MI.getOperand(OpIdx+2); 89654fea632b161f98e96ec7275922e35102bcecc5dJim Grosbach unsigned Rn = getARMRegisterNumbering(MO.getReg()); 89754fea632b161f98e96ec7275922e35102bcecc5dJim Grosbach unsigned Rm = getARMRegisterNumbering(MO1.getReg()); 89854fea632b161f98e96ec7275922e35102bcecc5dJim Grosbach unsigned ShImm = ARM_AM::getAM2Offset(MO2.getImm()); 89954fea632b161f98e96ec7275922e35102bcecc5dJim Grosbach bool isAdd = ARM_AM::getAM2Op(MO2.getImm()) == ARM_AM::add; 90099f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach ARM_AM::ShiftOpc ShOp = ARM_AM::getAM2ShiftOpc(MO2.getImm()); 90199f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach unsigned SBits = getShiftOp(ShOp); 90254fea632b161f98e96ec7275922e35102bcecc5dJim Grosbach 90354fea632b161f98e96ec7275922e35102bcecc5dJim Grosbach // {16-13} = Rn 90454fea632b161f98e96ec7275922e35102bcecc5dJim Grosbach // {12} = isAdd 90554fea632b161f98e96ec7275922e35102bcecc5dJim Grosbach // {11-0} = shifter 90654fea632b161f98e96ec7275922e35102bcecc5dJim Grosbach // {3-0} = Rm 90754fea632b161f98e96ec7275922e35102bcecc5dJim Grosbach // {4} = 0 90854fea632b161f98e96ec7275922e35102bcecc5dJim Grosbach // {6-5} = type 90954fea632b161f98e96ec7275922e35102bcecc5dJim Grosbach // {11-7} = imm 910570a9226913ebe1af04832b8fb3273c70b4ee152Jim Grosbach uint32_t Binary = Rm; 91154fea632b161f98e96ec7275922e35102bcecc5dJim Grosbach Binary |= Rn << 13; 91254fea632b161f98e96ec7275922e35102bcecc5dJim Grosbach Binary |= SBits << 5; 91354fea632b161f98e96ec7275922e35102bcecc5dJim Grosbach Binary |= ShImm << 7; 91454fea632b161f98e96ec7275922e35102bcecc5dJim Grosbach if (isAdd) 91554fea632b161f98e96ec7275922e35102bcecc5dJim Grosbach Binary |= 1 << 12; 91654fea632b161f98e96ec7275922e35102bcecc5dJim Grosbach return Binary; 91754fea632b161f98e96ec7275922e35102bcecc5dJim Grosbach} 91854fea632b161f98e96ec7275922e35102bcecc5dJim Grosbach 919570a9226913ebe1af04832b8fb3273c70b4ee152Jim Grosbachuint32_t ARMMCCodeEmitter:: 92099f53d13efc259b47c93dc0d90a5db763cbe371aJim GrosbachgetAddrMode2OpValue(const MCInst &MI, unsigned OpIdx, 92199f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach SmallVectorImpl<MCFixup> &Fixups) const { 92299f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach // {17-14} Rn 92399f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach // {13} 1 == imm12, 0 == Rm 92499f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach // {12} isAdd 92599f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach // {11-0} imm12/Rm 92699f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach const MCOperand &MO = MI.getOperand(OpIdx); 92799f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach unsigned Rn = getARMRegisterNumbering(MO.getReg()); 92899f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach uint32_t Binary = getAddrMode2OffsetOpValue(MI, OpIdx + 1, Fixups); 92999f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach Binary |= Rn << 14; 93099f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach return Binary; 93199f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach} 93299f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach 93399f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbachuint32_t ARMMCCodeEmitter:: 93499f53d13efc259b47c93dc0d90a5db763cbe371aJim GrosbachgetAddrMode2OffsetOpValue(const MCInst &MI, unsigned OpIdx, 93599f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach SmallVectorImpl<MCFixup> &Fixups) const { 93699f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach // {13} 1 == imm12, 0 == Rm 93799f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach // {12} isAdd 93899f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach // {11-0} imm12/Rm 93999f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach const MCOperand &MO = MI.getOperand(OpIdx); 94099f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach const MCOperand &MO1 = MI.getOperand(OpIdx+1); 94199f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach unsigned Imm = MO1.getImm(); 94299f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach bool isAdd = ARM_AM::getAM2Op(Imm) == ARM_AM::add; 94399f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach bool isReg = MO.getReg() != 0; 94499f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach uint32_t Binary = ARM_AM::getAM2Offset(Imm); 94599f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach // if reg +/- reg, Rm will be non-zero. Otherwise, we have reg +/- imm12 94699f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach if (isReg) { 94799f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach ARM_AM::ShiftOpc ShOp = ARM_AM::getAM2ShiftOpc(Imm); 94899f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach Binary <<= 7; // Shift amount is bits [11:7] 94999f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach Binary |= getShiftOp(ShOp) << 5; // Shift type is bits [6:5] 95099f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach Binary |= getARMRegisterNumbering(MO.getReg()); // Rm is bits [3:0] 95199f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach } 95299f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach return Binary | (isAdd << 12) | (isReg << 13); 95399f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach} 95499f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach 95599f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbachuint32_t ARMMCCodeEmitter:: 9567ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim GrosbachgetPostIdxRegOpValue(const MCInst &MI, unsigned OpIdx, 9577ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach SmallVectorImpl<MCFixup> &Fixups) const { 9587ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // {4} isAdd 9597ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // {3-0} Rm 9607ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach const MCOperand &MO = MI.getOperand(OpIdx); 9617ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach const MCOperand &MO1 = MI.getOperand(OpIdx+1); 96216578b50889329eb62774148091ba0f38b681a09Jim Grosbach bool isAdd = MO1.getImm() != 0; 9637ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return getARMRegisterNumbering(MO.getReg()) | (isAdd << 4); 9647ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach} 9657ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach 9667ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbachuint32_t ARMMCCodeEmitter:: 9677eab97f260ba0f56d1d4a82f3a4eb2c979452011Jim GrosbachgetAddrMode3OffsetOpValue(const MCInst &MI, unsigned OpIdx, 9687eab97f260ba0f56d1d4a82f3a4eb2c979452011Jim Grosbach SmallVectorImpl<MCFixup> &Fixups) const { 9697eab97f260ba0f56d1d4a82f3a4eb2c979452011Jim Grosbach // {9} 1 == imm8, 0 == Rm 9707eab97f260ba0f56d1d4a82f3a4eb2c979452011Jim Grosbach // {8} isAdd 9717eab97f260ba0f56d1d4a82f3a4eb2c979452011Jim Grosbach // {7-4} imm7_4/zero 9727eab97f260ba0f56d1d4a82f3a4eb2c979452011Jim Grosbach // {3-0} imm3_0/Rm 9737eab97f260ba0f56d1d4a82f3a4eb2c979452011Jim Grosbach const MCOperand &MO = MI.getOperand(OpIdx); 9747eab97f260ba0f56d1d4a82f3a4eb2c979452011Jim Grosbach const MCOperand &MO1 = MI.getOperand(OpIdx+1); 9757eab97f260ba0f56d1d4a82f3a4eb2c979452011Jim Grosbach unsigned Imm = MO1.getImm(); 9767eab97f260ba0f56d1d4a82f3a4eb2c979452011Jim Grosbach bool isAdd = ARM_AM::getAM3Op(Imm) == ARM_AM::add; 9777eab97f260ba0f56d1d4a82f3a4eb2c979452011Jim Grosbach bool isImm = MO.getReg() == 0; 9787eab97f260ba0f56d1d4a82f3a4eb2c979452011Jim Grosbach uint32_t Imm8 = ARM_AM::getAM3Offset(Imm); 9797eab97f260ba0f56d1d4a82f3a4eb2c979452011Jim Grosbach // if reg +/- reg, Rm will be non-zero. Otherwise, we have reg +/- imm8 9807eab97f260ba0f56d1d4a82f3a4eb2c979452011Jim Grosbach if (!isImm) 9817eab97f260ba0f56d1d4a82f3a4eb2c979452011Jim Grosbach Imm8 = getARMRegisterNumbering(MO.getReg()); 9827eab97f260ba0f56d1d4a82f3a4eb2c979452011Jim Grosbach return Imm8 | (isAdd << 8) | (isImm << 9); 9837eab97f260ba0f56d1d4a82f3a4eb2c979452011Jim Grosbach} 9847eab97f260ba0f56d1d4a82f3a4eb2c979452011Jim Grosbach 9857eab97f260ba0f56d1d4a82f3a4eb2c979452011Jim Grosbachuint32_t ARMMCCodeEmitter:: 986570a9226913ebe1af04832b8fb3273c70b4ee152Jim GrosbachgetAddrMode3OpValue(const MCInst &MI, unsigned OpIdx, 987570a9226913ebe1af04832b8fb3273c70b4ee152Jim Grosbach SmallVectorImpl<MCFixup> &Fixups) const { 988570a9226913ebe1af04832b8fb3273c70b4ee152Jim Grosbach // {13} 1 == imm8, 0 == Rm 989570a9226913ebe1af04832b8fb3273c70b4ee152Jim Grosbach // {12-9} Rn 990570a9226913ebe1af04832b8fb3273c70b4ee152Jim Grosbach // {8} isAdd 991570a9226913ebe1af04832b8fb3273c70b4ee152Jim Grosbach // {7-4} imm7_4/zero 992570a9226913ebe1af04832b8fb3273c70b4ee152Jim Grosbach // {3-0} imm3_0/Rm 993570a9226913ebe1af04832b8fb3273c70b4ee152Jim Grosbach const MCOperand &MO = MI.getOperand(OpIdx); 994570a9226913ebe1af04832b8fb3273c70b4ee152Jim Grosbach const MCOperand &MO1 = MI.getOperand(OpIdx+1); 995570a9226913ebe1af04832b8fb3273c70b4ee152Jim Grosbach const MCOperand &MO2 = MI.getOperand(OpIdx+2); 9962f196747f15240691bd4e622f7995edfedf90f61Jim Grosbach 9972f196747f15240691bd4e622f7995edfedf90f61Jim Grosbach // If The first operand isn't a register, we have a label reference. 9982f196747f15240691bd4e622f7995edfedf90f61Jim Grosbach if (!MO.isReg()) { 9992f196747f15240691bd4e622f7995edfedf90f61Jim Grosbach unsigned Rn = getARMRegisterNumbering(ARM::PC); // Rn is PC. 10002f196747f15240691bd4e622f7995edfedf90f61Jim Grosbach 10012f196747f15240691bd4e622f7995edfedf90f61Jim Grosbach assert(MO.isExpr() && "Unexpected machine operand type!"); 10022f196747f15240691bd4e622f7995edfedf90f61Jim Grosbach const MCExpr *Expr = MO.getExpr(); 10032f196747f15240691bd4e622f7995edfedf90f61Jim Grosbach MCFixupKind Kind = MCFixupKind(ARM::fixup_arm_pcrel_10_unscaled); 10042f196747f15240691bd4e622f7995edfedf90f61Jim Grosbach Fixups.push_back(MCFixup::Create(0, Expr, Kind)); 10052f196747f15240691bd4e622f7995edfedf90f61Jim Grosbach 10062f196747f15240691bd4e622f7995edfedf90f61Jim Grosbach ++MCNumCPRelocations; 10072f196747f15240691bd4e622f7995edfedf90f61Jim Grosbach return (Rn << 9) | (1 << 13); 10082f196747f15240691bd4e622f7995edfedf90f61Jim Grosbach } 1009570a9226913ebe1af04832b8fb3273c70b4ee152Jim Grosbach unsigned Rn = getARMRegisterNumbering(MO.getReg()); 1010570a9226913ebe1af04832b8fb3273c70b4ee152Jim Grosbach unsigned Imm = MO2.getImm(); 1011570a9226913ebe1af04832b8fb3273c70b4ee152Jim Grosbach bool isAdd = ARM_AM::getAM3Op(Imm) == ARM_AM::add; 1012570a9226913ebe1af04832b8fb3273c70b4ee152Jim Grosbach bool isImm = MO1.getReg() == 0; 1013570a9226913ebe1af04832b8fb3273c70b4ee152Jim Grosbach uint32_t Imm8 = ARM_AM::getAM3Offset(Imm); 1014570a9226913ebe1af04832b8fb3273c70b4ee152Jim Grosbach // if reg +/- reg, Rm will be non-zero. Otherwise, we have reg +/- imm8 1015570a9226913ebe1af04832b8fb3273c70b4ee152Jim Grosbach if (!isImm) 1016570a9226913ebe1af04832b8fb3273c70b4ee152Jim Grosbach Imm8 = getARMRegisterNumbering(MO1.getReg()); 1017570a9226913ebe1af04832b8fb3273c70b4ee152Jim Grosbach return (Rn << 9) | Imm8 | (isAdd << 8) | (isImm << 13); 1018570a9226913ebe1af04832b8fb3273c70b4ee152Jim Grosbach} 1019570a9226913ebe1af04832b8fb3273c70b4ee152Jim Grosbach 1020b8958b031ec5163261f490f131780c5dc3d823d6Bill Wendling/// getAddrModeThumbSPOpValue - Encode the t_addrmode_sp operands. 1021d967cd096ae87accf2f1df86b2dfac969d9c9da2Jim Grosbachuint32_t ARMMCCodeEmitter:: 1022d967cd096ae87accf2f1df86b2dfac969d9c9da2Jim GrosbachgetAddrModeThumbSPOpValue(const MCInst &MI, unsigned OpIdx, 1023d967cd096ae87accf2f1df86b2dfac969d9c9da2Jim Grosbach SmallVectorImpl<MCFixup> &Fixups) const { 1024d967cd096ae87accf2f1df86b2dfac969d9c9da2Jim Grosbach // [SP, #imm] 1025d967cd096ae87accf2f1df86b2dfac969d9c9da2Jim Grosbach // {7-0} = imm8 1026d967cd096ae87accf2f1df86b2dfac969d9c9da2Jim Grosbach const MCOperand &MO1 = MI.getOperand(OpIdx + 1); 1027b8958b031ec5163261f490f131780c5dc3d823d6Bill Wendling assert(MI.getOperand(OpIdx).getReg() == ARM::SP && 1028b8958b031ec5163261f490f131780c5dc3d823d6Bill Wendling "Unexpected base register!"); 10297a905a82f7425d1a10b828c8bb3365b2ebc15833Bill Wendling 1030d967cd096ae87accf2f1df86b2dfac969d9c9da2Jim Grosbach // The immediate is already shifted for the implicit zeroes, so no change 1031d967cd096ae87accf2f1df86b2dfac969d9c9da2Jim Grosbach // here. 1032d967cd096ae87accf2f1df86b2dfac969d9c9da2Jim Grosbach return MO1.getImm() & 0xff; 1033d967cd096ae87accf2f1df86b2dfac969d9c9da2Jim Grosbach} 1034d967cd096ae87accf2f1df86b2dfac969d9c9da2Jim Grosbach 1035f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling/// getAddrModeISOpValue - Encode the t_addrmode_is# operands. 1036272df516d7a9b1f0f69174276abaa759816ee456Bill Wendlinguint32_t ARMMCCodeEmitter:: 1037f4caf69720d807573c50d41aa06bcec1c99bdbbdBill WendlinggetAddrModeISOpValue(const MCInst &MI, unsigned OpIdx, 103822447ae54bcb8ca94ed994cad103074a24e66781Bill Wendling SmallVectorImpl<MCFixup> &Fixups) const { 1039ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling // [Rn, #imm] 1040ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling // {7-3} = imm5 1041ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling // {2-0} = Rn 1042ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling const MCOperand &MO = MI.getOperand(OpIdx); 1043ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling const MCOperand &MO1 = MI.getOperand(OpIdx + 1); 1044ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling unsigned Rn = getARMRegisterNumbering(MO.getReg()); 1045656b3d22f70c2d1c8a5286f7270cb380df862565Matt Beaumont-Gay unsigned Imm5 = MO1.getImm(); 1046272df516d7a9b1f0f69174276abaa759816ee456Bill Wendling return ((Imm5 & 0x1f) << 3) | Rn; 10471fd374e9c1c074c1681336bef31e65f0170b0f7eBill Wendling} 10481fd374e9c1c074c1681336bef31e65f0170b0f7eBill Wendling 1049b8958b031ec5163261f490f131780c5dc3d823d6Bill Wendling/// getAddrModePCOpValue - Return encoding for t_addrmode_pc operands. 1050b8958b031ec5163261f490f131780c5dc3d823d6Bill Wendlinguint32_t ARMMCCodeEmitter:: 1051b8958b031ec5163261f490f131780c5dc3d823d6Bill WendlinggetAddrModePCOpValue(const MCInst &MI, unsigned OpIdx, 1052b8958b031ec5163261f490f131780c5dc3d823d6Bill Wendling SmallVectorImpl<MCFixup> &Fixups) const { 1053a7710edd98d71a81c43f8e3889cf0c790885d1b8Owen Anderson const MCOperand MO = MI.getOperand(OpIdx); 1054a7710edd98d71a81c43f8e3889cf0c790885d1b8Owen Anderson if (MO.isExpr()) 1055a7710edd98d71a81c43f8e3889cf0c790885d1b8Owen Anderson return ::getBranchTargetOpValue(MI, OpIdx, ARM::fixup_arm_thumb_cp, Fixups); 1056a7710edd98d71a81c43f8e3889cf0c790885d1b8Owen Anderson return (MO.getImm() >> 2); 1057b8958b031ec5163261f490f131780c5dc3d823d6Bill Wendling} 1058b8958b031ec5163261f490f131780c5dc3d823d6Bill Wendling 10595177f79c378b47e38bed5ac05ba4b597f31b864eJim Grosbach/// getAddrMode5OpValue - Return encoding info for 'reg +/- imm10' operand. 1060806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbachuint32_t ARMMCCodeEmitter:: 1061806e80ef42bdb416f409142a1ff1d4e8752baac8Jim GrosbachgetAddrMode5OpValue(const MCInst &MI, unsigned OpIdx, 1062806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbach SmallVectorImpl<MCFixup> &Fixups) const { 106392b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling // {12-9} = reg 106492b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling // {8} = (U)nsigned (add == '1', sub == '0') 106592b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling // {7-0} = imm8 106692b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling unsigned Reg, Imm8; 106797dd28fb89dc4c4caa3c60890335dc99489981a6Jim Grosbach bool isAdd; 106870933266ae73c891d9d1c2f0de72ecd1db8f86dfJim Grosbach // If The first operand isn't a register, we have a label reference. 106970933266ae73c891d9d1c2f0de72ecd1db8f86dfJim Grosbach const MCOperand &MO = MI.getOperand(OpIdx); 107070933266ae73c891d9d1c2f0de72ecd1db8f86dfJim Grosbach if (!MO.isReg()) { 1071679cbd3b215b1769a6035e334f9009aeeb940dddJim Grosbach Reg = getARMRegisterNumbering(ARM::PC); // Rn is PC. 107270933266ae73c891d9d1c2f0de72ecd1db8f86dfJim Grosbach Imm8 = 0; 107397dd28fb89dc4c4caa3c60890335dc99489981a6Jim Grosbach isAdd = false; // 'U' bit is handled as part of the fixup. 107470933266ae73c891d9d1c2f0de72ecd1db8f86dfJim Grosbach 107570933266ae73c891d9d1c2f0de72ecd1db8f86dfJim Grosbach assert(MO.isExpr() && "Unexpected machine operand type!"); 107670933266ae73c891d9d1c2f0de72ecd1db8f86dfJim Grosbach const MCExpr *Expr = MO.getExpr(); 1077d8e351b96f5fd7007fbdd636acaa1fc9f6e18f3cOwen Anderson MCFixupKind Kind; 107859ee62d2418df8db499eca1ae17f5900dc2dcbbaEvan Cheng if (isThumb2()) 1079d8e351b96f5fd7007fbdd636acaa1fc9f6e18f3cOwen Anderson Kind = MCFixupKind(ARM::fixup_t2_pcrel_10); 1080d8e351b96f5fd7007fbdd636acaa1fc9f6e18f3cOwen Anderson else 1081d8e351b96f5fd7007fbdd636acaa1fc9f6e18f3cOwen Anderson Kind = MCFixupKind(ARM::fixup_arm_pcrel_10); 108270933266ae73c891d9d1c2f0de72ecd1db8f86dfJim Grosbach Fixups.push_back(MCFixup::Create(0, Expr, Kind)); 108370933266ae73c891d9d1c2f0de72ecd1db8f86dfJim Grosbach 108470933266ae73c891d9d1c2f0de72ecd1db8f86dfJim Grosbach ++MCNumCPRelocations; 108597dd28fb89dc4c4caa3c60890335dc99489981a6Jim Grosbach } else { 108670933266ae73c891d9d1c2f0de72ecd1db8f86dfJim Grosbach EncodeAddrModeOpValues(MI, OpIdx, Reg, Imm8, Fixups); 108797dd28fb89dc4c4caa3c60890335dc99489981a6Jim Grosbach isAdd = ARM_AM::getAM5Op(Imm8) == ARM_AM::add; 108897dd28fb89dc4c4caa3c60890335dc99489981a6Jim Grosbach } 108992b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling 109092b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling uint32_t Binary = ARM_AM::getAM5Offset(Imm8); 109192b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling // Immediate is always encoded as positive. The 'U' bit controls add vs sub. 109297dd28fb89dc4c4caa3c60890335dc99489981a6Jim Grosbach if (isAdd) 109392b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling Binary |= (1 << 8); 109492b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling Binary |= (Reg << 9); 10953e5561247202bae994dd259a2d8dc4eff8f799f3Jim Grosbach return Binary; 10963e5561247202bae994dd259a2d8dc4eff8f799f3Jim Grosbach} 10973e5561247202bae994dd259a2d8dc4eff8f799f3Jim Grosbach 1098806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbachunsigned ARMMCCodeEmitter:: 1099152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen AndersongetSORegRegOpValue(const MCInst &MI, unsigned OpIdx, 1100806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbach SmallVectorImpl<MCFixup> &Fixups) const { 11010800ce71896ccd7f49b37861a8cfbc21b6b10022Bill Wendling // Sub-operands are [reg, reg, imm]. The first register is Rm, the reg to be 1102354712c5a506449676e6fcac6b623af4092e7100Owen Anderson // shifted. The second is Rs, the amount to shift by, and the third specifies 1103354712c5a506449676e6fcac6b623af4092e7100Owen Anderson // the type of the shift. 110435b2de012d9404e3e9e4373e45f41711f752dd3aJim Grosbach // 1105ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach // {3-0} = Rm. 1106354712c5a506449676e6fcac6b623af4092e7100Owen Anderson // {4} = 1 1107ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach // {6-5} = type 1108354712c5a506449676e6fcac6b623af4092e7100Owen Anderson // {11-8} = Rs 1109354712c5a506449676e6fcac6b623af4092e7100Owen Anderson // {7} = 0 1110ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach 1111ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach const MCOperand &MO = MI.getOperand(OpIdx); 1112ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach const MCOperand &MO1 = MI.getOperand(OpIdx + 1); 1113ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach const MCOperand &MO2 = MI.getOperand(OpIdx + 2); 1114ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach ARM_AM::ShiftOpc SOpc = ARM_AM::getSORegShOp(MO2.getImm()); 1115ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach 1116ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach // Encode Rm. 1117ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach unsigned Binary = getARMRegisterNumbering(MO.getReg()); 1118ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach 1119ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach // Encode the shift opcode. 1120ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach unsigned SBits = 0; 1121ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach unsigned Rs = MO1.getReg(); 1122ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach if (Rs) { 1123ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach // Set shift operand (bit[7:4]). 1124ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach // LSL - 0001 1125ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach // LSR - 0011 1126ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach // ASR - 0101 1127ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach // ROR - 0111 1128ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach switch (SOpc) { 1129ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach default: llvm_unreachable("Unknown shift opc!"); 1130ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach case ARM_AM::lsl: SBits = 0x1; break; 1131ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach case ARM_AM::lsr: SBits = 0x3; break; 1132ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach case ARM_AM::asr: SBits = 0x5; break; 1133ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach case ARM_AM::ror: SBits = 0x7; break; 1134ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach } 1135ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach } 11360800ce71896ccd7f49b37861a8cfbc21b6b10022Bill Wendling 1137ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach Binary |= SBits << 4; 1138ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach 1139354712c5a506449676e6fcac6b623af4092e7100Owen Anderson // Encode the shift operation Rs. 1140152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson // Encode Rs bit[11:8]. 1141152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson assert(ARM_AM::getSORegOffset(MO2.getImm()) == 0); 1142152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson return Binary | (getARMRegisterNumbering(Rs) << ARMII::RegRsShift); 1143152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson} 1144152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson 1145152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Andersonunsigned ARMMCCodeEmitter:: 1146152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen AndersongetSORegImmOpValue(const MCInst &MI, unsigned OpIdx, 1147152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson SmallVectorImpl<MCFixup> &Fixups) const { 1148354712c5a506449676e6fcac6b623af4092e7100Owen Anderson // Sub-operands are [reg, imm]. The first register is Rm, the reg to be 1149354712c5a506449676e6fcac6b623af4092e7100Owen Anderson // shifted. The second is the amount to shift by. 1150152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson // 1151152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson // {3-0} = Rm. 1152354712c5a506449676e6fcac6b623af4092e7100Owen Anderson // {4} = 0 1153152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson // {6-5} = type 1154354712c5a506449676e6fcac6b623af4092e7100Owen Anderson // {11-7} = imm 1155152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson 1156152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson const MCOperand &MO = MI.getOperand(OpIdx); 1157152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson const MCOperand &MO1 = MI.getOperand(OpIdx + 1); 1158152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson ARM_AM::ShiftOpc SOpc = ARM_AM::getSORegShOp(MO1.getImm()); 1159152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson 1160152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson // Encode Rm. 1161152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson unsigned Binary = getARMRegisterNumbering(MO.getReg()); 1162152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson 1163152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson // Encode the shift opcode. 1164152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson unsigned SBits = 0; 1165152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson 1166152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson // Set shift operand (bit[6:4]). 1167152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson // LSL - 000 1168152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson // LSR - 010 1169152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson // ASR - 100 1170152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson // ROR - 110 1171152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson // RRX - 110 and bit[11:8] clear. 1172152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson switch (SOpc) { 1173152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson default: llvm_unreachable("Unknown shift opc!"); 1174152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson case ARM_AM::lsl: SBits = 0x0; break; 1175152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson case ARM_AM::lsr: SBits = 0x2; break; 1176152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson case ARM_AM::asr: SBits = 0x4; break; 1177152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson case ARM_AM::ror: SBits = 0x6; break; 1178152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson case ARM_AM::rrx: 1179152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson Binary |= 0x60; 1180152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson return Binary; 1181ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach } 1182ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach 1183ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach // Encode shift_imm bit[11:7]. 1184152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson Binary |= SBits << 4; 11853dac0bec7e7874ffb378385b6160bd2117184ca9Owen Anderson unsigned Offset = ARM_AM::getSORegOffset(MO1.getImm()); 11863dac0bec7e7874ffb378385b6160bd2117184ca9Owen Anderson assert(Offset && "Offset must be in range 1-32!"); 11873dac0bec7e7874ffb378385b6160bd2117184ca9Owen Anderson if (Offset == 32) Offset = 0; 11883dac0bec7e7874ffb378385b6160bd2117184ca9Owen Anderson return Binary | (Offset << 7); 1189ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach} 1190ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach 1191152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson 1192806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbachunsigned ARMMCCodeEmitter:: 119375579f739fbc99a92a15f3ce75bbd7628ba00f8cOwen AndersongetT2AddrModeSORegOpValue(const MCInst &MI, unsigned OpNum, 119475579f739fbc99a92a15f3ce75bbd7628ba00f8cOwen Anderson SmallVectorImpl<MCFixup> &Fixups) const { 119575579f739fbc99a92a15f3ce75bbd7628ba00f8cOwen Anderson const MCOperand &MO1 = MI.getOperand(OpNum); 119675579f739fbc99a92a15f3ce75bbd7628ba00f8cOwen Anderson const MCOperand &MO2 = MI.getOperand(OpNum+1); 11977bf4c02789f97e32225fc248dff6622b994a15eeJim Grosbach const MCOperand &MO3 = MI.getOperand(OpNum+2); 11987bf4c02789f97e32225fc248dff6622b994a15eeJim Grosbach 119975579f739fbc99a92a15f3ce75bbd7628ba00f8cOwen Anderson // Encoded as [Rn, Rm, imm]. 120075579f739fbc99a92a15f3ce75bbd7628ba00f8cOwen Anderson // FIXME: Needs fixup support. 120175579f739fbc99a92a15f3ce75bbd7628ba00f8cOwen Anderson unsigned Value = getARMRegisterNumbering(MO1.getReg()); 120275579f739fbc99a92a15f3ce75bbd7628ba00f8cOwen Anderson Value <<= 4; 120375579f739fbc99a92a15f3ce75bbd7628ba00f8cOwen Anderson Value |= getARMRegisterNumbering(MO2.getReg()); 120475579f739fbc99a92a15f3ce75bbd7628ba00f8cOwen Anderson Value <<= 2; 120575579f739fbc99a92a15f3ce75bbd7628ba00f8cOwen Anderson Value |= MO3.getImm(); 12067bf4c02789f97e32225fc248dff6622b994a15eeJim Grosbach 120775579f739fbc99a92a15f3ce75bbd7628ba00f8cOwen Anderson return Value; 120875579f739fbc99a92a15f3ce75bbd7628ba00f8cOwen Anderson} 120975579f739fbc99a92a15f3ce75bbd7628ba00f8cOwen Anderson 121075579f739fbc99a92a15f3ce75bbd7628ba00f8cOwen Andersonunsigned ARMMCCodeEmitter:: 121175579f739fbc99a92a15f3ce75bbd7628ba00f8cOwen AndersongetT2AddrModeImm8OpValue(const MCInst &MI, unsigned OpNum, 121275579f739fbc99a92a15f3ce75bbd7628ba00f8cOwen Anderson SmallVectorImpl<MCFixup> &Fixups) const { 121375579f739fbc99a92a15f3ce75bbd7628ba00f8cOwen Anderson const MCOperand &MO1 = MI.getOperand(OpNum); 121475579f739fbc99a92a15f3ce75bbd7628ba00f8cOwen Anderson const MCOperand &MO2 = MI.getOperand(OpNum+1); 121575579f739fbc99a92a15f3ce75bbd7628ba00f8cOwen Anderson 121675579f739fbc99a92a15f3ce75bbd7628ba00f8cOwen Anderson // FIXME: Needs fixup support. 121775579f739fbc99a92a15f3ce75bbd7628ba00f8cOwen Anderson unsigned Value = getARMRegisterNumbering(MO1.getReg()); 12187bf4c02789f97e32225fc248dff6622b994a15eeJim Grosbach 121975579f739fbc99a92a15f3ce75bbd7628ba00f8cOwen Anderson // Even though the immediate is 8 bits long, we need 9 bits in order 122075579f739fbc99a92a15f3ce75bbd7628ba00f8cOwen Anderson // to represent the (inverse of the) sign bit. 122175579f739fbc99a92a15f3ce75bbd7628ba00f8cOwen Anderson Value <<= 9; 12226af50f7dd12d82f0a80f3158102180eee4c921aaOwen Anderson int32_t tmp = (int32_t)MO2.getImm(); 12236af50f7dd12d82f0a80f3158102180eee4c921aaOwen Anderson if (tmp < 0) 12246af50f7dd12d82f0a80f3158102180eee4c921aaOwen Anderson tmp = abs(tmp); 12256af50f7dd12d82f0a80f3158102180eee4c921aaOwen Anderson else 12266af50f7dd12d82f0a80f3158102180eee4c921aaOwen Anderson Value |= 256; // Set the ADD bit 12276af50f7dd12d82f0a80f3158102180eee4c921aaOwen Anderson Value |= tmp & 255; 12286af50f7dd12d82f0a80f3158102180eee4c921aaOwen Anderson return Value; 12296af50f7dd12d82f0a80f3158102180eee4c921aaOwen Anderson} 12306af50f7dd12d82f0a80f3158102180eee4c921aaOwen Anderson 12316af50f7dd12d82f0a80f3158102180eee4c921aaOwen Andersonunsigned ARMMCCodeEmitter:: 12326af50f7dd12d82f0a80f3158102180eee4c921aaOwen AndersongetT2AddrModeImm8OffsetOpValue(const MCInst &MI, unsigned OpNum, 12336af50f7dd12d82f0a80f3158102180eee4c921aaOwen Anderson SmallVectorImpl<MCFixup> &Fixups) const { 12346af50f7dd12d82f0a80f3158102180eee4c921aaOwen Anderson const MCOperand &MO1 = MI.getOperand(OpNum); 12356af50f7dd12d82f0a80f3158102180eee4c921aaOwen Anderson 12366af50f7dd12d82f0a80f3158102180eee4c921aaOwen Anderson // FIXME: Needs fixup support. 12376af50f7dd12d82f0a80f3158102180eee4c921aaOwen Anderson unsigned Value = 0; 12386af50f7dd12d82f0a80f3158102180eee4c921aaOwen Anderson int32_t tmp = (int32_t)MO1.getImm(); 12396af50f7dd12d82f0a80f3158102180eee4c921aaOwen Anderson if (tmp < 0) 12406af50f7dd12d82f0a80f3158102180eee4c921aaOwen Anderson tmp = abs(tmp); 12416af50f7dd12d82f0a80f3158102180eee4c921aaOwen Anderson else 12426af50f7dd12d82f0a80f3158102180eee4c921aaOwen Anderson Value |= 256; // Set the ADD bit 12436af50f7dd12d82f0a80f3158102180eee4c921aaOwen Anderson Value |= tmp & 255; 124475579f739fbc99a92a15f3ce75bbd7628ba00f8cOwen Anderson return Value; 124575579f739fbc99a92a15f3ce75bbd7628ba00f8cOwen Anderson} 124675579f739fbc99a92a15f3ce75bbd7628ba00f8cOwen Anderson 124775579f739fbc99a92a15f3ce75bbd7628ba00f8cOwen Andersonunsigned ARMMCCodeEmitter:: 12480e1bcdf4f7547bb5f47ed5ff5f2409a8f72f3609Owen AndersongetT2AddrModeImm12OffsetOpValue(const MCInst &MI, unsigned OpNum, 12490e1bcdf4f7547bb5f47ed5ff5f2409a8f72f3609Owen Anderson SmallVectorImpl<MCFixup> &Fixups) const { 12500e1bcdf4f7547bb5f47ed5ff5f2409a8f72f3609Owen Anderson const MCOperand &MO1 = MI.getOperand(OpNum); 12510e1bcdf4f7547bb5f47ed5ff5f2409a8f72f3609Owen Anderson 12520e1bcdf4f7547bb5f47ed5ff5f2409a8f72f3609Owen Anderson // FIXME: Needs fixup support. 12530e1bcdf4f7547bb5f47ed5ff5f2409a8f72f3609Owen Anderson unsigned Value = 0; 12540e1bcdf4f7547bb5f47ed5ff5f2409a8f72f3609Owen Anderson int32_t tmp = (int32_t)MO1.getImm(); 12550e1bcdf4f7547bb5f47ed5ff5f2409a8f72f3609Owen Anderson if (tmp < 0) 12560e1bcdf4f7547bb5f47ed5ff5f2409a8f72f3609Owen Anderson tmp = abs(tmp); 12570e1bcdf4f7547bb5f47ed5ff5f2409a8f72f3609Owen Anderson else 12580e1bcdf4f7547bb5f47ed5ff5f2409a8f72f3609Owen Anderson Value |= 4096; // Set the ADD bit 12590e1bcdf4f7547bb5f47ed5ff5f2409a8f72f3609Owen Anderson Value |= tmp & 4095; 12600e1bcdf4f7547bb5f47ed5ff5f2409a8f72f3609Owen Anderson return Value; 12610e1bcdf4f7547bb5f47ed5ff5f2409a8f72f3609Owen Anderson} 12620e1bcdf4f7547bb5f47ed5ff5f2409a8f72f3609Owen Anderson 12630e1bcdf4f7547bb5f47ed5ff5f2409a8f72f3609Owen Andersonunsigned ARMMCCodeEmitter:: 12645de6d841a5116152793dcab35a2e534a6a9aaa7aOwen AndersongetT2SORegOpValue(const MCInst &MI, unsigned OpIdx, 12655de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson SmallVectorImpl<MCFixup> &Fixups) const { 12665de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson // Sub-operands are [reg, imm]. The first register is Rm, the reg to be 12675de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson // shifted. The second is the amount to shift by. 12685de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson // 12695de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson // {3-0} = Rm. 12705de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson // {4} = 0 12715de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson // {6-5} = type 12725de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson // {11-7} = imm 12735de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson 12745de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson const MCOperand &MO = MI.getOperand(OpIdx); 12755de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson const MCOperand &MO1 = MI.getOperand(OpIdx + 1); 12765de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson ARM_AM::ShiftOpc SOpc = ARM_AM::getSORegShOp(MO1.getImm()); 12775de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson 12785de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson // Encode Rm. 12795de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson unsigned Binary = getARMRegisterNumbering(MO.getReg()); 12805de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson 12815de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson // Encode the shift opcode. 12825de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson unsigned SBits = 0; 12835de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson // Set shift operand (bit[6:4]). 12845de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson // LSL - 000 12855de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson // LSR - 010 12865de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson // ASR - 100 12875de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson // ROR - 110 12885de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson switch (SOpc) { 12895de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson default: llvm_unreachable("Unknown shift opc!"); 12905de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson case ARM_AM::lsl: SBits = 0x0; break; 12915de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson case ARM_AM::lsr: SBits = 0x2; break; 12925de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson case ARM_AM::asr: SBits = 0x4; break; 129312c7e90d369b4605aac0ddbd252231beacb2aabbOwen Anderson case ARM_AM::rrx: // FALLTHROUGH 12945de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson case ARM_AM::ror: SBits = 0x6; break; 12955de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson } 12965de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson 12975de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson Binary |= SBits << 4; 12985de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson if (SOpc == ARM_AM::rrx) 12995de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson return Binary; 13005de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson 13015de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson // Encode shift_imm bit[11:7]. 13025de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson return Binary | ARM_AM::getSORegOffset(MO1.getImm()) << 7; 13035de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson} 13045de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson 13055de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Andersonunsigned ARMMCCodeEmitter:: 1306806e80ef42bdb416f409142a1ff1d4e8752baac8Jim GrosbachgetBitfieldInvertedMaskOpValue(const MCInst &MI, unsigned Op, 1307806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbach SmallVectorImpl<MCFixup> &Fixups) const { 13083fea19105d4929ad694f0b6272de31924c9f9f09Jim Grosbach // 10 bits. lower 5 bits are are the lsb of the mask, high five bits are the 13093fea19105d4929ad694f0b6272de31924c9f9f09Jim Grosbach // msb of the mask. 13103fea19105d4929ad694f0b6272de31924c9f9f09Jim Grosbach const MCOperand &MO = MI.getOperand(Op); 13113fea19105d4929ad694f0b6272de31924c9f9f09Jim Grosbach uint32_t v = ~MO.getImm(); 13123fea19105d4929ad694f0b6272de31924c9f9f09Jim Grosbach uint32_t lsb = CountTrailingZeros_32(v); 13133fea19105d4929ad694f0b6272de31924c9f9f09Jim Grosbach uint32_t msb = (32 - CountLeadingZeros_32 (v)) - 1; 13143fea19105d4929ad694f0b6272de31924c9f9f09Jim Grosbach assert (v != 0 && lsb < 32 && msb < 32 && "Illegal bitfield mask!"); 13153fea19105d4929ad694f0b6272de31924c9f9f09Jim Grosbach return lsb | (msb << 5); 13163fea19105d4929ad694f0b6272de31924c9f9f09Jim Grosbach} 13173fea19105d4929ad694f0b6272de31924c9f9f09Jim Grosbach 1318806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbachunsigned ARMMCCodeEmitter:: 1319806e80ef42bdb416f409142a1ff1d4e8752baac8Jim GrosbachgetRegisterListOpValue(const MCInst &MI, unsigned Op, 13205e559a22c18166508a01fbd65471ec4e752726f9Bill Wendling SmallVectorImpl<MCFixup> &Fixups) const { 13216bc105a7b9282a0b5beb9d06267b31a3054fb3faBill Wendling // VLDM/VSTM: 13226bc105a7b9282a0b5beb9d06267b31a3054fb3faBill Wendling // {12-8} = Vd 13236bc105a7b9282a0b5beb9d06267b31a3054fb3faBill Wendling // {7-0} = Number of registers 13246bc105a7b9282a0b5beb9d06267b31a3054fb3faBill Wendling // 13256bc105a7b9282a0b5beb9d06267b31a3054fb3faBill Wendling // LDM/STM: 13266bc105a7b9282a0b5beb9d06267b31a3054fb3faBill Wendling // {15-0} = Bitfield of GPRs. 13276bc105a7b9282a0b5beb9d06267b31a3054fb3faBill Wendling unsigned Reg = MI.getOperand(Op).getReg(); 1328be74029f44c32efc09274a16cbff588ad10dc5eaEvan Cheng bool SPRRegs = llvm::ARMMCRegisterClasses[ARM::SPRRegClassID].contains(Reg); 1329be74029f44c32efc09274a16cbff588ad10dc5eaEvan Cheng bool DPRRegs = llvm::ARMMCRegisterClasses[ARM::DPRRegClassID].contains(Reg); 13306bc105a7b9282a0b5beb9d06267b31a3054fb3faBill Wendling 13315e559a22c18166508a01fbd65471ec4e752726f9Bill Wendling unsigned Binary = 0; 13326bc105a7b9282a0b5beb9d06267b31a3054fb3faBill Wendling 13336bc105a7b9282a0b5beb9d06267b31a3054fb3faBill Wendling if (SPRRegs || DPRRegs) { 13346bc105a7b9282a0b5beb9d06267b31a3054fb3faBill Wendling // VLDM/VSTM 13356bc105a7b9282a0b5beb9d06267b31a3054fb3faBill Wendling unsigned RegNo = getARMRegisterNumbering(Reg); 13366bc105a7b9282a0b5beb9d06267b31a3054fb3faBill Wendling unsigned NumRegs = (MI.getNumOperands() - Op) & 0xff; 13376bc105a7b9282a0b5beb9d06267b31a3054fb3faBill Wendling Binary |= (RegNo & 0x1f) << 8; 13386bc105a7b9282a0b5beb9d06267b31a3054fb3faBill Wendling if (SPRRegs) 13396bc105a7b9282a0b5beb9d06267b31a3054fb3faBill Wendling Binary |= NumRegs; 13406bc105a7b9282a0b5beb9d06267b31a3054fb3faBill Wendling else 13416bc105a7b9282a0b5beb9d06267b31a3054fb3faBill Wendling Binary |= NumRegs * 2; 13426bc105a7b9282a0b5beb9d06267b31a3054fb3faBill Wendling } else { 13436bc105a7b9282a0b5beb9d06267b31a3054fb3faBill Wendling for (unsigned I = Op, E = MI.getNumOperands(); I < E; ++I) { 13446bc105a7b9282a0b5beb9d06267b31a3054fb3faBill Wendling unsigned RegNo = getARMRegisterNumbering(MI.getOperand(I).getReg()); 13456bc105a7b9282a0b5beb9d06267b31a3054fb3faBill Wendling Binary |= 1 << RegNo; 13466bc105a7b9282a0b5beb9d06267b31a3054fb3faBill Wendling } 13475e559a22c18166508a01fbd65471ec4e752726f9Bill Wendling } 13486bc105a7b9282a0b5beb9d06267b31a3054fb3faBill Wendling 13496b5252db2db5eeeadec4602329ac56beb6dea54aJim Grosbach return Binary; 13506b5252db2db5eeeadec4602329ac56beb6dea54aJim Grosbach} 13516b5252db2db5eeeadec4602329ac56beb6dea54aJim Grosbach 13528e0c7b52877983b4838e54e233449912fc1a2325Bob Wilson/// getAddrMode6AddressOpValue - Encode an addrmode6 register number along 13538e0c7b52877983b4838e54e233449912fc1a2325Bob Wilson/// with the alignment operand. 1354806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbachunsigned ARMMCCodeEmitter:: 1355806e80ef42bdb416f409142a1ff1d4e8752baac8Jim GrosbachgetAddrMode6AddressOpValue(const MCInst &MI, unsigned Op, 1356806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbach SmallVectorImpl<MCFixup> &Fixups) const { 1357d9aa7d30aa277fba319ee4bcdb862cd79f1aabe5Owen Anderson const MCOperand &Reg = MI.getOperand(Op); 13580800ce71896ccd7f49b37861a8cfbc21b6b10022Bill Wendling const MCOperand &Imm = MI.getOperand(Op + 1); 135935b2de012d9404e3e9e4373e45f41711f752dd3aJim Grosbach 1360d9aa7d30aa277fba319ee4bcdb862cd79f1aabe5Owen Anderson unsigned RegNo = getARMRegisterNumbering(Reg.getReg()); 13610800ce71896ccd7f49b37861a8cfbc21b6b10022Bill Wendling unsigned Align = 0; 13620800ce71896ccd7f49b37861a8cfbc21b6b10022Bill Wendling 13630800ce71896ccd7f49b37861a8cfbc21b6b10022Bill Wendling switch (Imm.getImm()) { 13640800ce71896ccd7f49b37861a8cfbc21b6b10022Bill Wendling default: break; 13650800ce71896ccd7f49b37861a8cfbc21b6b10022Bill Wendling case 2: 13660800ce71896ccd7f49b37861a8cfbc21b6b10022Bill Wendling case 4: 13670800ce71896ccd7f49b37861a8cfbc21b6b10022Bill Wendling case 8: Align = 0x01; break; 13680800ce71896ccd7f49b37861a8cfbc21b6b10022Bill Wendling case 16: Align = 0x02; break; 13690800ce71896ccd7f49b37861a8cfbc21b6b10022Bill Wendling case 32: Align = 0x03; break; 1370d9aa7d30aa277fba319ee4bcdb862cd79f1aabe5Owen Anderson } 13710800ce71896ccd7f49b37861a8cfbc21b6b10022Bill Wendling 1372d9aa7d30aa277fba319ee4bcdb862cd79f1aabe5Owen Anderson return RegNo | (Align << 4); 1373d9aa7d30aa277fba319ee4bcdb862cd79f1aabe5Owen Anderson} 1374d9aa7d30aa277fba319ee4bcdb862cd79f1aabe5Owen Anderson 1375183c627d89be5d0e8f3255ab7f6d1204c2fabedfMon P Wang/// getAddrMode6OneLane32AddressOpValue - Encode an addrmode6 register number 1376183c627d89be5d0e8f3255ab7f6d1204c2fabedfMon P Wang/// along with the alignment operand for use in VST1 and VLD1 with size 32. 1377183c627d89be5d0e8f3255ab7f6d1204c2fabedfMon P Wangunsigned ARMMCCodeEmitter:: 1378183c627d89be5d0e8f3255ab7f6d1204c2fabedfMon P WanggetAddrMode6OneLane32AddressOpValue(const MCInst &MI, unsigned Op, 1379183c627d89be5d0e8f3255ab7f6d1204c2fabedfMon P Wang SmallVectorImpl<MCFixup> &Fixups) const { 1380183c627d89be5d0e8f3255ab7f6d1204c2fabedfMon P Wang const MCOperand &Reg = MI.getOperand(Op); 1381183c627d89be5d0e8f3255ab7f6d1204c2fabedfMon P Wang const MCOperand &Imm = MI.getOperand(Op + 1); 1382183c627d89be5d0e8f3255ab7f6d1204c2fabedfMon P Wang 1383183c627d89be5d0e8f3255ab7f6d1204c2fabedfMon P Wang unsigned RegNo = getARMRegisterNumbering(Reg.getReg()); 1384183c627d89be5d0e8f3255ab7f6d1204c2fabedfMon P Wang unsigned Align = 0; 1385183c627d89be5d0e8f3255ab7f6d1204c2fabedfMon P Wang 1386183c627d89be5d0e8f3255ab7f6d1204c2fabedfMon P Wang switch (Imm.getImm()) { 1387183c627d89be5d0e8f3255ab7f6d1204c2fabedfMon P Wang default: break; 1388183c627d89be5d0e8f3255ab7f6d1204c2fabedfMon P Wang case 8: 1389eeaf1c1636c664c707fd9ecc96916fd20ddf137aJim Grosbach case 16: 1390eeaf1c1636c664c707fd9ecc96916fd20ddf137aJim Grosbach case 32: // Default '0' value for invalid alignments of 8, 16, 32 bytes. 1391eeaf1c1636c664c707fd9ecc96916fd20ddf137aJim Grosbach case 2: Align = 0x00; break; 1392eeaf1c1636c664c707fd9ecc96916fd20ddf137aJim Grosbach case 4: Align = 0x03; break; 1393183c627d89be5d0e8f3255ab7f6d1204c2fabedfMon P Wang } 1394183c627d89be5d0e8f3255ab7f6d1204c2fabedfMon P Wang 1395183c627d89be5d0e8f3255ab7f6d1204c2fabedfMon P Wang return RegNo | (Align << 4); 1396183c627d89be5d0e8f3255ab7f6d1204c2fabedfMon P Wang} 1397183c627d89be5d0e8f3255ab7f6d1204c2fabedfMon P Wang 1398183c627d89be5d0e8f3255ab7f6d1204c2fabedfMon P Wang 13998e0c7b52877983b4838e54e233449912fc1a2325Bob Wilson/// getAddrMode6DupAddressOpValue - Encode an addrmode6 register number and 14008e0c7b52877983b4838e54e233449912fc1a2325Bob Wilson/// alignment operand for use in VLD-dup instructions. This is the same as 14018e0c7b52877983b4838e54e233449912fc1a2325Bob Wilson/// getAddrMode6AddressOpValue except for the alignment encoding, which is 14028e0c7b52877983b4838e54e233449912fc1a2325Bob Wilson/// different for VLD4-dup. 14038e0c7b52877983b4838e54e233449912fc1a2325Bob Wilsonunsigned ARMMCCodeEmitter:: 14048e0c7b52877983b4838e54e233449912fc1a2325Bob WilsongetAddrMode6DupAddressOpValue(const MCInst &MI, unsigned Op, 14058e0c7b52877983b4838e54e233449912fc1a2325Bob Wilson SmallVectorImpl<MCFixup> &Fixups) const { 14068e0c7b52877983b4838e54e233449912fc1a2325Bob Wilson const MCOperand &Reg = MI.getOperand(Op); 14078e0c7b52877983b4838e54e233449912fc1a2325Bob Wilson const MCOperand &Imm = MI.getOperand(Op + 1); 14088e0c7b52877983b4838e54e233449912fc1a2325Bob Wilson 14098e0c7b52877983b4838e54e233449912fc1a2325Bob Wilson unsigned RegNo = getARMRegisterNumbering(Reg.getReg()); 14108e0c7b52877983b4838e54e233449912fc1a2325Bob Wilson unsigned Align = 0; 14118e0c7b52877983b4838e54e233449912fc1a2325Bob Wilson 14128e0c7b52877983b4838e54e233449912fc1a2325Bob Wilson switch (Imm.getImm()) { 14138e0c7b52877983b4838e54e233449912fc1a2325Bob Wilson default: break; 14148e0c7b52877983b4838e54e233449912fc1a2325Bob Wilson case 2: 14158e0c7b52877983b4838e54e233449912fc1a2325Bob Wilson case 4: 14168e0c7b52877983b4838e54e233449912fc1a2325Bob Wilson case 8: Align = 0x01; break; 14178e0c7b52877983b4838e54e233449912fc1a2325Bob Wilson case 16: Align = 0x03; break; 14188e0c7b52877983b4838e54e233449912fc1a2325Bob Wilson } 14198e0c7b52877983b4838e54e233449912fc1a2325Bob Wilson 14208e0c7b52877983b4838e54e233449912fc1a2325Bob Wilson return RegNo | (Align << 4); 14218e0c7b52877983b4838e54e233449912fc1a2325Bob Wilson} 14228e0c7b52877983b4838e54e233449912fc1a2325Bob Wilson 1423806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbachunsigned ARMMCCodeEmitter:: 1424806e80ef42bdb416f409142a1ff1d4e8752baac8Jim GrosbachgetAddrMode6OffsetOpValue(const MCInst &MI, unsigned Op, 1425806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbach SmallVectorImpl<MCFixup> &Fixups) const { 14260800ce71896ccd7f49b37861a8cfbc21b6b10022Bill Wendling const MCOperand &MO = MI.getOperand(Op); 14270800ce71896ccd7f49b37861a8cfbc21b6b10022Bill Wendling if (MO.getReg() == 0) return 0x0D; 1428204aa64f30911f28c11e05ba2acf475d25c45fa0Jim Grosbach return getARMRegisterNumbering(MO.getReg()); 1429a656b63ee4d5b0e3f4d26a55dd4cc69795746684Bill Wendling} 1430a656b63ee4d5b0e3f4d26a55dd4cc69795746684Bill Wendling 1431a656b63ee4d5b0e3f4d26a55dd4cc69795746684Bill Wendlingunsigned ARMMCCodeEmitter:: 14323116dce33840a115130c5f8ffcb9679d023496d6Bill WendlinggetShiftRight8Imm(const MCInst &MI, unsigned Op, 14333116dce33840a115130c5f8ffcb9679d023496d6Bill Wendling SmallVectorImpl<MCFixup> &Fixups) const { 1434a656b63ee4d5b0e3f4d26a55dd4cc69795746684Bill Wendling return 8 - MI.getOperand(Op).getImm(); 1435a656b63ee4d5b0e3f4d26a55dd4cc69795746684Bill Wendling} 1436a656b63ee4d5b0e3f4d26a55dd4cc69795746684Bill Wendling 1437a656b63ee4d5b0e3f4d26a55dd4cc69795746684Bill Wendlingunsigned ARMMCCodeEmitter:: 14383116dce33840a115130c5f8ffcb9679d023496d6Bill WendlinggetShiftRight16Imm(const MCInst &MI, unsigned Op, 14393116dce33840a115130c5f8ffcb9679d023496d6Bill Wendling SmallVectorImpl<MCFixup> &Fixups) const { 1440a656b63ee4d5b0e3f4d26a55dd4cc69795746684Bill Wendling return 16 - MI.getOperand(Op).getImm(); 1441a656b63ee4d5b0e3f4d26a55dd4cc69795746684Bill Wendling} 1442a656b63ee4d5b0e3f4d26a55dd4cc69795746684Bill Wendling 1443a656b63ee4d5b0e3f4d26a55dd4cc69795746684Bill Wendlingunsigned ARMMCCodeEmitter:: 14443116dce33840a115130c5f8ffcb9679d023496d6Bill WendlinggetShiftRight32Imm(const MCInst &MI, unsigned Op, 14453116dce33840a115130c5f8ffcb9679d023496d6Bill Wendling SmallVectorImpl<MCFixup> &Fixups) const { 1446a656b63ee4d5b0e3f4d26a55dd4cc69795746684Bill Wendling return 32 - MI.getOperand(Op).getImm(); 14473116dce33840a115130c5f8ffcb9679d023496d6Bill Wendling} 14483116dce33840a115130c5f8ffcb9679d023496d6Bill Wendling 14493116dce33840a115130c5f8ffcb9679d023496d6Bill Wendlingunsigned ARMMCCodeEmitter:: 14503116dce33840a115130c5f8ffcb9679d023496d6Bill WendlinggetShiftRight64Imm(const MCInst &MI, unsigned Op, 14513116dce33840a115130c5f8ffcb9679d023496d6Bill Wendling SmallVectorImpl<MCFixup> &Fixups) const { 14523116dce33840a115130c5f8ffcb9679d023496d6Bill Wendling return 64 - MI.getOperand(Op).getImm(); 1453cf667be17b479fe276fd606b8fd72ccfa3065bb8Owen Anderson} 1454cf667be17b479fe276fd606b8fd72ccfa3065bb8Owen Anderson 1455568eeedea72c274abbba1310c18a31eef78e14a4Jim Grosbachvoid ARMMCCodeEmitter:: 1456568eeedea72c274abbba1310c18a31eef78e14a4Jim GrosbachEncodeInstruction(const MCInst &MI, raw_ostream &OS, 1457806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbach SmallVectorImpl<MCFixup> &Fixups) const { 1458d6d4b42ba473657b6d30242962f0d0fb23fe126eJim Grosbach // Pseudo instructions don't get encoded. 145959ee62d2418df8db499eca1ae17f5900dc2dcbbaEvan Cheng const MCInstrDesc &Desc = MCII.get(MI.getOpcode()); 1460e50e6bcd901ebb1cfc42fe9ca0796ae303d7f1a1Jim Grosbach uint64_t TSFlags = Desc.TSFlags; 1461e50e6bcd901ebb1cfc42fe9ca0796ae303d7f1a1Jim Grosbach if ((TSFlags & ARMII::FormMask) == ARMII::Pseudo) 1462d6d4b42ba473657b6d30242962f0d0fb23fe126eJim Grosbach return; 146316884415db751c75f2133bd04921393c792b1158Owen Anderson 1464e50e6bcd901ebb1cfc42fe9ca0796ae303d7f1a1Jim Grosbach int Size; 146516884415db751c75f2133bd04921393c792b1158Owen Anderson if (Desc.getSize() == 2 || Desc.getSize() == 4) 146616884415db751c75f2133bd04921393c792b1158Owen Anderson Size = Desc.getSize(); 146716884415db751c75f2133bd04921393c792b1158Owen Anderson else 146816884415db751c75f2133bd04921393c792b1158Owen Anderson llvm_unreachable("Unexpected instruction size!"); 146910096dbdef22a10a6a4444437c935ab428545525Owen Anderson 1470d91f4e40e6312304c60c83c3dd93f769a39a9772Jim Grosbach uint32_t Binary = getBinaryCodeForInstr(MI, Fixups); 14717597212abced110723f2fee985a7d60557c092ecEvan Cheng // Thumb 32-bit wide instructions need to emit the high order halfword 14727597212abced110723f2fee985a7d60557c092ecEvan Cheng // first. 147359ee62d2418df8db499eca1ae17f5900dc2dcbbaEvan Cheng if (isThumb() && Size == 4) { 1474d91f4e40e6312304c60c83c3dd93f769a39a9772Jim Grosbach EmitConstant(Binary >> 16, 2, OS); 1475d91f4e40e6312304c60c83c3dd93f769a39a9772Jim Grosbach EmitConstant(Binary & 0xffff, 2, OS); 1476d91f4e40e6312304c60c83c3dd93f769a39a9772Jim Grosbach } else 1477d91f4e40e6312304c60c83c3dd93f769a39a9772Jim Grosbach EmitConstant(Binary, Size, OS); 14787292e0a6564bb24707eff1c49da9044dd5eaec78Bill Wendling ++MCNumEmitted; // Keep track of the # of mi's emitted. 1479568eeedea72c274abbba1310c18a31eef78e14a4Jim Grosbach} 14809af82ba42b53905f580f8c4270626946e3548654Jim Grosbach 1481806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbach#include "ARMGenMCCodeEmitter.inc" 1482