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" 15d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "MCTargetDesc/ARMMCTargetDesc.h" 16ee04a6d3a40c3017124e3fd89a0db473a2824498Evan Cheng#include "MCTargetDesc/ARMAddressingModes.h" 17be74029f44c32efc09274a16cbff588ad10dc5eaEvan Cheng#include "MCTargetDesc/ARMBaseInfo.h" 18be74029f44c32efc09274a16cbff588ad10dc5eaEvan Cheng#include "MCTargetDesc/ARMFixupKinds.h" 19ee04a6d3a40c3017124e3fd89a0db473a2824498Evan Cheng#include "MCTargetDesc/ARMMCExpr.h" 20d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/ADT/APFloat.h" 21d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/ADT/Statistic.h" 22568eeedea72c274abbba1310c18a31eef78e14a4Jim Grosbach#include "llvm/MC/MCCodeEmitter.h" 23df1c637ac4b6f6587c037be55cafed665c732d8fEric Christopher#include "llvm/MC/MCContext.h" 24568eeedea72c274abbba1310c18a31eef78e14a4Jim Grosbach#include "llvm/MC/MCExpr.h" 25568eeedea72c274abbba1310c18a31eef78e14a4Jim Grosbach#include "llvm/MC/MCInst.h" 2659ee62d2418df8db499eca1ae17f5900dc2dcbbaEvan Cheng#include "llvm/MC/MCInstrInfo.h" 27be74029f44c32efc09274a16cbff588ad10dc5eaEvan Cheng#include "llvm/MC/MCRegisterInfo.h" 2859ee62d2418df8db499eca1ae17f5900dc2dcbbaEvan Cheng#include "llvm/MC/MCSubtargetInfo.h" 29568eeedea72c274abbba1310c18a31eef78e14a4Jim Grosbach#include "llvm/Support/raw_ostream.h" 3059ee62d2418df8db499eca1ae17f5900dc2dcbbaEvan Cheng 31568eeedea72c274abbba1310c18a31eef78e14a4Jim Grosbachusing namespace llvm; 32568eeedea72c274abbba1310c18a31eef78e14a4Jim Grosbach 3370933266ae73c891d9d1c2f0de72ecd1db8f86dfJim GrosbachSTATISTIC(MCNumEmitted, "Number of MC instructions emitted."); 3470933266ae73c891d9d1c2f0de72ecd1db8f86dfJim GrosbachSTATISTIC(MCNumCPRelocations, "Number of constant pool relocations created."); 35d6d4b42ba473657b6d30242962f0d0fb23fe126eJim Grosbach 36568eeedea72c274abbba1310c18a31eef78e14a4Jim Grosbachnamespace { 37568eeedea72c274abbba1310c18a31eef78e14a4Jim Grosbachclass ARMMCCodeEmitter : public MCCodeEmitter { 3886a1c32e67b23c5e9e42dff9eb86e99ba15bb42fCraig Topper ARMMCCodeEmitter(const ARMMCCodeEmitter &) LLVM_DELETED_FUNCTION; 3986a1c32e67b23c5e9e42dff9eb86e99ba15bb42fCraig Topper void operator=(const ARMMCCodeEmitter &) LLVM_DELETED_FUNCTION; 4059ee62d2418df8db499eca1ae17f5900dc2dcbbaEvan Cheng const MCInstrInfo &MCII; 4159ee62d2418df8db499eca1ae17f5900dc2dcbbaEvan Cheng const MCSubtargetInfo &STI; 42df1c637ac4b6f6587c037be55cafed665c732d8fEric Christopher const MCContext &CTX; 43568eeedea72c274abbba1310c18a31eef78e14a4Jim Grosbach 44568eeedea72c274abbba1310c18a31eef78e14a4Jim Grosbachpublic: 4559ee62d2418df8db499eca1ae17f5900dc2dcbbaEvan Cheng ARMMCCodeEmitter(const MCInstrInfo &mcii, const MCSubtargetInfo &sti, 4659ee62d2418df8db499eca1ae17f5900dc2dcbbaEvan Cheng MCContext &ctx) 47df1c637ac4b6f6587c037be55cafed665c732d8fEric Christopher : MCII(mcii), STI(sti), CTX(ctx) { 48568eeedea72c274abbba1310c18a31eef78e14a4Jim Grosbach } 49568eeedea72c274abbba1310c18a31eef78e14a4Jim Grosbach 50568eeedea72c274abbba1310c18a31eef78e14a4Jim Grosbach ~ARMMCCodeEmitter() {} 51568eeedea72c274abbba1310c18a31eef78e14a4Jim Grosbach 5259ee62d2418df8db499eca1ae17f5900dc2dcbbaEvan Cheng bool isThumb() const { 5359ee62d2418df8db499eca1ae17f5900dc2dcbbaEvan Cheng // FIXME: Can tablegen auto-generate this? 5459ee62d2418df8db499eca1ae17f5900dc2dcbbaEvan Cheng return (STI.getFeatureBits() & ARM::ModeThumb) != 0; 5559ee62d2418df8db499eca1ae17f5900dc2dcbbaEvan Cheng } 5659ee62d2418df8db499eca1ae17f5900dc2dcbbaEvan Cheng bool isThumb2() const { 5759ee62d2418df8db499eca1ae17f5900dc2dcbbaEvan Cheng return isThumb() && (STI.getFeatureBits() & ARM::FeatureThumb2) != 0; 5859ee62d2418df8db499eca1ae17f5900dc2dcbbaEvan Cheng } 5959ee62d2418df8db499eca1ae17f5900dc2dcbbaEvan Cheng bool isTargetDarwin() const { 6059ee62d2418df8db499eca1ae17f5900dc2dcbbaEvan Cheng Triple TT(STI.getTargetTriple()); 6159ee62d2418df8db499eca1ae17f5900dc2dcbbaEvan Cheng Triple::OSType OS = TT.getOS(); 6259ee62d2418df8db499eca1ae17f5900dc2dcbbaEvan Cheng return OS == Triple::Darwin || OS == Triple::MacOSX || OS == Triple::IOS; 6359ee62d2418df8db499eca1ae17f5900dc2dcbbaEvan Cheng } 6459ee62d2418df8db499eca1ae17f5900dc2dcbbaEvan Cheng 650de6ab3c43ed2143d661115dddf1480545236c91Jim Grosbach unsigned getMachineSoImmOpValue(unsigned SoImm) const; 660de6ab3c43ed2143d661115dddf1480545236c91Jim Grosbach 679af82ba42b53905f580f8c4270626946e3548654Jim Grosbach // getBinaryCodeForInstr - TableGen'erated function for getting the 689af82ba42b53905f580f8c4270626946e3548654Jim Grosbach // binary encoding for an instruction. 694f8dc7b17accf4f2ec953b80b2cc79786207492eOwen Anderson uint64_t getBinaryCodeForInstr(const MCInst &MI, 70806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbach SmallVectorImpl<MCFixup> &Fixups) const; 719af82ba42b53905f580f8c4270626946e3548654Jim Grosbach 729af82ba42b53905f580f8c4270626946e3548654Jim Grosbach /// getMachineOpValue - Return binary encoding of operand. If the machine 739af82ba42b53905f580f8c4270626946e3548654Jim Grosbach /// operand requires relocation, record the relocation and return zero. 74806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbach unsigned getMachineOpValue(const MCInst &MI,const MCOperand &MO, 75806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbach SmallVectorImpl<MCFixup> &Fixups) const; 769af82ba42b53905f580f8c4270626946e3548654Jim Grosbach 777597212abced110723f2fee985a7d60557c092ecEvan Cheng /// getHiLo16ImmOpValue - Return the encoding for the hi / low 16-bit of 78971b83b67a9812556cdb97bb58aa96fb37af458dOwen Anderson /// the specified operand. This is used for operands with :lower16: and 797597212abced110723f2fee985a7d60557c092ecEvan Cheng /// :upper16: prefixes. 807597212abced110723f2fee985a7d60557c092ecEvan Cheng uint32_t getHiLo16ImmOpValue(const MCInst &MI, unsigned OpIdx, 817597212abced110723f2fee985a7d60557c092ecEvan Cheng SmallVectorImpl<MCFixup> &Fixups) const; 82837caa9313e1f9480721f232f89f5c7b1b9c9d09Jason W Kim 8392b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling bool EncodeAddrModeOpValues(const MCInst &MI, unsigned OpIdx, 84806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbach unsigned &Reg, unsigned &Imm, 85806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbach SmallVectorImpl<MCFixup> &Fixups) const; 8692b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling 87662a816e89a9d77bf75e1328b09cf9235b4682aaJim Grosbach /// getThumbBLTargetOpValue - Return encoding info for Thumb immediate 8809aa3f0ef35d9241c92439d74b8d5e9a81d814c2Bill Wendling /// BL branch target. 89662a816e89a9d77bf75e1328b09cf9235b4682aaJim Grosbach uint32_t getThumbBLTargetOpValue(const MCInst &MI, unsigned OpIdx, 90662a816e89a9d77bf75e1328b09cf9235b4682aaJim Grosbach SmallVectorImpl<MCFixup> &Fixups) const; 91662a816e89a9d77bf75e1328b09cf9235b4682aaJim Grosbach 9209aa3f0ef35d9241c92439d74b8d5e9a81d814c2Bill Wendling /// getThumbBLXTargetOpValue - Return encoding info for Thumb immediate 9309aa3f0ef35d9241c92439d74b8d5e9a81d814c2Bill Wendling /// BLX branch target. 9409aa3f0ef35d9241c92439d74b8d5e9a81d814c2Bill Wendling uint32_t getThumbBLXTargetOpValue(const MCInst &MI, unsigned OpIdx, 9509aa3f0ef35d9241c92439d74b8d5e9a81d814c2Bill Wendling SmallVectorImpl<MCFixup> &Fixups) const; 9609aa3f0ef35d9241c92439d74b8d5e9a81d814c2Bill Wendling 97e246717c3a36a913fd4200776ed621649bb2b624Jim Grosbach /// getThumbBRTargetOpValue - Return encoding info for Thumb branch target. 98e246717c3a36a913fd4200776ed621649bb2b624Jim Grosbach uint32_t getThumbBRTargetOpValue(const MCInst &MI, unsigned OpIdx, 99e246717c3a36a913fd4200776ed621649bb2b624Jim Grosbach SmallVectorImpl<MCFixup> &Fixups) const; 100e246717c3a36a913fd4200776ed621649bb2b624Jim Grosbach 10101086451393ef33e82b6fad623989dd97dd70edfJim Grosbach /// getThumbBCCTargetOpValue - Return encoding info for Thumb branch target. 10201086451393ef33e82b6fad623989dd97dd70edfJim Grosbach uint32_t getThumbBCCTargetOpValue(const MCInst &MI, unsigned OpIdx, 10301086451393ef33e82b6fad623989dd97dd70edfJim Grosbach SmallVectorImpl<MCFixup> &Fixups) const; 10401086451393ef33e82b6fad623989dd97dd70edfJim Grosbach 105027d6e8d1ca04e4096fb3a27579b861d861466c5Jim Grosbach /// getThumbCBTargetOpValue - Return encoding info for Thumb branch target. 106027d6e8d1ca04e4096fb3a27579b861d861466c5Jim Grosbach uint32_t getThumbCBTargetOpValue(const MCInst &MI, unsigned OpIdx, 107dff2f7151f695b86db8c4b0c6604463bdb8a63eaBill Wendling SmallVectorImpl<MCFixup> &Fixups) const; 108dff2f7151f695b86db8c4b0c6604463bdb8a63eaBill Wendling 109c466b937dbdbaabeef0097fe340de1b8f49a3508Jim Grosbach /// getBranchTargetOpValue - Return encoding info for 24-bit immediate 110c466b937dbdbaabeef0097fe340de1b8f49a3508Jim Grosbach /// branch target. 111c466b937dbdbaabeef0097fe340de1b8f49a3508Jim Grosbach uint32_t getBranchTargetOpValue(const MCInst &MI, unsigned OpIdx, 112c466b937dbdbaabeef0097fe340de1b8f49a3508Jim Grosbach SmallVectorImpl<MCFixup> &Fixups) const; 113c466b937dbdbaabeef0097fe340de1b8f49a3508Jim Grosbach 114c266600bec4b5ba0ee93ffdfeaafcab8f1295145Owen Anderson /// getUnconditionalBranchTargetOpValue - Return encoding info for 24-bit 115c266600bec4b5ba0ee93ffdfeaafcab8f1295145Owen Anderson /// immediate Thumb2 direct branch target. 116c266600bec4b5ba0ee93ffdfeaafcab8f1295145Owen Anderson uint32_t getUnconditionalBranchTargetOpValue(const MCInst &MI, unsigned OpIdx, 117c266600bec4b5ba0ee93ffdfeaafcab8f1295145Owen Anderson SmallVectorImpl<MCFixup> &Fixups) const; 11810096dbdef22a10a6a4444437c935ab428545525Owen Anderson 119685c350ae76b588e1f00c01a511fe8bd57f18394Jason W Kim /// getARMBranchTargetOpValue - Return encoding info for 24-bit immediate 120685c350ae76b588e1f00c01a511fe8bd57f18394Jason W Kim /// branch target. 121685c350ae76b588e1f00c01a511fe8bd57f18394Jason W Kim uint32_t getARMBranchTargetOpValue(const MCInst &MI, unsigned OpIdx, 122685c350ae76b588e1f00c01a511fe8bd57f18394Jason W Kim SmallVectorImpl<MCFixup> &Fixups) const; 1237b25ecf6adbf3c4709c48033acfeb6ebbb4452abJim Grosbach uint32_t getARMBLTargetOpValue(const MCInst &MI, unsigned OpIdx, 1247b25ecf6adbf3c4709c48033acfeb6ebbb4452abJim Grosbach SmallVectorImpl<MCFixup> &Fixups) const; 125f1eab597b2316c6cfcabfcee98895fedb2071722Owen Anderson uint32_t getARMBLXTargetOpValue(const MCInst &MI, unsigned OpIdx, 1267b25ecf6adbf3c4709c48033acfeb6ebbb4452abJim Grosbach SmallVectorImpl<MCFixup> &Fixups) const; 127c266600bec4b5ba0ee93ffdfeaafcab8f1295145Owen Anderson 1285d14f9be7ba64162c7b996f36d419b11d8cdbe9aJim Grosbach /// getAdrLabelOpValue - Return encoding info for 12-bit immediate 1295d14f9be7ba64162c7b996f36d419b11d8cdbe9aJim Grosbach /// ADR label target. 1305d14f9be7ba64162c7b996f36d419b11d8cdbe9aJim Grosbach uint32_t getAdrLabelOpValue(const MCInst &MI, unsigned OpIdx, 1315d14f9be7ba64162c7b996f36d419b11d8cdbe9aJim Grosbach SmallVectorImpl<MCFixup> &Fixups) const; 132d40963c4065432ec7e47879d3ca665a54ee903b6Jim Grosbach uint32_t getThumbAdrLabelOpValue(const MCInst &MI, unsigned OpIdx, 133d40963c4065432ec7e47879d3ca665a54ee903b6Jim Grosbach SmallVectorImpl<MCFixup> &Fixups) const; 134a838a25d59838adfa91463f6a918ae3adeb352c1Owen Anderson uint32_t getT2AdrLabelOpValue(const MCInst &MI, unsigned OpIdx, 135a838a25d59838adfa91463f6a918ae3adeb352c1Owen Anderson SmallVectorImpl<MCFixup> &Fixups) const; 136971b83b67a9812556cdb97bb58aa96fb37af458dOwen Anderson 1375d14f9be7ba64162c7b996f36d419b11d8cdbe9aJim Grosbach 13892b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling /// getAddrModeImm12OpValue - Return encoding info for 'reg +/- imm12' 13992b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling /// operand. 140806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbach uint32_t getAddrModeImm12OpValue(const MCInst &MI, unsigned OpIdx, 141806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbach SmallVectorImpl<MCFixup> &Fixups) const; 14292b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling 143f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling /// getThumbAddrModeRegRegOpValue - Return encoding for 'reg + reg' operand. 144f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling uint32_t getThumbAddrModeRegRegOpValue(const MCInst &MI, unsigned OpIdx, 145f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling SmallVectorImpl<MCFixup> &Fixups)const; 1460f4b60d43a289671082deee3bd56a3a055afb16aOwen Anderson 1479d63d90de5e57ad96f467b270544443a9284eb2bOwen Anderson /// getT2AddrModeImm8s4OpValue - Return encoding info for 'reg +/- imm8<<2' 1489d63d90de5e57ad96f467b270544443a9284eb2bOwen Anderson /// operand. 1499d63d90de5e57ad96f467b270544443a9284eb2bOwen Anderson uint32_t getT2AddrModeImm8s4OpValue(const MCInst &MI, unsigned OpIdx, 1509d63d90de5e57ad96f467b270544443a9284eb2bOwen Anderson SmallVectorImpl<MCFixup> &Fixups) const; 151b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach 152b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach /// getT2AddrModeImm0_1020s4OpValue - Return encoding info for 'reg + imm8<<2' 153b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach /// operand. 154b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach uint32_t getT2AddrModeImm0_1020s4OpValue(const MCInst &MI, unsigned OpIdx, 155b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach SmallVectorImpl<MCFixup> &Fixups) const; 156b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach 157a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach /// getT2Imm8s4OpValue - Return encoding info for '+/- imm8<<2' 158a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach /// operand. 159a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach uint32_t getT2Imm8s4OpValue(const MCInst &MI, unsigned OpIdx, 160a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach SmallVectorImpl<MCFixup> &Fixups) const; 1619d63d90de5e57ad96f467b270544443a9284eb2bOwen Anderson 1629d63d90de5e57ad96f467b270544443a9284eb2bOwen Anderson 16354fea632b161f98e96ec7275922e35102bcecc5dJim Grosbach /// getLdStSORegOpValue - Return encoding info for 'reg +/- reg shop imm' 16454fea632b161f98e96ec7275922e35102bcecc5dJim Grosbach /// operand as needed by load/store instructions. 16554fea632b161f98e96ec7275922e35102bcecc5dJim Grosbach uint32_t getLdStSORegOpValue(const MCInst &MI, unsigned OpIdx, 16654fea632b161f98e96ec7275922e35102bcecc5dJim Grosbach SmallVectorImpl<MCFixup> &Fixups) const; 16754fea632b161f98e96ec7275922e35102bcecc5dJim Grosbach 1685d5eb9e3817a2765297e6dd5649ecb9b8b03e334Jim Grosbach /// getLdStmModeOpValue - Return encoding for load/store multiple mode. 1695d5eb9e3817a2765297e6dd5649ecb9b8b03e334Jim Grosbach uint32_t getLdStmModeOpValue(const MCInst &MI, unsigned OpIdx, 1705d5eb9e3817a2765297e6dd5649ecb9b8b03e334Jim Grosbach SmallVectorImpl<MCFixup> &Fixups) const { 1715d5eb9e3817a2765297e6dd5649ecb9b8b03e334Jim Grosbach ARM_AM::AMSubMode Mode = (ARM_AM::AMSubMode)MI.getOperand(OpIdx).getImm(); 1725d5eb9e3817a2765297e6dd5649ecb9b8b03e334Jim Grosbach switch (Mode) { 173bc2198133a1836598b54b943420748e75d5dea94Craig Topper default: llvm_unreachable("Unknown addressing sub-mode!"); 1745d5eb9e3817a2765297e6dd5649ecb9b8b03e334Jim Grosbach case ARM_AM::da: return 0; 1755d5eb9e3817a2765297e6dd5649ecb9b8b03e334Jim Grosbach case ARM_AM::ia: return 1; 1765d5eb9e3817a2765297e6dd5649ecb9b8b03e334Jim Grosbach case ARM_AM::db: return 2; 1775d5eb9e3817a2765297e6dd5649ecb9b8b03e334Jim Grosbach case ARM_AM::ib: return 3; 1785d5eb9e3817a2765297e6dd5649ecb9b8b03e334Jim Grosbach } 1795d5eb9e3817a2765297e6dd5649ecb9b8b03e334Jim Grosbach } 18099f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach /// getShiftOp - Return the shift opcode (bit[6:5]) of the immediate value. 18199f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach /// 18299f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach unsigned getShiftOp(ARM_AM::ShiftOpc ShOpc) const { 18399f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach switch (ShOpc) { 18499f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach case ARM_AM::no_shift: 18599f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach case ARM_AM::lsl: return 0; 18699f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach case ARM_AM::lsr: return 1; 18799f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach case ARM_AM::asr: return 2; 18899f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach case ARM_AM::ror: 18999f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach case ARM_AM::rrx: return 3; 19099f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach } 1914d6ccb5f68cd7c6418a209f1fa4dbade569e4493David Blaikie llvm_unreachable("Invalid ShiftOpc!"); 19299f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach } 19399f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach 19499f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach /// getAddrMode2OpValue - Return encoding for addrmode2 operands. 19599f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach uint32_t getAddrMode2OpValue(const MCInst &MI, unsigned OpIdx, 19699f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach SmallVectorImpl<MCFixup> &Fixups) const; 19799f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach 19899f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach /// getAddrMode2OffsetOpValue - Return encoding for am2offset operands. 19999f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach uint32_t getAddrMode2OffsetOpValue(const MCInst &MI, unsigned OpIdx, 20099f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach SmallVectorImpl<MCFixup> &Fixups) const; 20199f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach 2027ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach /// getPostIdxRegOpValue - Return encoding for postidx_reg operands. 2037ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach uint32_t getPostIdxRegOpValue(const MCInst &MI, unsigned OpIdx, 2047ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach SmallVectorImpl<MCFixup> &Fixups) const; 2057ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach 2067eab97f260ba0f56d1d4a82f3a4eb2c979452011Jim Grosbach /// getAddrMode3OffsetOpValue - Return encoding for am3offset operands. 2077eab97f260ba0f56d1d4a82f3a4eb2c979452011Jim Grosbach uint32_t getAddrMode3OffsetOpValue(const MCInst &MI, unsigned OpIdx, 2087eab97f260ba0f56d1d4a82f3a4eb2c979452011Jim Grosbach SmallVectorImpl<MCFixup> &Fixups) const; 2097eab97f260ba0f56d1d4a82f3a4eb2c979452011Jim Grosbach 210570a9226913ebe1af04832b8fb3273c70b4ee152Jim Grosbach /// getAddrMode3OpValue - Return encoding for addrmode3 operands. 211570a9226913ebe1af04832b8fb3273c70b4ee152Jim Grosbach uint32_t getAddrMode3OpValue(const MCInst &MI, unsigned OpIdx, 212570a9226913ebe1af04832b8fb3273c70b4ee152Jim Grosbach SmallVectorImpl<MCFixup> &Fixups) const; 2135d5eb9e3817a2765297e6dd5649ecb9b8b03e334Jim Grosbach 214d967cd096ae87accf2f1df86b2dfac969d9c9da2Jim Grosbach /// getAddrModeThumbSPOpValue - Return encoding info for 'reg +/- imm12' 215d967cd096ae87accf2f1df86b2dfac969d9c9da2Jim Grosbach /// operand. 216d967cd096ae87accf2f1df86b2dfac969d9c9da2Jim Grosbach uint32_t getAddrModeThumbSPOpValue(const MCInst &MI, unsigned OpIdx, 217d967cd096ae87accf2f1df86b2dfac969d9c9da2Jim Grosbach SmallVectorImpl<MCFixup> &Fixups) const; 218d967cd096ae87accf2f1df86b2dfac969d9c9da2Jim Grosbach 219f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling /// getAddrModeISOpValue - Encode the t_addrmode_is# operands. 220f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling uint32_t getAddrModeISOpValue(const MCInst &MI, unsigned OpIdx, 22122447ae54bcb8ca94ed994cad103074a24e66781Bill Wendling SmallVectorImpl<MCFixup> &Fixups) const; 2221fd374e9c1c074c1681336bef31e65f0170b0f7eBill Wendling 223b8958b031ec5163261f490f131780c5dc3d823d6Bill Wendling /// getAddrModePCOpValue - Return encoding for t_addrmode_pc operands. 224b8958b031ec5163261f490f131780c5dc3d823d6Bill Wendling uint32_t getAddrModePCOpValue(const MCInst &MI, unsigned OpIdx, 225b8958b031ec5163261f490f131780c5dc3d823d6Bill Wendling SmallVectorImpl<MCFixup> &Fixups) const; 226b8958b031ec5163261f490f131780c5dc3d823d6Bill Wendling 22792b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling /// getAddrMode5OpValue - Return encoding info for 'reg +/- imm8' operand. 228806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbach uint32_t getAddrMode5OpValue(const MCInst &MI, unsigned OpIdx, 229806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbach SmallVectorImpl<MCFixup> &Fixups) const; 2303e5561247202bae994dd259a2d8dc4eff8f799f3Jim Grosbach 23108bd54987f4ae482de13436e7254ff08b23f825fJim Grosbach /// getCCOutOpValue - Return encoding of the 's' bit. 232806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbach unsigned getCCOutOpValue(const MCInst &MI, unsigned Op, 233806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbach SmallVectorImpl<MCFixup> &Fixups) const { 23408bd54987f4ae482de13436e7254ff08b23f825fJim Grosbach // The operand is either reg0 or CPSR. The 's' bit is encoded as '0' or 23508bd54987f4ae482de13436e7254ff08b23f825fJim Grosbach // '1' respectively. 23608bd54987f4ae482de13436e7254ff08b23f825fJim Grosbach return MI.getOperand(Op).getReg() == ARM::CPSR; 23708bd54987f4ae482de13436e7254ff08b23f825fJim Grosbach } 238ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach 2392a6a93d5425b38546de2b6674719d52f565171d8Jim Grosbach /// getSOImmOpValue - Return an encoded 12-bit shifted-immediate value. 240806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbach unsigned getSOImmOpValue(const MCInst &MI, unsigned Op, 241806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbach SmallVectorImpl<MCFixup> &Fixups) const { 2422a6a93d5425b38546de2b6674719d52f565171d8Jim Grosbach unsigned SoImm = MI.getOperand(Op).getImm(); 2432a6a93d5425b38546de2b6674719d52f565171d8Jim Grosbach int SoImmVal = ARM_AM::getSOImmVal(SoImm); 2442a6a93d5425b38546de2b6674719d52f565171d8Jim Grosbach assert(SoImmVal != -1 && "Not a valid so_imm value!"); 2452a6a93d5425b38546de2b6674719d52f565171d8Jim Grosbach 2462a6a93d5425b38546de2b6674719d52f565171d8Jim Grosbach // Encode rotate_imm. 2472a6a93d5425b38546de2b6674719d52f565171d8Jim Grosbach unsigned Binary = (ARM_AM::getSOImmValRot((unsigned)SoImmVal) >> 1) 2482a6a93d5425b38546de2b6674719d52f565171d8Jim Grosbach << ARMII::SoRotImmShift; 2492a6a93d5425b38546de2b6674719d52f565171d8Jim Grosbach 2502a6a93d5425b38546de2b6674719d52f565171d8Jim Grosbach // Encode immed_8. 2512a6a93d5425b38546de2b6674719d52f565171d8Jim Grosbach Binary |= ARM_AM::getSOImmValImm((unsigned)SoImmVal); 2522a6a93d5425b38546de2b6674719d52f565171d8Jim Grosbach return Binary; 2532a6a93d5425b38546de2b6674719d52f565171d8Jim Grosbach } 2547bf4c02789f97e32225fc248dff6622b994a15eeJim Grosbach 2555de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson /// getT2SOImmOpValue - Return an encoded 12-bit shifted-immediate value. 2565de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson unsigned getT2SOImmOpValue(const MCInst &MI, unsigned Op, 2575de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson SmallVectorImpl<MCFixup> &Fixups) const { 2585de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson unsigned SoImm = MI.getOperand(Op).getImm(); 2595de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson unsigned Encoded = ARM_AM::getT2SOImmVal(SoImm); 2605de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson assert(Encoded != ~0U && "Not a Thumb2 so_imm value?"); 2615de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson return Encoded; 2625de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson } 26308bd54987f4ae482de13436e7254ff08b23f825fJim Grosbach 26475579f739fbc99a92a15f3ce75bbd7628ba00f8cOwen Anderson unsigned getT2AddrModeSORegOpValue(const MCInst &MI, unsigned OpNum, 26575579f739fbc99a92a15f3ce75bbd7628ba00f8cOwen Anderson SmallVectorImpl<MCFixup> &Fixups) const; 26675579f739fbc99a92a15f3ce75bbd7628ba00f8cOwen Anderson unsigned getT2AddrModeImm8OpValue(const MCInst &MI, unsigned OpNum, 26775579f739fbc99a92a15f3ce75bbd7628ba00f8cOwen Anderson SmallVectorImpl<MCFixup> &Fixups) const; 2686af50f7dd12d82f0a80f3158102180eee4c921aaOwen Anderson unsigned getT2AddrModeImm8OffsetOpValue(const MCInst &MI, unsigned OpNum, 2696af50f7dd12d82f0a80f3158102180eee4c921aaOwen Anderson SmallVectorImpl<MCFixup> &Fixups) const; 2700e1bcdf4f7547bb5f47ed5ff5f2409a8f72f3609Owen Anderson unsigned getT2AddrModeImm12OffsetOpValue(const MCInst &MI, unsigned OpNum, 2710e1bcdf4f7547bb5f47ed5ff5f2409a8f72f3609Owen Anderson SmallVectorImpl<MCFixup> &Fixups) const; 27275579f739fbc99a92a15f3ce75bbd7628ba00f8cOwen Anderson 273ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach /// getSORegOpValue - Return an encoded so_reg shifted register value. 274152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson unsigned getSORegRegOpValue(const MCInst &MI, unsigned Op, 275152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson SmallVectorImpl<MCFixup> &Fixups) const; 276152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson unsigned getSORegImmOpValue(const MCInst &MI, unsigned Op, 277806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbach SmallVectorImpl<MCFixup> &Fixups) const; 2785de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson unsigned getT2SORegOpValue(const MCInst &MI, unsigned Op, 2795de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson SmallVectorImpl<MCFixup> &Fixups) const; 280ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach 281806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbach unsigned getNEONVcvtImm32OpValue(const MCInst &MI, unsigned Op, 282806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbach SmallVectorImpl<MCFixup> &Fixups) const { 283498ec20703c89d0c2890b0967791f0f5f2b59a2fOwen Anderson return 64 - MI.getOperand(Op).getImm(); 284498ec20703c89d0c2890b0967791f0f5f2b59a2fOwen Anderson } 2858abe32af38b66bf4577526b23b6af6ec7eb6c155Jim Grosbach 286806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbach unsigned getBitfieldInvertedMaskOpValue(const MCInst &MI, unsigned Op, 287806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbach SmallVectorImpl<MCFixup> &Fixups) const; 2883fea19105d4929ad694f0b6272de31924c9f9f09Jim Grosbach 289806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbach unsigned getRegisterListOpValue(const MCInst &MI, unsigned Op, 290806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbach SmallVectorImpl<MCFixup> &Fixups) const; 291806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbach unsigned getAddrMode6AddressOpValue(const MCInst &MI, unsigned Op, 292806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbach SmallVectorImpl<MCFixup> &Fixups) const; 293183c627d89be5d0e8f3255ab7f6d1204c2fabedfMon P Wang unsigned getAddrMode6OneLane32AddressOpValue(const MCInst &MI, unsigned Op, 294183c627d89be5d0e8f3255ab7f6d1204c2fabedfMon P Wang SmallVectorImpl<MCFixup> &Fixups) const; 2958e0c7b52877983b4838e54e233449912fc1a2325Bob Wilson unsigned getAddrMode6DupAddressOpValue(const MCInst &MI, unsigned Op, 2968e0c7b52877983b4838e54e233449912fc1a2325Bob Wilson SmallVectorImpl<MCFixup> &Fixups) const; 297806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbach unsigned getAddrMode6OffsetOpValue(const MCInst &MI, unsigned Op, 298806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbach SmallVectorImpl<MCFixup> &Fixups) const; 2996b5252db2db5eeeadec4602329ac56beb6dea54aJim Grosbach 3003116dce33840a115130c5f8ffcb9679d023496d6Bill Wendling unsigned getShiftRight8Imm(const MCInst &MI, unsigned Op, 3013116dce33840a115130c5f8ffcb9679d023496d6Bill Wendling SmallVectorImpl<MCFixup> &Fixups) const; 3023116dce33840a115130c5f8ffcb9679d023496d6Bill Wendling unsigned getShiftRight16Imm(const MCInst &MI, unsigned Op, 3033116dce33840a115130c5f8ffcb9679d023496d6Bill Wendling SmallVectorImpl<MCFixup> &Fixups) const; 3043116dce33840a115130c5f8ffcb9679d023496d6Bill Wendling unsigned getShiftRight32Imm(const MCInst &MI, unsigned Op, 3053116dce33840a115130c5f8ffcb9679d023496d6Bill Wendling SmallVectorImpl<MCFixup> &Fixups) const; 3063116dce33840a115130c5f8ffcb9679d023496d6Bill Wendling unsigned getShiftRight64Imm(const MCInst &MI, unsigned Op, 3073116dce33840a115130c5f8ffcb9679d023496d6Bill Wendling SmallVectorImpl<MCFixup> &Fixups) const; 308a656b63ee4d5b0e3f4d26a55dd4cc69795746684Bill Wendling 3096d74631062e4464326eb5c680a4d62d340fa42ebOwen Anderson unsigned getThumbSRImmOpValue(const MCInst &MI, unsigned Op, 3106d74631062e4464326eb5c680a4d62d340fa42ebOwen Anderson SmallVectorImpl<MCFixup> &Fixups) const; 3116d74631062e4464326eb5c680a4d62d340fa42ebOwen Anderson 312c7139a6f0d3acd198ab9eb536ea1ec52e61ff130Owen Anderson unsigned NEONThumb2DataIPostEncoder(const MCInst &MI, 313c7139a6f0d3acd198ab9eb536ea1ec52e61ff130Owen Anderson unsigned EncodedValue) const; 31457dac88f775c1191a98cff89abd1f7ad33df5e29Owen Anderson unsigned NEONThumb2LoadStorePostEncoder(const MCInst &MI, 315cf590263cd5c24ccf1d08cef612738d99cd980d9Bill Wendling unsigned EncodedValue) const; 3168f143913141991baaa535ca0da7c8a81606d6392Owen Anderson unsigned NEONThumb2DupPostEncoder(const MCInst &MI, 317cf590263cd5c24ccf1d08cef612738d99cd980d9Bill Wendling unsigned EncodedValue) const; 31819c14abf1c4ccebfa7d07bdd6ea8462a15c0b749Joey Gouly unsigned NEONThumb2V8PostEncoder(const MCInst &MI, 31919c14abf1c4ccebfa7d07bdd6ea8462a15c0b749Joey Gouly unsigned EncodedValue) const; 320cf590263cd5c24ccf1d08cef612738d99cd980d9Bill Wendling 321cf590263cd5c24ccf1d08cef612738d99cd980d9Bill Wendling unsigned VFPThumb2PostEncoder(const MCInst &MI, 322cf590263cd5c24ccf1d08cef612738d99cd980d9Bill Wendling unsigned EncodedValue) const; 323c7139a6f0d3acd198ab9eb536ea1ec52e61ff130Owen Anderson 32470933266ae73c891d9d1c2f0de72ecd1db8f86dfJim Grosbach void EmitByte(unsigned char C, raw_ostream &OS) const { 325568eeedea72c274abbba1310c18a31eef78e14a4Jim Grosbach OS << (char)C; 326568eeedea72c274abbba1310c18a31eef78e14a4Jim Grosbach } 327568eeedea72c274abbba1310c18a31eef78e14a4Jim Grosbach 32870933266ae73c891d9d1c2f0de72ecd1db8f86dfJim Grosbach void EmitConstant(uint64_t Val, unsigned Size, raw_ostream &OS) const { 329568eeedea72c274abbba1310c18a31eef78e14a4Jim Grosbach // Output the constant in little endian byte order. 330568eeedea72c274abbba1310c18a31eef78e14a4Jim Grosbach for (unsigned i = 0; i != Size; ++i) { 33170933266ae73c891d9d1c2f0de72ecd1db8f86dfJim Grosbach EmitByte(Val & 255, OS); 332568eeedea72c274abbba1310c18a31eef78e14a4Jim Grosbach Val >>= 8; 333568eeedea72c274abbba1310c18a31eef78e14a4Jim Grosbach } 334568eeedea72c274abbba1310c18a31eef78e14a4Jim Grosbach } 335568eeedea72c274abbba1310c18a31eef78e14a4Jim Grosbach 336568eeedea72c274abbba1310c18a31eef78e14a4Jim Grosbach void EncodeInstruction(const MCInst &MI, raw_ostream &OS, 337568eeedea72c274abbba1310c18a31eef78e14a4Jim Grosbach SmallVectorImpl<MCFixup> &Fixups) const; 338568eeedea72c274abbba1310c18a31eef78e14a4Jim Grosbach}; 339568eeedea72c274abbba1310c18a31eef78e14a4Jim Grosbach 340568eeedea72c274abbba1310c18a31eef78e14a4Jim Grosbach} // end anonymous namespace 341568eeedea72c274abbba1310c18a31eef78e14a4Jim Grosbach 34259ee62d2418df8db499eca1ae17f5900dc2dcbbaEvan ChengMCCodeEmitter *llvm::createARMMCCodeEmitter(const MCInstrInfo &MCII, 343918f55fe239f00651e396be841f2b3b6e242f98dJim Grosbach const MCRegisterInfo &MRI, 34459ee62d2418df8db499eca1ae17f5900dc2dcbbaEvan Cheng const MCSubtargetInfo &STI, 3450800ce71896ccd7f49b37861a8cfbc21b6b10022Bill Wendling MCContext &Ctx) { 34659ee62d2418df8db499eca1ae17f5900dc2dcbbaEvan Cheng return new ARMMCCodeEmitter(MCII, STI, Ctx); 347568eeedea72c274abbba1310c18a31eef78e14a4Jim Grosbach} 348568eeedea72c274abbba1310c18a31eef78e14a4Jim Grosbach 3497bf4c02789f97e32225fc248dff6622b994a15eeJim Grosbach/// NEONThumb2DataIPostEncoder - Post-process encoded NEON data-processing 3507bf4c02789f97e32225fc248dff6622b994a15eeJim Grosbach/// instructions, and rewrite them to their Thumb2 form if we are currently in 351c7139a6f0d3acd198ab9eb536ea1ec52e61ff130Owen Anderson/// Thumb2 mode. 352c7139a6f0d3acd198ab9eb536ea1ec52e61ff130Owen Andersonunsigned ARMMCCodeEmitter::NEONThumb2DataIPostEncoder(const MCInst &MI, 353c7139a6f0d3acd198ab9eb536ea1ec52e61ff130Owen Anderson unsigned EncodedValue) const { 35459ee62d2418df8db499eca1ae17f5900dc2dcbbaEvan Cheng if (isThumb2()) { 3557bf4c02789f97e32225fc248dff6622b994a15eeJim Grosbach // NEON Thumb2 data-processsing encodings are very simple: bit 24 is moved 356c7139a6f0d3acd198ab9eb536ea1ec52e61ff130Owen Anderson // to bit 12 of the high half-word (i.e. bit 28), and bits 27-24 are 357c7139a6f0d3acd198ab9eb536ea1ec52e61ff130Owen Anderson // set to 1111. 358c7139a6f0d3acd198ab9eb536ea1ec52e61ff130Owen Anderson unsigned Bit24 = EncodedValue & 0x01000000; 359c7139a6f0d3acd198ab9eb536ea1ec52e61ff130Owen Anderson unsigned Bit28 = Bit24 << 4; 360c7139a6f0d3acd198ab9eb536ea1ec52e61ff130Owen Anderson EncodedValue &= 0xEFFFFFFF; 361c7139a6f0d3acd198ab9eb536ea1ec52e61ff130Owen Anderson EncodedValue |= Bit28; 362c7139a6f0d3acd198ab9eb536ea1ec52e61ff130Owen Anderson EncodedValue |= 0x0F000000; 363c7139a6f0d3acd198ab9eb536ea1ec52e61ff130Owen Anderson } 3647bf4c02789f97e32225fc248dff6622b994a15eeJim Grosbach 365c7139a6f0d3acd198ab9eb536ea1ec52e61ff130Owen Anderson return EncodedValue; 366c7139a6f0d3acd198ab9eb536ea1ec52e61ff130Owen Anderson} 367c7139a6f0d3acd198ab9eb536ea1ec52e61ff130Owen Anderson 36857dac88f775c1191a98cff89abd1f7ad33df5e29Owen Anderson/// NEONThumb2LoadStorePostEncoder - Post-process encoded NEON load/store 3697bf4c02789f97e32225fc248dff6622b994a15eeJim Grosbach/// instructions, and rewrite them to their Thumb2 form if we are currently in 37057dac88f775c1191a98cff89abd1f7ad33df5e29Owen Anderson/// Thumb2 mode. 37157dac88f775c1191a98cff89abd1f7ad33df5e29Owen Andersonunsigned ARMMCCodeEmitter::NEONThumb2LoadStorePostEncoder(const MCInst &MI, 37257dac88f775c1191a98cff89abd1f7ad33df5e29Owen Anderson unsigned EncodedValue) const { 37359ee62d2418df8db499eca1ae17f5900dc2dcbbaEvan Cheng if (isThumb2()) { 37457dac88f775c1191a98cff89abd1f7ad33df5e29Owen Anderson EncodedValue &= 0xF0FFFFFF; 37557dac88f775c1191a98cff89abd1f7ad33df5e29Owen Anderson EncodedValue |= 0x09000000; 37657dac88f775c1191a98cff89abd1f7ad33df5e29Owen Anderson } 3777bf4c02789f97e32225fc248dff6622b994a15eeJim Grosbach 37857dac88f775c1191a98cff89abd1f7ad33df5e29Owen Anderson return EncodedValue; 37957dac88f775c1191a98cff89abd1f7ad33df5e29Owen Anderson} 38057dac88f775c1191a98cff89abd1f7ad33df5e29Owen Anderson 3818f143913141991baaa535ca0da7c8a81606d6392Owen Anderson/// NEONThumb2DupPostEncoder - Post-process encoded NEON vdup 3827bf4c02789f97e32225fc248dff6622b994a15eeJim Grosbach/// instructions, and rewrite them to their Thumb2 form if we are currently in 3838f143913141991baaa535ca0da7c8a81606d6392Owen Anderson/// Thumb2 mode. 3848f143913141991baaa535ca0da7c8a81606d6392Owen Andersonunsigned ARMMCCodeEmitter::NEONThumb2DupPostEncoder(const MCInst &MI, 3858f143913141991baaa535ca0da7c8a81606d6392Owen Anderson unsigned EncodedValue) const { 38659ee62d2418df8db499eca1ae17f5900dc2dcbbaEvan Cheng if (isThumb2()) { 3878f143913141991baaa535ca0da7c8a81606d6392Owen Anderson EncodedValue &= 0x00FFFFFF; 3888f143913141991baaa535ca0da7c8a81606d6392Owen Anderson EncodedValue |= 0xEE000000; 3898f143913141991baaa535ca0da7c8a81606d6392Owen Anderson } 3907bf4c02789f97e32225fc248dff6622b994a15eeJim Grosbach 3918f143913141991baaa535ca0da7c8a81606d6392Owen Anderson return EncodedValue; 3928f143913141991baaa535ca0da7c8a81606d6392Owen Anderson} 3938f143913141991baaa535ca0da7c8a81606d6392Owen Anderson 39419c14abf1c4ccebfa7d07bdd6ea8462a15c0b749Joey Gouly/// Post-process encoded NEON v8 instructions, and rewrite them to Thumb2 form 39519c14abf1c4ccebfa7d07bdd6ea8462a15c0b749Joey Gouly/// if we are in Thumb2. 39619c14abf1c4ccebfa7d07bdd6ea8462a15c0b749Joey Goulyunsigned ARMMCCodeEmitter::NEONThumb2V8PostEncoder(const MCInst &MI, 39719c14abf1c4ccebfa7d07bdd6ea8462a15c0b749Joey Gouly unsigned EncodedValue) const { 39819c14abf1c4ccebfa7d07bdd6ea8462a15c0b749Joey Gouly if (isThumb2()) { 39919c14abf1c4ccebfa7d07bdd6ea8462a15c0b749Joey Gouly EncodedValue |= 0xC000000; // Set bits 27-26 40019c14abf1c4ccebfa7d07bdd6ea8462a15c0b749Joey Gouly } 40119c14abf1c4ccebfa7d07bdd6ea8462a15c0b749Joey Gouly 40219c14abf1c4ccebfa7d07bdd6ea8462a15c0b749Joey Gouly return EncodedValue; 40319c14abf1c4ccebfa7d07bdd6ea8462a15c0b749Joey Gouly} 40419c14abf1c4ccebfa7d07bdd6ea8462a15c0b749Joey Gouly 405cf590263cd5c24ccf1d08cef612738d99cd980d9Bill Wendling/// VFPThumb2PostEncoder - Post-process encoded VFP instructions and rewrite 406cf590263cd5c24ccf1d08cef612738d99cd980d9Bill Wendling/// them to their Thumb2 form if we are currently in Thumb2 mode. 407cf590263cd5c24ccf1d08cef612738d99cd980d9Bill Wendlingunsigned ARMMCCodeEmitter:: 408cf590263cd5c24ccf1d08cef612738d99cd980d9Bill WendlingVFPThumb2PostEncoder(const MCInst &MI, unsigned EncodedValue) const { 40959ee62d2418df8db499eca1ae17f5900dc2dcbbaEvan Cheng if (isThumb2()) { 410cf590263cd5c24ccf1d08cef612738d99cd980d9Bill Wendling EncodedValue &= 0x0FFFFFFF; 411cf590263cd5c24ccf1d08cef612738d99cd980d9Bill Wendling EncodedValue |= 0xE0000000; 412cf590263cd5c24ccf1d08cef612738d99cd980d9Bill Wendling } 413cf590263cd5c24ccf1d08cef612738d99cd980d9Bill Wendling return EncodedValue; 414cf590263cd5c24ccf1d08cef612738d99cd980d9Bill Wendling} 41557dac88f775c1191a98cff89abd1f7ad33df5e29Owen Anderson 41656ac907c57fcfddfd650238f03c856a9d55987e5Jim Grosbach/// getMachineOpValue - Return binary encoding of operand. If the machine 41756ac907c57fcfddfd650238f03c856a9d55987e5Jim Grosbach/// operand requires relocation, record the relocation and return zero. 418806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbachunsigned ARMMCCodeEmitter:: 419806e80ef42bdb416f409142a1ff1d4e8752baac8Jim GrosbachgetMachineOpValue(const MCInst &MI, const MCOperand &MO, 420806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbach SmallVectorImpl<MCFixup> &Fixups) const { 421bbbdcd453d22258cb4dd217eddf016668fcebf84Bill Wendling if (MO.isReg()) { 4220800ce71896ccd7f49b37861a8cfbc21b6b10022Bill Wendling unsigned Reg = MO.getReg(); 42399cb622041a0839c7dfcf0263c5102a305a0fdb5Bill Wendling unsigned RegNo = CTX.getRegisterInfo()->getEncodingValue(Reg); 424d8a11c25fa64c152628cfcf5f9d36eb60242b302Jim Grosbach 425b0708d292bbe04cfcfe0c5cb5e27d8a872c9839aJim Grosbach // Q registers are encoded as 2x their register number. 4260800ce71896ccd7f49b37861a8cfbc21b6b10022Bill Wendling switch (Reg) { 4270800ce71896ccd7f49b37861a8cfbc21b6b10022Bill Wendling default: 4280800ce71896ccd7f49b37861a8cfbc21b6b10022Bill Wendling return RegNo; 4290800ce71896ccd7f49b37861a8cfbc21b6b10022Bill Wendling case ARM::Q0: case ARM::Q1: case ARM::Q2: case ARM::Q3: 4300800ce71896ccd7f49b37861a8cfbc21b6b10022Bill Wendling case ARM::Q4: case ARM::Q5: case ARM::Q6: case ARM::Q7: 4310800ce71896ccd7f49b37861a8cfbc21b6b10022Bill Wendling case ARM::Q8: case ARM::Q9: case ARM::Q10: case ARM::Q11: 4320800ce71896ccd7f49b37861a8cfbc21b6b10022Bill Wendling case ARM::Q12: case ARM::Q13: case ARM::Q14: case ARM::Q15: 4330800ce71896ccd7f49b37861a8cfbc21b6b10022Bill Wendling return 2 * RegNo; 43490d4cf931477b497553a9f2d0ed53377dd5dd88cOwen Anderson } 435bbbdcd453d22258cb4dd217eddf016668fcebf84Bill Wendling } else if (MO.isImm()) { 43656ac907c57fcfddfd650238f03c856a9d55987e5Jim Grosbach return static_cast<unsigned>(MO.getImm()); 437bbbdcd453d22258cb4dd217eddf016668fcebf84Bill Wendling } else if (MO.isFPImm()) { 438bbbdcd453d22258cb4dd217eddf016668fcebf84Bill Wendling return static_cast<unsigned>(APFloat(MO.getFPImm()) 439bbbdcd453d22258cb4dd217eddf016668fcebf84Bill Wendling .bitcastToAPInt().getHiBits(32).getLimitedValue()); 4400800ce71896ccd7f49b37861a8cfbc21b6b10022Bill Wendling } 4410800ce71896ccd7f49b37861a8cfbc21b6b10022Bill Wendling 442817c1a6dddadb4664738777d224bc7eae6e62cf3Jim Grosbach llvm_unreachable("Unable to encode MCOperand!"); 44356ac907c57fcfddfd650238f03c856a9d55987e5Jim Grosbach} 44456ac907c57fcfddfd650238f03c856a9d55987e5Jim Grosbach 4455df0e0a61d6ac0e8dcf1a600bdc28d3e4a8db0adBill Wendling/// getAddrModeImmOpValue - Return encoding info for 'reg +/- imm' operand. 446806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbachbool ARMMCCodeEmitter:: 447806e80ef42bdb416f409142a1ff1d4e8752baac8Jim GrosbachEncodeAddrModeOpValues(const MCInst &MI, unsigned OpIdx, unsigned &Reg, 448806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbach unsigned &Imm, SmallVectorImpl<MCFixup> &Fixups) const { 4493e5561247202bae994dd259a2d8dc4eff8f799f3Jim Grosbach const MCOperand &MO = MI.getOperand(OpIdx); 4503e5561247202bae994dd259a2d8dc4eff8f799f3Jim Grosbach const MCOperand &MO1 = MI.getOperand(OpIdx + 1); 4519af3d1c0dc2250793ada1ca6cfa98e9f1253f7f9Jim Grosbach 45299cb622041a0839c7dfcf0263c5102a305a0fdb5Bill Wendling Reg = CTX.getRegisterInfo()->getEncodingValue(MO.getReg()); 45392b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling 45492b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling int32_t SImm = MO1.getImm(); 45592b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling bool isAdd = true; 4565df0e0a61d6ac0e8dcf1a600bdc28d3e4a8db0adBill Wendling 457ab682a2090f795d0b67f29889622da0a74cd97c3Jim Grosbach // Special value for #-0 4580da10cf44d0f22111dae728bb535ade2283d976bOwen Anderson if (SImm == INT32_MIN) { 45992b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling SImm = 0; 4600da10cf44d0f22111dae728bb535ade2283d976bOwen Anderson isAdd = false; 4610da10cf44d0f22111dae728bb535ade2283d976bOwen Anderson } 4625df0e0a61d6ac0e8dcf1a600bdc28d3e4a8db0adBill Wendling 463ab682a2090f795d0b67f29889622da0a74cd97c3Jim Grosbach // Immediate is always encoded as positive. The 'U' bit controls add vs sub. 46492b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling if (SImm < 0) { 46592b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling SImm = -SImm; 46692b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling isAdd = false; 46792b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling } 46892b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling 46992b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling Imm = SImm; 47092b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling return isAdd; 47192b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling} 4725df0e0a61d6ac0e8dcf1a600bdc28d3e4a8db0adBill Wendling 473dff2f7151f695b86db8c4b0c6604463bdb8a63eaBill Wendling/// getBranchTargetOpValue - Helper function to get the branch target operand, 474dff2f7151f695b86db8c4b0c6604463bdb8a63eaBill Wendling/// which is either an immediate or requires a fixup. 475dff2f7151f695b86db8c4b0c6604463bdb8a63eaBill Wendlingstatic uint32_t getBranchTargetOpValue(const MCInst &MI, unsigned OpIdx, 476dff2f7151f695b86db8c4b0c6604463bdb8a63eaBill Wendling unsigned FixupKind, 477dff2f7151f695b86db8c4b0c6604463bdb8a63eaBill Wendling SmallVectorImpl<MCFixup> &Fixups) { 478662a816e89a9d77bf75e1328b09cf9235b4682aaJim Grosbach const MCOperand &MO = MI.getOperand(OpIdx); 479662a816e89a9d77bf75e1328b09cf9235b4682aaJim Grosbach 480662a816e89a9d77bf75e1328b09cf9235b4682aaJim Grosbach // If the destination is an immediate, we have nothing to do. 481662a816e89a9d77bf75e1328b09cf9235b4682aaJim Grosbach if (MO.isImm()) return MO.getImm(); 482dff2f7151f695b86db8c4b0c6604463bdb8a63eaBill Wendling assert(MO.isExpr() && "Unexpected branch target type!"); 483662a816e89a9d77bf75e1328b09cf9235b4682aaJim Grosbach const MCExpr *Expr = MO.getExpr(); 484dff2f7151f695b86db8c4b0c6604463bdb8a63eaBill Wendling MCFixupKind Kind = MCFixupKind(FixupKind); 48542e6bd38e02e2e1c2cc50d2f12036c38c4ea3ab0Jim Grosbach Fixups.push_back(MCFixup::Create(0, Expr, Kind, MI.getLoc())); 486662a816e89a9d77bf75e1328b09cf9235b4682aaJim Grosbach 487662a816e89a9d77bf75e1328b09cf9235b4682aaJim Grosbach // All of the information is in the fixup. 488662a816e89a9d77bf75e1328b09cf9235b4682aaJim Grosbach return 0; 489662a816e89a9d77bf75e1328b09cf9235b4682aaJim Grosbach} 490662a816e89a9d77bf75e1328b09cf9235b4682aaJim Grosbach 491559c277aa9242dd5b32d2f2ccc353d938f886ee9Owen Anderson// Thumb BL and BLX use a strange offset encoding where bits 22 and 21 are 492559c277aa9242dd5b32d2f2ccc353d938f886ee9Owen Anderson// determined by negating them and XOR'ing them with bit 23. 493559c277aa9242dd5b32d2f2ccc353d938f886ee9Owen Andersonstatic int32_t encodeThumbBLOffset(int32_t offset) { 494559c277aa9242dd5b32d2f2ccc353d938f886ee9Owen Anderson offset >>= 1; 495559c277aa9242dd5b32d2f2ccc353d938f886ee9Owen Anderson uint32_t S = (offset & 0x800000) >> 23; 496559c277aa9242dd5b32d2f2ccc353d938f886ee9Owen Anderson uint32_t J1 = (offset & 0x400000) >> 22; 497559c277aa9242dd5b32d2f2ccc353d938f886ee9Owen Anderson uint32_t J2 = (offset & 0x200000) >> 21; 498559c277aa9242dd5b32d2f2ccc353d938f886ee9Owen Anderson J1 = (~J1 & 0x1); 499559c277aa9242dd5b32d2f2ccc353d938f886ee9Owen Anderson J2 = (~J2 & 0x1); 500559c277aa9242dd5b32d2f2ccc353d938f886ee9Owen Anderson J1 ^= S; 501559c277aa9242dd5b32d2f2ccc353d938f886ee9Owen Anderson J2 ^= S; 502559c277aa9242dd5b32d2f2ccc353d938f886ee9Owen Anderson 503559c277aa9242dd5b32d2f2ccc353d938f886ee9Owen Anderson offset &= ~0x600000; 504559c277aa9242dd5b32d2f2ccc353d938f886ee9Owen Anderson offset |= J1 << 22; 505559c277aa9242dd5b32d2f2ccc353d938f886ee9Owen Anderson offset |= J2 << 21; 506559c277aa9242dd5b32d2f2ccc353d938f886ee9Owen Anderson 507559c277aa9242dd5b32d2f2ccc353d938f886ee9Owen Anderson return offset; 508559c277aa9242dd5b32d2f2ccc353d938f886ee9Owen Anderson} 509559c277aa9242dd5b32d2f2ccc353d938f886ee9Owen Anderson 510dff2f7151f695b86db8c4b0c6604463bdb8a63eaBill Wendling/// getThumbBLTargetOpValue - Return encoding info for immediate branch target. 511c466b937dbdbaabeef0097fe340de1b8f49a3508Jim Grosbachuint32_t ARMMCCodeEmitter:: 512dff2f7151f695b86db8c4b0c6604463bdb8a63eaBill WendlinggetThumbBLTargetOpValue(const MCInst &MI, unsigned OpIdx, 513c466b937dbdbaabeef0097fe340de1b8f49a3508Jim Grosbach SmallVectorImpl<MCFixup> &Fixups) const { 514559c277aa9242dd5b32d2f2ccc353d938f886ee9Owen Anderson const MCOperand MO = MI.getOperand(OpIdx); 515559c277aa9242dd5b32d2f2ccc353d938f886ee9Owen Anderson if (MO.isExpr()) 516559c277aa9242dd5b32d2f2ccc353d938f886ee9Owen Anderson return ::getBranchTargetOpValue(MI, OpIdx, ARM::fixup_arm_thumb_bl, 517559c277aa9242dd5b32d2f2ccc353d938f886ee9Owen Anderson Fixups); 518559c277aa9242dd5b32d2f2ccc353d938f886ee9Owen Anderson return encodeThumbBLOffset(MO.getImm()); 519dff2f7151f695b86db8c4b0c6604463bdb8a63eaBill Wendling} 520c466b937dbdbaabeef0097fe340de1b8f49a3508Jim Grosbach 52109aa3f0ef35d9241c92439d74b8d5e9a81d814c2Bill Wendling/// getThumbBLXTargetOpValue - Return encoding info for Thumb immediate 52209aa3f0ef35d9241c92439d74b8d5e9a81d814c2Bill Wendling/// BLX branch target. 52309aa3f0ef35d9241c92439d74b8d5e9a81d814c2Bill Wendlinguint32_t ARMMCCodeEmitter:: 52409aa3f0ef35d9241c92439d74b8d5e9a81d814c2Bill WendlinggetThumbBLXTargetOpValue(const MCInst &MI, unsigned OpIdx, 52509aa3f0ef35d9241c92439d74b8d5e9a81d814c2Bill Wendling SmallVectorImpl<MCFixup> &Fixups) const { 526559c277aa9242dd5b32d2f2ccc353d938f886ee9Owen Anderson const MCOperand MO = MI.getOperand(OpIdx); 527559c277aa9242dd5b32d2f2ccc353d938f886ee9Owen Anderson if (MO.isExpr()) 528559c277aa9242dd5b32d2f2ccc353d938f886ee9Owen Anderson return ::getBranchTargetOpValue(MI, OpIdx, ARM::fixup_arm_thumb_blx, 529559c277aa9242dd5b32d2f2ccc353d938f886ee9Owen Anderson Fixups); 530559c277aa9242dd5b32d2f2ccc353d938f886ee9Owen Anderson return encodeThumbBLOffset(MO.getImm()); 53109aa3f0ef35d9241c92439d74b8d5e9a81d814c2Bill Wendling} 53209aa3f0ef35d9241c92439d74b8d5e9a81d814c2Bill Wendling 533e246717c3a36a913fd4200776ed621649bb2b624Jim Grosbach/// getThumbBRTargetOpValue - Return encoding info for Thumb branch target. 534e246717c3a36a913fd4200776ed621649bb2b624Jim Grosbachuint32_t ARMMCCodeEmitter:: 535e246717c3a36a913fd4200776ed621649bb2b624Jim GrosbachgetThumbBRTargetOpValue(const MCInst &MI, unsigned OpIdx, 536e246717c3a36a913fd4200776ed621649bb2b624Jim Grosbach SmallVectorImpl<MCFixup> &Fixups) const { 537391ac65377f2ad5e48a796e75120959e22430605Owen Anderson const MCOperand MO = MI.getOperand(OpIdx); 538391ac65377f2ad5e48a796e75120959e22430605Owen Anderson if (MO.isExpr()) 539559c277aa9242dd5b32d2f2ccc353d938f886ee9Owen Anderson return ::getBranchTargetOpValue(MI, OpIdx, ARM::fixup_arm_thumb_br, 540559c277aa9242dd5b32d2f2ccc353d938f886ee9Owen Anderson Fixups); 541391ac65377f2ad5e48a796e75120959e22430605Owen Anderson return (MO.getImm() >> 1); 542e246717c3a36a913fd4200776ed621649bb2b624Jim Grosbach} 543e246717c3a36a913fd4200776ed621649bb2b624Jim Grosbach 54401086451393ef33e82b6fad623989dd97dd70edfJim Grosbach/// getThumbBCCTargetOpValue - Return encoding info for Thumb branch target. 54501086451393ef33e82b6fad623989dd97dd70edfJim Grosbachuint32_t ARMMCCodeEmitter:: 54601086451393ef33e82b6fad623989dd97dd70edfJim GrosbachgetThumbBCCTargetOpValue(const MCInst &MI, unsigned OpIdx, 547e246717c3a36a913fd4200776ed621649bb2b624Jim Grosbach SmallVectorImpl<MCFixup> &Fixups) const { 548721cb1fde07423fd1905338d443172a8028ad634Owen Anderson const MCOperand MO = MI.getOperand(OpIdx); 549721cb1fde07423fd1905338d443172a8028ad634Owen Anderson if (MO.isExpr()) 550721cb1fde07423fd1905338d443172a8028ad634Owen Anderson return ::getBranchTargetOpValue(MI, OpIdx, ARM::fixup_arm_thumb_bcc, 551721cb1fde07423fd1905338d443172a8028ad634Owen Anderson Fixups); 552721cb1fde07423fd1905338d443172a8028ad634Owen Anderson return (MO.getImm() >> 1); 55301086451393ef33e82b6fad623989dd97dd70edfJim Grosbach} 55401086451393ef33e82b6fad623989dd97dd70edfJim Grosbach 555027d6e8d1ca04e4096fb3a27579b861d861466c5Jim Grosbach/// getThumbCBTargetOpValue - Return encoding info for Thumb branch target. 556dff2f7151f695b86db8c4b0c6604463bdb8a63eaBill Wendlinguint32_t ARMMCCodeEmitter:: 557027d6e8d1ca04e4096fb3a27579b861d861466c5Jim GrosbachgetThumbCBTargetOpValue(const MCInst &MI, unsigned OpIdx, 558dff2f7151f695b86db8c4b0c6604463bdb8a63eaBill Wendling SmallVectorImpl<MCFixup> &Fixups) const { 55921df36c57afc588c8073a070a47e3ba45fa87270Owen Anderson const MCOperand MO = MI.getOperand(OpIdx); 56021df36c57afc588c8073a070a47e3ba45fa87270Owen Anderson if (MO.isExpr()) 56121df36c57afc588c8073a070a47e3ba45fa87270Owen Anderson return ::getBranchTargetOpValue(MI, OpIdx, ARM::fixup_arm_thumb_cb, Fixups); 56221df36c57afc588c8073a070a47e3ba45fa87270Owen Anderson return (MO.getImm() >> 1); 563dff2f7151f695b86db8c4b0c6604463bdb8a63eaBill Wendling} 564c466b937dbdbaabeef0097fe340de1b8f49a3508Jim Grosbach 565685c350ae76b588e1f00c01a511fe8bd57f18394Jason W Kim/// Return true if this branch has a non-always predication 566685c350ae76b588e1f00c01a511fe8bd57f18394Jason W Kimstatic bool HasConditionalBranch(const MCInst &MI) { 567685c350ae76b588e1f00c01a511fe8bd57f18394Jason W Kim int NumOp = MI.getNumOperands(); 568685c350ae76b588e1f00c01a511fe8bd57f18394Jason W Kim if (NumOp >= 2) { 569685c350ae76b588e1f00c01a511fe8bd57f18394Jason W Kim for (int i = 0; i < NumOp-1; ++i) { 570685c350ae76b588e1f00c01a511fe8bd57f18394Jason W Kim const MCOperand &MCOp1 = MI.getOperand(i); 571685c350ae76b588e1f00c01a511fe8bd57f18394Jason W Kim const MCOperand &MCOp2 = MI.getOperand(i + 1); 57210096dbdef22a10a6a4444437c935ab428545525Owen Anderson if (MCOp1.isImm() && MCOp2.isReg() && 573685c350ae76b588e1f00c01a511fe8bd57f18394Jason W Kim (MCOp2.getReg() == 0 || MCOp2.getReg() == ARM::CPSR)) { 57410096dbdef22a10a6a4444437c935ab428545525Owen Anderson if (ARMCC::CondCodes(MCOp1.getImm()) != ARMCC::AL) 575685c350ae76b588e1f00c01a511fe8bd57f18394Jason W Kim return true; 576685c350ae76b588e1f00c01a511fe8bd57f18394Jason W Kim } 577685c350ae76b588e1f00c01a511fe8bd57f18394Jason W Kim } 578685c350ae76b588e1f00c01a511fe8bd57f18394Jason W Kim } 579685c350ae76b588e1f00c01a511fe8bd57f18394Jason W Kim return false; 580685c350ae76b588e1f00c01a511fe8bd57f18394Jason W Kim} 581685c350ae76b588e1f00c01a511fe8bd57f18394Jason W Kim 582dff2f7151f695b86db8c4b0c6604463bdb8a63eaBill Wendling/// getBranchTargetOpValue - Return encoding info for 24-bit immediate branch 583dff2f7151f695b86db8c4b0c6604463bdb8a63eaBill Wendling/// target. 584dff2f7151f695b86db8c4b0c6604463bdb8a63eaBill Wendlinguint32_t ARMMCCodeEmitter:: 585dff2f7151f695b86db8c4b0c6604463bdb8a63eaBill WendlinggetBranchTargetOpValue(const MCInst &MI, unsigned OpIdx, 586dff2f7151f695b86db8c4b0c6604463bdb8a63eaBill Wendling SmallVectorImpl<MCFixup> &Fixups) const { 587092e2cd5693114a4f1d93eb5b72f3e194de27236Jim Grosbach // FIXME: This really, really shouldn't use TargetMachine. We don't want 588092e2cd5693114a4f1d93eb5b72f3e194de27236Jim Grosbach // coupling between MC and TM anywhere we can help it. 58959ee62d2418df8db499eca1ae17f5900dc2dcbbaEvan Cheng if (isThumb2()) 590c266600bec4b5ba0ee93ffdfeaafcab8f1295145Owen Anderson return 591c266600bec4b5ba0ee93ffdfeaafcab8f1295145Owen Anderson ::getBranchTargetOpValue(MI, OpIdx, ARM::fixup_t2_condbranch, Fixups); 592685c350ae76b588e1f00c01a511fe8bd57f18394Jason W Kim return getARMBranchTargetOpValue(MI, OpIdx, Fixups); 593685c350ae76b588e1f00c01a511fe8bd57f18394Jason W Kim} 594685c350ae76b588e1f00c01a511fe8bd57f18394Jason W Kim 595685c350ae76b588e1f00c01a511fe8bd57f18394Jason W Kim/// getBranchTargetOpValue - Return encoding info for 24-bit immediate branch 596685c350ae76b588e1f00c01a511fe8bd57f18394Jason W Kim/// target. 597685c350ae76b588e1f00c01a511fe8bd57f18394Jason W Kimuint32_t ARMMCCodeEmitter:: 598685c350ae76b588e1f00c01a511fe8bd57f18394Jason W KimgetARMBranchTargetOpValue(const MCInst &MI, unsigned OpIdx, 599685c350ae76b588e1f00c01a511fe8bd57f18394Jason W Kim SmallVectorImpl<MCFixup> &Fixups) const { 600d7568e1c355f5e364eddafc15c6d5553559f32a5Owen Anderson const MCOperand MO = MI.getOperand(OpIdx); 601d7568e1c355f5e364eddafc15c6d5553559f32a5Owen Anderson if (MO.isExpr()) { 60210096dbdef22a10a6a4444437c935ab428545525Owen Anderson if (HasConditionalBranch(MI)) 603d7568e1c355f5e364eddafc15c6d5553559f32a5Owen Anderson return ::getBranchTargetOpValue(MI, OpIdx, 604d7568e1c355f5e364eddafc15c6d5553559f32a5Owen Anderson ARM::fixup_arm_condbranch, Fixups); 60510096dbdef22a10a6a4444437c935ab428545525Owen Anderson return ::getBranchTargetOpValue(MI, OpIdx, 606d7568e1c355f5e364eddafc15c6d5553559f32a5Owen Anderson ARM::fixup_arm_uncondbranch, Fixups); 607d7568e1c355f5e364eddafc15c6d5553559f32a5Owen Anderson } 608d7568e1c355f5e364eddafc15c6d5553559f32a5Owen Anderson 609d7568e1c355f5e364eddafc15c6d5553559f32a5Owen Anderson return MO.getImm() >> 2; 610c466b937dbdbaabeef0097fe340de1b8f49a3508Jim Grosbach} 611c466b937dbdbaabeef0097fe340de1b8f49a3508Jim Grosbach 612f1eab597b2316c6cfcabfcee98895fedb2071722Owen Andersonuint32_t ARMMCCodeEmitter:: 6137b25ecf6adbf3c4709c48033acfeb6ebbb4452abJim GrosbachgetARMBLTargetOpValue(const MCInst &MI, unsigned OpIdx, 6147b25ecf6adbf3c4709c48033acfeb6ebbb4452abJim Grosbach SmallVectorImpl<MCFixup> &Fixups) const { 6157b25ecf6adbf3c4709c48033acfeb6ebbb4452abJim Grosbach const MCOperand MO = MI.getOperand(OpIdx); 616cb0809b82b126e79b99755ae4fc3d9733faea038James Molloy if (MO.isExpr()) { 617cb0809b82b126e79b99755ae4fc3d9733faea038James Molloy if (HasConditionalBranch(MI)) 618cb0809b82b126e79b99755ae4fc3d9733faea038James Molloy return ::getBranchTargetOpValue(MI, OpIdx, 619cb0809b82b126e79b99755ae4fc3d9733faea038James Molloy ARM::fixup_arm_condbl, Fixups); 620cb0809b82b126e79b99755ae4fc3d9733faea038James Molloy return ::getBranchTargetOpValue(MI, OpIdx, ARM::fixup_arm_uncondbl, Fixups); 621cb0809b82b126e79b99755ae4fc3d9733faea038James Molloy } 6227b25ecf6adbf3c4709c48033acfeb6ebbb4452abJim Grosbach 6237b25ecf6adbf3c4709c48033acfeb6ebbb4452abJim Grosbach return MO.getImm() >> 2; 6247b25ecf6adbf3c4709c48033acfeb6ebbb4452abJim Grosbach} 6257b25ecf6adbf3c4709c48033acfeb6ebbb4452abJim Grosbach 6267b25ecf6adbf3c4709c48033acfeb6ebbb4452abJim Grosbachuint32_t ARMMCCodeEmitter:: 627f1eab597b2316c6cfcabfcee98895fedb2071722Owen AndersongetARMBLXTargetOpValue(const MCInst &MI, unsigned OpIdx, 628f1eab597b2316c6cfcabfcee98895fedb2071722Owen Anderson SmallVectorImpl<MCFixup> &Fixups) const { 629f1eab597b2316c6cfcabfcee98895fedb2071722Owen Anderson const MCOperand MO = MI.getOperand(OpIdx); 6307b25ecf6adbf3c4709c48033acfeb6ebbb4452abJim Grosbach if (MO.isExpr()) 6317b25ecf6adbf3c4709c48033acfeb6ebbb4452abJim Grosbach return ::getBranchTargetOpValue(MI, OpIdx, ARM::fixup_arm_blx, Fixups); 632685c350ae76b588e1f00c01a511fe8bd57f18394Jason W Kim 633f1eab597b2316c6cfcabfcee98895fedb2071722Owen Anderson return MO.getImm() >> 1; 634f1eab597b2316c6cfcabfcee98895fedb2071722Owen Anderson} 635685c350ae76b588e1f00c01a511fe8bd57f18394Jason W Kim 636c266600bec4b5ba0ee93ffdfeaafcab8f1295145Owen Anderson/// getUnconditionalBranchTargetOpValue - Return encoding info for 24-bit 637c266600bec4b5ba0ee93ffdfeaafcab8f1295145Owen Anderson/// immediate branch target. 638c266600bec4b5ba0ee93ffdfeaafcab8f1295145Owen Andersonuint32_t ARMMCCodeEmitter:: 639c266600bec4b5ba0ee93ffdfeaafcab8f1295145Owen AndersongetUnconditionalBranchTargetOpValue(const MCInst &MI, unsigned OpIdx, 640c266600bec4b5ba0ee93ffdfeaafcab8f1295145Owen Anderson SmallVectorImpl<MCFixup> &Fixups) const { 641c266600bec4b5ba0ee93ffdfeaafcab8f1295145Owen Anderson unsigned Val = 642c266600bec4b5ba0ee93ffdfeaafcab8f1295145Owen Anderson ::getBranchTargetOpValue(MI, OpIdx, ARM::fixup_t2_uncondbranch, Fixups); 643c266600bec4b5ba0ee93ffdfeaafcab8f1295145Owen Anderson bool I = (Val & 0x800000); 644c266600bec4b5ba0ee93ffdfeaafcab8f1295145Owen Anderson bool J1 = (Val & 0x400000); 645c266600bec4b5ba0ee93ffdfeaafcab8f1295145Owen Anderson bool J2 = (Val & 0x200000); 646c266600bec4b5ba0ee93ffdfeaafcab8f1295145Owen Anderson if (I ^ J1) 647c266600bec4b5ba0ee93ffdfeaafcab8f1295145Owen Anderson Val &= ~0x400000; 648c266600bec4b5ba0ee93ffdfeaafcab8f1295145Owen Anderson else 649c266600bec4b5ba0ee93ffdfeaafcab8f1295145Owen Anderson Val |= 0x400000; 650971b83b67a9812556cdb97bb58aa96fb37af458dOwen Anderson 651c266600bec4b5ba0ee93ffdfeaafcab8f1295145Owen Anderson if (I ^ J2) 652c266600bec4b5ba0ee93ffdfeaafcab8f1295145Owen Anderson Val &= ~0x200000; 653c266600bec4b5ba0ee93ffdfeaafcab8f1295145Owen Anderson else 654c266600bec4b5ba0ee93ffdfeaafcab8f1295145Owen Anderson Val |= 0x200000; 655971b83b67a9812556cdb97bb58aa96fb37af458dOwen Anderson 656c266600bec4b5ba0ee93ffdfeaafcab8f1295145Owen Anderson return Val; 657c266600bec4b5ba0ee93ffdfeaafcab8f1295145Owen Anderson} 658c266600bec4b5ba0ee93ffdfeaafcab8f1295145Owen Anderson 6591fb27eccf5b7eabde9678d84411eb1df8a693683Jiangning Liu/// getAdrLabelOpValue - Return encoding info for 12-bit shifted-immediate 6601fb27eccf5b7eabde9678d84411eb1df8a693683Jiangning Liu/// ADR label target. 6615d14f9be7ba64162c7b996f36d419b11d8cdbe9aJim Grosbachuint32_t ARMMCCodeEmitter:: 6625d14f9be7ba64162c7b996f36d419b11d8cdbe9aJim GrosbachgetAdrLabelOpValue(const MCInst &MI, unsigned OpIdx, 6635d14f9be7ba64162c7b996f36d419b11d8cdbe9aJim Grosbach SmallVectorImpl<MCFixup> &Fixups) const { 66496425c846494c1c20a4c931f4783571295ab170cOwen Anderson const MCOperand MO = MI.getOperand(OpIdx); 66596425c846494c1c20a4c931f4783571295ab170cOwen Anderson if (MO.isExpr()) 66696425c846494c1c20a4c931f4783571295ab170cOwen Anderson return ::getBranchTargetOpValue(MI, OpIdx, ARM::fixup_arm_adr_pcrel_12, 66796425c846494c1c20a4c931f4783571295ab170cOwen Anderson Fixups); 66896425c846494c1c20a4c931f4783571295ab170cOwen Anderson int32_t offset = MO.getImm(); 66996425c846494c1c20a4c931f4783571295ab170cOwen Anderson uint32_t Val = 0x2000; 6701fb27eccf5b7eabde9678d84411eb1df8a693683Jiangning Liu 671d65dfd83421f4d26e6dc20476718d7d9b6ba3f3bTim Northover int SoImmVal; 6721fb27eccf5b7eabde9678d84411eb1df8a693683Jiangning Liu if (offset == INT32_MIN) { 6731fb27eccf5b7eabde9678d84411eb1df8a693683Jiangning Liu Val = 0x1000; 674d65dfd83421f4d26e6dc20476718d7d9b6ba3f3bTim Northover SoImmVal = 0; 6751fb27eccf5b7eabde9678d84411eb1df8a693683Jiangning Liu } else if (offset < 0) { 67696425c846494c1c20a4c931f4783571295ab170cOwen Anderson Val = 0x1000; 67796425c846494c1c20a4c931f4783571295ab170cOwen Anderson offset *= -1; 678d65dfd83421f4d26e6dc20476718d7d9b6ba3f3bTim Northover SoImmVal = ARM_AM::getSOImmVal(offset); 679d65dfd83421f4d26e6dc20476718d7d9b6ba3f3bTim Northover if(SoImmVal == -1) { 680d65dfd83421f4d26e6dc20476718d7d9b6ba3f3bTim Northover Val = 0x2000; 681d65dfd83421f4d26e6dc20476718d7d9b6ba3f3bTim Northover offset *= -1; 682d65dfd83421f4d26e6dc20476718d7d9b6ba3f3bTim Northover SoImmVal = ARM_AM::getSOImmVal(offset); 683d65dfd83421f4d26e6dc20476718d7d9b6ba3f3bTim Northover } 684d65dfd83421f4d26e6dc20476718d7d9b6ba3f3bTim Northover } else { 685d65dfd83421f4d26e6dc20476718d7d9b6ba3f3bTim Northover SoImmVal = ARM_AM::getSOImmVal(offset); 686d65dfd83421f4d26e6dc20476718d7d9b6ba3f3bTim Northover if(SoImmVal == -1) { 687d65dfd83421f4d26e6dc20476718d7d9b6ba3f3bTim Northover Val = 0x1000; 688d65dfd83421f4d26e6dc20476718d7d9b6ba3f3bTim Northover offset *= -1; 689d65dfd83421f4d26e6dc20476718d7d9b6ba3f3bTim Northover SoImmVal = ARM_AM::getSOImmVal(offset); 690d65dfd83421f4d26e6dc20476718d7d9b6ba3f3bTim Northover } 69196425c846494c1c20a4c931f4783571295ab170cOwen Anderson } 6921fb27eccf5b7eabde9678d84411eb1df8a693683Jiangning Liu 6931fb27eccf5b7eabde9678d84411eb1df8a693683Jiangning Liu assert(SoImmVal != -1 && "Not a valid so_imm value!"); 6941fb27eccf5b7eabde9678d84411eb1df8a693683Jiangning Liu 6951fb27eccf5b7eabde9678d84411eb1df8a693683Jiangning Liu Val |= SoImmVal; 69696425c846494c1c20a4c931f4783571295ab170cOwen Anderson return Val; 6975d14f9be7ba64162c7b996f36d419b11d8cdbe9aJim Grosbach} 6985d14f9be7ba64162c7b996f36d419b11d8cdbe9aJim Grosbach 6991fb27eccf5b7eabde9678d84411eb1df8a693683Jiangning Liu/// getT2AdrLabelOpValue - Return encoding info for 12-bit immediate ADR label 700a838a25d59838adfa91463f6a918ae3adeb352c1Owen Anderson/// target. 701a838a25d59838adfa91463f6a918ae3adeb352c1Owen Andersonuint32_t ARMMCCodeEmitter:: 702a838a25d59838adfa91463f6a918ae3adeb352c1Owen AndersongetT2AdrLabelOpValue(const MCInst &MI, unsigned OpIdx, 703a838a25d59838adfa91463f6a918ae3adeb352c1Owen Anderson SmallVectorImpl<MCFixup> &Fixups) const { 70496425c846494c1c20a4c931f4783571295ab170cOwen Anderson const MCOperand MO = MI.getOperand(OpIdx); 70596425c846494c1c20a4c931f4783571295ab170cOwen Anderson if (MO.isExpr()) 70696425c846494c1c20a4c931f4783571295ab170cOwen Anderson return ::getBranchTargetOpValue(MI, OpIdx, ARM::fixup_t2_adr_pcrel_12, 70796425c846494c1c20a4c931f4783571295ab170cOwen Anderson Fixups); 70808fef885eb39339a47e3be7f0842b1db33683003Owen Anderson int32_t Val = MO.getImm(); 7091fb27eccf5b7eabde9678d84411eb1df8a693683Jiangning Liu if (Val == INT32_MIN) 7101fb27eccf5b7eabde9678d84411eb1df8a693683Jiangning Liu Val = 0x1000; 7111fb27eccf5b7eabde9678d84411eb1df8a693683Jiangning Liu else if (Val < 0) { 71208fef885eb39339a47e3be7f0842b1db33683003Owen Anderson Val *= -1; 71308fef885eb39339a47e3be7f0842b1db33683003Owen Anderson Val |= 0x1000; 71408fef885eb39339a47e3be7f0842b1db33683003Owen Anderson } 71508fef885eb39339a47e3be7f0842b1db33683003Owen Anderson return Val; 716a838a25d59838adfa91463f6a918ae3adeb352c1Owen Anderson} 717a838a25d59838adfa91463f6a918ae3adeb352c1Owen Anderson 7181fb27eccf5b7eabde9678d84411eb1df8a693683Jiangning Liu/// getThumbAdrLabelOpValue - Return encoding info for 8-bit immediate ADR label 719d40963c4065432ec7e47879d3ca665a54ee903b6Jim Grosbach/// target. 720d40963c4065432ec7e47879d3ca665a54ee903b6Jim Grosbachuint32_t ARMMCCodeEmitter:: 721d40963c4065432ec7e47879d3ca665a54ee903b6Jim GrosbachgetThumbAdrLabelOpValue(const MCInst &MI, unsigned OpIdx, 722d40963c4065432ec7e47879d3ca665a54ee903b6Jim Grosbach SmallVectorImpl<MCFixup> &Fixups) const { 72396425c846494c1c20a4c931f4783571295ab170cOwen Anderson const MCOperand MO = MI.getOperand(OpIdx); 72496425c846494c1c20a4c931f4783571295ab170cOwen Anderson if (MO.isExpr()) 72596425c846494c1c20a4c931f4783571295ab170cOwen Anderson return ::getBranchTargetOpValue(MI, OpIdx, ARM::fixup_thumb_adr_pcrel_10, 72696425c846494c1c20a4c931f4783571295ab170cOwen Anderson Fixups); 72796425c846494c1c20a4c931f4783571295ab170cOwen Anderson return MO.getImm(); 728d40963c4065432ec7e47879d3ca665a54ee903b6Jim Grosbach} 729d40963c4065432ec7e47879d3ca665a54ee903b6Jim Grosbach 730f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling/// getThumbAddrModeRegRegOpValue - Return encoding info for 'reg + reg' 731f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling/// operand. 7320f4b60d43a289671082deee3bd56a3a055afb16aOwen Andersonuint32_t ARMMCCodeEmitter:: 733f4caf69720d807573c50d41aa06bcec1c99bdbbdBill WendlinggetThumbAddrModeRegRegOpValue(const MCInst &MI, unsigned OpIdx, 734f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling SmallVectorImpl<MCFixup> &) const { 735f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling // [Rn, Rm] 736f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling // {5-3} = Rm 737f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling // {2-0} = Rn 7380f4b60d43a289671082deee3bd56a3a055afb16aOwen Anderson const MCOperand &MO1 = MI.getOperand(OpIdx); 739f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling const MCOperand &MO2 = MI.getOperand(OpIdx + 1); 74099cb622041a0839c7dfcf0263c5102a305a0fdb5Bill Wendling unsigned Rn = CTX.getRegisterInfo()->getEncodingValue(MO1.getReg()); 74199cb622041a0839c7dfcf0263c5102a305a0fdb5Bill Wendling unsigned Rm = CTX.getRegisterInfo()->getEncodingValue(MO2.getReg()); 7420f4b60d43a289671082deee3bd56a3a055afb16aOwen Anderson return (Rm << 3) | Rn; 7430f4b60d43a289671082deee3bd56a3a055afb16aOwen Anderson} 7440f4b60d43a289671082deee3bd56a3a055afb16aOwen Anderson 74592b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling/// getAddrModeImm12OpValue - Return encoding info for 'reg +/- imm12' operand. 746806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbachuint32_t ARMMCCodeEmitter:: 747806e80ef42bdb416f409142a1ff1d4e8752baac8Jim GrosbachgetAddrModeImm12OpValue(const MCInst &MI, unsigned OpIdx, 748806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbach SmallVectorImpl<MCFixup> &Fixups) const { 74992b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling // {17-13} = reg 75092b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling // {12} = (U)nsigned (add == '1', sub == '0') 75192b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling // {11-0} = imm12 75292b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling unsigned Reg, Imm12; 75370933266ae73c891d9d1c2f0de72ecd1db8f86dfJim Grosbach bool isAdd = true; 75470933266ae73c891d9d1c2f0de72ecd1db8f86dfJim Grosbach // If The first operand isn't a register, we have a label reference. 75570933266ae73c891d9d1c2f0de72ecd1db8f86dfJim Grosbach const MCOperand &MO = MI.getOperand(OpIdx); 756971b83b67a9812556cdb97bb58aa96fb37af458dOwen Anderson if (!MO.isReg()) { 75799cb622041a0839c7dfcf0263c5102a305a0fdb5Bill Wendling Reg = CTX.getRegisterInfo()->getEncodingValue(ARM::PC); // Rn is PC. 75870933266ae73c891d9d1c2f0de72ecd1db8f86dfJim Grosbach Imm12 = 0; 75970933266ae73c891d9d1c2f0de72ecd1db8f86dfJim Grosbach 760fd92d2e106acfbf13ed29b5d15f3a690cd8699b2Owen Anderson if (MO.isExpr()) { 761fd92d2e106acfbf13ed29b5d15f3a690cd8699b2Owen Anderson const MCExpr *Expr = MO.getExpr(); 762beb920fce6ccc89b4735f280f94cb8c227f4ef5eAmaury de la Vieuville isAdd = false ; // 'U' bit is set as part of the fixup. 763fd92d2e106acfbf13ed29b5d15f3a690cd8699b2Owen Anderson 764fd92d2e106acfbf13ed29b5d15f3a690cd8699b2Owen Anderson MCFixupKind Kind; 765fd92d2e106acfbf13ed29b5d15f3a690cd8699b2Owen Anderson if (isThumb2()) 766fd92d2e106acfbf13ed29b5d15f3a690cd8699b2Owen Anderson Kind = MCFixupKind(ARM::fixup_t2_ldst_pcrel_12); 767fd92d2e106acfbf13ed29b5d15f3a690cd8699b2Owen Anderson else 768fd92d2e106acfbf13ed29b5d15f3a690cd8699b2Owen Anderson Kind = MCFixupKind(ARM::fixup_arm_ldst_pcrel_12); 76942e6bd38e02e2e1c2cc50d2f12036c38c4ea3ab0Jim Grosbach Fixups.push_back(MCFixup::Create(0, Expr, Kind, MI.getLoc())); 770fd92d2e106acfbf13ed29b5d15f3a690cd8699b2Owen Anderson 771fd92d2e106acfbf13ed29b5d15f3a690cd8699b2Owen Anderson ++MCNumCPRelocations; 772fd92d2e106acfbf13ed29b5d15f3a690cd8699b2Owen Anderson } else { 773fd92d2e106acfbf13ed29b5d15f3a690cd8699b2Owen Anderson Reg = ARM::PC; 774fd92d2e106acfbf13ed29b5d15f3a690cd8699b2Owen Anderson int32_t Offset = MO.getImm(); 7750b4c6738868e11ba06047a406f79489cb1db8c5aJim Grosbach // FIXME: Handle #-0. 776fd92d2e106acfbf13ed29b5d15f3a690cd8699b2Owen Anderson if (Offset < 0) { 777fd92d2e106acfbf13ed29b5d15f3a690cd8699b2Owen Anderson Offset *= -1; 778fd92d2e106acfbf13ed29b5d15f3a690cd8699b2Owen Anderson isAdd = false; 779fd92d2e106acfbf13ed29b5d15f3a690cd8699b2Owen Anderson } 780fd92d2e106acfbf13ed29b5d15f3a690cd8699b2Owen Anderson Imm12 = Offset; 781fd92d2e106acfbf13ed29b5d15f3a690cd8699b2Owen Anderson } 78270933266ae73c891d9d1c2f0de72ecd1db8f86dfJim Grosbach } else 78370933266ae73c891d9d1c2f0de72ecd1db8f86dfJim Grosbach isAdd = EncodeAddrModeOpValues(MI, OpIdx, Reg, Imm12, Fixups); 78492b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling 78592b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling uint32_t Binary = Imm12 & 0xfff; 78692b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling // Immediate is always encoded as positive. The 'U' bit controls add vs sub. 787ab682a2090f795d0b67f29889622da0a74cd97c3Jim Grosbach if (isAdd) 78892b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling Binary |= (1 << 12); 78992b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling Binary |= (Reg << 13); 79092b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling return Binary; 79192b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling} 79292b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling 793a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach/// getT2Imm8s4OpValue - Return encoding info for 794a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach/// '+/- imm8<<2' operand. 795a77295db19527503d6b290e4f34f273d0a789365Jim Grosbachuint32_t ARMMCCodeEmitter:: 796a77295db19527503d6b290e4f34f273d0a789365Jim GrosbachgetT2Imm8s4OpValue(const MCInst &MI, unsigned OpIdx, 797a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach SmallVectorImpl<MCFixup> &Fixups) const { 798a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach // FIXME: The immediate operand should have already been encoded like this 799a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach // before ever getting here. The encoder method should just need to combine 800a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach // the MI operands for the register and the offset into a single 801a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach // representation for the complex operand in the .td file. This isn't just 802a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach // style, unfortunately. As-is, we can't represent the distinct encoding 803a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach // for #-0. 804a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach 805a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach // {8} = (U)nsigned (add == '1', sub == '0') 806a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach // {7-0} = imm8 807a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach int32_t Imm8 = MI.getOperand(OpIdx).getImm(); 808a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach bool isAdd = Imm8 >= 0; 809a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach 810a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach // Immediate is always encoded as positive. The 'U' bit controls add vs sub. 811a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach if (Imm8 < 0) 812aaf217953bef3b2cc0e0f26bf474616cc20cf7f0Richard Smith Imm8 = -(uint32_t)Imm8; 813a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach 814a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach // Scaled by 4. 815a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach Imm8 /= 4; 816a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach 817a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach uint32_t Binary = Imm8 & 0xff; 818a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach // Immediate is always encoded as positive. The 'U' bit controls add vs sub. 819a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach if (isAdd) 820a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach Binary |= (1 << 8); 821a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach return Binary; 822a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach} 823a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach 8249d63d90de5e57ad96f467b270544443a9284eb2bOwen Anderson/// getT2AddrModeImm8s4OpValue - Return encoding info for 8259d63d90de5e57ad96f467b270544443a9284eb2bOwen Anderson/// 'reg +/- imm8<<2' operand. 8269d63d90de5e57ad96f467b270544443a9284eb2bOwen Andersonuint32_t ARMMCCodeEmitter:: 8279d63d90de5e57ad96f467b270544443a9284eb2bOwen AndersongetT2AddrModeImm8s4OpValue(const MCInst &MI, unsigned OpIdx, 8289d63d90de5e57ad96f467b270544443a9284eb2bOwen Anderson SmallVectorImpl<MCFixup> &Fixups) const { 82990cc533fda9742f5c67203f97e69e5efd270c676Jim Grosbach // {12-9} = reg 83090cc533fda9742f5c67203f97e69e5efd270c676Jim Grosbach // {8} = (U)nsigned (add == '1', sub == '0') 83190cc533fda9742f5c67203f97e69e5efd270c676Jim Grosbach // {7-0} = imm8 8329d63d90de5e57ad96f467b270544443a9284eb2bOwen Anderson unsigned Reg, Imm8; 8339d63d90de5e57ad96f467b270544443a9284eb2bOwen Anderson bool isAdd = true; 8349d63d90de5e57ad96f467b270544443a9284eb2bOwen Anderson // If The first operand isn't a register, we have a label reference. 8359d63d90de5e57ad96f467b270544443a9284eb2bOwen Anderson const MCOperand &MO = MI.getOperand(OpIdx); 8369d63d90de5e57ad96f467b270544443a9284eb2bOwen Anderson if (!MO.isReg()) { 83799cb622041a0839c7dfcf0263c5102a305a0fdb5Bill Wendling Reg = CTX.getRegisterInfo()->getEncodingValue(ARM::PC); // Rn is PC. 8389d63d90de5e57ad96f467b270544443a9284eb2bOwen Anderson Imm8 = 0; 8399d63d90de5e57ad96f467b270544443a9284eb2bOwen Anderson isAdd = false ; // 'U' bit is set as part of the fixup. 8409d63d90de5e57ad96f467b270544443a9284eb2bOwen Anderson 8419d63d90de5e57ad96f467b270544443a9284eb2bOwen Anderson assert(MO.isExpr() && "Unexpected machine operand type!"); 8429d63d90de5e57ad96f467b270544443a9284eb2bOwen Anderson const MCExpr *Expr = MO.getExpr(); 8432f196747f15240691bd4e622f7995edfedf90f61Jim Grosbach MCFixupKind Kind = MCFixupKind(ARM::fixup_t2_pcrel_10); 84442e6bd38e02e2e1c2cc50d2f12036c38c4ea3ab0Jim Grosbach Fixups.push_back(MCFixup::Create(0, Expr, Kind, MI.getLoc())); 8459d63d90de5e57ad96f467b270544443a9284eb2bOwen Anderson 8469d63d90de5e57ad96f467b270544443a9284eb2bOwen Anderson ++MCNumCPRelocations; 8479d63d90de5e57ad96f467b270544443a9284eb2bOwen Anderson } else 8489d63d90de5e57ad96f467b270544443a9284eb2bOwen Anderson isAdd = EncodeAddrModeOpValues(MI, OpIdx, Reg, Imm8, Fixups); 8499d63d90de5e57ad96f467b270544443a9284eb2bOwen Anderson 850a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach // FIXME: The immediate operand should have already been encoded like this 851a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach // before ever getting here. The encoder method should just need to combine 852a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach // the MI operands for the register and the offset into a single 853a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach // representation for the complex operand in the .td file. This isn't just 854a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach // style, unfortunately. As-is, we can't represent the distinct encoding 855a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach // for #-0. 8569d63d90de5e57ad96f467b270544443a9284eb2bOwen Anderson uint32_t Binary = (Imm8 >> 2) & 0xff; 8579d63d90de5e57ad96f467b270544443a9284eb2bOwen Anderson // Immediate is always encoded as positive. The 'U' bit controls add vs sub. 8589d63d90de5e57ad96f467b270544443a9284eb2bOwen Anderson if (isAdd) 85990cc533fda9742f5c67203f97e69e5efd270c676Jim Grosbach Binary |= (1 << 8); 8609d63d90de5e57ad96f467b270544443a9284eb2bOwen Anderson Binary |= (Reg << 9); 8619d63d90de5e57ad96f467b270544443a9284eb2bOwen Anderson return Binary; 8629d63d90de5e57ad96f467b270544443a9284eb2bOwen Anderson} 8639d63d90de5e57ad96f467b270544443a9284eb2bOwen Anderson 864b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach/// getT2AddrModeImm0_1020s4OpValue - Return encoding info for 865b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach/// 'reg + imm8<<2' operand. 866b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbachuint32_t ARMMCCodeEmitter:: 867b6aed508e310e31dcb080e761ca856127cec0773Jim GrosbachgetT2AddrModeImm0_1020s4OpValue(const MCInst &MI, unsigned OpIdx, 868b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach SmallVectorImpl<MCFixup> &Fixups) const { 869b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach // {11-8} = reg 870b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach // {7-0} = imm8 871b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach const MCOperand &MO = MI.getOperand(OpIdx); 872b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach const MCOperand &MO1 = MI.getOperand(OpIdx + 1); 87399cb622041a0839c7dfcf0263c5102a305a0fdb5Bill Wendling unsigned Reg = CTX.getRegisterInfo()->getEncodingValue(MO.getReg()); 874b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach unsigned Imm8 = MO1.getImm(); 875b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach return (Reg << 8) | Imm8; 876b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach} 877b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach 87886a97f2e4d0cde5e992f52ac287da0de687e0110Jason W Kim// FIXME: This routine assumes that a binary 87986a97f2e4d0cde5e992f52ac287da0de687e0110Jason W Kim// expression will always result in a PCRel expression 88086a97f2e4d0cde5e992f52ac287da0de687e0110Jason W Kim// In reality, its only true if one or more subexpressions 88186a97f2e4d0cde5e992f52ac287da0de687e0110Jason W Kim// is itself a PCRel (i.e. "." in asm or some other pcrel construct) 88286a97f2e4d0cde5e992f52ac287da0de687e0110Jason W Kim// but this is good enough for now. 88386a97f2e4d0cde5e992f52ac287da0de687e0110Jason W Kimstatic bool EvaluateAsPCRel(const MCExpr *Expr) { 88486a97f2e4d0cde5e992f52ac287da0de687e0110Jason W Kim switch (Expr->getKind()) { 885bc2198133a1836598b54b943420748e75d5dea94Craig Topper default: llvm_unreachable("Unexpected expression type"); 88686a97f2e4d0cde5e992f52ac287da0de687e0110Jason W Kim case MCExpr::SymbolRef: return false; 88786a97f2e4d0cde5e992f52ac287da0de687e0110Jason W Kim case MCExpr::Binary: return true; 88886a97f2e4d0cde5e992f52ac287da0de687e0110Jason W Kim } 88986a97f2e4d0cde5e992f52ac287da0de687e0110Jason W Kim} 89086a97f2e4d0cde5e992f52ac287da0de687e0110Jason W Kim 8917597212abced110723f2fee985a7d60557c092ecEvan Chenguint32_t 8927597212abced110723f2fee985a7d60557c092ecEvan ChengARMMCCodeEmitter::getHiLo16ImmOpValue(const MCInst &MI, unsigned OpIdx, 8937597212abced110723f2fee985a7d60557c092ecEvan Cheng SmallVectorImpl<MCFixup> &Fixups) const { 894837caa9313e1f9480721f232f89f5c7b1b9c9d09Jason W Kim // {20-16} = imm{15-12} 895837caa9313e1f9480721f232f89f5c7b1b9c9d09Jason W Kim // {11-0} = imm{11-0} 8967bf4c02789f97e32225fc248dff6622b994a15eeJim Grosbach const MCOperand &MO = MI.getOperand(OpIdx); 8977597212abced110723f2fee985a7d60557c092ecEvan Cheng if (MO.isImm()) 8987597212abced110723f2fee985a7d60557c092ecEvan Cheng // Hi / lo 16 bits already extracted during earlier passes. 899837caa9313e1f9480721f232f89f5c7b1b9c9d09Jason W Kim return static_cast<unsigned>(MO.getImm()); 9007597212abced110723f2fee985a7d60557c092ecEvan Cheng 9017597212abced110723f2fee985a7d60557c092ecEvan Cheng // Handle :upper16: and :lower16: assembly prefixes. 9027597212abced110723f2fee985a7d60557c092ecEvan Cheng const MCExpr *E = MO.getExpr(); 90394b590f8faf4dbba406f263e6a839882b0c68a94Jim Grosbach MCFixupKind Kind; 9047597212abced110723f2fee985a7d60557c092ecEvan Cheng if (E->getKind() == MCExpr::Target) { 9057597212abced110723f2fee985a7d60557c092ecEvan Cheng const ARMMCExpr *ARM16Expr = cast<ARMMCExpr>(E); 9067597212abced110723f2fee985a7d60557c092ecEvan Cheng E = ARM16Expr->getSubExpr(); 9077597212abced110723f2fee985a7d60557c092ecEvan Cheng 9087597212abced110723f2fee985a7d60557c092ecEvan Cheng switch (ARM16Expr->getKind()) { 909bc2198133a1836598b54b943420748e75d5dea94Craig Topper default: llvm_unreachable("Unsupported ARMFixup"); 9107597212abced110723f2fee985a7d60557c092ecEvan Cheng case ARMMCExpr::VK_ARM_HI16: 91159ee62d2418df8db499eca1ae17f5900dc2dcbbaEvan Cheng if (!isTargetDarwin() && EvaluateAsPCRel(E)) 91259ee62d2418df8db499eca1ae17f5900dc2dcbbaEvan Cheng Kind = MCFixupKind(isThumb2() 913f3eb3bba1614a7935b44fc963a805088d71267f3Evan Cheng ? ARM::fixup_t2_movt_hi16_pcrel 914f3eb3bba1614a7935b44fc963a805088d71267f3Evan Cheng : ARM::fixup_arm_movt_hi16_pcrel); 915f3eb3bba1614a7935b44fc963a805088d71267f3Evan Cheng else 91659ee62d2418df8db499eca1ae17f5900dc2dcbbaEvan Cheng Kind = MCFixupKind(isThumb2() 917f3eb3bba1614a7935b44fc963a805088d71267f3Evan Cheng ? ARM::fixup_t2_movt_hi16 918f3eb3bba1614a7935b44fc963a805088d71267f3Evan Cheng : ARM::fixup_arm_movt_hi16); 919837caa9313e1f9480721f232f89f5c7b1b9c9d09Jason W Kim break; 9207597212abced110723f2fee985a7d60557c092ecEvan Cheng case ARMMCExpr::VK_ARM_LO16: 92159ee62d2418df8db499eca1ae17f5900dc2dcbbaEvan Cheng if (!isTargetDarwin() && EvaluateAsPCRel(E)) 92259ee62d2418df8db499eca1ae17f5900dc2dcbbaEvan Cheng Kind = MCFixupKind(isThumb2() 923f3eb3bba1614a7935b44fc963a805088d71267f3Evan Cheng ? ARM::fixup_t2_movw_lo16_pcrel 924f3eb3bba1614a7935b44fc963a805088d71267f3Evan Cheng : ARM::fixup_arm_movw_lo16_pcrel); 925f3eb3bba1614a7935b44fc963a805088d71267f3Evan Cheng else 92659ee62d2418df8db499eca1ae17f5900dc2dcbbaEvan Cheng Kind = MCFixupKind(isThumb2() 927f3eb3bba1614a7935b44fc963a805088d71267f3Evan Cheng ? ARM::fixup_t2_movw_lo16 928f3eb3bba1614a7935b44fc963a805088d71267f3Evan Cheng : ARM::fixup_arm_movw_lo16); 929837caa9313e1f9480721f232f89f5c7b1b9c9d09Jason W Kim break; 930837caa9313e1f9480721f232f89f5c7b1b9c9d09Jason W Kim } 93142e6bd38e02e2e1c2cc50d2f12036c38c4ea3ab0Jim Grosbach Fixups.push_back(MCFixup::Create(0, E, Kind, MI.getLoc())); 932837caa9313e1f9480721f232f89f5c7b1b9c9d09Jason W Kim return 0; 93394b590f8faf4dbba406f263e6a839882b0c68a94Jim Grosbach } 93494b590f8faf4dbba406f263e6a839882b0c68a94Jim Grosbach // If the expression doesn't have :upper16: or :lower16: on it, 93594b590f8faf4dbba406f263e6a839882b0c68a94Jim Grosbach // it's just a plain immediate expression, and those evaluate to 93694b590f8faf4dbba406f263e6a839882b0c68a94Jim Grosbach // the lower 16 bits of the expression regardless of whether 93794b590f8faf4dbba406f263e6a839882b0c68a94Jim Grosbach // we have a movt or a movw. 93894b590f8faf4dbba406f263e6a839882b0c68a94Jim Grosbach if (!isTargetDarwin() && EvaluateAsPCRel(E)) 93994b590f8faf4dbba406f263e6a839882b0c68a94Jim Grosbach Kind = MCFixupKind(isThumb2() 94094b590f8faf4dbba406f263e6a839882b0c68a94Jim Grosbach ? ARM::fixup_t2_movw_lo16_pcrel 94194b590f8faf4dbba406f263e6a839882b0c68a94Jim Grosbach : ARM::fixup_arm_movw_lo16_pcrel); 94294b590f8faf4dbba406f263e6a839882b0c68a94Jim Grosbach else 94394b590f8faf4dbba406f263e6a839882b0c68a94Jim Grosbach Kind = MCFixupKind(isThumb2() 94494b590f8faf4dbba406f263e6a839882b0c68a94Jim Grosbach ? ARM::fixup_t2_movw_lo16 94594b590f8faf4dbba406f263e6a839882b0c68a94Jim Grosbach : ARM::fixup_arm_movw_lo16); 94694b590f8faf4dbba406f263e6a839882b0c68a94Jim Grosbach Fixups.push_back(MCFixup::Create(0, E, Kind, MI.getLoc())); 94794b590f8faf4dbba406f263e6a839882b0c68a94Jim Grosbach return 0; 948837caa9313e1f9480721f232f89f5c7b1b9c9d09Jason W Kim} 949837caa9313e1f9480721f232f89f5c7b1b9c9d09Jason W Kim 950837caa9313e1f9480721f232f89f5c7b1b9c9d09Jason W Kimuint32_t ARMMCCodeEmitter:: 95154fea632b161f98e96ec7275922e35102bcecc5dJim GrosbachgetLdStSORegOpValue(const MCInst &MI, unsigned OpIdx, 95254fea632b161f98e96ec7275922e35102bcecc5dJim Grosbach SmallVectorImpl<MCFixup> &Fixups) const { 95354fea632b161f98e96ec7275922e35102bcecc5dJim Grosbach const MCOperand &MO = MI.getOperand(OpIdx); 95454fea632b161f98e96ec7275922e35102bcecc5dJim Grosbach const MCOperand &MO1 = MI.getOperand(OpIdx+1); 95554fea632b161f98e96ec7275922e35102bcecc5dJim Grosbach const MCOperand &MO2 = MI.getOperand(OpIdx+2); 95699cb622041a0839c7dfcf0263c5102a305a0fdb5Bill Wendling unsigned Rn = CTX.getRegisterInfo()->getEncodingValue(MO.getReg()); 95799cb622041a0839c7dfcf0263c5102a305a0fdb5Bill Wendling unsigned Rm = CTX.getRegisterInfo()->getEncodingValue(MO1.getReg()); 95854fea632b161f98e96ec7275922e35102bcecc5dJim Grosbach unsigned ShImm = ARM_AM::getAM2Offset(MO2.getImm()); 95954fea632b161f98e96ec7275922e35102bcecc5dJim Grosbach bool isAdd = ARM_AM::getAM2Op(MO2.getImm()) == ARM_AM::add; 96099f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach ARM_AM::ShiftOpc ShOp = ARM_AM::getAM2ShiftOpc(MO2.getImm()); 96199f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach unsigned SBits = getShiftOp(ShOp); 96254fea632b161f98e96ec7275922e35102bcecc5dJim Grosbach 96393c7c449a1351542fa5a275587187154dbedb8e0Tim Northover // While "lsr #32" and "asr #32" exist, they are encoded with a 0 in the shift 96493c7c449a1351542fa5a275587187154dbedb8e0Tim Northover // amount. However, it would be an easy mistake to make so check here. 96593c7c449a1351542fa5a275587187154dbedb8e0Tim Northover assert((ShImm & ~0x1f) == 0 && "Out of range shift amount"); 96693c7c449a1351542fa5a275587187154dbedb8e0Tim Northover 96754fea632b161f98e96ec7275922e35102bcecc5dJim Grosbach // {16-13} = Rn 96854fea632b161f98e96ec7275922e35102bcecc5dJim Grosbach // {12} = isAdd 96954fea632b161f98e96ec7275922e35102bcecc5dJim Grosbach // {11-0} = shifter 97054fea632b161f98e96ec7275922e35102bcecc5dJim Grosbach // {3-0} = Rm 97154fea632b161f98e96ec7275922e35102bcecc5dJim Grosbach // {4} = 0 97254fea632b161f98e96ec7275922e35102bcecc5dJim Grosbach // {6-5} = type 97354fea632b161f98e96ec7275922e35102bcecc5dJim Grosbach // {11-7} = imm 974570a9226913ebe1af04832b8fb3273c70b4ee152Jim Grosbach uint32_t Binary = Rm; 97554fea632b161f98e96ec7275922e35102bcecc5dJim Grosbach Binary |= Rn << 13; 97654fea632b161f98e96ec7275922e35102bcecc5dJim Grosbach Binary |= SBits << 5; 97754fea632b161f98e96ec7275922e35102bcecc5dJim Grosbach Binary |= ShImm << 7; 97854fea632b161f98e96ec7275922e35102bcecc5dJim Grosbach if (isAdd) 97954fea632b161f98e96ec7275922e35102bcecc5dJim Grosbach Binary |= 1 << 12; 98054fea632b161f98e96ec7275922e35102bcecc5dJim Grosbach return Binary; 98154fea632b161f98e96ec7275922e35102bcecc5dJim Grosbach} 98254fea632b161f98e96ec7275922e35102bcecc5dJim Grosbach 983570a9226913ebe1af04832b8fb3273c70b4ee152Jim Grosbachuint32_t ARMMCCodeEmitter:: 98499f53d13efc259b47c93dc0d90a5db763cbe371aJim GrosbachgetAddrMode2OpValue(const MCInst &MI, unsigned OpIdx, 98599f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach SmallVectorImpl<MCFixup> &Fixups) const { 98699f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach // {17-14} Rn 98799f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach // {13} 1 == imm12, 0 == Rm 98899f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach // {12} isAdd 98999f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach // {11-0} imm12/Rm 99099f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach const MCOperand &MO = MI.getOperand(OpIdx); 99199cb622041a0839c7dfcf0263c5102a305a0fdb5Bill Wendling unsigned Rn = CTX.getRegisterInfo()->getEncodingValue(MO.getReg()); 99299f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach uint32_t Binary = getAddrMode2OffsetOpValue(MI, OpIdx + 1, Fixups); 99399f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach Binary |= Rn << 14; 99499f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach return Binary; 99599f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach} 99699f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach 99799f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbachuint32_t ARMMCCodeEmitter:: 99899f53d13efc259b47c93dc0d90a5db763cbe371aJim GrosbachgetAddrMode2OffsetOpValue(const MCInst &MI, unsigned OpIdx, 99999f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach SmallVectorImpl<MCFixup> &Fixups) const { 100099f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach // {13} 1 == imm12, 0 == Rm 100199f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach // {12} isAdd 100299f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach // {11-0} imm12/Rm 100399f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach const MCOperand &MO = MI.getOperand(OpIdx); 100499f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach const MCOperand &MO1 = MI.getOperand(OpIdx+1); 100599f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach unsigned Imm = MO1.getImm(); 100699f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach bool isAdd = ARM_AM::getAM2Op(Imm) == ARM_AM::add; 100799f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach bool isReg = MO.getReg() != 0; 100899f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach uint32_t Binary = ARM_AM::getAM2Offset(Imm); 100999f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach // if reg +/- reg, Rm will be non-zero. Otherwise, we have reg +/- imm12 101099f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach if (isReg) { 101199f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach ARM_AM::ShiftOpc ShOp = ARM_AM::getAM2ShiftOpc(Imm); 101299f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach Binary <<= 7; // Shift amount is bits [11:7] 101399f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach Binary |= getShiftOp(ShOp) << 5; // Shift type is bits [6:5] 101499cb622041a0839c7dfcf0263c5102a305a0fdb5Bill Wendling Binary |= CTX.getRegisterInfo()->getEncodingValue(MO.getReg()); // Rm is bits [3:0] 101599f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach } 101699f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach return Binary | (isAdd << 12) | (isReg << 13); 101799f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach} 101899f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach 101999f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbachuint32_t ARMMCCodeEmitter:: 10207ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim GrosbachgetPostIdxRegOpValue(const MCInst &MI, unsigned OpIdx, 10217ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach SmallVectorImpl<MCFixup> &Fixups) const { 10227ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // {4} isAdd 10237ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // {3-0} Rm 10247ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach const MCOperand &MO = MI.getOperand(OpIdx); 10257ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach const MCOperand &MO1 = MI.getOperand(OpIdx+1); 102616578b50889329eb62774148091ba0f38b681a09Jim Grosbach bool isAdd = MO1.getImm() != 0; 102799cb622041a0839c7dfcf0263c5102a305a0fdb5Bill Wendling return CTX.getRegisterInfo()->getEncodingValue(MO.getReg()) | (isAdd << 4); 10287ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach} 10297ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach 10307ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbachuint32_t ARMMCCodeEmitter:: 10317eab97f260ba0f56d1d4a82f3a4eb2c979452011Jim GrosbachgetAddrMode3OffsetOpValue(const MCInst &MI, unsigned OpIdx, 10327eab97f260ba0f56d1d4a82f3a4eb2c979452011Jim Grosbach SmallVectorImpl<MCFixup> &Fixups) const { 10337eab97f260ba0f56d1d4a82f3a4eb2c979452011Jim Grosbach // {9} 1 == imm8, 0 == Rm 10347eab97f260ba0f56d1d4a82f3a4eb2c979452011Jim Grosbach // {8} isAdd 10357eab97f260ba0f56d1d4a82f3a4eb2c979452011Jim Grosbach // {7-4} imm7_4/zero 10367eab97f260ba0f56d1d4a82f3a4eb2c979452011Jim Grosbach // {3-0} imm3_0/Rm 10377eab97f260ba0f56d1d4a82f3a4eb2c979452011Jim Grosbach const MCOperand &MO = MI.getOperand(OpIdx); 10387eab97f260ba0f56d1d4a82f3a4eb2c979452011Jim Grosbach const MCOperand &MO1 = MI.getOperand(OpIdx+1); 10397eab97f260ba0f56d1d4a82f3a4eb2c979452011Jim Grosbach unsigned Imm = MO1.getImm(); 10407eab97f260ba0f56d1d4a82f3a4eb2c979452011Jim Grosbach bool isAdd = ARM_AM::getAM3Op(Imm) == ARM_AM::add; 10417eab97f260ba0f56d1d4a82f3a4eb2c979452011Jim Grosbach bool isImm = MO.getReg() == 0; 10427eab97f260ba0f56d1d4a82f3a4eb2c979452011Jim Grosbach uint32_t Imm8 = ARM_AM::getAM3Offset(Imm); 10437eab97f260ba0f56d1d4a82f3a4eb2c979452011Jim Grosbach // if reg +/- reg, Rm will be non-zero. Otherwise, we have reg +/- imm8 10447eab97f260ba0f56d1d4a82f3a4eb2c979452011Jim Grosbach if (!isImm) 104599cb622041a0839c7dfcf0263c5102a305a0fdb5Bill Wendling Imm8 = CTX.getRegisterInfo()->getEncodingValue(MO.getReg()); 10467eab97f260ba0f56d1d4a82f3a4eb2c979452011Jim Grosbach return Imm8 | (isAdd << 8) | (isImm << 9); 10477eab97f260ba0f56d1d4a82f3a4eb2c979452011Jim Grosbach} 10487eab97f260ba0f56d1d4a82f3a4eb2c979452011Jim Grosbach 10497eab97f260ba0f56d1d4a82f3a4eb2c979452011Jim Grosbachuint32_t ARMMCCodeEmitter:: 1050570a9226913ebe1af04832b8fb3273c70b4ee152Jim GrosbachgetAddrMode3OpValue(const MCInst &MI, unsigned OpIdx, 1051570a9226913ebe1af04832b8fb3273c70b4ee152Jim Grosbach SmallVectorImpl<MCFixup> &Fixups) const { 1052570a9226913ebe1af04832b8fb3273c70b4ee152Jim Grosbach // {13} 1 == imm8, 0 == Rm 1053570a9226913ebe1af04832b8fb3273c70b4ee152Jim Grosbach // {12-9} Rn 1054570a9226913ebe1af04832b8fb3273c70b4ee152Jim Grosbach // {8} isAdd 1055570a9226913ebe1af04832b8fb3273c70b4ee152Jim Grosbach // {7-4} imm7_4/zero 1056570a9226913ebe1af04832b8fb3273c70b4ee152Jim Grosbach // {3-0} imm3_0/Rm 1057570a9226913ebe1af04832b8fb3273c70b4ee152Jim Grosbach const MCOperand &MO = MI.getOperand(OpIdx); 1058570a9226913ebe1af04832b8fb3273c70b4ee152Jim Grosbach const MCOperand &MO1 = MI.getOperand(OpIdx+1); 1059570a9226913ebe1af04832b8fb3273c70b4ee152Jim Grosbach const MCOperand &MO2 = MI.getOperand(OpIdx+2); 10602f196747f15240691bd4e622f7995edfedf90f61Jim Grosbach 10612f196747f15240691bd4e622f7995edfedf90f61Jim Grosbach // If The first operand isn't a register, we have a label reference. 10622f196747f15240691bd4e622f7995edfedf90f61Jim Grosbach if (!MO.isReg()) { 106399cb622041a0839c7dfcf0263c5102a305a0fdb5Bill Wendling unsigned Rn = CTX.getRegisterInfo()->getEncodingValue(ARM::PC); // Rn is PC. 10642f196747f15240691bd4e622f7995edfedf90f61Jim Grosbach 10652f196747f15240691bd4e622f7995edfedf90f61Jim Grosbach assert(MO.isExpr() && "Unexpected machine operand type!"); 10662f196747f15240691bd4e622f7995edfedf90f61Jim Grosbach const MCExpr *Expr = MO.getExpr(); 10672f196747f15240691bd4e622f7995edfedf90f61Jim Grosbach MCFixupKind Kind = MCFixupKind(ARM::fixup_arm_pcrel_10_unscaled); 106842e6bd38e02e2e1c2cc50d2f12036c38c4ea3ab0Jim Grosbach Fixups.push_back(MCFixup::Create(0, Expr, Kind, MI.getLoc())); 10692f196747f15240691bd4e622f7995edfedf90f61Jim Grosbach 10702f196747f15240691bd4e622f7995edfedf90f61Jim Grosbach ++MCNumCPRelocations; 10712f196747f15240691bd4e622f7995edfedf90f61Jim Grosbach return (Rn << 9) | (1 << 13); 10722f196747f15240691bd4e622f7995edfedf90f61Jim Grosbach } 107399cb622041a0839c7dfcf0263c5102a305a0fdb5Bill Wendling unsigned Rn = CTX.getRegisterInfo()->getEncodingValue(MO.getReg()); 1074570a9226913ebe1af04832b8fb3273c70b4ee152Jim Grosbach unsigned Imm = MO2.getImm(); 1075570a9226913ebe1af04832b8fb3273c70b4ee152Jim Grosbach bool isAdd = ARM_AM::getAM3Op(Imm) == ARM_AM::add; 1076570a9226913ebe1af04832b8fb3273c70b4ee152Jim Grosbach bool isImm = MO1.getReg() == 0; 1077570a9226913ebe1af04832b8fb3273c70b4ee152Jim Grosbach uint32_t Imm8 = ARM_AM::getAM3Offset(Imm); 1078570a9226913ebe1af04832b8fb3273c70b4ee152Jim Grosbach // if reg +/- reg, Rm will be non-zero. Otherwise, we have reg +/- imm8 1079570a9226913ebe1af04832b8fb3273c70b4ee152Jim Grosbach if (!isImm) 108099cb622041a0839c7dfcf0263c5102a305a0fdb5Bill Wendling Imm8 = CTX.getRegisterInfo()->getEncodingValue(MO1.getReg()); 1081570a9226913ebe1af04832b8fb3273c70b4ee152Jim Grosbach return (Rn << 9) | Imm8 | (isAdd << 8) | (isImm << 13); 1082570a9226913ebe1af04832b8fb3273c70b4ee152Jim Grosbach} 1083570a9226913ebe1af04832b8fb3273c70b4ee152Jim Grosbach 1084b8958b031ec5163261f490f131780c5dc3d823d6Bill Wendling/// getAddrModeThumbSPOpValue - Encode the t_addrmode_sp operands. 1085d967cd096ae87accf2f1df86b2dfac969d9c9da2Jim Grosbachuint32_t ARMMCCodeEmitter:: 1086d967cd096ae87accf2f1df86b2dfac969d9c9da2Jim GrosbachgetAddrModeThumbSPOpValue(const MCInst &MI, unsigned OpIdx, 1087d967cd096ae87accf2f1df86b2dfac969d9c9da2Jim Grosbach SmallVectorImpl<MCFixup> &Fixups) const { 1088d967cd096ae87accf2f1df86b2dfac969d9c9da2Jim Grosbach // [SP, #imm] 1089d967cd096ae87accf2f1df86b2dfac969d9c9da2Jim Grosbach // {7-0} = imm8 1090d967cd096ae87accf2f1df86b2dfac969d9c9da2Jim Grosbach const MCOperand &MO1 = MI.getOperand(OpIdx + 1); 1091b8958b031ec5163261f490f131780c5dc3d823d6Bill Wendling assert(MI.getOperand(OpIdx).getReg() == ARM::SP && 1092b8958b031ec5163261f490f131780c5dc3d823d6Bill Wendling "Unexpected base register!"); 10937a905a82f7425d1a10b828c8bb3365b2ebc15833Bill Wendling 1094d967cd096ae87accf2f1df86b2dfac969d9c9da2Jim Grosbach // The immediate is already shifted for the implicit zeroes, so no change 1095d967cd096ae87accf2f1df86b2dfac969d9c9da2Jim Grosbach // here. 1096d967cd096ae87accf2f1df86b2dfac969d9c9da2Jim Grosbach return MO1.getImm() & 0xff; 1097d967cd096ae87accf2f1df86b2dfac969d9c9da2Jim Grosbach} 1098d967cd096ae87accf2f1df86b2dfac969d9c9da2Jim Grosbach 1099f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling/// getAddrModeISOpValue - Encode the t_addrmode_is# operands. 1100272df516d7a9b1f0f69174276abaa759816ee456Bill Wendlinguint32_t ARMMCCodeEmitter:: 1101f4caf69720d807573c50d41aa06bcec1c99bdbbdBill WendlinggetAddrModeISOpValue(const MCInst &MI, unsigned OpIdx, 110222447ae54bcb8ca94ed994cad103074a24e66781Bill Wendling SmallVectorImpl<MCFixup> &Fixups) const { 1103ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling // [Rn, #imm] 1104ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling // {7-3} = imm5 1105ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling // {2-0} = Rn 1106ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling const MCOperand &MO = MI.getOperand(OpIdx); 1107ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling const MCOperand &MO1 = MI.getOperand(OpIdx + 1); 110899cb622041a0839c7dfcf0263c5102a305a0fdb5Bill Wendling unsigned Rn = CTX.getRegisterInfo()->getEncodingValue(MO.getReg()); 1109656b3d22f70c2d1c8a5286f7270cb380df862565Matt Beaumont-Gay unsigned Imm5 = MO1.getImm(); 1110272df516d7a9b1f0f69174276abaa759816ee456Bill Wendling return ((Imm5 & 0x1f) << 3) | Rn; 11111fd374e9c1c074c1681336bef31e65f0170b0f7eBill Wendling} 11121fd374e9c1c074c1681336bef31e65f0170b0f7eBill Wendling 1113b8958b031ec5163261f490f131780c5dc3d823d6Bill Wendling/// getAddrModePCOpValue - Return encoding for t_addrmode_pc operands. 1114b8958b031ec5163261f490f131780c5dc3d823d6Bill Wendlinguint32_t ARMMCCodeEmitter:: 1115b8958b031ec5163261f490f131780c5dc3d823d6Bill WendlinggetAddrModePCOpValue(const MCInst &MI, unsigned OpIdx, 1116b8958b031ec5163261f490f131780c5dc3d823d6Bill Wendling SmallVectorImpl<MCFixup> &Fixups) const { 1117a7710edd98d71a81c43f8e3889cf0c790885d1b8Owen Anderson const MCOperand MO = MI.getOperand(OpIdx); 1118a7710edd98d71a81c43f8e3889cf0c790885d1b8Owen Anderson if (MO.isExpr()) 1119a7710edd98d71a81c43f8e3889cf0c790885d1b8Owen Anderson return ::getBranchTargetOpValue(MI, OpIdx, ARM::fixup_arm_thumb_cp, Fixups); 1120a7710edd98d71a81c43f8e3889cf0c790885d1b8Owen Anderson return (MO.getImm() >> 2); 1121b8958b031ec5163261f490f131780c5dc3d823d6Bill Wendling} 1122b8958b031ec5163261f490f131780c5dc3d823d6Bill Wendling 11235177f79c378b47e38bed5ac05ba4b597f31b864eJim Grosbach/// getAddrMode5OpValue - Return encoding info for 'reg +/- imm10' operand. 1124806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbachuint32_t ARMMCCodeEmitter:: 1125806e80ef42bdb416f409142a1ff1d4e8752baac8Jim GrosbachgetAddrMode5OpValue(const MCInst &MI, unsigned OpIdx, 1126806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbach SmallVectorImpl<MCFixup> &Fixups) const { 112792b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling // {12-9} = reg 112892b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling // {8} = (U)nsigned (add == '1', sub == '0') 112992b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling // {7-0} = imm8 113092b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling unsigned Reg, Imm8; 113197dd28fb89dc4c4caa3c60890335dc99489981a6Jim Grosbach bool isAdd; 113270933266ae73c891d9d1c2f0de72ecd1db8f86dfJim Grosbach // If The first operand isn't a register, we have a label reference. 113370933266ae73c891d9d1c2f0de72ecd1db8f86dfJim Grosbach const MCOperand &MO = MI.getOperand(OpIdx); 113470933266ae73c891d9d1c2f0de72ecd1db8f86dfJim Grosbach if (!MO.isReg()) { 113599cb622041a0839c7dfcf0263c5102a305a0fdb5Bill Wendling Reg = CTX.getRegisterInfo()->getEncodingValue(ARM::PC); // Rn is PC. 113670933266ae73c891d9d1c2f0de72ecd1db8f86dfJim Grosbach Imm8 = 0; 113797dd28fb89dc4c4caa3c60890335dc99489981a6Jim Grosbach isAdd = false; // 'U' bit is handled as part of the fixup. 113870933266ae73c891d9d1c2f0de72ecd1db8f86dfJim Grosbach 113970933266ae73c891d9d1c2f0de72ecd1db8f86dfJim Grosbach assert(MO.isExpr() && "Unexpected machine operand type!"); 114070933266ae73c891d9d1c2f0de72ecd1db8f86dfJim Grosbach const MCExpr *Expr = MO.getExpr(); 1141d8e351b96f5fd7007fbdd636acaa1fc9f6e18f3cOwen Anderson MCFixupKind Kind; 114259ee62d2418df8db499eca1ae17f5900dc2dcbbaEvan Cheng if (isThumb2()) 1143d8e351b96f5fd7007fbdd636acaa1fc9f6e18f3cOwen Anderson Kind = MCFixupKind(ARM::fixup_t2_pcrel_10); 1144d8e351b96f5fd7007fbdd636acaa1fc9f6e18f3cOwen Anderson else 1145d8e351b96f5fd7007fbdd636acaa1fc9f6e18f3cOwen Anderson Kind = MCFixupKind(ARM::fixup_arm_pcrel_10); 114642e6bd38e02e2e1c2cc50d2f12036c38c4ea3ab0Jim Grosbach Fixups.push_back(MCFixup::Create(0, Expr, Kind, MI.getLoc())); 114770933266ae73c891d9d1c2f0de72ecd1db8f86dfJim Grosbach 114870933266ae73c891d9d1c2f0de72ecd1db8f86dfJim Grosbach ++MCNumCPRelocations; 114997dd28fb89dc4c4caa3c60890335dc99489981a6Jim Grosbach } else { 115070933266ae73c891d9d1c2f0de72ecd1db8f86dfJim Grosbach EncodeAddrModeOpValues(MI, OpIdx, Reg, Imm8, Fixups); 115197dd28fb89dc4c4caa3c60890335dc99489981a6Jim Grosbach isAdd = ARM_AM::getAM5Op(Imm8) == ARM_AM::add; 115297dd28fb89dc4c4caa3c60890335dc99489981a6Jim Grosbach } 115392b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling 115492b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling uint32_t Binary = ARM_AM::getAM5Offset(Imm8); 115592b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling // Immediate is always encoded as positive. The 'U' bit controls add vs sub. 115697dd28fb89dc4c4caa3c60890335dc99489981a6Jim Grosbach if (isAdd) 115792b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling Binary |= (1 << 8); 115892b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling Binary |= (Reg << 9); 11593e5561247202bae994dd259a2d8dc4eff8f799f3Jim Grosbach return Binary; 11603e5561247202bae994dd259a2d8dc4eff8f799f3Jim Grosbach} 11613e5561247202bae994dd259a2d8dc4eff8f799f3Jim Grosbach 1162806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbachunsigned ARMMCCodeEmitter:: 1163152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen AndersongetSORegRegOpValue(const MCInst &MI, unsigned OpIdx, 1164806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbach SmallVectorImpl<MCFixup> &Fixups) const { 11650800ce71896ccd7f49b37861a8cfbc21b6b10022Bill Wendling // Sub-operands are [reg, reg, imm]. The first register is Rm, the reg to be 1166354712c5a506449676e6fcac6b623af4092e7100Owen Anderson // shifted. The second is Rs, the amount to shift by, and the third specifies 1167354712c5a506449676e6fcac6b623af4092e7100Owen Anderson // the type of the shift. 116835b2de012d9404e3e9e4373e45f41711f752dd3aJim Grosbach // 1169ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach // {3-0} = Rm. 1170354712c5a506449676e6fcac6b623af4092e7100Owen Anderson // {4} = 1 1171ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach // {6-5} = type 1172354712c5a506449676e6fcac6b623af4092e7100Owen Anderson // {11-8} = Rs 1173354712c5a506449676e6fcac6b623af4092e7100Owen Anderson // {7} = 0 1174ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach 1175ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach const MCOperand &MO = MI.getOperand(OpIdx); 1176ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach const MCOperand &MO1 = MI.getOperand(OpIdx + 1); 1177ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach const MCOperand &MO2 = MI.getOperand(OpIdx + 2); 1178ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach ARM_AM::ShiftOpc SOpc = ARM_AM::getSORegShOp(MO2.getImm()); 1179ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach 1180ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach // Encode Rm. 118199cb622041a0839c7dfcf0263c5102a305a0fdb5Bill Wendling unsigned Binary = CTX.getRegisterInfo()->getEncodingValue(MO.getReg()); 1182ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach 1183ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach // Encode the shift opcode. 1184ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach unsigned SBits = 0; 1185ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach unsigned Rs = MO1.getReg(); 1186ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach if (Rs) { 1187ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach // Set shift operand (bit[7:4]). 1188ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach // LSL - 0001 1189ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach // LSR - 0011 1190ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach // ASR - 0101 1191ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach // ROR - 0111 1192ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach switch (SOpc) { 1193ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach default: llvm_unreachable("Unknown shift opc!"); 1194ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach case ARM_AM::lsl: SBits = 0x1; break; 1195ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach case ARM_AM::lsr: SBits = 0x3; break; 1196ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach case ARM_AM::asr: SBits = 0x5; break; 1197ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach case ARM_AM::ror: SBits = 0x7; break; 1198ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach } 1199ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach } 12000800ce71896ccd7f49b37861a8cfbc21b6b10022Bill Wendling 1201ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach Binary |= SBits << 4; 1202ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach 1203354712c5a506449676e6fcac6b623af4092e7100Owen Anderson // Encode the shift operation Rs. 1204152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson // Encode Rs bit[11:8]. 1205152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson assert(ARM_AM::getSORegOffset(MO2.getImm()) == 0); 120699cb622041a0839c7dfcf0263c5102a305a0fdb5Bill Wendling return Binary | (CTX.getRegisterInfo()->getEncodingValue(Rs) << ARMII::RegRsShift); 1207152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson} 1208152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson 1209152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Andersonunsigned ARMMCCodeEmitter:: 1210152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen AndersongetSORegImmOpValue(const MCInst &MI, unsigned OpIdx, 1211152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson SmallVectorImpl<MCFixup> &Fixups) const { 1212354712c5a506449676e6fcac6b623af4092e7100Owen Anderson // Sub-operands are [reg, imm]. The first register is Rm, the reg to be 1213354712c5a506449676e6fcac6b623af4092e7100Owen Anderson // shifted. The second is the amount to shift by. 1214152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson // 1215152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson // {3-0} = Rm. 1216354712c5a506449676e6fcac6b623af4092e7100Owen Anderson // {4} = 0 1217152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson // {6-5} = type 1218354712c5a506449676e6fcac6b623af4092e7100Owen Anderson // {11-7} = imm 1219152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson 1220152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson const MCOperand &MO = MI.getOperand(OpIdx); 1221152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson const MCOperand &MO1 = MI.getOperand(OpIdx + 1); 1222152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson ARM_AM::ShiftOpc SOpc = ARM_AM::getSORegShOp(MO1.getImm()); 1223152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson 1224152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson // Encode Rm. 122599cb622041a0839c7dfcf0263c5102a305a0fdb5Bill Wendling unsigned Binary = CTX.getRegisterInfo()->getEncodingValue(MO.getReg()); 1226152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson 1227152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson // Encode the shift opcode. 1228152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson unsigned SBits = 0; 1229152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson 1230152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson // Set shift operand (bit[6:4]). 1231152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson // LSL - 000 1232152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson // LSR - 010 1233152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson // ASR - 100 1234152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson // ROR - 110 1235152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson // RRX - 110 and bit[11:8] clear. 1236152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson switch (SOpc) { 1237152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson default: llvm_unreachable("Unknown shift opc!"); 1238152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson case ARM_AM::lsl: SBits = 0x0; break; 1239152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson case ARM_AM::lsr: SBits = 0x2; break; 1240152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson case ARM_AM::asr: SBits = 0x4; break; 1241152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson case ARM_AM::ror: SBits = 0x6; break; 1242152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson case ARM_AM::rrx: 1243152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson Binary |= 0x60; 1244152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson return Binary; 1245ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach } 1246ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach 1247ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach // Encode shift_imm bit[11:7]. 1248152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson Binary |= SBits << 4; 12493dac0bec7e7874ffb378385b6160bd2117184ca9Owen Anderson unsigned Offset = ARM_AM::getSORegOffset(MO1.getImm()); 1250b56e4115ed33dae56108ed4ce88ee3a0e0392bfcRichard Barton assert(Offset < 32 && "Offset must be in range 0-31!"); 12513dac0bec7e7874ffb378385b6160bd2117184ca9Owen Anderson return Binary | (Offset << 7); 1252ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach} 1253ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach 1254152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson 1255806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbachunsigned ARMMCCodeEmitter:: 125675579f739fbc99a92a15f3ce75bbd7628ba00f8cOwen AndersongetT2AddrModeSORegOpValue(const MCInst &MI, unsigned OpNum, 125775579f739fbc99a92a15f3ce75bbd7628ba00f8cOwen Anderson SmallVectorImpl<MCFixup> &Fixups) const { 125875579f739fbc99a92a15f3ce75bbd7628ba00f8cOwen Anderson const MCOperand &MO1 = MI.getOperand(OpNum); 125975579f739fbc99a92a15f3ce75bbd7628ba00f8cOwen Anderson const MCOperand &MO2 = MI.getOperand(OpNum+1); 12607bf4c02789f97e32225fc248dff6622b994a15eeJim Grosbach const MCOperand &MO3 = MI.getOperand(OpNum+2); 12617bf4c02789f97e32225fc248dff6622b994a15eeJim Grosbach 126275579f739fbc99a92a15f3ce75bbd7628ba00f8cOwen Anderson // Encoded as [Rn, Rm, imm]. 126375579f739fbc99a92a15f3ce75bbd7628ba00f8cOwen Anderson // FIXME: Needs fixup support. 126499cb622041a0839c7dfcf0263c5102a305a0fdb5Bill Wendling unsigned Value = CTX.getRegisterInfo()->getEncodingValue(MO1.getReg()); 126575579f739fbc99a92a15f3ce75bbd7628ba00f8cOwen Anderson Value <<= 4; 126699cb622041a0839c7dfcf0263c5102a305a0fdb5Bill Wendling Value |= CTX.getRegisterInfo()->getEncodingValue(MO2.getReg()); 126775579f739fbc99a92a15f3ce75bbd7628ba00f8cOwen Anderson Value <<= 2; 126875579f739fbc99a92a15f3ce75bbd7628ba00f8cOwen Anderson Value |= MO3.getImm(); 12697bf4c02789f97e32225fc248dff6622b994a15eeJim Grosbach 127075579f739fbc99a92a15f3ce75bbd7628ba00f8cOwen Anderson return Value; 127175579f739fbc99a92a15f3ce75bbd7628ba00f8cOwen Anderson} 127275579f739fbc99a92a15f3ce75bbd7628ba00f8cOwen Anderson 127375579f739fbc99a92a15f3ce75bbd7628ba00f8cOwen Andersonunsigned ARMMCCodeEmitter:: 127475579f739fbc99a92a15f3ce75bbd7628ba00f8cOwen AndersongetT2AddrModeImm8OpValue(const MCInst &MI, unsigned OpNum, 127575579f739fbc99a92a15f3ce75bbd7628ba00f8cOwen Anderson SmallVectorImpl<MCFixup> &Fixups) const { 127675579f739fbc99a92a15f3ce75bbd7628ba00f8cOwen Anderson const MCOperand &MO1 = MI.getOperand(OpNum); 127775579f739fbc99a92a15f3ce75bbd7628ba00f8cOwen Anderson const MCOperand &MO2 = MI.getOperand(OpNum+1); 127875579f739fbc99a92a15f3ce75bbd7628ba00f8cOwen Anderson 127975579f739fbc99a92a15f3ce75bbd7628ba00f8cOwen Anderson // FIXME: Needs fixup support. 128099cb622041a0839c7dfcf0263c5102a305a0fdb5Bill Wendling unsigned Value = CTX.getRegisterInfo()->getEncodingValue(MO1.getReg()); 12817bf4c02789f97e32225fc248dff6622b994a15eeJim Grosbach 128275579f739fbc99a92a15f3ce75bbd7628ba00f8cOwen Anderson // Even though the immediate is 8 bits long, we need 9 bits in order 128375579f739fbc99a92a15f3ce75bbd7628ba00f8cOwen Anderson // to represent the (inverse of the) sign bit. 128475579f739fbc99a92a15f3ce75bbd7628ba00f8cOwen Anderson Value <<= 9; 12856af50f7dd12d82f0a80f3158102180eee4c921aaOwen Anderson int32_t tmp = (int32_t)MO2.getImm(); 12866af50f7dd12d82f0a80f3158102180eee4c921aaOwen Anderson if (tmp < 0) 12876af50f7dd12d82f0a80f3158102180eee4c921aaOwen Anderson tmp = abs(tmp); 12886af50f7dd12d82f0a80f3158102180eee4c921aaOwen Anderson else 12896af50f7dd12d82f0a80f3158102180eee4c921aaOwen Anderson Value |= 256; // Set the ADD bit 12906af50f7dd12d82f0a80f3158102180eee4c921aaOwen Anderson Value |= tmp & 255; 12916af50f7dd12d82f0a80f3158102180eee4c921aaOwen Anderson return Value; 12926af50f7dd12d82f0a80f3158102180eee4c921aaOwen Anderson} 12936af50f7dd12d82f0a80f3158102180eee4c921aaOwen Anderson 12946af50f7dd12d82f0a80f3158102180eee4c921aaOwen Andersonunsigned ARMMCCodeEmitter:: 12956af50f7dd12d82f0a80f3158102180eee4c921aaOwen AndersongetT2AddrModeImm8OffsetOpValue(const MCInst &MI, unsigned OpNum, 12966af50f7dd12d82f0a80f3158102180eee4c921aaOwen Anderson SmallVectorImpl<MCFixup> &Fixups) const { 12976af50f7dd12d82f0a80f3158102180eee4c921aaOwen Anderson const MCOperand &MO1 = MI.getOperand(OpNum); 12986af50f7dd12d82f0a80f3158102180eee4c921aaOwen Anderson 12996af50f7dd12d82f0a80f3158102180eee4c921aaOwen Anderson // FIXME: Needs fixup support. 13006af50f7dd12d82f0a80f3158102180eee4c921aaOwen Anderson unsigned Value = 0; 13016af50f7dd12d82f0a80f3158102180eee4c921aaOwen Anderson int32_t tmp = (int32_t)MO1.getImm(); 13026af50f7dd12d82f0a80f3158102180eee4c921aaOwen Anderson if (tmp < 0) 13036af50f7dd12d82f0a80f3158102180eee4c921aaOwen Anderson tmp = abs(tmp); 13046af50f7dd12d82f0a80f3158102180eee4c921aaOwen Anderson else 13056af50f7dd12d82f0a80f3158102180eee4c921aaOwen Anderson Value |= 256; // Set the ADD bit 13066af50f7dd12d82f0a80f3158102180eee4c921aaOwen Anderson Value |= tmp & 255; 130775579f739fbc99a92a15f3ce75bbd7628ba00f8cOwen Anderson return Value; 130875579f739fbc99a92a15f3ce75bbd7628ba00f8cOwen Anderson} 130975579f739fbc99a92a15f3ce75bbd7628ba00f8cOwen Anderson 131075579f739fbc99a92a15f3ce75bbd7628ba00f8cOwen Andersonunsigned ARMMCCodeEmitter:: 13110e1bcdf4f7547bb5f47ed5ff5f2409a8f72f3609Owen AndersongetT2AddrModeImm12OffsetOpValue(const MCInst &MI, unsigned OpNum, 13120e1bcdf4f7547bb5f47ed5ff5f2409a8f72f3609Owen Anderson SmallVectorImpl<MCFixup> &Fixups) const { 13130e1bcdf4f7547bb5f47ed5ff5f2409a8f72f3609Owen Anderson const MCOperand &MO1 = MI.getOperand(OpNum); 13140e1bcdf4f7547bb5f47ed5ff5f2409a8f72f3609Owen Anderson 13150e1bcdf4f7547bb5f47ed5ff5f2409a8f72f3609Owen Anderson // FIXME: Needs fixup support. 13160e1bcdf4f7547bb5f47ed5ff5f2409a8f72f3609Owen Anderson unsigned Value = 0; 13170e1bcdf4f7547bb5f47ed5ff5f2409a8f72f3609Owen Anderson int32_t tmp = (int32_t)MO1.getImm(); 13180e1bcdf4f7547bb5f47ed5ff5f2409a8f72f3609Owen Anderson if (tmp < 0) 13190e1bcdf4f7547bb5f47ed5ff5f2409a8f72f3609Owen Anderson tmp = abs(tmp); 13200e1bcdf4f7547bb5f47ed5ff5f2409a8f72f3609Owen Anderson else 13210e1bcdf4f7547bb5f47ed5ff5f2409a8f72f3609Owen Anderson Value |= 4096; // Set the ADD bit 13220e1bcdf4f7547bb5f47ed5ff5f2409a8f72f3609Owen Anderson Value |= tmp & 4095; 13230e1bcdf4f7547bb5f47ed5ff5f2409a8f72f3609Owen Anderson return Value; 13240e1bcdf4f7547bb5f47ed5ff5f2409a8f72f3609Owen Anderson} 13250e1bcdf4f7547bb5f47ed5ff5f2409a8f72f3609Owen Anderson 13260e1bcdf4f7547bb5f47ed5ff5f2409a8f72f3609Owen Andersonunsigned ARMMCCodeEmitter:: 13275de6d841a5116152793dcab35a2e534a6a9aaa7aOwen AndersongetT2SORegOpValue(const MCInst &MI, unsigned OpIdx, 13285de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson SmallVectorImpl<MCFixup> &Fixups) const { 13295de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson // Sub-operands are [reg, imm]. The first register is Rm, the reg to be 13305de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson // shifted. The second is the amount to shift by. 13315de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson // 13325de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson // {3-0} = Rm. 13335de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson // {4} = 0 13345de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson // {6-5} = type 13355de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson // {11-7} = imm 13365de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson 13375de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson const MCOperand &MO = MI.getOperand(OpIdx); 13385de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson const MCOperand &MO1 = MI.getOperand(OpIdx + 1); 13395de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson ARM_AM::ShiftOpc SOpc = ARM_AM::getSORegShOp(MO1.getImm()); 13405de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson 13415de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson // Encode Rm. 134299cb622041a0839c7dfcf0263c5102a305a0fdb5Bill Wendling unsigned Binary = CTX.getRegisterInfo()->getEncodingValue(MO.getReg()); 13435de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson 13445de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson // Encode the shift opcode. 13455de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson unsigned SBits = 0; 13465de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson // Set shift operand (bit[6:4]). 13475de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson // LSL - 000 13485de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson // LSR - 010 13495de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson // ASR - 100 13505de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson // ROR - 110 13515de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson switch (SOpc) { 13525de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson default: llvm_unreachable("Unknown shift opc!"); 13535de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson case ARM_AM::lsl: SBits = 0x0; break; 13545de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson case ARM_AM::lsr: SBits = 0x2; break; 13555de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson case ARM_AM::asr: SBits = 0x4; break; 135612c7e90d369b4605aac0ddbd252231beacb2aabbOwen Anderson case ARM_AM::rrx: // FALLTHROUGH 13575de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson case ARM_AM::ror: SBits = 0x6; break; 13585de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson } 13595de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson 13605de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson Binary |= SBits << 4; 13615de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson if (SOpc == ARM_AM::rrx) 13625de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson return Binary; 13635de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson 13645de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson // Encode shift_imm bit[11:7]. 13655de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson return Binary | ARM_AM::getSORegOffset(MO1.getImm()) << 7; 13665de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson} 13675de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson 13685de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Andersonunsigned ARMMCCodeEmitter:: 1369806e80ef42bdb416f409142a1ff1d4e8752baac8Jim GrosbachgetBitfieldInvertedMaskOpValue(const MCInst &MI, unsigned Op, 1370806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbach SmallVectorImpl<MCFixup> &Fixups) const { 13713fea19105d4929ad694f0b6272de31924c9f9f09Jim Grosbach // 10 bits. lower 5 bits are are the lsb of the mask, high five bits are the 13723fea19105d4929ad694f0b6272de31924c9f9f09Jim Grosbach // msb of the mask. 13733fea19105d4929ad694f0b6272de31924c9f9f09Jim Grosbach const MCOperand &MO = MI.getOperand(Op); 13743fea19105d4929ad694f0b6272de31924c9f9f09Jim Grosbach uint32_t v = ~MO.getImm(); 1375c6af2432c802d241c8fffbe0371c023e6c58844eMichael J. Spencer uint32_t lsb = countTrailingZeros(v); 1376c6af2432c802d241c8fffbe0371c023e6c58844eMichael J. Spencer uint32_t msb = (32 - countLeadingZeros (v)) - 1; 13773fea19105d4929ad694f0b6272de31924c9f9f09Jim Grosbach assert (v != 0 && lsb < 32 && msb < 32 && "Illegal bitfield mask!"); 13783fea19105d4929ad694f0b6272de31924c9f9f09Jim Grosbach return lsb | (msb << 5); 13793fea19105d4929ad694f0b6272de31924c9f9f09Jim Grosbach} 13803fea19105d4929ad694f0b6272de31924c9f9f09Jim Grosbach 1381806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbachunsigned ARMMCCodeEmitter:: 1382806e80ef42bdb416f409142a1ff1d4e8752baac8Jim GrosbachgetRegisterListOpValue(const MCInst &MI, unsigned Op, 13835e559a22c18166508a01fbd65471ec4e752726f9Bill Wendling SmallVectorImpl<MCFixup> &Fixups) const { 13846bc105a7b9282a0b5beb9d06267b31a3054fb3faBill Wendling // VLDM/VSTM: 13856bc105a7b9282a0b5beb9d06267b31a3054fb3faBill Wendling // {12-8} = Vd 13866bc105a7b9282a0b5beb9d06267b31a3054fb3faBill Wendling // {7-0} = Number of registers 13876bc105a7b9282a0b5beb9d06267b31a3054fb3faBill Wendling // 13886bc105a7b9282a0b5beb9d06267b31a3054fb3faBill Wendling // LDM/STM: 13896bc105a7b9282a0b5beb9d06267b31a3054fb3faBill Wendling // {15-0} = Bitfield of GPRs. 13906bc105a7b9282a0b5beb9d06267b31a3054fb3faBill Wendling unsigned Reg = MI.getOperand(Op).getReg(); 1391c89c744b69cecac576317a98322fd295e36e9886Craig Topper bool SPRRegs = ARMMCRegisterClasses[ARM::SPRRegClassID].contains(Reg); 1392c89c744b69cecac576317a98322fd295e36e9886Craig Topper bool DPRRegs = ARMMCRegisterClasses[ARM::DPRRegClassID].contains(Reg); 13936bc105a7b9282a0b5beb9d06267b31a3054fb3faBill Wendling 13945e559a22c18166508a01fbd65471ec4e752726f9Bill Wendling unsigned Binary = 0; 13956bc105a7b9282a0b5beb9d06267b31a3054fb3faBill Wendling 13966bc105a7b9282a0b5beb9d06267b31a3054fb3faBill Wendling if (SPRRegs || DPRRegs) { 13976bc105a7b9282a0b5beb9d06267b31a3054fb3faBill Wendling // VLDM/VSTM 139899cb622041a0839c7dfcf0263c5102a305a0fdb5Bill Wendling unsigned RegNo = CTX.getRegisterInfo()->getEncodingValue(Reg); 13996bc105a7b9282a0b5beb9d06267b31a3054fb3faBill Wendling unsigned NumRegs = (MI.getNumOperands() - Op) & 0xff; 14006bc105a7b9282a0b5beb9d06267b31a3054fb3faBill Wendling Binary |= (RegNo & 0x1f) << 8; 14016bc105a7b9282a0b5beb9d06267b31a3054fb3faBill Wendling if (SPRRegs) 14026bc105a7b9282a0b5beb9d06267b31a3054fb3faBill Wendling Binary |= NumRegs; 14036bc105a7b9282a0b5beb9d06267b31a3054fb3faBill Wendling else 14046bc105a7b9282a0b5beb9d06267b31a3054fb3faBill Wendling Binary |= NumRegs * 2; 14056bc105a7b9282a0b5beb9d06267b31a3054fb3faBill Wendling } else { 14066bc105a7b9282a0b5beb9d06267b31a3054fb3faBill Wendling for (unsigned I = Op, E = MI.getNumOperands(); I < E; ++I) { 140799cb622041a0839c7dfcf0263c5102a305a0fdb5Bill Wendling unsigned RegNo = CTX.getRegisterInfo()->getEncodingValue(MI.getOperand(I).getReg()); 14086bc105a7b9282a0b5beb9d06267b31a3054fb3faBill Wendling Binary |= 1 << RegNo; 14096bc105a7b9282a0b5beb9d06267b31a3054fb3faBill Wendling } 14105e559a22c18166508a01fbd65471ec4e752726f9Bill Wendling } 14116bc105a7b9282a0b5beb9d06267b31a3054fb3faBill Wendling 14126b5252db2db5eeeadec4602329ac56beb6dea54aJim Grosbach return Binary; 14136b5252db2db5eeeadec4602329ac56beb6dea54aJim Grosbach} 14146b5252db2db5eeeadec4602329ac56beb6dea54aJim Grosbach 14158e0c7b52877983b4838e54e233449912fc1a2325Bob Wilson/// getAddrMode6AddressOpValue - Encode an addrmode6 register number along 14168e0c7b52877983b4838e54e233449912fc1a2325Bob Wilson/// with the alignment operand. 1417806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbachunsigned ARMMCCodeEmitter:: 1418806e80ef42bdb416f409142a1ff1d4e8752baac8Jim GrosbachgetAddrMode6AddressOpValue(const MCInst &MI, unsigned Op, 1419806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbach SmallVectorImpl<MCFixup> &Fixups) const { 1420d9aa7d30aa277fba319ee4bcdb862cd79f1aabe5Owen Anderson const MCOperand &Reg = MI.getOperand(Op); 14210800ce71896ccd7f49b37861a8cfbc21b6b10022Bill Wendling const MCOperand &Imm = MI.getOperand(Op + 1); 142235b2de012d9404e3e9e4373e45f41711f752dd3aJim Grosbach 142399cb622041a0839c7dfcf0263c5102a305a0fdb5Bill Wendling unsigned RegNo = CTX.getRegisterInfo()->getEncodingValue(Reg.getReg()); 14240800ce71896ccd7f49b37861a8cfbc21b6b10022Bill Wendling unsigned Align = 0; 14250800ce71896ccd7f49b37861a8cfbc21b6b10022Bill Wendling 14260800ce71896ccd7f49b37861a8cfbc21b6b10022Bill Wendling switch (Imm.getImm()) { 14270800ce71896ccd7f49b37861a8cfbc21b6b10022Bill Wendling default: break; 14280800ce71896ccd7f49b37861a8cfbc21b6b10022Bill Wendling case 2: 14290800ce71896ccd7f49b37861a8cfbc21b6b10022Bill Wendling case 4: 14300800ce71896ccd7f49b37861a8cfbc21b6b10022Bill Wendling case 8: Align = 0x01; break; 14310800ce71896ccd7f49b37861a8cfbc21b6b10022Bill Wendling case 16: Align = 0x02; break; 14320800ce71896ccd7f49b37861a8cfbc21b6b10022Bill Wendling case 32: Align = 0x03; break; 1433d9aa7d30aa277fba319ee4bcdb862cd79f1aabe5Owen Anderson } 14340800ce71896ccd7f49b37861a8cfbc21b6b10022Bill Wendling 1435d9aa7d30aa277fba319ee4bcdb862cd79f1aabe5Owen Anderson return RegNo | (Align << 4); 1436d9aa7d30aa277fba319ee4bcdb862cd79f1aabe5Owen Anderson} 1437d9aa7d30aa277fba319ee4bcdb862cd79f1aabe5Owen Anderson 1438183c627d89be5d0e8f3255ab7f6d1204c2fabedfMon P Wang/// getAddrMode6OneLane32AddressOpValue - Encode an addrmode6 register number 1439183c627d89be5d0e8f3255ab7f6d1204c2fabedfMon P Wang/// along with the alignment operand for use in VST1 and VLD1 with size 32. 1440183c627d89be5d0e8f3255ab7f6d1204c2fabedfMon P Wangunsigned ARMMCCodeEmitter:: 1441183c627d89be5d0e8f3255ab7f6d1204c2fabedfMon P WanggetAddrMode6OneLane32AddressOpValue(const MCInst &MI, unsigned Op, 1442183c627d89be5d0e8f3255ab7f6d1204c2fabedfMon P Wang SmallVectorImpl<MCFixup> &Fixups) const { 1443183c627d89be5d0e8f3255ab7f6d1204c2fabedfMon P Wang const MCOperand &Reg = MI.getOperand(Op); 1444183c627d89be5d0e8f3255ab7f6d1204c2fabedfMon P Wang const MCOperand &Imm = MI.getOperand(Op + 1); 1445183c627d89be5d0e8f3255ab7f6d1204c2fabedfMon P Wang 144699cb622041a0839c7dfcf0263c5102a305a0fdb5Bill Wendling unsigned RegNo = CTX.getRegisterInfo()->getEncodingValue(Reg.getReg()); 1447183c627d89be5d0e8f3255ab7f6d1204c2fabedfMon P Wang unsigned Align = 0; 1448183c627d89be5d0e8f3255ab7f6d1204c2fabedfMon P Wang 1449183c627d89be5d0e8f3255ab7f6d1204c2fabedfMon P Wang switch (Imm.getImm()) { 1450183c627d89be5d0e8f3255ab7f6d1204c2fabedfMon P Wang default: break; 1451183c627d89be5d0e8f3255ab7f6d1204c2fabedfMon P Wang case 8: 1452eeaf1c1636c664c707fd9ecc96916fd20ddf137aJim Grosbach case 16: 1453eeaf1c1636c664c707fd9ecc96916fd20ddf137aJim Grosbach case 32: // Default '0' value for invalid alignments of 8, 16, 32 bytes. 1454eeaf1c1636c664c707fd9ecc96916fd20ddf137aJim Grosbach case 2: Align = 0x00; break; 1455eeaf1c1636c664c707fd9ecc96916fd20ddf137aJim Grosbach case 4: Align = 0x03; break; 1456183c627d89be5d0e8f3255ab7f6d1204c2fabedfMon P Wang } 1457183c627d89be5d0e8f3255ab7f6d1204c2fabedfMon P Wang 1458183c627d89be5d0e8f3255ab7f6d1204c2fabedfMon P Wang return RegNo | (Align << 4); 1459183c627d89be5d0e8f3255ab7f6d1204c2fabedfMon P Wang} 1460183c627d89be5d0e8f3255ab7f6d1204c2fabedfMon P Wang 1461183c627d89be5d0e8f3255ab7f6d1204c2fabedfMon P Wang 14628e0c7b52877983b4838e54e233449912fc1a2325Bob Wilson/// getAddrMode6DupAddressOpValue - Encode an addrmode6 register number and 14638e0c7b52877983b4838e54e233449912fc1a2325Bob Wilson/// alignment operand for use in VLD-dup instructions. This is the same as 14648e0c7b52877983b4838e54e233449912fc1a2325Bob Wilson/// getAddrMode6AddressOpValue except for the alignment encoding, which is 14658e0c7b52877983b4838e54e233449912fc1a2325Bob Wilson/// different for VLD4-dup. 14668e0c7b52877983b4838e54e233449912fc1a2325Bob Wilsonunsigned ARMMCCodeEmitter:: 14678e0c7b52877983b4838e54e233449912fc1a2325Bob WilsongetAddrMode6DupAddressOpValue(const MCInst &MI, unsigned Op, 14688e0c7b52877983b4838e54e233449912fc1a2325Bob Wilson SmallVectorImpl<MCFixup> &Fixups) const { 14698e0c7b52877983b4838e54e233449912fc1a2325Bob Wilson const MCOperand &Reg = MI.getOperand(Op); 14708e0c7b52877983b4838e54e233449912fc1a2325Bob Wilson const MCOperand &Imm = MI.getOperand(Op + 1); 14718e0c7b52877983b4838e54e233449912fc1a2325Bob Wilson 147299cb622041a0839c7dfcf0263c5102a305a0fdb5Bill Wendling unsigned RegNo = CTX.getRegisterInfo()->getEncodingValue(Reg.getReg()); 14738e0c7b52877983b4838e54e233449912fc1a2325Bob Wilson unsigned Align = 0; 14748e0c7b52877983b4838e54e233449912fc1a2325Bob Wilson 14758e0c7b52877983b4838e54e233449912fc1a2325Bob Wilson switch (Imm.getImm()) { 14768e0c7b52877983b4838e54e233449912fc1a2325Bob Wilson default: break; 14778e0c7b52877983b4838e54e233449912fc1a2325Bob Wilson case 2: 14788e0c7b52877983b4838e54e233449912fc1a2325Bob Wilson case 4: 14798e0c7b52877983b4838e54e233449912fc1a2325Bob Wilson case 8: Align = 0x01; break; 14808e0c7b52877983b4838e54e233449912fc1a2325Bob Wilson case 16: Align = 0x03; break; 14818e0c7b52877983b4838e54e233449912fc1a2325Bob Wilson } 14828e0c7b52877983b4838e54e233449912fc1a2325Bob Wilson 14838e0c7b52877983b4838e54e233449912fc1a2325Bob Wilson return RegNo | (Align << 4); 14848e0c7b52877983b4838e54e233449912fc1a2325Bob Wilson} 14858e0c7b52877983b4838e54e233449912fc1a2325Bob Wilson 1486806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbachunsigned ARMMCCodeEmitter:: 1487806e80ef42bdb416f409142a1ff1d4e8752baac8Jim GrosbachgetAddrMode6OffsetOpValue(const MCInst &MI, unsigned Op, 1488806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbach SmallVectorImpl<MCFixup> &Fixups) const { 14890800ce71896ccd7f49b37861a8cfbc21b6b10022Bill Wendling const MCOperand &MO = MI.getOperand(Op); 14900800ce71896ccd7f49b37861a8cfbc21b6b10022Bill Wendling if (MO.getReg() == 0) return 0x0D; 149199cb622041a0839c7dfcf0263c5102a305a0fdb5Bill Wendling return CTX.getRegisterInfo()->getEncodingValue(MO.getReg()); 1492a656b63ee4d5b0e3f4d26a55dd4cc69795746684Bill Wendling} 1493a656b63ee4d5b0e3f4d26a55dd4cc69795746684Bill Wendling 1494a656b63ee4d5b0e3f4d26a55dd4cc69795746684Bill Wendlingunsigned ARMMCCodeEmitter:: 14953116dce33840a115130c5f8ffcb9679d023496d6Bill WendlinggetShiftRight8Imm(const MCInst &MI, unsigned Op, 14963116dce33840a115130c5f8ffcb9679d023496d6Bill Wendling SmallVectorImpl<MCFixup> &Fixups) const { 1497a656b63ee4d5b0e3f4d26a55dd4cc69795746684Bill Wendling return 8 - MI.getOperand(Op).getImm(); 1498a656b63ee4d5b0e3f4d26a55dd4cc69795746684Bill Wendling} 1499a656b63ee4d5b0e3f4d26a55dd4cc69795746684Bill Wendling 1500a656b63ee4d5b0e3f4d26a55dd4cc69795746684Bill Wendlingunsigned ARMMCCodeEmitter:: 15013116dce33840a115130c5f8ffcb9679d023496d6Bill WendlinggetShiftRight16Imm(const MCInst &MI, unsigned Op, 15023116dce33840a115130c5f8ffcb9679d023496d6Bill Wendling SmallVectorImpl<MCFixup> &Fixups) const { 1503a656b63ee4d5b0e3f4d26a55dd4cc69795746684Bill Wendling return 16 - MI.getOperand(Op).getImm(); 1504a656b63ee4d5b0e3f4d26a55dd4cc69795746684Bill Wendling} 1505a656b63ee4d5b0e3f4d26a55dd4cc69795746684Bill Wendling 1506a656b63ee4d5b0e3f4d26a55dd4cc69795746684Bill Wendlingunsigned ARMMCCodeEmitter:: 15073116dce33840a115130c5f8ffcb9679d023496d6Bill WendlinggetShiftRight32Imm(const MCInst &MI, unsigned Op, 15083116dce33840a115130c5f8ffcb9679d023496d6Bill Wendling SmallVectorImpl<MCFixup> &Fixups) const { 1509a656b63ee4d5b0e3f4d26a55dd4cc69795746684Bill Wendling return 32 - MI.getOperand(Op).getImm(); 15103116dce33840a115130c5f8ffcb9679d023496d6Bill Wendling} 15113116dce33840a115130c5f8ffcb9679d023496d6Bill Wendling 15123116dce33840a115130c5f8ffcb9679d023496d6Bill Wendlingunsigned ARMMCCodeEmitter:: 15133116dce33840a115130c5f8ffcb9679d023496d6Bill WendlinggetShiftRight64Imm(const MCInst &MI, unsigned Op, 15143116dce33840a115130c5f8ffcb9679d023496d6Bill Wendling SmallVectorImpl<MCFixup> &Fixups) const { 15153116dce33840a115130c5f8ffcb9679d023496d6Bill Wendling return 64 - MI.getOperand(Op).getImm(); 1516cf667be17b479fe276fd606b8fd72ccfa3065bb8Owen Anderson} 1517cf667be17b479fe276fd606b8fd72ccfa3065bb8Owen Anderson 1518568eeedea72c274abbba1310c18a31eef78e14a4Jim Grosbachvoid ARMMCCodeEmitter:: 1519568eeedea72c274abbba1310c18a31eef78e14a4Jim GrosbachEncodeInstruction(const MCInst &MI, raw_ostream &OS, 1520806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbach SmallVectorImpl<MCFixup> &Fixups) const { 1521d6d4b42ba473657b6d30242962f0d0fb23fe126eJim Grosbach // Pseudo instructions don't get encoded. 152259ee62d2418df8db499eca1ae17f5900dc2dcbbaEvan Cheng const MCInstrDesc &Desc = MCII.get(MI.getOpcode()); 1523e50e6bcd901ebb1cfc42fe9ca0796ae303d7f1a1Jim Grosbach uint64_t TSFlags = Desc.TSFlags; 1524e50e6bcd901ebb1cfc42fe9ca0796ae303d7f1a1Jim Grosbach if ((TSFlags & ARMII::FormMask) == ARMII::Pseudo) 1525d6d4b42ba473657b6d30242962f0d0fb23fe126eJim Grosbach return; 152616884415db751c75f2133bd04921393c792b1158Owen Anderson 1527e50e6bcd901ebb1cfc42fe9ca0796ae303d7f1a1Jim Grosbach int Size; 152816884415db751c75f2133bd04921393c792b1158Owen Anderson if (Desc.getSize() == 2 || Desc.getSize() == 4) 152916884415db751c75f2133bd04921393c792b1158Owen Anderson Size = Desc.getSize(); 153016884415db751c75f2133bd04921393c792b1158Owen Anderson else 153116884415db751c75f2133bd04921393c792b1158Owen Anderson llvm_unreachable("Unexpected instruction size!"); 153210096dbdef22a10a6a4444437c935ab428545525Owen Anderson 1533d91f4e40e6312304c60c83c3dd93f769a39a9772Jim Grosbach uint32_t Binary = getBinaryCodeForInstr(MI, Fixups); 15347597212abced110723f2fee985a7d60557c092ecEvan Cheng // Thumb 32-bit wide instructions need to emit the high order halfword 15357597212abced110723f2fee985a7d60557c092ecEvan Cheng // first. 153659ee62d2418df8db499eca1ae17f5900dc2dcbbaEvan Cheng if (isThumb() && Size == 4) { 1537d91f4e40e6312304c60c83c3dd93f769a39a9772Jim Grosbach EmitConstant(Binary >> 16, 2, OS); 1538d91f4e40e6312304c60c83c3dd93f769a39a9772Jim Grosbach EmitConstant(Binary & 0xffff, 2, OS); 1539d91f4e40e6312304c60c83c3dd93f769a39a9772Jim Grosbach } else 1540d91f4e40e6312304c60c83c3dd93f769a39a9772Jim Grosbach EmitConstant(Binary, Size, OS); 15417292e0a6564bb24707eff1c49da9044dd5eaec78Bill Wendling ++MCNumEmitted; // Keep track of the # of mi's emitted. 1542568eeedea72c274abbba1310c18a31eef78e14a4Jim Grosbach} 15439af82ba42b53905f580f8c4270626946e3548654Jim Grosbach 1544806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbach#include "ARMGenMCCodeEmitter.inc" 1545