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 14d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "MCTargetDesc/ARMMCTargetDesc.h" 15ee04a6d3a40c3017124e3fd89a0db473a2824498Evan Cheng#include "MCTargetDesc/ARMAddressingModes.h" 16be74029f44c32efc09274a16cbff588ad10dc5eaEvan Cheng#include "MCTargetDesc/ARMBaseInfo.h" 17be74029f44c32efc09274a16cbff588ad10dc5eaEvan Cheng#include "MCTargetDesc/ARMFixupKinds.h" 18ee04a6d3a40c3017124e3fd89a0db473a2824498Evan Cheng#include "MCTargetDesc/ARMMCExpr.h" 19d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/ADT/APFloat.h" 20d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/ADT/Statistic.h" 21568eeedea72c274abbba1310c18a31eef78e14a4Jim Grosbach#include "llvm/MC/MCCodeEmitter.h" 22df1c637ac4b6f6587c037be55cafed665c732d8fEric Christopher#include "llvm/MC/MCContext.h" 23568eeedea72c274abbba1310c18a31eef78e14a4Jim Grosbach#include "llvm/MC/MCExpr.h" 24568eeedea72c274abbba1310c18a31eef78e14a4Jim Grosbach#include "llvm/MC/MCInst.h" 2559ee62d2418df8db499eca1ae17f5900dc2dcbbaEvan Cheng#include "llvm/MC/MCInstrInfo.h" 26be74029f44c32efc09274a16cbff588ad10dc5eaEvan Cheng#include "llvm/MC/MCRegisterInfo.h" 2759ee62d2418df8db499eca1ae17f5900dc2dcbbaEvan Cheng#include "llvm/MC/MCSubtargetInfo.h" 2836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include "llvm/Support/ErrorHandling.h" 29568eeedea72c274abbba1310c18a31eef78e14a4Jim Grosbach#include "llvm/Support/raw_ostream.h" 3059ee62d2418df8db499eca1ae17f5900dc2dcbbaEvan Cheng 31568eeedea72c274abbba1310c18a31eef78e14a4Jim Grosbachusing namespace llvm; 32568eeedea72c274abbba1310c18a31eef78e14a4Jim Grosbach 33dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines#define DEBUG_TYPE "mccodeemitter" 34dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 3570933266ae73c891d9d1c2f0de72ecd1db8f86dfJim GrosbachSTATISTIC(MCNumEmitted, "Number of MC instructions emitted."); 3670933266ae73c891d9d1c2f0de72ecd1db8f86dfJim GrosbachSTATISTIC(MCNumCPRelocations, "Number of constant pool relocations created."); 37d6d4b42ba473657b6d30242962f0d0fb23fe126eJim Grosbach 38568eeedea72c274abbba1310c18a31eef78e14a4Jim Grosbachnamespace { 39568eeedea72c274abbba1310c18a31eef78e14a4Jim Grosbachclass ARMMCCodeEmitter : public MCCodeEmitter { 40ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines ARMMCCodeEmitter(const ARMMCCodeEmitter &) = delete; 41ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines void operator=(const ARMMCCodeEmitter &) = delete; 4259ee62d2418df8db499eca1ae17f5900dc2dcbbaEvan Cheng const MCInstrInfo &MCII; 43df1c637ac4b6f6587c037be55cafed665c732d8fEric Christopher const MCContext &CTX; 4436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines bool IsLittleEndian; 45568eeedea72c274abbba1310c18a31eef78e14a4Jim Grosbach 46568eeedea72c274abbba1310c18a31eef78e14a4Jim Grosbachpublic: 4736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines ARMMCCodeEmitter(const MCInstrInfo &mcii, MCContext &ctx, bool IsLittle) 4836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines : MCII(mcii), CTX(ctx), IsLittleEndian(IsLittle) { 49568eeedea72c274abbba1310c18a31eef78e14a4Jim Grosbach } 50568eeedea72c274abbba1310c18a31eef78e14a4Jim Grosbach 512c3e0051c31c3f5b2328b447eadf1cf9c4427442Pirama Arumuga Nainar ~ARMMCCodeEmitter() override {} 52568eeedea72c274abbba1310c18a31eef78e14a4Jim Grosbach 5336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines bool isThumb(const MCSubtargetInfo &STI) const { 5459ee62d2418df8db499eca1ae17f5900dc2dcbbaEvan Cheng return (STI.getFeatureBits() & ARM::ModeThumb) != 0; 5559ee62d2418df8db499eca1ae17f5900dc2dcbbaEvan Cheng } 5636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines bool isThumb2(const MCSubtargetInfo &STI) const { 5736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return isThumb(STI) && (STI.getFeatureBits() & ARM::FeatureThumb2) != 0; 5859ee62d2418df8db499eca1ae17f5900dc2dcbbaEvan Cheng } 5936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines bool isTargetMachO(const MCSubtargetInfo &STI) const { 6059ee62d2418df8db499eca1ae17f5900dc2dcbbaEvan Cheng Triple TT(STI.getTargetTriple()); 6136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return TT.isOSBinFormatMachO(); 6259ee62d2418df8db499eca1ae17f5900dc2dcbbaEvan Cheng } 6359ee62d2418df8db499eca1ae17f5900dc2dcbbaEvan Cheng 640de6ab3c43ed2143d661115dddf1480545236c91Jim Grosbach unsigned getMachineSoImmOpValue(unsigned SoImm) const; 650de6ab3c43ed2143d661115dddf1480545236c91Jim Grosbach 669af82ba42b53905f580f8c4270626946e3548654Jim Grosbach // getBinaryCodeForInstr - TableGen'erated function for getting the 679af82ba42b53905f580f8c4270626946e3548654Jim Grosbach // binary encoding for an instruction. 684f8dc7b17accf4f2ec953b80b2cc79786207492eOwen Anderson uint64_t getBinaryCodeForInstr(const MCInst &MI, 6936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines SmallVectorImpl<MCFixup> &Fixups, 7036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines const MCSubtargetInfo &STI) 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, 7536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines SmallVectorImpl<MCFixup> &Fixups, 7636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines const MCSubtargetInfo &STI) const; 779af82ba42b53905f580f8c4270626946e3548654Jim Grosbach 787597212abced110723f2fee985a7d60557c092ecEvan Cheng /// getHiLo16ImmOpValue - Return the encoding for the hi / low 16-bit of 79971b83b67a9812556cdb97bb58aa96fb37af458dOwen Anderson /// the specified operand. This is used for operands with :lower16: and 807597212abced110723f2fee985a7d60557c092ecEvan Cheng /// :upper16: prefixes. 817597212abced110723f2fee985a7d60557c092ecEvan Cheng uint32_t getHiLo16ImmOpValue(const MCInst &MI, unsigned OpIdx, 8236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines SmallVectorImpl<MCFixup> &Fixups, 8336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines const MCSubtargetInfo &STI) const; 84837caa9313e1f9480721f232f89f5c7b1b9c9d09Jason W Kim 8592b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling bool EncodeAddrModeOpValues(const MCInst &MI, unsigned OpIdx, 86806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbach unsigned &Reg, unsigned &Imm, 8736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines SmallVectorImpl<MCFixup> &Fixups, 8836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines const MCSubtargetInfo &STI) const; 8992b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling 90662a816e89a9d77bf75e1328b09cf9235b4682aaJim Grosbach /// getThumbBLTargetOpValue - Return encoding info for Thumb immediate 9109aa3f0ef35d9241c92439d74b8d5e9a81d814c2Bill Wendling /// BL branch target. 92662a816e89a9d77bf75e1328b09cf9235b4682aaJim Grosbach uint32_t getThumbBLTargetOpValue(const MCInst &MI, unsigned OpIdx, 9336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines SmallVectorImpl<MCFixup> &Fixups, 9436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines const MCSubtargetInfo &STI) const; 95662a816e89a9d77bf75e1328b09cf9235b4682aaJim Grosbach 9609aa3f0ef35d9241c92439d74b8d5e9a81d814c2Bill Wendling /// getThumbBLXTargetOpValue - Return encoding info for Thumb immediate 9709aa3f0ef35d9241c92439d74b8d5e9a81d814c2Bill Wendling /// BLX branch target. 9809aa3f0ef35d9241c92439d74b8d5e9a81d814c2Bill Wendling uint32_t getThumbBLXTargetOpValue(const MCInst &MI, unsigned OpIdx, 9936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines SmallVectorImpl<MCFixup> &Fixups, 10036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines const MCSubtargetInfo &STI) const; 10109aa3f0ef35d9241c92439d74b8d5e9a81d814c2Bill Wendling 102e246717c3a36a913fd4200776ed621649bb2b624Jim Grosbach /// getThumbBRTargetOpValue - Return encoding info for Thumb branch target. 103e246717c3a36a913fd4200776ed621649bb2b624Jim Grosbach uint32_t getThumbBRTargetOpValue(const MCInst &MI, unsigned OpIdx, 10436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines SmallVectorImpl<MCFixup> &Fixups, 10536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines const MCSubtargetInfo &STI) const; 106e246717c3a36a913fd4200776ed621649bb2b624Jim Grosbach 10701086451393ef33e82b6fad623989dd97dd70edfJim Grosbach /// getThumbBCCTargetOpValue - Return encoding info for Thumb branch target. 10801086451393ef33e82b6fad623989dd97dd70edfJim Grosbach uint32_t getThumbBCCTargetOpValue(const MCInst &MI, unsigned OpIdx, 10936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines SmallVectorImpl<MCFixup> &Fixups, 11036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines const MCSubtargetInfo &STI) const; 11101086451393ef33e82b6fad623989dd97dd70edfJim Grosbach 112027d6e8d1ca04e4096fb3a27579b861d861466c5Jim Grosbach /// getThumbCBTargetOpValue - Return encoding info for Thumb branch target. 113027d6e8d1ca04e4096fb3a27579b861d861466c5Jim Grosbach uint32_t getThumbCBTargetOpValue(const MCInst &MI, unsigned OpIdx, 11436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines SmallVectorImpl<MCFixup> &Fixups, 11536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines const MCSubtargetInfo &STI) const; 116dff2f7151f695b86db8c4b0c6604463bdb8a63eaBill Wendling 117c466b937dbdbaabeef0097fe340de1b8f49a3508Jim Grosbach /// getBranchTargetOpValue - Return encoding info for 24-bit immediate 118c466b937dbdbaabeef0097fe340de1b8f49a3508Jim Grosbach /// branch target. 119c466b937dbdbaabeef0097fe340de1b8f49a3508Jim Grosbach uint32_t getBranchTargetOpValue(const MCInst &MI, unsigned OpIdx, 12036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines SmallVectorImpl<MCFixup> &Fixups, 12136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines const MCSubtargetInfo &STI) const; 122c466b937dbdbaabeef0097fe340de1b8f49a3508Jim Grosbach 123c266600bec4b5ba0ee93ffdfeaafcab8f1295145Owen Anderson /// getUnconditionalBranchTargetOpValue - Return encoding info for 24-bit 124c266600bec4b5ba0ee93ffdfeaafcab8f1295145Owen Anderson /// immediate Thumb2 direct branch target. 125c266600bec4b5ba0ee93ffdfeaafcab8f1295145Owen Anderson uint32_t getUnconditionalBranchTargetOpValue(const MCInst &MI, unsigned OpIdx, 12636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines SmallVectorImpl<MCFixup> &Fixups, 12736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines const MCSubtargetInfo &STI) const; 12810096dbdef22a10a6a4444437c935ab428545525Owen Anderson 129685c350ae76b588e1f00c01a511fe8bd57f18394Jason W Kim /// getARMBranchTargetOpValue - Return encoding info for 24-bit immediate 130685c350ae76b588e1f00c01a511fe8bd57f18394Jason W Kim /// branch target. 131685c350ae76b588e1f00c01a511fe8bd57f18394Jason W Kim uint32_t getARMBranchTargetOpValue(const MCInst &MI, unsigned OpIdx, 13236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines SmallVectorImpl<MCFixup> &Fixups, 13336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines const MCSubtargetInfo &STI) const; 1347b25ecf6adbf3c4709c48033acfeb6ebbb4452abJim Grosbach uint32_t getARMBLTargetOpValue(const MCInst &MI, unsigned OpIdx, 13536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines SmallVectorImpl<MCFixup> &Fixups, 13636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines const MCSubtargetInfo &STI) const; 137f1eab597b2316c6cfcabfcee98895fedb2071722Owen Anderson uint32_t getARMBLXTargetOpValue(const MCInst &MI, unsigned OpIdx, 13836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines SmallVectorImpl<MCFixup> &Fixups, 13936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines const MCSubtargetInfo &STI) const; 140c266600bec4b5ba0ee93ffdfeaafcab8f1295145Owen Anderson 1415d14f9be7ba64162c7b996f36d419b11d8cdbe9aJim Grosbach /// getAdrLabelOpValue - Return encoding info for 12-bit immediate 1425d14f9be7ba64162c7b996f36d419b11d8cdbe9aJim Grosbach /// ADR label target. 1435d14f9be7ba64162c7b996f36d419b11d8cdbe9aJim Grosbach uint32_t getAdrLabelOpValue(const MCInst &MI, unsigned OpIdx, 14436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines SmallVectorImpl<MCFixup> &Fixups, 14536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines const MCSubtargetInfo &STI) const; 146d40963c4065432ec7e47879d3ca665a54ee903b6Jim Grosbach uint32_t getThumbAdrLabelOpValue(const MCInst &MI, unsigned OpIdx, 14736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines SmallVectorImpl<MCFixup> &Fixups, 14836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines const MCSubtargetInfo &STI) const; 149a838a25d59838adfa91463f6a918ae3adeb352c1Owen Anderson uint32_t getT2AdrLabelOpValue(const MCInst &MI, unsigned OpIdx, 15036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines SmallVectorImpl<MCFixup> &Fixups, 15136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines const MCSubtargetInfo &STI) const; 152971b83b67a9812556cdb97bb58aa96fb37af458dOwen Anderson 1535d14f9be7ba64162c7b996f36d419b11d8cdbe9aJim Grosbach 15492b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling /// getAddrModeImm12OpValue - Return encoding info for 'reg +/- imm12' 15592b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling /// operand. 156806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbach uint32_t getAddrModeImm12OpValue(const MCInst &MI, unsigned OpIdx, 15736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines SmallVectorImpl<MCFixup> &Fixups, 15836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines const MCSubtargetInfo &STI) const; 15992b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling 160f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling /// getThumbAddrModeRegRegOpValue - Return encoding for 'reg + reg' operand. 161f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling uint32_t getThumbAddrModeRegRegOpValue(const MCInst &MI, unsigned OpIdx, 16236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines SmallVectorImpl<MCFixup> &Fixups, 16336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines const MCSubtargetInfo &STI) const; 1640f4b60d43a289671082deee3bd56a3a055afb16aOwen Anderson 1659d63d90de5e57ad96f467b270544443a9284eb2bOwen Anderson /// getT2AddrModeImm8s4OpValue - Return encoding info for 'reg +/- imm8<<2' 1669d63d90de5e57ad96f467b270544443a9284eb2bOwen Anderson /// operand. 1679d63d90de5e57ad96f467b270544443a9284eb2bOwen Anderson uint32_t getT2AddrModeImm8s4OpValue(const MCInst &MI, unsigned OpIdx, 16836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines SmallVectorImpl<MCFixup> &Fixups, 16936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines const MCSubtargetInfo &STI) const; 170b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach 171b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach /// getT2AddrModeImm0_1020s4OpValue - Return encoding info for 'reg + imm8<<2' 172b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach /// operand. 173b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach uint32_t getT2AddrModeImm0_1020s4OpValue(const MCInst &MI, unsigned OpIdx, 17436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines SmallVectorImpl<MCFixup> &Fixups, 17536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines const MCSubtargetInfo &STI) const; 176b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach 177a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach /// getT2Imm8s4OpValue - Return encoding info for '+/- imm8<<2' 178a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach /// operand. 179a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach uint32_t getT2Imm8s4OpValue(const MCInst &MI, unsigned OpIdx, 18036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines SmallVectorImpl<MCFixup> &Fixups, 18136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines const MCSubtargetInfo &STI) const; 1829d63d90de5e57ad96f467b270544443a9284eb2bOwen Anderson 1839d63d90de5e57ad96f467b270544443a9284eb2bOwen Anderson 18454fea632b161f98e96ec7275922e35102bcecc5dJim Grosbach /// getLdStSORegOpValue - Return encoding info for 'reg +/- reg shop imm' 18554fea632b161f98e96ec7275922e35102bcecc5dJim Grosbach /// operand as needed by load/store instructions. 18654fea632b161f98e96ec7275922e35102bcecc5dJim Grosbach uint32_t getLdStSORegOpValue(const MCInst &MI, unsigned OpIdx, 18736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines SmallVectorImpl<MCFixup> &Fixups, 18836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines const MCSubtargetInfo &STI) const; 18954fea632b161f98e96ec7275922e35102bcecc5dJim Grosbach 1905d5eb9e3817a2765297e6dd5649ecb9b8b03e334Jim Grosbach /// getLdStmModeOpValue - Return encoding for load/store multiple mode. 1915d5eb9e3817a2765297e6dd5649ecb9b8b03e334Jim Grosbach uint32_t getLdStmModeOpValue(const MCInst &MI, unsigned OpIdx, 19236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines SmallVectorImpl<MCFixup> &Fixups, 19336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines const MCSubtargetInfo &STI) const { 1945d5eb9e3817a2765297e6dd5649ecb9b8b03e334Jim Grosbach ARM_AM::AMSubMode Mode = (ARM_AM::AMSubMode)MI.getOperand(OpIdx).getImm(); 1955d5eb9e3817a2765297e6dd5649ecb9b8b03e334Jim Grosbach switch (Mode) { 196bc2198133a1836598b54b943420748e75d5dea94Craig Topper default: llvm_unreachable("Unknown addressing sub-mode!"); 1975d5eb9e3817a2765297e6dd5649ecb9b8b03e334Jim Grosbach case ARM_AM::da: return 0; 1985d5eb9e3817a2765297e6dd5649ecb9b8b03e334Jim Grosbach case ARM_AM::ia: return 1; 1995d5eb9e3817a2765297e6dd5649ecb9b8b03e334Jim Grosbach case ARM_AM::db: return 2; 2005d5eb9e3817a2765297e6dd5649ecb9b8b03e334Jim Grosbach case ARM_AM::ib: return 3; 2015d5eb9e3817a2765297e6dd5649ecb9b8b03e334Jim Grosbach } 2025d5eb9e3817a2765297e6dd5649ecb9b8b03e334Jim Grosbach } 20399f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach /// getShiftOp - Return the shift opcode (bit[6:5]) of the immediate value. 20499f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach /// 20599f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach unsigned getShiftOp(ARM_AM::ShiftOpc ShOpc) const { 20699f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach switch (ShOpc) { 20799f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach case ARM_AM::no_shift: 20899f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach case ARM_AM::lsl: return 0; 20999f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach case ARM_AM::lsr: return 1; 21099f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach case ARM_AM::asr: return 2; 21199f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach case ARM_AM::ror: 21299f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach case ARM_AM::rrx: return 3; 21399f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach } 2144d6ccb5f68cd7c6418a209f1fa4dbade569e4493David Blaikie llvm_unreachable("Invalid ShiftOpc!"); 21599f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach } 21699f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach 21799f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach /// getAddrMode2OpValue - Return encoding for addrmode2 operands. 21899f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach uint32_t getAddrMode2OpValue(const MCInst &MI, unsigned OpIdx, 21936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines SmallVectorImpl<MCFixup> &Fixups, 22036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines const MCSubtargetInfo &STI) const; 22199f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach 22299f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach /// getAddrMode2OffsetOpValue - Return encoding for am2offset operands. 22399f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach uint32_t getAddrMode2OffsetOpValue(const MCInst &MI, unsigned OpIdx, 22436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines SmallVectorImpl<MCFixup> &Fixups, 22536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines const MCSubtargetInfo &STI) const; 22699f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach 2277ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach /// getPostIdxRegOpValue - Return encoding for postidx_reg operands. 2287ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach uint32_t getPostIdxRegOpValue(const MCInst &MI, unsigned OpIdx, 22936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines SmallVectorImpl<MCFixup> &Fixups, 23036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines const MCSubtargetInfo &STI) const; 2317ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach 2327eab97f260ba0f56d1d4a82f3a4eb2c979452011Jim Grosbach /// getAddrMode3OffsetOpValue - Return encoding for am3offset operands. 2337eab97f260ba0f56d1d4a82f3a4eb2c979452011Jim Grosbach uint32_t getAddrMode3OffsetOpValue(const MCInst &MI, unsigned OpIdx, 23436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines SmallVectorImpl<MCFixup> &Fixups, 23536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines const MCSubtargetInfo &STI) const; 2367eab97f260ba0f56d1d4a82f3a4eb2c979452011Jim Grosbach 237570a9226913ebe1af04832b8fb3273c70b4ee152Jim Grosbach /// getAddrMode3OpValue - Return encoding for addrmode3 operands. 238570a9226913ebe1af04832b8fb3273c70b4ee152Jim Grosbach uint32_t getAddrMode3OpValue(const MCInst &MI, unsigned OpIdx, 23936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines SmallVectorImpl<MCFixup> &Fixups, 24036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines const MCSubtargetInfo &STI) const; 2415d5eb9e3817a2765297e6dd5649ecb9b8b03e334Jim Grosbach 242d967cd096ae87accf2f1df86b2dfac969d9c9da2Jim Grosbach /// getAddrModeThumbSPOpValue - Return encoding info for 'reg +/- imm12' 243d967cd096ae87accf2f1df86b2dfac969d9c9da2Jim Grosbach /// operand. 244d967cd096ae87accf2f1df86b2dfac969d9c9da2Jim Grosbach uint32_t getAddrModeThumbSPOpValue(const MCInst &MI, unsigned OpIdx, 24536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines SmallVectorImpl<MCFixup> &Fixups, 24636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines const MCSubtargetInfo &STI) const; 247d967cd096ae87accf2f1df86b2dfac969d9c9da2Jim Grosbach 248f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling /// getAddrModeISOpValue - Encode the t_addrmode_is# operands. 249f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling uint32_t getAddrModeISOpValue(const MCInst &MI, unsigned OpIdx, 25036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines SmallVectorImpl<MCFixup> &Fixups, 25136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines const MCSubtargetInfo &STI) const; 2521fd374e9c1c074c1681336bef31e65f0170b0f7eBill Wendling 253b8958b031ec5163261f490f131780c5dc3d823d6Bill Wendling /// getAddrModePCOpValue - Return encoding for t_addrmode_pc operands. 254b8958b031ec5163261f490f131780c5dc3d823d6Bill Wendling uint32_t getAddrModePCOpValue(const MCInst &MI, unsigned OpIdx, 25536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines SmallVectorImpl<MCFixup> &Fixups, 25636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines const MCSubtargetInfo &STI) const; 257b8958b031ec5163261f490f131780c5dc3d823d6Bill Wendling 25892b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling /// getAddrMode5OpValue - Return encoding info for 'reg +/- imm8' operand. 259806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbach uint32_t getAddrMode5OpValue(const MCInst &MI, unsigned OpIdx, 26036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines SmallVectorImpl<MCFixup> &Fixups, 26136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines const MCSubtargetInfo &STI) const; 2623e5561247202bae994dd259a2d8dc4eff8f799f3Jim Grosbach 26308bd54987f4ae482de13436e7254ff08b23f825fJim Grosbach /// getCCOutOpValue - Return encoding of the 's' bit. 264806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbach unsigned getCCOutOpValue(const MCInst &MI, unsigned Op, 26536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines SmallVectorImpl<MCFixup> &Fixups, 26636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines const MCSubtargetInfo &STI) const { 26708bd54987f4ae482de13436e7254ff08b23f825fJim Grosbach // The operand is either reg0 or CPSR. The 's' bit is encoded as '0' or 26808bd54987f4ae482de13436e7254ff08b23f825fJim Grosbach // '1' respectively. 26908bd54987f4ae482de13436e7254ff08b23f825fJim Grosbach return MI.getOperand(Op).getReg() == ARM::CPSR; 27008bd54987f4ae482de13436e7254ff08b23f825fJim Grosbach } 271ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach 2722a6a93d5425b38546de2b6674719d52f565171d8Jim Grosbach /// getSOImmOpValue - Return an encoded 12-bit shifted-immediate value. 273806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbach unsigned getSOImmOpValue(const MCInst &MI, unsigned Op, 27436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines SmallVectorImpl<MCFixup> &Fixups, 27536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines const MCSubtargetInfo &STI) const { 27636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 27736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines const MCOperand &MO = MI.getOperand(Op); 27836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 27936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // We expect MO to be an immediate or an expression, 28036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // if it is an immediate - that's fine, just encode the value. 28136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // Otherwise - create a Fixup. 28236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (MO.isExpr()) { 28336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines const MCExpr *Expr = MO.getExpr(); 28436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // In instruction code this value always encoded as lowest 12 bits, 28536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // so we don't have to perform any specific adjustments. 28636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // Due to requirements of relocatable records we have to use FK_Data_4. 28736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // See ARMELFObjectWriter::ExplicitRelSym and 28836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // ARMELFObjectWriter::GetRelocTypeInner for more details. 28936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines MCFixupKind Kind = MCFixupKind(FK_Data_4); 29036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Fixups.push_back(MCFixup::Create(0, Expr, Kind, MI.getLoc())); 29136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return 0; 29236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 29336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 29436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines unsigned SoImm = MO.getImm(); 2952a6a93d5425b38546de2b6674719d52f565171d8Jim Grosbach int SoImmVal = ARM_AM::getSOImmVal(SoImm); 2962a6a93d5425b38546de2b6674719d52f565171d8Jim Grosbach assert(SoImmVal != -1 && "Not a valid so_imm value!"); 2972a6a93d5425b38546de2b6674719d52f565171d8Jim Grosbach 2982a6a93d5425b38546de2b6674719d52f565171d8Jim Grosbach // Encode rotate_imm. 2992a6a93d5425b38546de2b6674719d52f565171d8Jim Grosbach unsigned Binary = (ARM_AM::getSOImmValRot((unsigned)SoImmVal) >> 1) 3002a6a93d5425b38546de2b6674719d52f565171d8Jim Grosbach << ARMII::SoRotImmShift; 3012a6a93d5425b38546de2b6674719d52f565171d8Jim Grosbach 3022a6a93d5425b38546de2b6674719d52f565171d8Jim Grosbach // Encode immed_8. 3032a6a93d5425b38546de2b6674719d52f565171d8Jim Grosbach Binary |= ARM_AM::getSOImmValImm((unsigned)SoImmVal); 3042a6a93d5425b38546de2b6674719d52f565171d8Jim Grosbach return Binary; 3052a6a93d5425b38546de2b6674719d52f565171d8Jim Grosbach } 3067bf4c02789f97e32225fc248dff6622b994a15eeJim Grosbach 307ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines unsigned getModImmOpValue(const MCInst &MI, unsigned Op, 308ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines SmallVectorImpl<MCFixup> &Fixups, 309ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines const MCSubtargetInfo &ST) const { 310ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines const MCOperand &MO = MI.getOperand(Op); 311ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 312ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // Support for fixups (MCFixup) 313ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines if (MO.isExpr()) { 314ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines const MCExpr *Expr = MO.getExpr(); 315ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // In instruction code this value always encoded as lowest 12 bits, 316ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // so we don't have to perform any specific adjustments. 317ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // Due to requirements of relocatable records we have to use FK_Data_4. 318ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // See ARMELFObjectWriter::ExplicitRelSym and 319ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // ARMELFObjectWriter::GetRelocTypeInner for more details. 320ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines MCFixupKind Kind = MCFixupKind(FK_Data_4); 321ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Fixups.push_back(MCFixup::Create(0, Expr, Kind, MI.getLoc())); 322ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines return 0; 323ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines } 324ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 325ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // Immediate is already in its encoded format 326ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines return MO.getImm(); 327ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines } 328ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 3295de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson /// getT2SOImmOpValue - Return an encoded 12-bit shifted-immediate value. 3305de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson unsigned getT2SOImmOpValue(const MCInst &MI, unsigned Op, 33136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines SmallVectorImpl<MCFixup> &Fixups, 33236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines const MCSubtargetInfo &STI) const { 3335de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson unsigned SoImm = MI.getOperand(Op).getImm(); 3345de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson unsigned Encoded = ARM_AM::getT2SOImmVal(SoImm); 3355de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson assert(Encoded != ~0U && "Not a Thumb2 so_imm value?"); 3365de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson return Encoded; 3375de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson } 33808bd54987f4ae482de13436e7254ff08b23f825fJim Grosbach 33975579f739fbc99a92a15f3ce75bbd7628ba00f8cOwen Anderson unsigned getT2AddrModeSORegOpValue(const MCInst &MI, unsigned OpNum, 34036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines SmallVectorImpl<MCFixup> &Fixups, 34136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines const MCSubtargetInfo &STI) const; 34275579f739fbc99a92a15f3ce75bbd7628ba00f8cOwen Anderson unsigned getT2AddrModeImm8OpValue(const MCInst &MI, unsigned OpNum, 34336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines SmallVectorImpl<MCFixup> &Fixups, 34436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines const MCSubtargetInfo &STI) const; 3456af50f7dd12d82f0a80f3158102180eee4c921aaOwen Anderson unsigned getT2AddrModeImm8OffsetOpValue(const MCInst &MI, unsigned OpNum, 34636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines SmallVectorImpl<MCFixup> &Fixups, 34736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines const MCSubtargetInfo &STI) const; 3480e1bcdf4f7547bb5f47ed5ff5f2409a8f72f3609Owen Anderson unsigned getT2AddrModeImm12OffsetOpValue(const MCInst &MI, unsigned OpNum, 34936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines SmallVectorImpl<MCFixup> &Fixups, 35036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines const MCSubtargetInfo &STI) const; 35175579f739fbc99a92a15f3ce75bbd7628ba00f8cOwen Anderson 352ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach /// getSORegOpValue - Return an encoded so_reg shifted register value. 353152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson unsigned getSORegRegOpValue(const MCInst &MI, unsigned Op, 35436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines SmallVectorImpl<MCFixup> &Fixups, 35536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines const MCSubtargetInfo &STI) const; 356152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson unsigned getSORegImmOpValue(const MCInst &MI, unsigned Op, 35736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines SmallVectorImpl<MCFixup> &Fixups, 35836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines const MCSubtargetInfo &STI) const; 3595de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson unsigned getT2SORegOpValue(const MCInst &MI, unsigned Op, 36036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines SmallVectorImpl<MCFixup> &Fixups, 36136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines const MCSubtargetInfo &STI) const; 362ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach 363806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbach unsigned getNEONVcvtImm32OpValue(const MCInst &MI, unsigned Op, 36436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines SmallVectorImpl<MCFixup> &Fixups, 36536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines const MCSubtargetInfo &STI) const { 366498ec20703c89d0c2890b0967791f0f5f2b59a2fOwen Anderson return 64 - MI.getOperand(Op).getImm(); 367498ec20703c89d0c2890b0967791f0f5f2b59a2fOwen Anderson } 3688abe32af38b66bf4577526b23b6af6ec7eb6c155Jim Grosbach 369806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbach unsigned getBitfieldInvertedMaskOpValue(const MCInst &MI, unsigned Op, 37036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines SmallVectorImpl<MCFixup> &Fixups, 37136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines const MCSubtargetInfo &STI) const; 3723fea19105d4929ad694f0b6272de31924c9f9f09Jim Grosbach 373806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbach unsigned getRegisterListOpValue(const MCInst &MI, unsigned Op, 37436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines SmallVectorImpl<MCFixup> &Fixups, 37536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines const MCSubtargetInfo &STI) const; 376806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbach unsigned getAddrMode6AddressOpValue(const MCInst &MI, unsigned Op, 37736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines SmallVectorImpl<MCFixup> &Fixups, 37836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines const MCSubtargetInfo &STI) const; 379183c627d89be5d0e8f3255ab7f6d1204c2fabedfMon P Wang unsigned getAddrMode6OneLane32AddressOpValue(const MCInst &MI, unsigned Op, 38036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines SmallVectorImpl<MCFixup> &Fixups, 38136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines const MCSubtargetInfo &STI) const; 3828e0c7b52877983b4838e54e233449912fc1a2325Bob Wilson unsigned getAddrMode6DupAddressOpValue(const MCInst &MI, unsigned Op, 38336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines SmallVectorImpl<MCFixup> &Fixups, 38436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines const MCSubtargetInfo &STI) const; 385806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbach unsigned getAddrMode6OffsetOpValue(const MCInst &MI, unsigned Op, 38636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines SmallVectorImpl<MCFixup> &Fixups, 38736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines const MCSubtargetInfo &STI) const; 3886b5252db2db5eeeadec4602329ac56beb6dea54aJim Grosbach 3893116dce33840a115130c5f8ffcb9679d023496d6Bill Wendling unsigned getShiftRight8Imm(const MCInst &MI, unsigned Op, 39036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines SmallVectorImpl<MCFixup> &Fixups, 39136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines const MCSubtargetInfo &STI) const; 3923116dce33840a115130c5f8ffcb9679d023496d6Bill Wendling unsigned getShiftRight16Imm(const MCInst &MI, unsigned Op, 39336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines SmallVectorImpl<MCFixup> &Fixups, 39436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines const MCSubtargetInfo &STI) const; 3953116dce33840a115130c5f8ffcb9679d023496d6Bill Wendling unsigned getShiftRight32Imm(const MCInst &MI, unsigned Op, 39636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines SmallVectorImpl<MCFixup> &Fixups, 39736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines const MCSubtargetInfo &STI) const; 3983116dce33840a115130c5f8ffcb9679d023496d6Bill Wendling unsigned getShiftRight64Imm(const MCInst &MI, unsigned Op, 39936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines SmallVectorImpl<MCFixup> &Fixups, 40036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines const MCSubtargetInfo &STI) const; 401a656b63ee4d5b0e3f4d26a55dd4cc69795746684Bill Wendling 4026d74631062e4464326eb5c680a4d62d340fa42ebOwen Anderson unsigned getThumbSRImmOpValue(const MCInst &MI, unsigned Op, 40336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines SmallVectorImpl<MCFixup> &Fixups, 40436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines const MCSubtargetInfo &STI) const; 4056d74631062e4464326eb5c680a4d62d340fa42ebOwen Anderson 406c7139a6f0d3acd198ab9eb536ea1ec52e61ff130Owen Anderson unsigned NEONThumb2DataIPostEncoder(const MCInst &MI, 40736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines unsigned EncodedValue, 40836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines const MCSubtargetInfo &STI) const; 40957dac88f775c1191a98cff89abd1f7ad33df5e29Owen Anderson unsigned NEONThumb2LoadStorePostEncoder(const MCInst &MI, 41036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines unsigned EncodedValue, 41136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines const MCSubtargetInfo &STI) const; 4128f143913141991baaa535ca0da7c8a81606d6392Owen Anderson unsigned NEONThumb2DupPostEncoder(const MCInst &MI, 41336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines unsigned EncodedValue, 41436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines const MCSubtargetInfo &STI) const; 41519c14abf1c4ccebfa7d07bdd6ea8462a15c0b749Joey Gouly unsigned NEONThumb2V8PostEncoder(const MCInst &MI, 41636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines unsigned EncodedValue, 41736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines const MCSubtargetInfo &STI) const; 418cf590263cd5c24ccf1d08cef612738d99cd980d9Bill Wendling 419cf590263cd5c24ccf1d08cef612738d99cd980d9Bill Wendling unsigned VFPThumb2PostEncoder(const MCInst &MI, 42036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines unsigned EncodedValue, 42136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines const MCSubtargetInfo &STI) const; 422c7139a6f0d3acd198ab9eb536ea1ec52e61ff130Owen Anderson 42370933266ae73c891d9d1c2f0de72ecd1db8f86dfJim Grosbach void EmitByte(unsigned char C, raw_ostream &OS) const { 424568eeedea72c274abbba1310c18a31eef78e14a4Jim Grosbach OS << (char)C; 425568eeedea72c274abbba1310c18a31eef78e14a4Jim Grosbach } 426568eeedea72c274abbba1310c18a31eef78e14a4Jim Grosbach 42770933266ae73c891d9d1c2f0de72ecd1db8f86dfJim Grosbach void EmitConstant(uint64_t Val, unsigned Size, raw_ostream &OS) const { 428568eeedea72c274abbba1310c18a31eef78e14a4Jim Grosbach // Output the constant in little endian byte order. 429568eeedea72c274abbba1310c18a31eef78e14a4Jim Grosbach for (unsigned i = 0; i != Size; ++i) { 43036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines unsigned Shift = IsLittleEndian ? i * 8 : (Size - 1 - i) * 8; 43136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines EmitByte((Val >> Shift) & 0xff, OS); 432568eeedea72c274abbba1310c18a31eef78e14a4Jim Grosbach } 433568eeedea72c274abbba1310c18a31eef78e14a4Jim Grosbach } 434568eeedea72c274abbba1310c18a31eef78e14a4Jim Grosbach 435568eeedea72c274abbba1310c18a31eef78e14a4Jim Grosbach void EncodeInstruction(const MCInst &MI, raw_ostream &OS, 43636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines SmallVectorImpl<MCFixup> &Fixups, 43736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines const MCSubtargetInfo &STI) const override; 438568eeedea72c274abbba1310c18a31eef78e14a4Jim Grosbach}; 439568eeedea72c274abbba1310c18a31eef78e14a4Jim Grosbach 440568eeedea72c274abbba1310c18a31eef78e14a4Jim Grosbach} // end anonymous namespace 441568eeedea72c274abbba1310c18a31eef78e14a4Jim Grosbach 44236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen HinesMCCodeEmitter *llvm::createARMLEMCCodeEmitter(const MCInstrInfo &MCII, 44336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines const MCRegisterInfo &MRI, 44436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines MCContext &Ctx) { 44536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return new ARMMCCodeEmitter(MCII, Ctx, true); 44636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines} 44736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 44836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen HinesMCCodeEmitter *llvm::createARMBEMCCodeEmitter(const MCInstrInfo &MCII, 44936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines const MCRegisterInfo &MRI, 45036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines MCContext &Ctx) { 45136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return new ARMMCCodeEmitter(MCII, Ctx, false); 452568eeedea72c274abbba1310c18a31eef78e14a4Jim Grosbach} 453568eeedea72c274abbba1310c18a31eef78e14a4Jim Grosbach 4547bf4c02789f97e32225fc248dff6622b994a15eeJim Grosbach/// NEONThumb2DataIPostEncoder - Post-process encoded NEON data-processing 4557bf4c02789f97e32225fc248dff6622b994a15eeJim Grosbach/// instructions, and rewrite them to their Thumb2 form if we are currently in 456c7139a6f0d3acd198ab9eb536ea1ec52e61ff130Owen Anderson/// Thumb2 mode. 457c7139a6f0d3acd198ab9eb536ea1ec52e61ff130Owen Andersonunsigned ARMMCCodeEmitter::NEONThumb2DataIPostEncoder(const MCInst &MI, 45836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines unsigned EncodedValue, 45936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines const MCSubtargetInfo &STI) const { 46036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (isThumb2(STI)) { 4617bf4c02789f97e32225fc248dff6622b994a15eeJim Grosbach // NEON Thumb2 data-processsing encodings are very simple: bit 24 is moved 462c7139a6f0d3acd198ab9eb536ea1ec52e61ff130Owen Anderson // to bit 12 of the high half-word (i.e. bit 28), and bits 27-24 are 463c7139a6f0d3acd198ab9eb536ea1ec52e61ff130Owen Anderson // set to 1111. 464c7139a6f0d3acd198ab9eb536ea1ec52e61ff130Owen Anderson unsigned Bit24 = EncodedValue & 0x01000000; 465c7139a6f0d3acd198ab9eb536ea1ec52e61ff130Owen Anderson unsigned Bit28 = Bit24 << 4; 466c7139a6f0d3acd198ab9eb536ea1ec52e61ff130Owen Anderson EncodedValue &= 0xEFFFFFFF; 467c7139a6f0d3acd198ab9eb536ea1ec52e61ff130Owen Anderson EncodedValue |= Bit28; 468c7139a6f0d3acd198ab9eb536ea1ec52e61ff130Owen Anderson EncodedValue |= 0x0F000000; 469c7139a6f0d3acd198ab9eb536ea1ec52e61ff130Owen Anderson } 4707bf4c02789f97e32225fc248dff6622b994a15eeJim Grosbach 471c7139a6f0d3acd198ab9eb536ea1ec52e61ff130Owen Anderson return EncodedValue; 472c7139a6f0d3acd198ab9eb536ea1ec52e61ff130Owen Anderson} 473c7139a6f0d3acd198ab9eb536ea1ec52e61ff130Owen Anderson 47457dac88f775c1191a98cff89abd1f7ad33df5e29Owen Anderson/// NEONThumb2LoadStorePostEncoder - Post-process encoded NEON load/store 4757bf4c02789f97e32225fc248dff6622b994a15eeJim Grosbach/// instructions, and rewrite them to their Thumb2 form if we are currently in 47657dac88f775c1191a98cff89abd1f7ad33df5e29Owen Anderson/// Thumb2 mode. 47757dac88f775c1191a98cff89abd1f7ad33df5e29Owen Andersonunsigned ARMMCCodeEmitter::NEONThumb2LoadStorePostEncoder(const MCInst &MI, 47836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines unsigned EncodedValue, 47936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines const MCSubtargetInfo &STI) const { 48036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (isThumb2(STI)) { 48157dac88f775c1191a98cff89abd1f7ad33df5e29Owen Anderson EncodedValue &= 0xF0FFFFFF; 48257dac88f775c1191a98cff89abd1f7ad33df5e29Owen Anderson EncodedValue |= 0x09000000; 48357dac88f775c1191a98cff89abd1f7ad33df5e29Owen Anderson } 4847bf4c02789f97e32225fc248dff6622b994a15eeJim Grosbach 48557dac88f775c1191a98cff89abd1f7ad33df5e29Owen Anderson return EncodedValue; 48657dac88f775c1191a98cff89abd1f7ad33df5e29Owen Anderson} 48757dac88f775c1191a98cff89abd1f7ad33df5e29Owen Anderson 4888f143913141991baaa535ca0da7c8a81606d6392Owen Anderson/// NEONThumb2DupPostEncoder - Post-process encoded NEON vdup 4897bf4c02789f97e32225fc248dff6622b994a15eeJim Grosbach/// instructions, and rewrite them to their Thumb2 form if we are currently in 4908f143913141991baaa535ca0da7c8a81606d6392Owen Anderson/// Thumb2 mode. 4918f143913141991baaa535ca0da7c8a81606d6392Owen Andersonunsigned ARMMCCodeEmitter::NEONThumb2DupPostEncoder(const MCInst &MI, 49236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines unsigned EncodedValue, 49336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines const MCSubtargetInfo &STI) const { 49436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (isThumb2(STI)) { 4958f143913141991baaa535ca0da7c8a81606d6392Owen Anderson EncodedValue &= 0x00FFFFFF; 4968f143913141991baaa535ca0da7c8a81606d6392Owen Anderson EncodedValue |= 0xEE000000; 4978f143913141991baaa535ca0da7c8a81606d6392Owen Anderson } 4987bf4c02789f97e32225fc248dff6622b994a15eeJim Grosbach 4998f143913141991baaa535ca0da7c8a81606d6392Owen Anderson return EncodedValue; 5008f143913141991baaa535ca0da7c8a81606d6392Owen Anderson} 5018f143913141991baaa535ca0da7c8a81606d6392Owen Anderson 50219c14abf1c4ccebfa7d07bdd6ea8462a15c0b749Joey Gouly/// Post-process encoded NEON v8 instructions, and rewrite them to Thumb2 form 50319c14abf1c4ccebfa7d07bdd6ea8462a15c0b749Joey Gouly/// if we are in Thumb2. 50419c14abf1c4ccebfa7d07bdd6ea8462a15c0b749Joey Goulyunsigned ARMMCCodeEmitter::NEONThumb2V8PostEncoder(const MCInst &MI, 50536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines unsigned EncodedValue, 50636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines const MCSubtargetInfo &STI) const { 50736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (isThumb2(STI)) { 50819c14abf1c4ccebfa7d07bdd6ea8462a15c0b749Joey Gouly EncodedValue |= 0xC000000; // Set bits 27-26 50919c14abf1c4ccebfa7d07bdd6ea8462a15c0b749Joey Gouly } 51019c14abf1c4ccebfa7d07bdd6ea8462a15c0b749Joey Gouly 51119c14abf1c4ccebfa7d07bdd6ea8462a15c0b749Joey Gouly return EncodedValue; 51219c14abf1c4ccebfa7d07bdd6ea8462a15c0b749Joey Gouly} 51319c14abf1c4ccebfa7d07bdd6ea8462a15c0b749Joey Gouly 514cf590263cd5c24ccf1d08cef612738d99cd980d9Bill Wendling/// VFPThumb2PostEncoder - Post-process encoded VFP instructions and rewrite 515cf590263cd5c24ccf1d08cef612738d99cd980d9Bill Wendling/// them to their Thumb2 form if we are currently in Thumb2 mode. 516cf590263cd5c24ccf1d08cef612738d99cd980d9Bill Wendlingunsigned ARMMCCodeEmitter:: 51736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen HinesVFPThumb2PostEncoder(const MCInst &MI, unsigned EncodedValue, 51836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines const MCSubtargetInfo &STI) const { 51936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (isThumb2(STI)) { 520cf590263cd5c24ccf1d08cef612738d99cd980d9Bill Wendling EncodedValue &= 0x0FFFFFFF; 521cf590263cd5c24ccf1d08cef612738d99cd980d9Bill Wendling EncodedValue |= 0xE0000000; 522cf590263cd5c24ccf1d08cef612738d99cd980d9Bill Wendling } 523cf590263cd5c24ccf1d08cef612738d99cd980d9Bill Wendling return EncodedValue; 524cf590263cd5c24ccf1d08cef612738d99cd980d9Bill Wendling} 52557dac88f775c1191a98cff89abd1f7ad33df5e29Owen Anderson 52656ac907c57fcfddfd650238f03c856a9d55987e5Jim Grosbach/// getMachineOpValue - Return binary encoding of operand. If the machine 52756ac907c57fcfddfd650238f03c856a9d55987e5Jim Grosbach/// operand requires relocation, record the relocation and return zero. 528806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbachunsigned ARMMCCodeEmitter:: 529806e80ef42bdb416f409142a1ff1d4e8752baac8Jim GrosbachgetMachineOpValue(const MCInst &MI, const MCOperand &MO, 53036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines SmallVectorImpl<MCFixup> &Fixups, 53136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines const MCSubtargetInfo &STI) const { 532bbbdcd453d22258cb4dd217eddf016668fcebf84Bill Wendling if (MO.isReg()) { 5330800ce71896ccd7f49b37861a8cfbc21b6b10022Bill Wendling unsigned Reg = MO.getReg(); 53499cb622041a0839c7dfcf0263c5102a305a0fdb5Bill Wendling unsigned RegNo = CTX.getRegisterInfo()->getEncodingValue(Reg); 535d8a11c25fa64c152628cfcf5f9d36eb60242b302Jim Grosbach 536b0708d292bbe04cfcfe0c5cb5e27d8a872c9839aJim Grosbach // Q registers are encoded as 2x their register number. 5370800ce71896ccd7f49b37861a8cfbc21b6b10022Bill Wendling switch (Reg) { 5380800ce71896ccd7f49b37861a8cfbc21b6b10022Bill Wendling default: 5390800ce71896ccd7f49b37861a8cfbc21b6b10022Bill Wendling return RegNo; 5400800ce71896ccd7f49b37861a8cfbc21b6b10022Bill Wendling case ARM::Q0: case ARM::Q1: case ARM::Q2: case ARM::Q3: 5410800ce71896ccd7f49b37861a8cfbc21b6b10022Bill Wendling case ARM::Q4: case ARM::Q5: case ARM::Q6: case ARM::Q7: 5420800ce71896ccd7f49b37861a8cfbc21b6b10022Bill Wendling case ARM::Q8: case ARM::Q9: case ARM::Q10: case ARM::Q11: 5430800ce71896ccd7f49b37861a8cfbc21b6b10022Bill Wendling case ARM::Q12: case ARM::Q13: case ARM::Q14: case ARM::Q15: 5440800ce71896ccd7f49b37861a8cfbc21b6b10022Bill Wendling return 2 * RegNo; 54590d4cf931477b497553a9f2d0ed53377dd5dd88cOwen Anderson } 546bbbdcd453d22258cb4dd217eddf016668fcebf84Bill Wendling } else if (MO.isImm()) { 54756ac907c57fcfddfd650238f03c856a9d55987e5Jim Grosbach return static_cast<unsigned>(MO.getImm()); 548bbbdcd453d22258cb4dd217eddf016668fcebf84Bill Wendling } else if (MO.isFPImm()) { 549bbbdcd453d22258cb4dd217eddf016668fcebf84Bill Wendling return static_cast<unsigned>(APFloat(MO.getFPImm()) 550bbbdcd453d22258cb4dd217eddf016668fcebf84Bill Wendling .bitcastToAPInt().getHiBits(32).getLimitedValue()); 5510800ce71896ccd7f49b37861a8cfbc21b6b10022Bill Wendling } 5520800ce71896ccd7f49b37861a8cfbc21b6b10022Bill Wendling 553817c1a6dddadb4664738777d224bc7eae6e62cf3Jim Grosbach llvm_unreachable("Unable to encode MCOperand!"); 55456ac907c57fcfddfd650238f03c856a9d55987e5Jim Grosbach} 55556ac907c57fcfddfd650238f03c856a9d55987e5Jim Grosbach 5565df0e0a61d6ac0e8dcf1a600bdc28d3e4a8db0adBill Wendling/// getAddrModeImmOpValue - Return encoding info for 'reg +/- imm' operand. 557806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbachbool ARMMCCodeEmitter:: 558806e80ef42bdb416f409142a1ff1d4e8752baac8Jim GrosbachEncodeAddrModeOpValues(const MCInst &MI, unsigned OpIdx, unsigned &Reg, 55936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines unsigned &Imm, SmallVectorImpl<MCFixup> &Fixups, 56036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines const MCSubtargetInfo &STI) const { 5613e5561247202bae994dd259a2d8dc4eff8f799f3Jim Grosbach const MCOperand &MO = MI.getOperand(OpIdx); 5623e5561247202bae994dd259a2d8dc4eff8f799f3Jim Grosbach const MCOperand &MO1 = MI.getOperand(OpIdx + 1); 5639af3d1c0dc2250793ada1ca6cfa98e9f1253f7f9Jim Grosbach 56499cb622041a0839c7dfcf0263c5102a305a0fdb5Bill Wendling Reg = CTX.getRegisterInfo()->getEncodingValue(MO.getReg()); 56592b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling 56692b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling int32_t SImm = MO1.getImm(); 56792b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling bool isAdd = true; 5685df0e0a61d6ac0e8dcf1a600bdc28d3e4a8db0adBill Wendling 569ab682a2090f795d0b67f29889622da0a74cd97c3Jim Grosbach // Special value for #-0 5700da10cf44d0f22111dae728bb535ade2283d976bOwen Anderson if (SImm == INT32_MIN) { 57192b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling SImm = 0; 5720da10cf44d0f22111dae728bb535ade2283d976bOwen Anderson isAdd = false; 5730da10cf44d0f22111dae728bb535ade2283d976bOwen Anderson } 5745df0e0a61d6ac0e8dcf1a600bdc28d3e4a8db0adBill Wendling 575ab682a2090f795d0b67f29889622da0a74cd97c3Jim Grosbach // Immediate is always encoded as positive. The 'U' bit controls add vs sub. 57692b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling if (SImm < 0) { 57792b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling SImm = -SImm; 57892b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling isAdd = false; 57992b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling } 58092b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling 58192b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling Imm = SImm; 58292b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling return isAdd; 58392b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling} 5845df0e0a61d6ac0e8dcf1a600bdc28d3e4a8db0adBill Wendling 585dff2f7151f695b86db8c4b0c6604463bdb8a63eaBill Wendling/// getBranchTargetOpValue - Helper function to get the branch target operand, 586dff2f7151f695b86db8c4b0c6604463bdb8a63eaBill Wendling/// which is either an immediate or requires a fixup. 587dff2f7151f695b86db8c4b0c6604463bdb8a63eaBill Wendlingstatic uint32_t getBranchTargetOpValue(const MCInst &MI, unsigned OpIdx, 588dff2f7151f695b86db8c4b0c6604463bdb8a63eaBill Wendling unsigned FixupKind, 58936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines SmallVectorImpl<MCFixup> &Fixups, 59036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines const MCSubtargetInfo &STI) { 591662a816e89a9d77bf75e1328b09cf9235b4682aaJim Grosbach const MCOperand &MO = MI.getOperand(OpIdx); 592662a816e89a9d77bf75e1328b09cf9235b4682aaJim Grosbach 593662a816e89a9d77bf75e1328b09cf9235b4682aaJim Grosbach // If the destination is an immediate, we have nothing to do. 594662a816e89a9d77bf75e1328b09cf9235b4682aaJim Grosbach if (MO.isImm()) return MO.getImm(); 595dff2f7151f695b86db8c4b0c6604463bdb8a63eaBill Wendling assert(MO.isExpr() && "Unexpected branch target type!"); 596662a816e89a9d77bf75e1328b09cf9235b4682aaJim Grosbach const MCExpr *Expr = MO.getExpr(); 597dff2f7151f695b86db8c4b0c6604463bdb8a63eaBill Wendling MCFixupKind Kind = MCFixupKind(FixupKind); 59842e6bd38e02e2e1c2cc50d2f12036c38c4ea3ab0Jim Grosbach Fixups.push_back(MCFixup::Create(0, Expr, Kind, MI.getLoc())); 599662a816e89a9d77bf75e1328b09cf9235b4682aaJim Grosbach 600662a816e89a9d77bf75e1328b09cf9235b4682aaJim Grosbach // All of the information is in the fixup. 601662a816e89a9d77bf75e1328b09cf9235b4682aaJim Grosbach return 0; 602662a816e89a9d77bf75e1328b09cf9235b4682aaJim Grosbach} 603662a816e89a9d77bf75e1328b09cf9235b4682aaJim Grosbach 604559c277aa9242dd5b32d2f2ccc353d938f886ee9Owen Anderson// Thumb BL and BLX use a strange offset encoding where bits 22 and 21 are 605559c277aa9242dd5b32d2f2ccc353d938f886ee9Owen Anderson// determined by negating them and XOR'ing them with bit 23. 606559c277aa9242dd5b32d2f2ccc353d938f886ee9Owen Andersonstatic int32_t encodeThumbBLOffset(int32_t offset) { 607559c277aa9242dd5b32d2f2ccc353d938f886ee9Owen Anderson offset >>= 1; 608559c277aa9242dd5b32d2f2ccc353d938f886ee9Owen Anderson uint32_t S = (offset & 0x800000) >> 23; 609559c277aa9242dd5b32d2f2ccc353d938f886ee9Owen Anderson uint32_t J1 = (offset & 0x400000) >> 22; 610559c277aa9242dd5b32d2f2ccc353d938f886ee9Owen Anderson uint32_t J2 = (offset & 0x200000) >> 21; 611559c277aa9242dd5b32d2f2ccc353d938f886ee9Owen Anderson J1 = (~J1 & 0x1); 612559c277aa9242dd5b32d2f2ccc353d938f886ee9Owen Anderson J2 = (~J2 & 0x1); 613559c277aa9242dd5b32d2f2ccc353d938f886ee9Owen Anderson J1 ^= S; 614559c277aa9242dd5b32d2f2ccc353d938f886ee9Owen Anderson J2 ^= S; 615559c277aa9242dd5b32d2f2ccc353d938f886ee9Owen Anderson 616559c277aa9242dd5b32d2f2ccc353d938f886ee9Owen Anderson offset &= ~0x600000; 617559c277aa9242dd5b32d2f2ccc353d938f886ee9Owen Anderson offset |= J1 << 22; 618559c277aa9242dd5b32d2f2ccc353d938f886ee9Owen Anderson offset |= J2 << 21; 619559c277aa9242dd5b32d2f2ccc353d938f886ee9Owen Anderson 620559c277aa9242dd5b32d2f2ccc353d938f886ee9Owen Anderson return offset; 621559c277aa9242dd5b32d2f2ccc353d938f886ee9Owen Anderson} 622559c277aa9242dd5b32d2f2ccc353d938f886ee9Owen Anderson 623dff2f7151f695b86db8c4b0c6604463bdb8a63eaBill Wendling/// getThumbBLTargetOpValue - Return encoding info for immediate branch target. 624c466b937dbdbaabeef0097fe340de1b8f49a3508Jim Grosbachuint32_t ARMMCCodeEmitter:: 625dff2f7151f695b86db8c4b0c6604463bdb8a63eaBill WendlinggetThumbBLTargetOpValue(const MCInst &MI, unsigned OpIdx, 62636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines SmallVectorImpl<MCFixup> &Fixups, 62736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines const MCSubtargetInfo &STI) const { 628559c277aa9242dd5b32d2f2ccc353d938f886ee9Owen Anderson const MCOperand MO = MI.getOperand(OpIdx); 629559c277aa9242dd5b32d2f2ccc353d938f886ee9Owen Anderson if (MO.isExpr()) 630559c277aa9242dd5b32d2f2ccc353d938f886ee9Owen Anderson return ::getBranchTargetOpValue(MI, OpIdx, ARM::fixup_arm_thumb_bl, 63136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Fixups, STI); 632559c277aa9242dd5b32d2f2ccc353d938f886ee9Owen Anderson return encodeThumbBLOffset(MO.getImm()); 633dff2f7151f695b86db8c4b0c6604463bdb8a63eaBill Wendling} 634c466b937dbdbaabeef0097fe340de1b8f49a3508Jim Grosbach 63509aa3f0ef35d9241c92439d74b8d5e9a81d814c2Bill Wendling/// getThumbBLXTargetOpValue - Return encoding info for Thumb immediate 63609aa3f0ef35d9241c92439d74b8d5e9a81d814c2Bill Wendling/// BLX branch target. 63709aa3f0ef35d9241c92439d74b8d5e9a81d814c2Bill Wendlinguint32_t ARMMCCodeEmitter:: 63809aa3f0ef35d9241c92439d74b8d5e9a81d814c2Bill WendlinggetThumbBLXTargetOpValue(const MCInst &MI, unsigned OpIdx, 63936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines SmallVectorImpl<MCFixup> &Fixups, 64036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines const MCSubtargetInfo &STI) const { 641559c277aa9242dd5b32d2f2ccc353d938f886ee9Owen Anderson const MCOperand MO = MI.getOperand(OpIdx); 642559c277aa9242dd5b32d2f2ccc353d938f886ee9Owen Anderson if (MO.isExpr()) 643559c277aa9242dd5b32d2f2ccc353d938f886ee9Owen Anderson return ::getBranchTargetOpValue(MI, OpIdx, ARM::fixup_arm_thumb_blx, 64436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Fixups, STI); 645559c277aa9242dd5b32d2f2ccc353d938f886ee9Owen Anderson return encodeThumbBLOffset(MO.getImm()); 64609aa3f0ef35d9241c92439d74b8d5e9a81d814c2Bill Wendling} 64709aa3f0ef35d9241c92439d74b8d5e9a81d814c2Bill Wendling 648e246717c3a36a913fd4200776ed621649bb2b624Jim Grosbach/// getThumbBRTargetOpValue - Return encoding info for Thumb branch target. 649e246717c3a36a913fd4200776ed621649bb2b624Jim Grosbachuint32_t ARMMCCodeEmitter:: 650e246717c3a36a913fd4200776ed621649bb2b624Jim GrosbachgetThumbBRTargetOpValue(const MCInst &MI, unsigned OpIdx, 65136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines SmallVectorImpl<MCFixup> &Fixups, 65236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines const MCSubtargetInfo &STI) const { 653391ac65377f2ad5e48a796e75120959e22430605Owen Anderson const MCOperand MO = MI.getOperand(OpIdx); 654391ac65377f2ad5e48a796e75120959e22430605Owen Anderson if (MO.isExpr()) 655559c277aa9242dd5b32d2f2ccc353d938f886ee9Owen Anderson return ::getBranchTargetOpValue(MI, OpIdx, ARM::fixup_arm_thumb_br, 65636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Fixups, STI); 657391ac65377f2ad5e48a796e75120959e22430605Owen Anderson return (MO.getImm() >> 1); 658e246717c3a36a913fd4200776ed621649bb2b624Jim Grosbach} 659e246717c3a36a913fd4200776ed621649bb2b624Jim Grosbach 66001086451393ef33e82b6fad623989dd97dd70edfJim Grosbach/// getThumbBCCTargetOpValue - Return encoding info for Thumb branch target. 66101086451393ef33e82b6fad623989dd97dd70edfJim Grosbachuint32_t ARMMCCodeEmitter:: 66201086451393ef33e82b6fad623989dd97dd70edfJim GrosbachgetThumbBCCTargetOpValue(const MCInst &MI, unsigned OpIdx, 66336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines SmallVectorImpl<MCFixup> &Fixups, 66436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines const MCSubtargetInfo &STI) const { 665721cb1fde07423fd1905338d443172a8028ad634Owen Anderson const MCOperand MO = MI.getOperand(OpIdx); 666721cb1fde07423fd1905338d443172a8028ad634Owen Anderson if (MO.isExpr()) 667721cb1fde07423fd1905338d443172a8028ad634Owen Anderson return ::getBranchTargetOpValue(MI, OpIdx, ARM::fixup_arm_thumb_bcc, 66836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Fixups, STI); 669721cb1fde07423fd1905338d443172a8028ad634Owen Anderson return (MO.getImm() >> 1); 67001086451393ef33e82b6fad623989dd97dd70edfJim Grosbach} 67101086451393ef33e82b6fad623989dd97dd70edfJim Grosbach 672027d6e8d1ca04e4096fb3a27579b861d861466c5Jim Grosbach/// getThumbCBTargetOpValue - Return encoding info for Thumb branch target. 673dff2f7151f695b86db8c4b0c6604463bdb8a63eaBill Wendlinguint32_t ARMMCCodeEmitter:: 674027d6e8d1ca04e4096fb3a27579b861d861466c5Jim GrosbachgetThumbCBTargetOpValue(const MCInst &MI, unsigned OpIdx, 67536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines SmallVectorImpl<MCFixup> &Fixups, 67636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines const MCSubtargetInfo &STI) const { 67721df36c57afc588c8073a070a47e3ba45fa87270Owen Anderson const MCOperand MO = MI.getOperand(OpIdx); 67821df36c57afc588c8073a070a47e3ba45fa87270Owen Anderson if (MO.isExpr()) 67936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return ::getBranchTargetOpValue(MI, OpIdx, ARM::fixup_arm_thumb_cb, Fixups, STI); 68021df36c57afc588c8073a070a47e3ba45fa87270Owen Anderson return (MO.getImm() >> 1); 681dff2f7151f695b86db8c4b0c6604463bdb8a63eaBill Wendling} 682c466b937dbdbaabeef0097fe340de1b8f49a3508Jim Grosbach 683685c350ae76b588e1f00c01a511fe8bd57f18394Jason W Kim/// Return true if this branch has a non-always predication 684685c350ae76b588e1f00c01a511fe8bd57f18394Jason W Kimstatic bool HasConditionalBranch(const MCInst &MI) { 685685c350ae76b588e1f00c01a511fe8bd57f18394Jason W Kim int NumOp = MI.getNumOperands(); 686685c350ae76b588e1f00c01a511fe8bd57f18394Jason W Kim if (NumOp >= 2) { 687685c350ae76b588e1f00c01a511fe8bd57f18394Jason W Kim for (int i = 0; i < NumOp-1; ++i) { 688685c350ae76b588e1f00c01a511fe8bd57f18394Jason W Kim const MCOperand &MCOp1 = MI.getOperand(i); 689685c350ae76b588e1f00c01a511fe8bd57f18394Jason W Kim const MCOperand &MCOp2 = MI.getOperand(i + 1); 69010096dbdef22a10a6a4444437c935ab428545525Owen Anderson if (MCOp1.isImm() && MCOp2.isReg() && 691685c350ae76b588e1f00c01a511fe8bd57f18394Jason W Kim (MCOp2.getReg() == 0 || MCOp2.getReg() == ARM::CPSR)) { 69210096dbdef22a10a6a4444437c935ab428545525Owen Anderson if (ARMCC::CondCodes(MCOp1.getImm()) != ARMCC::AL) 693685c350ae76b588e1f00c01a511fe8bd57f18394Jason W Kim return true; 694685c350ae76b588e1f00c01a511fe8bd57f18394Jason W Kim } 695685c350ae76b588e1f00c01a511fe8bd57f18394Jason W Kim } 696685c350ae76b588e1f00c01a511fe8bd57f18394Jason W Kim } 697685c350ae76b588e1f00c01a511fe8bd57f18394Jason W Kim return false; 698685c350ae76b588e1f00c01a511fe8bd57f18394Jason W Kim} 699685c350ae76b588e1f00c01a511fe8bd57f18394Jason W Kim 700dff2f7151f695b86db8c4b0c6604463bdb8a63eaBill Wendling/// getBranchTargetOpValue - Return encoding info for 24-bit immediate branch 701dff2f7151f695b86db8c4b0c6604463bdb8a63eaBill Wendling/// target. 702dff2f7151f695b86db8c4b0c6604463bdb8a63eaBill Wendlinguint32_t ARMMCCodeEmitter:: 703dff2f7151f695b86db8c4b0c6604463bdb8a63eaBill WendlinggetBranchTargetOpValue(const MCInst &MI, unsigned OpIdx, 70436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines SmallVectorImpl<MCFixup> &Fixups, 70536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines const MCSubtargetInfo &STI) const { 706092e2cd5693114a4f1d93eb5b72f3e194de27236Jim Grosbach // FIXME: This really, really shouldn't use TargetMachine. We don't want 707092e2cd5693114a4f1d93eb5b72f3e194de27236Jim Grosbach // coupling between MC and TM anywhere we can help it. 70836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (isThumb2(STI)) 709c266600bec4b5ba0ee93ffdfeaafcab8f1295145Owen Anderson return 71036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines ::getBranchTargetOpValue(MI, OpIdx, ARM::fixup_t2_condbranch, Fixups, STI); 71136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return getARMBranchTargetOpValue(MI, OpIdx, Fixups, STI); 712685c350ae76b588e1f00c01a511fe8bd57f18394Jason W Kim} 713685c350ae76b588e1f00c01a511fe8bd57f18394Jason W Kim 714685c350ae76b588e1f00c01a511fe8bd57f18394Jason W Kim/// getBranchTargetOpValue - Return encoding info for 24-bit immediate branch 715685c350ae76b588e1f00c01a511fe8bd57f18394Jason W Kim/// target. 716685c350ae76b588e1f00c01a511fe8bd57f18394Jason W Kimuint32_t ARMMCCodeEmitter:: 717685c350ae76b588e1f00c01a511fe8bd57f18394Jason W KimgetARMBranchTargetOpValue(const MCInst &MI, unsigned OpIdx, 71836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines SmallVectorImpl<MCFixup> &Fixups, 71936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines const MCSubtargetInfo &STI) const { 720d7568e1c355f5e364eddafc15c6d5553559f32a5Owen Anderson const MCOperand MO = MI.getOperand(OpIdx); 721d7568e1c355f5e364eddafc15c6d5553559f32a5Owen Anderson if (MO.isExpr()) { 72210096dbdef22a10a6a4444437c935ab428545525Owen Anderson if (HasConditionalBranch(MI)) 723d7568e1c355f5e364eddafc15c6d5553559f32a5Owen Anderson return ::getBranchTargetOpValue(MI, OpIdx, 72436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines ARM::fixup_arm_condbranch, Fixups, STI); 72510096dbdef22a10a6a4444437c935ab428545525Owen Anderson return ::getBranchTargetOpValue(MI, OpIdx, 72636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines ARM::fixup_arm_uncondbranch, Fixups, STI); 727d7568e1c355f5e364eddafc15c6d5553559f32a5Owen Anderson } 728d7568e1c355f5e364eddafc15c6d5553559f32a5Owen Anderson 729d7568e1c355f5e364eddafc15c6d5553559f32a5Owen Anderson return MO.getImm() >> 2; 730c466b937dbdbaabeef0097fe340de1b8f49a3508Jim Grosbach} 731c466b937dbdbaabeef0097fe340de1b8f49a3508Jim Grosbach 732f1eab597b2316c6cfcabfcee98895fedb2071722Owen Andersonuint32_t ARMMCCodeEmitter:: 7337b25ecf6adbf3c4709c48033acfeb6ebbb4452abJim GrosbachgetARMBLTargetOpValue(const MCInst &MI, unsigned OpIdx, 73436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines SmallVectorImpl<MCFixup> &Fixups, 73536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines const MCSubtargetInfo &STI) const { 7367b25ecf6adbf3c4709c48033acfeb6ebbb4452abJim Grosbach const MCOperand MO = MI.getOperand(OpIdx); 737cb0809b82b126e79b99755ae4fc3d9733faea038James Molloy if (MO.isExpr()) { 738cb0809b82b126e79b99755ae4fc3d9733faea038James Molloy if (HasConditionalBranch(MI)) 739cb0809b82b126e79b99755ae4fc3d9733faea038James Molloy return ::getBranchTargetOpValue(MI, OpIdx, 74036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines ARM::fixup_arm_condbl, Fixups, STI); 74136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return ::getBranchTargetOpValue(MI, OpIdx, ARM::fixup_arm_uncondbl, Fixups, STI); 742cb0809b82b126e79b99755ae4fc3d9733faea038James Molloy } 7437b25ecf6adbf3c4709c48033acfeb6ebbb4452abJim Grosbach 7447b25ecf6adbf3c4709c48033acfeb6ebbb4452abJim Grosbach return MO.getImm() >> 2; 7457b25ecf6adbf3c4709c48033acfeb6ebbb4452abJim Grosbach} 7467b25ecf6adbf3c4709c48033acfeb6ebbb4452abJim Grosbach 7477b25ecf6adbf3c4709c48033acfeb6ebbb4452abJim Grosbachuint32_t ARMMCCodeEmitter:: 748f1eab597b2316c6cfcabfcee98895fedb2071722Owen AndersongetARMBLXTargetOpValue(const MCInst &MI, unsigned OpIdx, 74936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines SmallVectorImpl<MCFixup> &Fixups, 75036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines const MCSubtargetInfo &STI) const { 751f1eab597b2316c6cfcabfcee98895fedb2071722Owen Anderson const MCOperand MO = MI.getOperand(OpIdx); 7527b25ecf6adbf3c4709c48033acfeb6ebbb4452abJim Grosbach if (MO.isExpr()) 75336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return ::getBranchTargetOpValue(MI, OpIdx, ARM::fixup_arm_blx, Fixups, STI); 754685c350ae76b588e1f00c01a511fe8bd57f18394Jason W Kim 755f1eab597b2316c6cfcabfcee98895fedb2071722Owen Anderson return MO.getImm() >> 1; 756f1eab597b2316c6cfcabfcee98895fedb2071722Owen Anderson} 757685c350ae76b588e1f00c01a511fe8bd57f18394Jason W Kim 758c266600bec4b5ba0ee93ffdfeaafcab8f1295145Owen Anderson/// getUnconditionalBranchTargetOpValue - Return encoding info for 24-bit 759c266600bec4b5ba0ee93ffdfeaafcab8f1295145Owen Anderson/// immediate branch target. 760c266600bec4b5ba0ee93ffdfeaafcab8f1295145Owen Andersonuint32_t ARMMCCodeEmitter:: 761c266600bec4b5ba0ee93ffdfeaafcab8f1295145Owen AndersongetUnconditionalBranchTargetOpValue(const MCInst &MI, unsigned OpIdx, 76236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines SmallVectorImpl<MCFixup> &Fixups, 76336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines const MCSubtargetInfo &STI) const { 764e921f323533ee751b3fa34bd00d10fa72096ffd3Mihai Popa unsigned Val = 0; 765e921f323533ee751b3fa34bd00d10fa72096ffd3Mihai Popa const MCOperand MO = MI.getOperand(OpIdx); 766e921f323533ee751b3fa34bd00d10fa72096ffd3Mihai Popa 767e921f323533ee751b3fa34bd00d10fa72096ffd3Mihai Popa if(MO.isExpr()) 76836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return ::getBranchTargetOpValue(MI, OpIdx, ARM::fixup_t2_uncondbranch, Fixups, STI); 769e921f323533ee751b3fa34bd00d10fa72096ffd3Mihai Popa else 770e921f323533ee751b3fa34bd00d10fa72096ffd3Mihai Popa Val = MO.getImm() >> 1; 771e921f323533ee751b3fa34bd00d10fa72096ffd3Mihai Popa 772c266600bec4b5ba0ee93ffdfeaafcab8f1295145Owen Anderson bool I = (Val & 0x800000); 773c266600bec4b5ba0ee93ffdfeaafcab8f1295145Owen Anderson bool J1 = (Val & 0x400000); 774c266600bec4b5ba0ee93ffdfeaafcab8f1295145Owen Anderson bool J2 = (Val & 0x200000); 775c266600bec4b5ba0ee93ffdfeaafcab8f1295145Owen Anderson if (I ^ J1) 776c266600bec4b5ba0ee93ffdfeaafcab8f1295145Owen Anderson Val &= ~0x400000; 777c266600bec4b5ba0ee93ffdfeaafcab8f1295145Owen Anderson else 778c266600bec4b5ba0ee93ffdfeaafcab8f1295145Owen Anderson Val |= 0x400000; 779971b83b67a9812556cdb97bb58aa96fb37af458dOwen Anderson 780c266600bec4b5ba0ee93ffdfeaafcab8f1295145Owen Anderson if (I ^ J2) 781c266600bec4b5ba0ee93ffdfeaafcab8f1295145Owen Anderson Val &= ~0x200000; 782c266600bec4b5ba0ee93ffdfeaafcab8f1295145Owen Anderson else 783c266600bec4b5ba0ee93ffdfeaafcab8f1295145Owen Anderson Val |= 0x200000; 784971b83b67a9812556cdb97bb58aa96fb37af458dOwen Anderson 785c266600bec4b5ba0ee93ffdfeaafcab8f1295145Owen Anderson return Val; 786c266600bec4b5ba0ee93ffdfeaafcab8f1295145Owen Anderson} 787c266600bec4b5ba0ee93ffdfeaafcab8f1295145Owen Anderson 7881fb27eccf5b7eabde9678d84411eb1df8a693683Jiangning Liu/// getAdrLabelOpValue - Return encoding info for 12-bit shifted-immediate 7891fb27eccf5b7eabde9678d84411eb1df8a693683Jiangning Liu/// ADR label target. 7905d14f9be7ba64162c7b996f36d419b11d8cdbe9aJim Grosbachuint32_t ARMMCCodeEmitter:: 7915d14f9be7ba64162c7b996f36d419b11d8cdbe9aJim GrosbachgetAdrLabelOpValue(const MCInst &MI, unsigned OpIdx, 79236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines SmallVectorImpl<MCFixup> &Fixups, 79336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines const MCSubtargetInfo &STI) const { 79496425c846494c1c20a4c931f4783571295ab170cOwen Anderson const MCOperand MO = MI.getOperand(OpIdx); 79596425c846494c1c20a4c931f4783571295ab170cOwen Anderson if (MO.isExpr()) 79696425c846494c1c20a4c931f4783571295ab170cOwen Anderson return ::getBranchTargetOpValue(MI, OpIdx, ARM::fixup_arm_adr_pcrel_12, 79736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Fixups, STI); 798ea8ddd86b1e364a799e57fc0ac468a9c4a8f8bcfMihai Popa int64_t offset = MO.getImm(); 79996425c846494c1c20a4c931f4783571295ab170cOwen Anderson uint32_t Val = 0x2000; 8001fb27eccf5b7eabde9678d84411eb1df8a693683Jiangning Liu 801d65dfd83421f4d26e6dc20476718d7d9b6ba3f3bTim Northover int SoImmVal; 8021fb27eccf5b7eabde9678d84411eb1df8a693683Jiangning Liu if (offset == INT32_MIN) { 8031fb27eccf5b7eabde9678d84411eb1df8a693683Jiangning Liu Val = 0x1000; 804d65dfd83421f4d26e6dc20476718d7d9b6ba3f3bTim Northover SoImmVal = 0; 8051fb27eccf5b7eabde9678d84411eb1df8a693683Jiangning Liu } else if (offset < 0) { 80696425c846494c1c20a4c931f4783571295ab170cOwen Anderson Val = 0x1000; 80796425c846494c1c20a4c931f4783571295ab170cOwen Anderson offset *= -1; 808d65dfd83421f4d26e6dc20476718d7d9b6ba3f3bTim Northover SoImmVal = ARM_AM::getSOImmVal(offset); 809d65dfd83421f4d26e6dc20476718d7d9b6ba3f3bTim Northover if(SoImmVal == -1) { 810d65dfd83421f4d26e6dc20476718d7d9b6ba3f3bTim Northover Val = 0x2000; 811d65dfd83421f4d26e6dc20476718d7d9b6ba3f3bTim Northover offset *= -1; 812d65dfd83421f4d26e6dc20476718d7d9b6ba3f3bTim Northover SoImmVal = ARM_AM::getSOImmVal(offset); 813d65dfd83421f4d26e6dc20476718d7d9b6ba3f3bTim Northover } 814d65dfd83421f4d26e6dc20476718d7d9b6ba3f3bTim Northover } else { 815d65dfd83421f4d26e6dc20476718d7d9b6ba3f3bTim Northover SoImmVal = ARM_AM::getSOImmVal(offset); 816d65dfd83421f4d26e6dc20476718d7d9b6ba3f3bTim Northover if(SoImmVal == -1) { 817d65dfd83421f4d26e6dc20476718d7d9b6ba3f3bTim Northover Val = 0x1000; 818d65dfd83421f4d26e6dc20476718d7d9b6ba3f3bTim Northover offset *= -1; 819d65dfd83421f4d26e6dc20476718d7d9b6ba3f3bTim Northover SoImmVal = ARM_AM::getSOImmVal(offset); 820d65dfd83421f4d26e6dc20476718d7d9b6ba3f3bTim Northover } 82196425c846494c1c20a4c931f4783571295ab170cOwen Anderson } 8221fb27eccf5b7eabde9678d84411eb1df8a693683Jiangning Liu 8231fb27eccf5b7eabde9678d84411eb1df8a693683Jiangning Liu assert(SoImmVal != -1 && "Not a valid so_imm value!"); 8241fb27eccf5b7eabde9678d84411eb1df8a693683Jiangning Liu 8251fb27eccf5b7eabde9678d84411eb1df8a693683Jiangning Liu Val |= SoImmVal; 82696425c846494c1c20a4c931f4783571295ab170cOwen Anderson return Val; 8275d14f9be7ba64162c7b996f36d419b11d8cdbe9aJim Grosbach} 8285d14f9be7ba64162c7b996f36d419b11d8cdbe9aJim Grosbach 8291fb27eccf5b7eabde9678d84411eb1df8a693683Jiangning Liu/// getT2AdrLabelOpValue - Return encoding info for 12-bit immediate ADR label 830a838a25d59838adfa91463f6a918ae3adeb352c1Owen Anderson/// target. 831a838a25d59838adfa91463f6a918ae3adeb352c1Owen Andersonuint32_t ARMMCCodeEmitter:: 832a838a25d59838adfa91463f6a918ae3adeb352c1Owen AndersongetT2AdrLabelOpValue(const MCInst &MI, unsigned OpIdx, 83336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines SmallVectorImpl<MCFixup> &Fixups, 83436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines const MCSubtargetInfo &STI) const { 83596425c846494c1c20a4c931f4783571295ab170cOwen Anderson const MCOperand MO = MI.getOperand(OpIdx); 83696425c846494c1c20a4c931f4783571295ab170cOwen Anderson if (MO.isExpr()) 83796425c846494c1c20a4c931f4783571295ab170cOwen Anderson return ::getBranchTargetOpValue(MI, OpIdx, ARM::fixup_t2_adr_pcrel_12, 83836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Fixups, STI); 83908fef885eb39339a47e3be7f0842b1db33683003Owen Anderson int32_t Val = MO.getImm(); 8401fb27eccf5b7eabde9678d84411eb1df8a693683Jiangning Liu if (Val == INT32_MIN) 8411fb27eccf5b7eabde9678d84411eb1df8a693683Jiangning Liu Val = 0x1000; 8421fb27eccf5b7eabde9678d84411eb1df8a693683Jiangning Liu else if (Val < 0) { 84308fef885eb39339a47e3be7f0842b1db33683003Owen Anderson Val *= -1; 84408fef885eb39339a47e3be7f0842b1db33683003Owen Anderson Val |= 0x1000; 84508fef885eb39339a47e3be7f0842b1db33683003Owen Anderson } 84608fef885eb39339a47e3be7f0842b1db33683003Owen Anderson return Val; 847a838a25d59838adfa91463f6a918ae3adeb352c1Owen Anderson} 848a838a25d59838adfa91463f6a918ae3adeb352c1Owen Anderson 8491fb27eccf5b7eabde9678d84411eb1df8a693683Jiangning Liu/// getThumbAdrLabelOpValue - Return encoding info for 8-bit immediate ADR label 850d40963c4065432ec7e47879d3ca665a54ee903b6Jim Grosbach/// target. 851d40963c4065432ec7e47879d3ca665a54ee903b6Jim Grosbachuint32_t ARMMCCodeEmitter:: 852d40963c4065432ec7e47879d3ca665a54ee903b6Jim GrosbachgetThumbAdrLabelOpValue(const MCInst &MI, unsigned OpIdx, 85336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines SmallVectorImpl<MCFixup> &Fixups, 85436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines const MCSubtargetInfo &STI) const { 85596425c846494c1c20a4c931f4783571295ab170cOwen Anderson const MCOperand MO = MI.getOperand(OpIdx); 85696425c846494c1c20a4c931f4783571295ab170cOwen Anderson if (MO.isExpr()) 85796425c846494c1c20a4c931f4783571295ab170cOwen Anderson return ::getBranchTargetOpValue(MI, OpIdx, ARM::fixup_thumb_adr_pcrel_10, 85836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Fixups, STI); 85996425c846494c1c20a4c931f4783571295ab170cOwen Anderson return MO.getImm(); 860d40963c4065432ec7e47879d3ca665a54ee903b6Jim Grosbach} 861d40963c4065432ec7e47879d3ca665a54ee903b6Jim Grosbach 862f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling/// getThumbAddrModeRegRegOpValue - Return encoding info for 'reg + reg' 863f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling/// operand. 8640f4b60d43a289671082deee3bd56a3a055afb16aOwen Andersonuint32_t ARMMCCodeEmitter:: 865f4caf69720d807573c50d41aa06bcec1c99bdbbdBill WendlinggetThumbAddrModeRegRegOpValue(const MCInst &MI, unsigned OpIdx, 86636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines SmallVectorImpl<MCFixup> &, 86736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines const MCSubtargetInfo &STI) const { 868f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling // [Rn, Rm] 869f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling // {5-3} = Rm 870f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling // {2-0} = Rn 8710f4b60d43a289671082deee3bd56a3a055afb16aOwen Anderson const MCOperand &MO1 = MI.getOperand(OpIdx); 872f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling const MCOperand &MO2 = MI.getOperand(OpIdx + 1); 87399cb622041a0839c7dfcf0263c5102a305a0fdb5Bill Wendling unsigned Rn = CTX.getRegisterInfo()->getEncodingValue(MO1.getReg()); 87499cb622041a0839c7dfcf0263c5102a305a0fdb5Bill Wendling unsigned Rm = CTX.getRegisterInfo()->getEncodingValue(MO2.getReg()); 8750f4b60d43a289671082deee3bd56a3a055afb16aOwen Anderson return (Rm << 3) | Rn; 8760f4b60d43a289671082deee3bd56a3a055afb16aOwen Anderson} 8770f4b60d43a289671082deee3bd56a3a055afb16aOwen Anderson 87892b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling/// getAddrModeImm12OpValue - Return encoding info for 'reg +/- imm12' operand. 879806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbachuint32_t ARMMCCodeEmitter:: 880806e80ef42bdb416f409142a1ff1d4e8752baac8Jim GrosbachgetAddrModeImm12OpValue(const MCInst &MI, unsigned OpIdx, 88136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines SmallVectorImpl<MCFixup> &Fixups, 88236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines const MCSubtargetInfo &STI) const { 88392b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling // {17-13} = reg 88492b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling // {12} = (U)nsigned (add == '1', sub == '0') 88592b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling // {11-0} = imm12 88692b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling unsigned Reg, Imm12; 88770933266ae73c891d9d1c2f0de72ecd1db8f86dfJim Grosbach bool isAdd = true; 88870933266ae73c891d9d1c2f0de72ecd1db8f86dfJim Grosbach // If The first operand isn't a register, we have a label reference. 88970933266ae73c891d9d1c2f0de72ecd1db8f86dfJim Grosbach const MCOperand &MO = MI.getOperand(OpIdx); 890971b83b67a9812556cdb97bb58aa96fb37af458dOwen Anderson if (!MO.isReg()) { 89199cb622041a0839c7dfcf0263c5102a305a0fdb5Bill Wendling Reg = CTX.getRegisterInfo()->getEncodingValue(ARM::PC); // Rn is PC. 89270933266ae73c891d9d1c2f0de72ecd1db8f86dfJim Grosbach Imm12 = 0; 89370933266ae73c891d9d1c2f0de72ecd1db8f86dfJim Grosbach 894fd92d2e106acfbf13ed29b5d15f3a690cd8699b2Owen Anderson if (MO.isExpr()) { 895fd92d2e106acfbf13ed29b5d15f3a690cd8699b2Owen Anderson const MCExpr *Expr = MO.getExpr(); 896beb920fce6ccc89b4735f280f94cb8c227f4ef5eAmaury de la Vieuville isAdd = false ; // 'U' bit is set as part of the fixup. 897fd92d2e106acfbf13ed29b5d15f3a690cd8699b2Owen Anderson 898fd92d2e106acfbf13ed29b5d15f3a690cd8699b2Owen Anderson MCFixupKind Kind; 89936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (isThumb2(STI)) 900fd92d2e106acfbf13ed29b5d15f3a690cd8699b2Owen Anderson Kind = MCFixupKind(ARM::fixup_t2_ldst_pcrel_12); 901fd92d2e106acfbf13ed29b5d15f3a690cd8699b2Owen Anderson else 902fd92d2e106acfbf13ed29b5d15f3a690cd8699b2Owen Anderson Kind = MCFixupKind(ARM::fixup_arm_ldst_pcrel_12); 90342e6bd38e02e2e1c2cc50d2f12036c38c4ea3ab0Jim Grosbach Fixups.push_back(MCFixup::Create(0, Expr, Kind, MI.getLoc())); 904fd92d2e106acfbf13ed29b5d15f3a690cd8699b2Owen Anderson 905fd92d2e106acfbf13ed29b5d15f3a690cd8699b2Owen Anderson ++MCNumCPRelocations; 906fd92d2e106acfbf13ed29b5d15f3a690cd8699b2Owen Anderson } else { 907fd92d2e106acfbf13ed29b5d15f3a690cd8699b2Owen Anderson Reg = ARM::PC; 908fd92d2e106acfbf13ed29b5d15f3a690cd8699b2Owen Anderson int32_t Offset = MO.getImm(); 909e97fc44045732de9fc4715241013f9238ec007dcMihai Popa if (Offset == INT32_MIN) { 910e97fc44045732de9fc4715241013f9238ec007dcMihai Popa Offset = 0; 911e97fc44045732de9fc4715241013f9238ec007dcMihai Popa isAdd = false; 912e97fc44045732de9fc4715241013f9238ec007dcMihai Popa } else if (Offset < 0) { 913fd92d2e106acfbf13ed29b5d15f3a690cd8699b2Owen Anderson Offset *= -1; 914fd92d2e106acfbf13ed29b5d15f3a690cd8699b2Owen Anderson isAdd = false; 915fd92d2e106acfbf13ed29b5d15f3a690cd8699b2Owen Anderson } 916fd92d2e106acfbf13ed29b5d15f3a690cd8699b2Owen Anderson Imm12 = Offset; 917fd92d2e106acfbf13ed29b5d15f3a690cd8699b2Owen Anderson } 91870933266ae73c891d9d1c2f0de72ecd1db8f86dfJim Grosbach } else 91936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines isAdd = EncodeAddrModeOpValues(MI, OpIdx, Reg, Imm12, Fixups, STI); 92092b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling 92192b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling uint32_t Binary = Imm12 & 0xfff; 92292b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling // Immediate is always encoded as positive. The 'U' bit controls add vs sub. 923ab682a2090f795d0b67f29889622da0a74cd97c3Jim Grosbach if (isAdd) 92492b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling Binary |= (1 << 12); 92592b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling Binary |= (Reg << 13); 92692b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling return Binary; 92792b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling} 92892b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling 929a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach/// getT2Imm8s4OpValue - Return encoding info for 930a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach/// '+/- imm8<<2' operand. 931a77295db19527503d6b290e4f34f273d0a789365Jim Grosbachuint32_t ARMMCCodeEmitter:: 932a77295db19527503d6b290e4f34f273d0a789365Jim GrosbachgetT2Imm8s4OpValue(const MCInst &MI, unsigned OpIdx, 93336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines SmallVectorImpl<MCFixup> &Fixups, 93436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines const MCSubtargetInfo &STI) const { 935a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach // FIXME: The immediate operand should have already been encoded like this 936a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach // before ever getting here. The encoder method should just need to combine 937a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach // the MI operands for the register and the offset into a single 938a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach // representation for the complex operand in the .td file. This isn't just 939a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach // style, unfortunately. As-is, we can't represent the distinct encoding 940a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach // for #-0. 941a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach 942a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach // {8} = (U)nsigned (add == '1', sub == '0') 943a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach // {7-0} = imm8 944a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach int32_t Imm8 = MI.getOperand(OpIdx).getImm(); 945a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach bool isAdd = Imm8 >= 0; 946a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach 947a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach // Immediate is always encoded as positive. The 'U' bit controls add vs sub. 948a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach if (Imm8 < 0) 949aaf217953bef3b2cc0e0f26bf474616cc20cf7f0Richard Smith Imm8 = -(uint32_t)Imm8; 950a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach 951a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach // Scaled by 4. 952a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach Imm8 /= 4; 953a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach 954a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach uint32_t Binary = Imm8 & 0xff; 955a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach // Immediate is always encoded as positive. The 'U' bit controls add vs sub. 956a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach if (isAdd) 957a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach Binary |= (1 << 8); 958a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach return Binary; 959a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach} 960a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach 9619d63d90de5e57ad96f467b270544443a9284eb2bOwen Anderson/// getT2AddrModeImm8s4OpValue - Return encoding info for 9629d63d90de5e57ad96f467b270544443a9284eb2bOwen Anderson/// 'reg +/- imm8<<2' operand. 9639d63d90de5e57ad96f467b270544443a9284eb2bOwen Andersonuint32_t ARMMCCodeEmitter:: 9649d63d90de5e57ad96f467b270544443a9284eb2bOwen AndersongetT2AddrModeImm8s4OpValue(const MCInst &MI, unsigned OpIdx, 96536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines SmallVectorImpl<MCFixup> &Fixups, 96636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines const MCSubtargetInfo &STI) const { 96790cc533fda9742f5c67203f97e69e5efd270c676Jim Grosbach // {12-9} = reg 96890cc533fda9742f5c67203f97e69e5efd270c676Jim Grosbach // {8} = (U)nsigned (add == '1', sub == '0') 96990cc533fda9742f5c67203f97e69e5efd270c676Jim Grosbach // {7-0} = imm8 9709d63d90de5e57ad96f467b270544443a9284eb2bOwen Anderson unsigned Reg, Imm8; 9719d63d90de5e57ad96f467b270544443a9284eb2bOwen Anderson bool isAdd = true; 9729d63d90de5e57ad96f467b270544443a9284eb2bOwen Anderson // If The first operand isn't a register, we have a label reference. 9739d63d90de5e57ad96f467b270544443a9284eb2bOwen Anderson const MCOperand &MO = MI.getOperand(OpIdx); 9749d63d90de5e57ad96f467b270544443a9284eb2bOwen Anderson if (!MO.isReg()) { 97599cb622041a0839c7dfcf0263c5102a305a0fdb5Bill Wendling Reg = CTX.getRegisterInfo()->getEncodingValue(ARM::PC); // Rn is PC. 9769d63d90de5e57ad96f467b270544443a9284eb2bOwen Anderson Imm8 = 0; 9779d63d90de5e57ad96f467b270544443a9284eb2bOwen Anderson isAdd = false ; // 'U' bit is set as part of the fixup. 9789d63d90de5e57ad96f467b270544443a9284eb2bOwen Anderson 9799d63d90de5e57ad96f467b270544443a9284eb2bOwen Anderson assert(MO.isExpr() && "Unexpected machine operand type!"); 9809d63d90de5e57ad96f467b270544443a9284eb2bOwen Anderson const MCExpr *Expr = MO.getExpr(); 9812f196747f15240691bd4e622f7995edfedf90f61Jim Grosbach MCFixupKind Kind = MCFixupKind(ARM::fixup_t2_pcrel_10); 98242e6bd38e02e2e1c2cc50d2f12036c38c4ea3ab0Jim Grosbach Fixups.push_back(MCFixup::Create(0, Expr, Kind, MI.getLoc())); 9839d63d90de5e57ad96f467b270544443a9284eb2bOwen Anderson 9849d63d90de5e57ad96f467b270544443a9284eb2bOwen Anderson ++MCNumCPRelocations; 9859d63d90de5e57ad96f467b270544443a9284eb2bOwen Anderson } else 98636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines isAdd = EncodeAddrModeOpValues(MI, OpIdx, Reg, Imm8, Fixups, STI); 9879d63d90de5e57ad96f467b270544443a9284eb2bOwen Anderson 988a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach // FIXME: The immediate operand should have already been encoded like this 989a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach // before ever getting here. The encoder method should just need to combine 990a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach // the MI operands for the register and the offset into a single 991a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach // representation for the complex operand in the .td file. This isn't just 992a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach // style, unfortunately. As-is, we can't represent the distinct encoding 993a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach // for #-0. 9949d63d90de5e57ad96f467b270544443a9284eb2bOwen Anderson uint32_t Binary = (Imm8 >> 2) & 0xff; 9959d63d90de5e57ad96f467b270544443a9284eb2bOwen Anderson // Immediate is always encoded as positive. The 'U' bit controls add vs sub. 9969d63d90de5e57ad96f467b270544443a9284eb2bOwen Anderson if (isAdd) 99790cc533fda9742f5c67203f97e69e5efd270c676Jim Grosbach Binary |= (1 << 8); 9989d63d90de5e57ad96f467b270544443a9284eb2bOwen Anderson Binary |= (Reg << 9); 9999d63d90de5e57ad96f467b270544443a9284eb2bOwen Anderson return Binary; 10009d63d90de5e57ad96f467b270544443a9284eb2bOwen Anderson} 10019d63d90de5e57ad96f467b270544443a9284eb2bOwen Anderson 1002b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach/// getT2AddrModeImm0_1020s4OpValue - Return encoding info for 1003b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach/// 'reg + imm8<<2' operand. 1004b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbachuint32_t ARMMCCodeEmitter:: 1005b6aed508e310e31dcb080e761ca856127cec0773Jim GrosbachgetT2AddrModeImm0_1020s4OpValue(const MCInst &MI, unsigned OpIdx, 100636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines SmallVectorImpl<MCFixup> &Fixups, 100736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines const MCSubtargetInfo &STI) const { 1008b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach // {11-8} = reg 1009b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach // {7-0} = imm8 1010b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach const MCOperand &MO = MI.getOperand(OpIdx); 1011b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach const MCOperand &MO1 = MI.getOperand(OpIdx + 1); 101299cb622041a0839c7dfcf0263c5102a305a0fdb5Bill Wendling unsigned Reg = CTX.getRegisterInfo()->getEncodingValue(MO.getReg()); 1013b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach unsigned Imm8 = MO1.getImm(); 1014b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach return (Reg << 8) | Imm8; 1015b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach} 1016b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach 10177597212abced110723f2fee985a7d60557c092ecEvan Chenguint32_t 10187597212abced110723f2fee985a7d60557c092ecEvan ChengARMMCCodeEmitter::getHiLo16ImmOpValue(const MCInst &MI, unsigned OpIdx, 101936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines SmallVectorImpl<MCFixup> &Fixups, 102036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines const MCSubtargetInfo &STI) const { 1021837caa9313e1f9480721f232f89f5c7b1b9c9d09Jason W Kim // {20-16} = imm{15-12} 1022837caa9313e1f9480721f232f89f5c7b1b9c9d09Jason W Kim // {11-0} = imm{11-0} 10237bf4c02789f97e32225fc248dff6622b994a15eeJim Grosbach const MCOperand &MO = MI.getOperand(OpIdx); 10247597212abced110723f2fee985a7d60557c092ecEvan Cheng if (MO.isImm()) 10257597212abced110723f2fee985a7d60557c092ecEvan Cheng // Hi / lo 16 bits already extracted during earlier passes. 1026837caa9313e1f9480721f232f89f5c7b1b9c9d09Jason W Kim return static_cast<unsigned>(MO.getImm()); 10277597212abced110723f2fee985a7d60557c092ecEvan Cheng 10287597212abced110723f2fee985a7d60557c092ecEvan Cheng // Handle :upper16: and :lower16: assembly prefixes. 10297597212abced110723f2fee985a7d60557c092ecEvan Cheng const MCExpr *E = MO.getExpr(); 103094b590f8faf4dbba406f263e6a839882b0c68a94Jim Grosbach MCFixupKind Kind; 10317597212abced110723f2fee985a7d60557c092ecEvan Cheng if (E->getKind() == MCExpr::Target) { 10327597212abced110723f2fee985a7d60557c092ecEvan Cheng const ARMMCExpr *ARM16Expr = cast<ARMMCExpr>(E); 10337597212abced110723f2fee985a7d60557c092ecEvan Cheng E = ARM16Expr->getSubExpr(); 10347597212abced110723f2fee985a7d60557c092ecEvan Cheng 103536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(E)) { 103636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines const int64_t Value = MCE->getValue(); 103736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (Value > UINT32_MAX) 103836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines report_fatal_error("constant value truncated (limited to 32-bit)"); 103936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 104036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines switch (ARM16Expr->getKind()) { 104136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines case ARMMCExpr::VK_ARM_HI16: 104236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return (int32_t(Value) & 0xffff0000) >> 16; 104336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines case ARMMCExpr::VK_ARM_LO16: 104436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return (int32_t(Value) & 0x0000ffff); 104536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines default: llvm_unreachable("Unsupported ARMFixup"); 104636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 104736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 104836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 10497597212abced110723f2fee985a7d60557c092ecEvan Cheng switch (ARM16Expr->getKind()) { 1050bc2198133a1836598b54b943420748e75d5dea94Craig Topper default: llvm_unreachable("Unsupported ARMFixup"); 10517597212abced110723f2fee985a7d60557c092ecEvan Cheng case ARMMCExpr::VK_ARM_HI16: 105236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Kind = MCFixupKind(isThumb2(STI) ? ARM::fixup_t2_movt_hi16 105336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines : ARM::fixup_arm_movt_hi16); 1054837caa9313e1f9480721f232f89f5c7b1b9c9d09Jason W Kim break; 10557597212abced110723f2fee985a7d60557c092ecEvan Cheng case ARMMCExpr::VK_ARM_LO16: 105636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Kind = MCFixupKind(isThumb2(STI) ? ARM::fixup_t2_movw_lo16 105736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines : ARM::fixup_arm_movw_lo16); 1058837caa9313e1f9480721f232f89f5c7b1b9c9d09Jason W Kim break; 1059837caa9313e1f9480721f232f89f5c7b1b9c9d09Jason W Kim } 1060dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 106142e6bd38e02e2e1c2cc50d2f12036c38c4ea3ab0Jim Grosbach Fixups.push_back(MCFixup::Create(0, E, Kind, MI.getLoc())); 1062837caa9313e1f9480721f232f89f5c7b1b9c9d09Jason W Kim return 0; 106394b590f8faf4dbba406f263e6a839882b0c68a94Jim Grosbach } 106494b590f8faf4dbba406f263e6a839882b0c68a94Jim Grosbach // If the expression doesn't have :upper16: or :lower16: on it, 1065dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines // it's just a plain immediate expression, previously those evaluated to 106694b590f8faf4dbba406f263e6a839882b0c68a94Jim Grosbach // the lower 16 bits of the expression regardless of whether 1067dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines // we have a movt or a movw, but that led to misleadingly results. 1068dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines // This is now disallowed in the the AsmParser in validateInstruction() 1069dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines // so this should never happen. 1070c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines llvm_unreachable("expression without :upper16: or :lower16:"); 1071837caa9313e1f9480721f232f89f5c7b1b9c9d09Jason W Kim} 1072837caa9313e1f9480721f232f89f5c7b1b9c9d09Jason W Kim 1073837caa9313e1f9480721f232f89f5c7b1b9c9d09Jason W Kimuint32_t ARMMCCodeEmitter:: 107454fea632b161f98e96ec7275922e35102bcecc5dJim GrosbachgetLdStSORegOpValue(const MCInst &MI, unsigned OpIdx, 107536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines SmallVectorImpl<MCFixup> &Fixups, 107636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines const MCSubtargetInfo &STI) const { 107754fea632b161f98e96ec7275922e35102bcecc5dJim Grosbach const MCOperand &MO = MI.getOperand(OpIdx); 107854fea632b161f98e96ec7275922e35102bcecc5dJim Grosbach const MCOperand &MO1 = MI.getOperand(OpIdx+1); 107954fea632b161f98e96ec7275922e35102bcecc5dJim Grosbach const MCOperand &MO2 = MI.getOperand(OpIdx+2); 108099cb622041a0839c7dfcf0263c5102a305a0fdb5Bill Wendling unsigned Rn = CTX.getRegisterInfo()->getEncodingValue(MO.getReg()); 108199cb622041a0839c7dfcf0263c5102a305a0fdb5Bill Wendling unsigned Rm = CTX.getRegisterInfo()->getEncodingValue(MO1.getReg()); 108254fea632b161f98e96ec7275922e35102bcecc5dJim Grosbach unsigned ShImm = ARM_AM::getAM2Offset(MO2.getImm()); 108354fea632b161f98e96ec7275922e35102bcecc5dJim Grosbach bool isAdd = ARM_AM::getAM2Op(MO2.getImm()) == ARM_AM::add; 108499f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach ARM_AM::ShiftOpc ShOp = ARM_AM::getAM2ShiftOpc(MO2.getImm()); 108599f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach unsigned SBits = getShiftOp(ShOp); 108654fea632b161f98e96ec7275922e35102bcecc5dJim Grosbach 108793c7c449a1351542fa5a275587187154dbedb8e0Tim Northover // While "lsr #32" and "asr #32" exist, they are encoded with a 0 in the shift 108893c7c449a1351542fa5a275587187154dbedb8e0Tim Northover // amount. However, it would be an easy mistake to make so check here. 108993c7c449a1351542fa5a275587187154dbedb8e0Tim Northover assert((ShImm & ~0x1f) == 0 && "Out of range shift amount"); 109093c7c449a1351542fa5a275587187154dbedb8e0Tim Northover 109154fea632b161f98e96ec7275922e35102bcecc5dJim Grosbach // {16-13} = Rn 109254fea632b161f98e96ec7275922e35102bcecc5dJim Grosbach // {12} = isAdd 109354fea632b161f98e96ec7275922e35102bcecc5dJim Grosbach // {11-0} = shifter 109454fea632b161f98e96ec7275922e35102bcecc5dJim Grosbach // {3-0} = Rm 109554fea632b161f98e96ec7275922e35102bcecc5dJim Grosbach // {4} = 0 109654fea632b161f98e96ec7275922e35102bcecc5dJim Grosbach // {6-5} = type 109754fea632b161f98e96ec7275922e35102bcecc5dJim Grosbach // {11-7} = imm 1098570a9226913ebe1af04832b8fb3273c70b4ee152Jim Grosbach uint32_t Binary = Rm; 109954fea632b161f98e96ec7275922e35102bcecc5dJim Grosbach Binary |= Rn << 13; 110054fea632b161f98e96ec7275922e35102bcecc5dJim Grosbach Binary |= SBits << 5; 110154fea632b161f98e96ec7275922e35102bcecc5dJim Grosbach Binary |= ShImm << 7; 110254fea632b161f98e96ec7275922e35102bcecc5dJim Grosbach if (isAdd) 110354fea632b161f98e96ec7275922e35102bcecc5dJim Grosbach Binary |= 1 << 12; 110454fea632b161f98e96ec7275922e35102bcecc5dJim Grosbach return Binary; 110554fea632b161f98e96ec7275922e35102bcecc5dJim Grosbach} 110654fea632b161f98e96ec7275922e35102bcecc5dJim Grosbach 1107570a9226913ebe1af04832b8fb3273c70b4ee152Jim Grosbachuint32_t ARMMCCodeEmitter:: 110899f53d13efc259b47c93dc0d90a5db763cbe371aJim GrosbachgetAddrMode2OpValue(const MCInst &MI, unsigned OpIdx, 110936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines SmallVectorImpl<MCFixup> &Fixups, 111036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines const MCSubtargetInfo &STI) const { 111199f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach // {17-14} Rn 111299f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach // {13} 1 == imm12, 0 == Rm 111399f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach // {12} isAdd 111499f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach // {11-0} imm12/Rm 111599f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach const MCOperand &MO = MI.getOperand(OpIdx); 111699cb622041a0839c7dfcf0263c5102a305a0fdb5Bill Wendling unsigned Rn = CTX.getRegisterInfo()->getEncodingValue(MO.getReg()); 111736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines uint32_t Binary = getAddrMode2OffsetOpValue(MI, OpIdx + 1, Fixups, STI); 111899f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach Binary |= Rn << 14; 111999f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach return Binary; 112099f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach} 112199f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach 112299f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbachuint32_t ARMMCCodeEmitter:: 112399f53d13efc259b47c93dc0d90a5db763cbe371aJim GrosbachgetAddrMode2OffsetOpValue(const MCInst &MI, unsigned OpIdx, 112436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines SmallVectorImpl<MCFixup> &Fixups, 112536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines const MCSubtargetInfo &STI) const { 112699f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach // {13} 1 == imm12, 0 == Rm 112799f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach // {12} isAdd 112899f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach // {11-0} imm12/Rm 112999f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach const MCOperand &MO = MI.getOperand(OpIdx); 113099f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach const MCOperand &MO1 = MI.getOperand(OpIdx+1); 113199f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach unsigned Imm = MO1.getImm(); 113299f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach bool isAdd = ARM_AM::getAM2Op(Imm) == ARM_AM::add; 113399f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach bool isReg = MO.getReg() != 0; 113499f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach uint32_t Binary = ARM_AM::getAM2Offset(Imm); 113599f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach // if reg +/- reg, Rm will be non-zero. Otherwise, we have reg +/- imm12 113699f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach if (isReg) { 113799f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach ARM_AM::ShiftOpc ShOp = ARM_AM::getAM2ShiftOpc(Imm); 113899f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach Binary <<= 7; // Shift amount is bits [11:7] 113999f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach Binary |= getShiftOp(ShOp) << 5; // Shift type is bits [6:5] 114099cb622041a0839c7dfcf0263c5102a305a0fdb5Bill Wendling Binary |= CTX.getRegisterInfo()->getEncodingValue(MO.getReg()); // Rm is bits [3:0] 114199f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach } 114299f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach return Binary | (isAdd << 12) | (isReg << 13); 114399f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach} 114499f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach 114599f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbachuint32_t ARMMCCodeEmitter:: 11467ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim GrosbachgetPostIdxRegOpValue(const MCInst &MI, unsigned OpIdx, 114736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines SmallVectorImpl<MCFixup> &Fixups, 114836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines const MCSubtargetInfo &STI) const { 11497ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // {4} isAdd 11507ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // {3-0} Rm 11517ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach const MCOperand &MO = MI.getOperand(OpIdx); 11527ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach const MCOperand &MO1 = MI.getOperand(OpIdx+1); 115316578b50889329eb62774148091ba0f38b681a09Jim Grosbach bool isAdd = MO1.getImm() != 0; 115499cb622041a0839c7dfcf0263c5102a305a0fdb5Bill Wendling return CTX.getRegisterInfo()->getEncodingValue(MO.getReg()) | (isAdd << 4); 11557ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach} 11567ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach 11577ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbachuint32_t ARMMCCodeEmitter:: 11587eab97f260ba0f56d1d4a82f3a4eb2c979452011Jim GrosbachgetAddrMode3OffsetOpValue(const MCInst &MI, unsigned OpIdx, 115936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines SmallVectorImpl<MCFixup> &Fixups, 116036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines const MCSubtargetInfo &STI) const { 11617eab97f260ba0f56d1d4a82f3a4eb2c979452011Jim Grosbach // {9} 1 == imm8, 0 == Rm 11627eab97f260ba0f56d1d4a82f3a4eb2c979452011Jim Grosbach // {8} isAdd 11637eab97f260ba0f56d1d4a82f3a4eb2c979452011Jim Grosbach // {7-4} imm7_4/zero 11647eab97f260ba0f56d1d4a82f3a4eb2c979452011Jim Grosbach // {3-0} imm3_0/Rm 11657eab97f260ba0f56d1d4a82f3a4eb2c979452011Jim Grosbach const MCOperand &MO = MI.getOperand(OpIdx); 11667eab97f260ba0f56d1d4a82f3a4eb2c979452011Jim Grosbach const MCOperand &MO1 = MI.getOperand(OpIdx+1); 11677eab97f260ba0f56d1d4a82f3a4eb2c979452011Jim Grosbach unsigned Imm = MO1.getImm(); 11687eab97f260ba0f56d1d4a82f3a4eb2c979452011Jim Grosbach bool isAdd = ARM_AM::getAM3Op(Imm) == ARM_AM::add; 11697eab97f260ba0f56d1d4a82f3a4eb2c979452011Jim Grosbach bool isImm = MO.getReg() == 0; 11707eab97f260ba0f56d1d4a82f3a4eb2c979452011Jim Grosbach uint32_t Imm8 = ARM_AM::getAM3Offset(Imm); 11717eab97f260ba0f56d1d4a82f3a4eb2c979452011Jim Grosbach // if reg +/- reg, Rm will be non-zero. Otherwise, we have reg +/- imm8 11727eab97f260ba0f56d1d4a82f3a4eb2c979452011Jim Grosbach if (!isImm) 117399cb622041a0839c7dfcf0263c5102a305a0fdb5Bill Wendling Imm8 = CTX.getRegisterInfo()->getEncodingValue(MO.getReg()); 11747eab97f260ba0f56d1d4a82f3a4eb2c979452011Jim Grosbach return Imm8 | (isAdd << 8) | (isImm << 9); 11757eab97f260ba0f56d1d4a82f3a4eb2c979452011Jim Grosbach} 11767eab97f260ba0f56d1d4a82f3a4eb2c979452011Jim Grosbach 11777eab97f260ba0f56d1d4a82f3a4eb2c979452011Jim Grosbachuint32_t ARMMCCodeEmitter:: 1178570a9226913ebe1af04832b8fb3273c70b4ee152Jim GrosbachgetAddrMode3OpValue(const MCInst &MI, unsigned OpIdx, 117936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines SmallVectorImpl<MCFixup> &Fixups, 118036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines const MCSubtargetInfo &STI) const { 1181570a9226913ebe1af04832b8fb3273c70b4ee152Jim Grosbach // {13} 1 == imm8, 0 == Rm 1182570a9226913ebe1af04832b8fb3273c70b4ee152Jim Grosbach // {12-9} Rn 1183570a9226913ebe1af04832b8fb3273c70b4ee152Jim Grosbach // {8} isAdd 1184570a9226913ebe1af04832b8fb3273c70b4ee152Jim Grosbach // {7-4} imm7_4/zero 1185570a9226913ebe1af04832b8fb3273c70b4ee152Jim Grosbach // {3-0} imm3_0/Rm 1186570a9226913ebe1af04832b8fb3273c70b4ee152Jim Grosbach const MCOperand &MO = MI.getOperand(OpIdx); 1187570a9226913ebe1af04832b8fb3273c70b4ee152Jim Grosbach const MCOperand &MO1 = MI.getOperand(OpIdx+1); 1188570a9226913ebe1af04832b8fb3273c70b4ee152Jim Grosbach const MCOperand &MO2 = MI.getOperand(OpIdx+2); 11892f196747f15240691bd4e622f7995edfedf90f61Jim Grosbach 11902f196747f15240691bd4e622f7995edfedf90f61Jim Grosbach // If The first operand isn't a register, we have a label reference. 11912f196747f15240691bd4e622f7995edfedf90f61Jim Grosbach if (!MO.isReg()) { 119299cb622041a0839c7dfcf0263c5102a305a0fdb5Bill Wendling unsigned Rn = CTX.getRegisterInfo()->getEncodingValue(ARM::PC); // Rn is PC. 11932f196747f15240691bd4e622f7995edfedf90f61Jim Grosbach 11942f196747f15240691bd4e622f7995edfedf90f61Jim Grosbach assert(MO.isExpr() && "Unexpected machine operand type!"); 11952f196747f15240691bd4e622f7995edfedf90f61Jim Grosbach const MCExpr *Expr = MO.getExpr(); 11962f196747f15240691bd4e622f7995edfedf90f61Jim Grosbach MCFixupKind Kind = MCFixupKind(ARM::fixup_arm_pcrel_10_unscaled); 119742e6bd38e02e2e1c2cc50d2f12036c38c4ea3ab0Jim Grosbach Fixups.push_back(MCFixup::Create(0, Expr, Kind, MI.getLoc())); 11982f196747f15240691bd4e622f7995edfedf90f61Jim Grosbach 11992f196747f15240691bd4e622f7995edfedf90f61Jim Grosbach ++MCNumCPRelocations; 12002f196747f15240691bd4e622f7995edfedf90f61Jim Grosbach return (Rn << 9) | (1 << 13); 12012f196747f15240691bd4e622f7995edfedf90f61Jim Grosbach } 120299cb622041a0839c7dfcf0263c5102a305a0fdb5Bill Wendling unsigned Rn = CTX.getRegisterInfo()->getEncodingValue(MO.getReg()); 1203570a9226913ebe1af04832b8fb3273c70b4ee152Jim Grosbach unsigned Imm = MO2.getImm(); 1204570a9226913ebe1af04832b8fb3273c70b4ee152Jim Grosbach bool isAdd = ARM_AM::getAM3Op(Imm) == ARM_AM::add; 1205570a9226913ebe1af04832b8fb3273c70b4ee152Jim Grosbach bool isImm = MO1.getReg() == 0; 1206570a9226913ebe1af04832b8fb3273c70b4ee152Jim Grosbach uint32_t Imm8 = ARM_AM::getAM3Offset(Imm); 1207570a9226913ebe1af04832b8fb3273c70b4ee152Jim Grosbach // if reg +/- reg, Rm will be non-zero. Otherwise, we have reg +/- imm8 1208570a9226913ebe1af04832b8fb3273c70b4ee152Jim Grosbach if (!isImm) 120999cb622041a0839c7dfcf0263c5102a305a0fdb5Bill Wendling Imm8 = CTX.getRegisterInfo()->getEncodingValue(MO1.getReg()); 1210570a9226913ebe1af04832b8fb3273c70b4ee152Jim Grosbach return (Rn << 9) | Imm8 | (isAdd << 8) | (isImm << 13); 1211570a9226913ebe1af04832b8fb3273c70b4ee152Jim Grosbach} 1212570a9226913ebe1af04832b8fb3273c70b4ee152Jim Grosbach 1213b8958b031ec5163261f490f131780c5dc3d823d6Bill Wendling/// getAddrModeThumbSPOpValue - Encode the t_addrmode_sp operands. 1214d967cd096ae87accf2f1df86b2dfac969d9c9da2Jim Grosbachuint32_t ARMMCCodeEmitter:: 1215d967cd096ae87accf2f1df86b2dfac969d9c9da2Jim GrosbachgetAddrModeThumbSPOpValue(const MCInst &MI, unsigned OpIdx, 121636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines SmallVectorImpl<MCFixup> &Fixups, 121736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines const MCSubtargetInfo &STI) const { 1218d967cd096ae87accf2f1df86b2dfac969d9c9da2Jim Grosbach // [SP, #imm] 1219d967cd096ae87accf2f1df86b2dfac969d9c9da2Jim Grosbach // {7-0} = imm8 1220d967cd096ae87accf2f1df86b2dfac969d9c9da2Jim Grosbach const MCOperand &MO1 = MI.getOperand(OpIdx + 1); 1221b8958b031ec5163261f490f131780c5dc3d823d6Bill Wendling assert(MI.getOperand(OpIdx).getReg() == ARM::SP && 1222b8958b031ec5163261f490f131780c5dc3d823d6Bill Wendling "Unexpected base register!"); 12237a905a82f7425d1a10b828c8bb3365b2ebc15833Bill Wendling 1224d967cd096ae87accf2f1df86b2dfac969d9c9da2Jim Grosbach // The immediate is already shifted for the implicit zeroes, so no change 1225d967cd096ae87accf2f1df86b2dfac969d9c9da2Jim Grosbach // here. 1226d967cd096ae87accf2f1df86b2dfac969d9c9da2Jim Grosbach return MO1.getImm() & 0xff; 1227d967cd096ae87accf2f1df86b2dfac969d9c9da2Jim Grosbach} 1228d967cd096ae87accf2f1df86b2dfac969d9c9da2Jim Grosbach 1229f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling/// getAddrModeISOpValue - Encode the t_addrmode_is# operands. 1230272df516d7a9b1f0f69174276abaa759816ee456Bill Wendlinguint32_t ARMMCCodeEmitter:: 1231f4caf69720d807573c50d41aa06bcec1c99bdbbdBill WendlinggetAddrModeISOpValue(const MCInst &MI, unsigned OpIdx, 123236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines SmallVectorImpl<MCFixup> &Fixups, 123336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines const MCSubtargetInfo &STI) const { 1234ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling // [Rn, #imm] 1235ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling // {7-3} = imm5 1236ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling // {2-0} = Rn 1237ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling const MCOperand &MO = MI.getOperand(OpIdx); 1238ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling const MCOperand &MO1 = MI.getOperand(OpIdx + 1); 123999cb622041a0839c7dfcf0263c5102a305a0fdb5Bill Wendling unsigned Rn = CTX.getRegisterInfo()->getEncodingValue(MO.getReg()); 1240656b3d22f70c2d1c8a5286f7270cb380df862565Matt Beaumont-Gay unsigned Imm5 = MO1.getImm(); 1241272df516d7a9b1f0f69174276abaa759816ee456Bill Wendling return ((Imm5 & 0x1f) << 3) | Rn; 12421fd374e9c1c074c1681336bef31e65f0170b0f7eBill Wendling} 12431fd374e9c1c074c1681336bef31e65f0170b0f7eBill Wendling 1244b8958b031ec5163261f490f131780c5dc3d823d6Bill Wendling/// getAddrModePCOpValue - Return encoding for t_addrmode_pc operands. 1245b8958b031ec5163261f490f131780c5dc3d823d6Bill Wendlinguint32_t ARMMCCodeEmitter:: 1246b8958b031ec5163261f490f131780c5dc3d823d6Bill WendlinggetAddrModePCOpValue(const MCInst &MI, unsigned OpIdx, 124736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines SmallVectorImpl<MCFixup> &Fixups, 124836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines const MCSubtargetInfo &STI) const { 1249a7710edd98d71a81c43f8e3889cf0c790885d1b8Owen Anderson const MCOperand MO = MI.getOperand(OpIdx); 1250a7710edd98d71a81c43f8e3889cf0c790885d1b8Owen Anderson if (MO.isExpr()) 125136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return ::getBranchTargetOpValue(MI, OpIdx, ARM::fixup_arm_thumb_cp, Fixups, STI); 1252a7710edd98d71a81c43f8e3889cf0c790885d1b8Owen Anderson return (MO.getImm() >> 2); 1253b8958b031ec5163261f490f131780c5dc3d823d6Bill Wendling} 1254b8958b031ec5163261f490f131780c5dc3d823d6Bill Wendling 12555177f79c378b47e38bed5ac05ba4b597f31b864eJim Grosbach/// getAddrMode5OpValue - Return encoding info for 'reg +/- imm10' operand. 1256806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbachuint32_t ARMMCCodeEmitter:: 1257806e80ef42bdb416f409142a1ff1d4e8752baac8Jim GrosbachgetAddrMode5OpValue(const MCInst &MI, unsigned OpIdx, 125836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines SmallVectorImpl<MCFixup> &Fixups, 125936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines const MCSubtargetInfo &STI) const { 126092b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling // {12-9} = reg 126192b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling // {8} = (U)nsigned (add == '1', sub == '0') 126292b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling // {7-0} = imm8 126392b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling unsigned Reg, Imm8; 126497dd28fb89dc4c4caa3c60890335dc99489981a6Jim Grosbach bool isAdd; 126570933266ae73c891d9d1c2f0de72ecd1db8f86dfJim Grosbach // If The first operand isn't a register, we have a label reference. 126670933266ae73c891d9d1c2f0de72ecd1db8f86dfJim Grosbach const MCOperand &MO = MI.getOperand(OpIdx); 126770933266ae73c891d9d1c2f0de72ecd1db8f86dfJim Grosbach if (!MO.isReg()) { 126899cb622041a0839c7dfcf0263c5102a305a0fdb5Bill Wendling Reg = CTX.getRegisterInfo()->getEncodingValue(ARM::PC); // Rn is PC. 126970933266ae73c891d9d1c2f0de72ecd1db8f86dfJim Grosbach Imm8 = 0; 127097dd28fb89dc4c4caa3c60890335dc99489981a6Jim Grosbach isAdd = false; // 'U' bit is handled as part of the fixup. 127170933266ae73c891d9d1c2f0de72ecd1db8f86dfJim Grosbach 127270933266ae73c891d9d1c2f0de72ecd1db8f86dfJim Grosbach assert(MO.isExpr() && "Unexpected machine operand type!"); 127370933266ae73c891d9d1c2f0de72ecd1db8f86dfJim Grosbach const MCExpr *Expr = MO.getExpr(); 1274d8e351b96f5fd7007fbdd636acaa1fc9f6e18f3cOwen Anderson MCFixupKind Kind; 127536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (isThumb2(STI)) 1276d8e351b96f5fd7007fbdd636acaa1fc9f6e18f3cOwen Anderson Kind = MCFixupKind(ARM::fixup_t2_pcrel_10); 1277d8e351b96f5fd7007fbdd636acaa1fc9f6e18f3cOwen Anderson else 1278d8e351b96f5fd7007fbdd636acaa1fc9f6e18f3cOwen Anderson Kind = MCFixupKind(ARM::fixup_arm_pcrel_10); 127942e6bd38e02e2e1c2cc50d2f12036c38c4ea3ab0Jim Grosbach Fixups.push_back(MCFixup::Create(0, Expr, Kind, MI.getLoc())); 128070933266ae73c891d9d1c2f0de72ecd1db8f86dfJim Grosbach 128170933266ae73c891d9d1c2f0de72ecd1db8f86dfJim Grosbach ++MCNumCPRelocations; 128297dd28fb89dc4c4caa3c60890335dc99489981a6Jim Grosbach } else { 128336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines EncodeAddrModeOpValues(MI, OpIdx, Reg, Imm8, Fixups, STI); 128497dd28fb89dc4c4caa3c60890335dc99489981a6Jim Grosbach isAdd = ARM_AM::getAM5Op(Imm8) == ARM_AM::add; 128597dd28fb89dc4c4caa3c60890335dc99489981a6Jim Grosbach } 128692b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling 128792b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling uint32_t Binary = ARM_AM::getAM5Offset(Imm8); 128892b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling // Immediate is always encoded as positive. The 'U' bit controls add vs sub. 128997dd28fb89dc4c4caa3c60890335dc99489981a6Jim Grosbach if (isAdd) 129092b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling Binary |= (1 << 8); 129192b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling Binary |= (Reg << 9); 12923e5561247202bae994dd259a2d8dc4eff8f799f3Jim Grosbach return Binary; 12933e5561247202bae994dd259a2d8dc4eff8f799f3Jim Grosbach} 12943e5561247202bae994dd259a2d8dc4eff8f799f3Jim Grosbach 1295806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbachunsigned ARMMCCodeEmitter:: 1296152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen AndersongetSORegRegOpValue(const MCInst &MI, unsigned OpIdx, 129736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines SmallVectorImpl<MCFixup> &Fixups, 129836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines const MCSubtargetInfo &STI) const { 12990800ce71896ccd7f49b37861a8cfbc21b6b10022Bill Wendling // Sub-operands are [reg, reg, imm]. The first register is Rm, the reg to be 1300354712c5a506449676e6fcac6b623af4092e7100Owen Anderson // shifted. The second is Rs, the amount to shift by, and the third specifies 1301354712c5a506449676e6fcac6b623af4092e7100Owen Anderson // the type of the shift. 130235b2de012d9404e3e9e4373e45f41711f752dd3aJim Grosbach // 1303ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach // {3-0} = Rm. 1304354712c5a506449676e6fcac6b623af4092e7100Owen Anderson // {4} = 1 1305ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach // {6-5} = type 1306354712c5a506449676e6fcac6b623af4092e7100Owen Anderson // {11-8} = Rs 1307354712c5a506449676e6fcac6b623af4092e7100Owen Anderson // {7} = 0 1308ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach 1309ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach const MCOperand &MO = MI.getOperand(OpIdx); 1310ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach const MCOperand &MO1 = MI.getOperand(OpIdx + 1); 1311ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach const MCOperand &MO2 = MI.getOperand(OpIdx + 2); 1312ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach ARM_AM::ShiftOpc SOpc = ARM_AM::getSORegShOp(MO2.getImm()); 1313ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach 1314ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach // Encode Rm. 131599cb622041a0839c7dfcf0263c5102a305a0fdb5Bill Wendling unsigned Binary = CTX.getRegisterInfo()->getEncodingValue(MO.getReg()); 1316ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach 1317ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach // Encode the shift opcode. 1318ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach unsigned SBits = 0; 1319ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach unsigned Rs = MO1.getReg(); 1320ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach if (Rs) { 1321ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach // Set shift operand (bit[7:4]). 1322ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach // LSL - 0001 1323ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach // LSR - 0011 1324ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach // ASR - 0101 1325ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach // ROR - 0111 1326ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach switch (SOpc) { 1327ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach default: llvm_unreachable("Unknown shift opc!"); 1328ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach case ARM_AM::lsl: SBits = 0x1; break; 1329ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach case ARM_AM::lsr: SBits = 0x3; break; 1330ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach case ARM_AM::asr: SBits = 0x5; break; 1331ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach case ARM_AM::ror: SBits = 0x7; break; 1332ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach } 1333ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach } 13340800ce71896ccd7f49b37861a8cfbc21b6b10022Bill Wendling 1335ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach Binary |= SBits << 4; 1336ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach 1337354712c5a506449676e6fcac6b623af4092e7100Owen Anderson // Encode the shift operation Rs. 1338152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson // Encode Rs bit[11:8]. 1339152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson assert(ARM_AM::getSORegOffset(MO2.getImm()) == 0); 134099cb622041a0839c7dfcf0263c5102a305a0fdb5Bill Wendling return Binary | (CTX.getRegisterInfo()->getEncodingValue(Rs) << ARMII::RegRsShift); 1341152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson} 1342152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson 1343152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Andersonunsigned ARMMCCodeEmitter:: 1344152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen AndersongetSORegImmOpValue(const MCInst &MI, unsigned OpIdx, 134536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines SmallVectorImpl<MCFixup> &Fixups, 134636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines const MCSubtargetInfo &STI) const { 1347354712c5a506449676e6fcac6b623af4092e7100Owen Anderson // Sub-operands are [reg, imm]. The first register is Rm, the reg to be 1348354712c5a506449676e6fcac6b623af4092e7100Owen Anderson // shifted. The second is the amount to shift by. 1349152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson // 1350152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson // {3-0} = Rm. 1351354712c5a506449676e6fcac6b623af4092e7100Owen Anderson // {4} = 0 1352152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson // {6-5} = type 1353354712c5a506449676e6fcac6b623af4092e7100Owen Anderson // {11-7} = imm 1354152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson 1355152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson const MCOperand &MO = MI.getOperand(OpIdx); 1356152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson const MCOperand &MO1 = MI.getOperand(OpIdx + 1); 1357152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson ARM_AM::ShiftOpc SOpc = ARM_AM::getSORegShOp(MO1.getImm()); 1358152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson 1359152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson // Encode Rm. 136099cb622041a0839c7dfcf0263c5102a305a0fdb5Bill Wendling unsigned Binary = CTX.getRegisterInfo()->getEncodingValue(MO.getReg()); 1361152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson 1362152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson // Encode the shift opcode. 1363152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson unsigned SBits = 0; 1364152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson 1365152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson // Set shift operand (bit[6:4]). 1366152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson // LSL - 000 1367152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson // LSR - 010 1368152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson // ASR - 100 1369152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson // ROR - 110 1370152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson // RRX - 110 and bit[11:8] clear. 1371152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson switch (SOpc) { 1372152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson default: llvm_unreachable("Unknown shift opc!"); 1373152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson case ARM_AM::lsl: SBits = 0x0; break; 1374152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson case ARM_AM::lsr: SBits = 0x2; break; 1375152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson case ARM_AM::asr: SBits = 0x4; break; 1376152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson case ARM_AM::ror: SBits = 0x6; break; 1377152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson case ARM_AM::rrx: 1378152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson Binary |= 0x60; 1379152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson return Binary; 1380ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach } 1381ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach 1382ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach // Encode shift_imm bit[11:7]. 1383152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson Binary |= SBits << 4; 13843dac0bec7e7874ffb378385b6160bd2117184ca9Owen Anderson unsigned Offset = ARM_AM::getSORegOffset(MO1.getImm()); 1385b56e4115ed33dae56108ed4ce88ee3a0e0392bfcRichard Barton assert(Offset < 32 && "Offset must be in range 0-31!"); 13863dac0bec7e7874ffb378385b6160bd2117184ca9Owen Anderson return Binary | (Offset << 7); 1387ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach} 1388ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach 1389152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson 1390806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbachunsigned ARMMCCodeEmitter:: 139175579f739fbc99a92a15f3ce75bbd7628ba00f8cOwen AndersongetT2AddrModeSORegOpValue(const MCInst &MI, unsigned OpNum, 139236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines SmallVectorImpl<MCFixup> &Fixups, 139336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines const MCSubtargetInfo &STI) const { 139475579f739fbc99a92a15f3ce75bbd7628ba00f8cOwen Anderson const MCOperand &MO1 = MI.getOperand(OpNum); 139575579f739fbc99a92a15f3ce75bbd7628ba00f8cOwen Anderson const MCOperand &MO2 = MI.getOperand(OpNum+1); 13967bf4c02789f97e32225fc248dff6622b994a15eeJim Grosbach const MCOperand &MO3 = MI.getOperand(OpNum+2); 13977bf4c02789f97e32225fc248dff6622b994a15eeJim Grosbach 139875579f739fbc99a92a15f3ce75bbd7628ba00f8cOwen Anderson // Encoded as [Rn, Rm, imm]. 139975579f739fbc99a92a15f3ce75bbd7628ba00f8cOwen Anderson // FIXME: Needs fixup support. 140099cb622041a0839c7dfcf0263c5102a305a0fdb5Bill Wendling unsigned Value = CTX.getRegisterInfo()->getEncodingValue(MO1.getReg()); 140175579f739fbc99a92a15f3ce75bbd7628ba00f8cOwen Anderson Value <<= 4; 140299cb622041a0839c7dfcf0263c5102a305a0fdb5Bill Wendling Value |= CTX.getRegisterInfo()->getEncodingValue(MO2.getReg()); 140375579f739fbc99a92a15f3ce75bbd7628ba00f8cOwen Anderson Value <<= 2; 140475579f739fbc99a92a15f3ce75bbd7628ba00f8cOwen Anderson Value |= MO3.getImm(); 14057bf4c02789f97e32225fc248dff6622b994a15eeJim Grosbach 140675579f739fbc99a92a15f3ce75bbd7628ba00f8cOwen Anderson return Value; 140775579f739fbc99a92a15f3ce75bbd7628ba00f8cOwen Anderson} 140875579f739fbc99a92a15f3ce75bbd7628ba00f8cOwen Anderson 140975579f739fbc99a92a15f3ce75bbd7628ba00f8cOwen Andersonunsigned ARMMCCodeEmitter:: 141075579f739fbc99a92a15f3ce75bbd7628ba00f8cOwen AndersongetT2AddrModeImm8OpValue(const MCInst &MI, unsigned OpNum, 141136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines SmallVectorImpl<MCFixup> &Fixups, 141236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines const MCSubtargetInfo &STI) const { 141375579f739fbc99a92a15f3ce75bbd7628ba00f8cOwen Anderson const MCOperand &MO1 = MI.getOperand(OpNum); 141475579f739fbc99a92a15f3ce75bbd7628ba00f8cOwen Anderson const MCOperand &MO2 = MI.getOperand(OpNum+1); 141575579f739fbc99a92a15f3ce75bbd7628ba00f8cOwen Anderson 141675579f739fbc99a92a15f3ce75bbd7628ba00f8cOwen Anderson // FIXME: Needs fixup support. 141799cb622041a0839c7dfcf0263c5102a305a0fdb5Bill Wendling unsigned Value = CTX.getRegisterInfo()->getEncodingValue(MO1.getReg()); 14187bf4c02789f97e32225fc248dff6622b994a15eeJim Grosbach 141975579f739fbc99a92a15f3ce75bbd7628ba00f8cOwen Anderson // Even though the immediate is 8 bits long, we need 9 bits in order 142075579f739fbc99a92a15f3ce75bbd7628ba00f8cOwen Anderson // to represent the (inverse of the) sign bit. 142175579f739fbc99a92a15f3ce75bbd7628ba00f8cOwen Anderson Value <<= 9; 14226af50f7dd12d82f0a80f3158102180eee4c921aaOwen Anderson int32_t tmp = (int32_t)MO2.getImm(); 14236af50f7dd12d82f0a80f3158102180eee4c921aaOwen Anderson if (tmp < 0) 14246af50f7dd12d82f0a80f3158102180eee4c921aaOwen Anderson tmp = abs(tmp); 14256af50f7dd12d82f0a80f3158102180eee4c921aaOwen Anderson else 14266af50f7dd12d82f0a80f3158102180eee4c921aaOwen Anderson Value |= 256; // Set the ADD bit 14276af50f7dd12d82f0a80f3158102180eee4c921aaOwen Anderson Value |= tmp & 255; 14286af50f7dd12d82f0a80f3158102180eee4c921aaOwen Anderson return Value; 14296af50f7dd12d82f0a80f3158102180eee4c921aaOwen Anderson} 14306af50f7dd12d82f0a80f3158102180eee4c921aaOwen Anderson 14316af50f7dd12d82f0a80f3158102180eee4c921aaOwen Andersonunsigned ARMMCCodeEmitter:: 14326af50f7dd12d82f0a80f3158102180eee4c921aaOwen AndersongetT2AddrModeImm8OffsetOpValue(const MCInst &MI, unsigned OpNum, 143336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines SmallVectorImpl<MCFixup> &Fixups, 143436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines const MCSubtargetInfo &STI) const { 14356af50f7dd12d82f0a80f3158102180eee4c921aaOwen Anderson const MCOperand &MO1 = MI.getOperand(OpNum); 14366af50f7dd12d82f0a80f3158102180eee4c921aaOwen Anderson 14376af50f7dd12d82f0a80f3158102180eee4c921aaOwen Anderson // FIXME: Needs fixup support. 14386af50f7dd12d82f0a80f3158102180eee4c921aaOwen Anderson unsigned Value = 0; 14396af50f7dd12d82f0a80f3158102180eee4c921aaOwen Anderson int32_t tmp = (int32_t)MO1.getImm(); 14406af50f7dd12d82f0a80f3158102180eee4c921aaOwen Anderson if (tmp < 0) 14416af50f7dd12d82f0a80f3158102180eee4c921aaOwen Anderson tmp = abs(tmp); 14426af50f7dd12d82f0a80f3158102180eee4c921aaOwen Anderson else 14436af50f7dd12d82f0a80f3158102180eee4c921aaOwen Anderson Value |= 256; // Set the ADD bit 14446af50f7dd12d82f0a80f3158102180eee4c921aaOwen Anderson Value |= tmp & 255; 144575579f739fbc99a92a15f3ce75bbd7628ba00f8cOwen Anderson return Value; 144675579f739fbc99a92a15f3ce75bbd7628ba00f8cOwen Anderson} 144775579f739fbc99a92a15f3ce75bbd7628ba00f8cOwen Anderson 144875579f739fbc99a92a15f3ce75bbd7628ba00f8cOwen Andersonunsigned ARMMCCodeEmitter:: 14490e1bcdf4f7547bb5f47ed5ff5f2409a8f72f3609Owen AndersongetT2AddrModeImm12OffsetOpValue(const MCInst &MI, unsigned OpNum, 145036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines SmallVectorImpl<MCFixup> &Fixups, 145136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines const MCSubtargetInfo &STI) const { 14520e1bcdf4f7547bb5f47ed5ff5f2409a8f72f3609Owen Anderson const MCOperand &MO1 = MI.getOperand(OpNum); 14530e1bcdf4f7547bb5f47ed5ff5f2409a8f72f3609Owen Anderson 14540e1bcdf4f7547bb5f47ed5ff5f2409a8f72f3609Owen Anderson // FIXME: Needs fixup support. 14550e1bcdf4f7547bb5f47ed5ff5f2409a8f72f3609Owen Anderson unsigned Value = 0; 14560e1bcdf4f7547bb5f47ed5ff5f2409a8f72f3609Owen Anderson int32_t tmp = (int32_t)MO1.getImm(); 14570e1bcdf4f7547bb5f47ed5ff5f2409a8f72f3609Owen Anderson if (tmp < 0) 14580e1bcdf4f7547bb5f47ed5ff5f2409a8f72f3609Owen Anderson tmp = abs(tmp); 14590e1bcdf4f7547bb5f47ed5ff5f2409a8f72f3609Owen Anderson else 14600e1bcdf4f7547bb5f47ed5ff5f2409a8f72f3609Owen Anderson Value |= 4096; // Set the ADD bit 14610e1bcdf4f7547bb5f47ed5ff5f2409a8f72f3609Owen Anderson Value |= tmp & 4095; 14620e1bcdf4f7547bb5f47ed5ff5f2409a8f72f3609Owen Anderson return Value; 14630e1bcdf4f7547bb5f47ed5ff5f2409a8f72f3609Owen Anderson} 14640e1bcdf4f7547bb5f47ed5ff5f2409a8f72f3609Owen Anderson 14650e1bcdf4f7547bb5f47ed5ff5f2409a8f72f3609Owen Andersonunsigned ARMMCCodeEmitter:: 14665de6d841a5116152793dcab35a2e534a6a9aaa7aOwen AndersongetT2SORegOpValue(const MCInst &MI, unsigned OpIdx, 146736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines SmallVectorImpl<MCFixup> &Fixups, 146836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines const MCSubtargetInfo &STI) const { 14695de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson // Sub-operands are [reg, imm]. The first register is Rm, the reg to be 14705de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson // shifted. The second is the amount to shift by. 14715de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson // 14725de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson // {3-0} = Rm. 14735de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson // {4} = 0 14745de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson // {6-5} = type 14755de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson // {11-7} = imm 14765de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson 14775de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson const MCOperand &MO = MI.getOperand(OpIdx); 14785de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson const MCOperand &MO1 = MI.getOperand(OpIdx + 1); 14795de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson ARM_AM::ShiftOpc SOpc = ARM_AM::getSORegShOp(MO1.getImm()); 14805de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson 14815de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson // Encode Rm. 148299cb622041a0839c7dfcf0263c5102a305a0fdb5Bill Wendling unsigned Binary = CTX.getRegisterInfo()->getEncodingValue(MO.getReg()); 14835de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson 14845de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson // Encode the shift opcode. 14855de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson unsigned SBits = 0; 14865de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson // Set shift operand (bit[6:4]). 14875de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson // LSL - 000 14885de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson // LSR - 010 14895de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson // ASR - 100 14905de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson // ROR - 110 14915de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson switch (SOpc) { 14925de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson default: llvm_unreachable("Unknown shift opc!"); 14935de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson case ARM_AM::lsl: SBits = 0x0; break; 14945de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson case ARM_AM::lsr: SBits = 0x2; break; 14955de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson case ARM_AM::asr: SBits = 0x4; break; 149612c7e90d369b4605aac0ddbd252231beacb2aabbOwen Anderson case ARM_AM::rrx: // FALLTHROUGH 14975de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson case ARM_AM::ror: SBits = 0x6; break; 14985de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson } 14995de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson 15005de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson Binary |= SBits << 4; 15015de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson if (SOpc == ARM_AM::rrx) 15025de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson return Binary; 15035de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson 15045de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson // Encode shift_imm bit[11:7]. 15055de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson return Binary | ARM_AM::getSORegOffset(MO1.getImm()) << 7; 15065de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson} 15075de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson 15085de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Andersonunsigned ARMMCCodeEmitter:: 1509806e80ef42bdb416f409142a1ff1d4e8752baac8Jim GrosbachgetBitfieldInvertedMaskOpValue(const MCInst &MI, unsigned Op, 151036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines SmallVectorImpl<MCFixup> &Fixups, 151136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines const MCSubtargetInfo &STI) const { 15123fea19105d4929ad694f0b6272de31924c9f9f09Jim Grosbach // 10 bits. lower 5 bits are are the lsb of the mask, high five bits are the 15133fea19105d4929ad694f0b6272de31924c9f9f09Jim Grosbach // msb of the mask. 15143fea19105d4929ad694f0b6272de31924c9f9f09Jim Grosbach const MCOperand &MO = MI.getOperand(Op); 15153fea19105d4929ad694f0b6272de31924c9f9f09Jim Grosbach uint32_t v = ~MO.getImm(); 1516c6af2432c802d241c8fffbe0371c023e6c58844eMichael J. Spencer uint32_t lsb = countTrailingZeros(v); 1517c6af2432c802d241c8fffbe0371c023e6c58844eMichael J. Spencer uint32_t msb = (32 - countLeadingZeros (v)) - 1; 15183fea19105d4929ad694f0b6272de31924c9f9f09Jim Grosbach assert (v != 0 && lsb < 32 && msb < 32 && "Illegal bitfield mask!"); 15193fea19105d4929ad694f0b6272de31924c9f9f09Jim Grosbach return lsb | (msb << 5); 15203fea19105d4929ad694f0b6272de31924c9f9f09Jim Grosbach} 15213fea19105d4929ad694f0b6272de31924c9f9f09Jim Grosbach 1522806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbachunsigned ARMMCCodeEmitter:: 1523806e80ef42bdb416f409142a1ff1d4e8752baac8Jim GrosbachgetRegisterListOpValue(const MCInst &MI, unsigned Op, 152436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines SmallVectorImpl<MCFixup> &Fixups, 152536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines const MCSubtargetInfo &STI) const { 15266bc105a7b9282a0b5beb9d06267b31a3054fb3faBill Wendling // VLDM/VSTM: 15276bc105a7b9282a0b5beb9d06267b31a3054fb3faBill Wendling // {12-8} = Vd 15286bc105a7b9282a0b5beb9d06267b31a3054fb3faBill Wendling // {7-0} = Number of registers 15296bc105a7b9282a0b5beb9d06267b31a3054fb3faBill Wendling // 15306bc105a7b9282a0b5beb9d06267b31a3054fb3faBill Wendling // LDM/STM: 15316bc105a7b9282a0b5beb9d06267b31a3054fb3faBill Wendling // {15-0} = Bitfield of GPRs. 15326bc105a7b9282a0b5beb9d06267b31a3054fb3faBill Wendling unsigned Reg = MI.getOperand(Op).getReg(); 1533c89c744b69cecac576317a98322fd295e36e9886Craig Topper bool SPRRegs = ARMMCRegisterClasses[ARM::SPRRegClassID].contains(Reg); 1534c89c744b69cecac576317a98322fd295e36e9886Craig Topper bool DPRRegs = ARMMCRegisterClasses[ARM::DPRRegClassID].contains(Reg); 15356bc105a7b9282a0b5beb9d06267b31a3054fb3faBill Wendling 15365e559a22c18166508a01fbd65471ec4e752726f9Bill Wendling unsigned Binary = 0; 15376bc105a7b9282a0b5beb9d06267b31a3054fb3faBill Wendling 15386bc105a7b9282a0b5beb9d06267b31a3054fb3faBill Wendling if (SPRRegs || DPRRegs) { 15396bc105a7b9282a0b5beb9d06267b31a3054fb3faBill Wendling // VLDM/VSTM 154099cb622041a0839c7dfcf0263c5102a305a0fdb5Bill Wendling unsigned RegNo = CTX.getRegisterInfo()->getEncodingValue(Reg); 15416bc105a7b9282a0b5beb9d06267b31a3054fb3faBill Wendling unsigned NumRegs = (MI.getNumOperands() - Op) & 0xff; 15426bc105a7b9282a0b5beb9d06267b31a3054fb3faBill Wendling Binary |= (RegNo & 0x1f) << 8; 15436bc105a7b9282a0b5beb9d06267b31a3054fb3faBill Wendling if (SPRRegs) 15446bc105a7b9282a0b5beb9d06267b31a3054fb3faBill Wendling Binary |= NumRegs; 15456bc105a7b9282a0b5beb9d06267b31a3054fb3faBill Wendling else 15466bc105a7b9282a0b5beb9d06267b31a3054fb3faBill Wendling Binary |= NumRegs * 2; 15476bc105a7b9282a0b5beb9d06267b31a3054fb3faBill Wendling } else { 15486bc105a7b9282a0b5beb9d06267b31a3054fb3faBill Wendling for (unsigned I = Op, E = MI.getNumOperands(); I < E; ++I) { 154999cb622041a0839c7dfcf0263c5102a305a0fdb5Bill Wendling unsigned RegNo = CTX.getRegisterInfo()->getEncodingValue(MI.getOperand(I).getReg()); 15506bc105a7b9282a0b5beb9d06267b31a3054fb3faBill Wendling Binary |= 1 << RegNo; 15516bc105a7b9282a0b5beb9d06267b31a3054fb3faBill Wendling } 15525e559a22c18166508a01fbd65471ec4e752726f9Bill Wendling } 15536bc105a7b9282a0b5beb9d06267b31a3054fb3faBill Wendling 15546b5252db2db5eeeadec4602329ac56beb6dea54aJim Grosbach return Binary; 15556b5252db2db5eeeadec4602329ac56beb6dea54aJim Grosbach} 15566b5252db2db5eeeadec4602329ac56beb6dea54aJim Grosbach 15578e0c7b52877983b4838e54e233449912fc1a2325Bob Wilson/// getAddrMode6AddressOpValue - Encode an addrmode6 register number along 15588e0c7b52877983b4838e54e233449912fc1a2325Bob Wilson/// with the alignment operand. 1559806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbachunsigned ARMMCCodeEmitter:: 1560806e80ef42bdb416f409142a1ff1d4e8752baac8Jim GrosbachgetAddrMode6AddressOpValue(const MCInst &MI, unsigned Op, 156136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines SmallVectorImpl<MCFixup> &Fixups, 156236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines const MCSubtargetInfo &STI) const { 1563d9aa7d30aa277fba319ee4bcdb862cd79f1aabe5Owen Anderson const MCOperand &Reg = MI.getOperand(Op); 15640800ce71896ccd7f49b37861a8cfbc21b6b10022Bill Wendling const MCOperand &Imm = MI.getOperand(Op + 1); 156535b2de012d9404e3e9e4373e45f41711f752dd3aJim Grosbach 156699cb622041a0839c7dfcf0263c5102a305a0fdb5Bill Wendling unsigned RegNo = CTX.getRegisterInfo()->getEncodingValue(Reg.getReg()); 15670800ce71896ccd7f49b37861a8cfbc21b6b10022Bill Wendling unsigned Align = 0; 15680800ce71896ccd7f49b37861a8cfbc21b6b10022Bill Wendling 15690800ce71896ccd7f49b37861a8cfbc21b6b10022Bill Wendling switch (Imm.getImm()) { 15700800ce71896ccd7f49b37861a8cfbc21b6b10022Bill Wendling default: break; 15710800ce71896ccd7f49b37861a8cfbc21b6b10022Bill Wendling case 2: 15720800ce71896ccd7f49b37861a8cfbc21b6b10022Bill Wendling case 4: 15730800ce71896ccd7f49b37861a8cfbc21b6b10022Bill Wendling case 8: Align = 0x01; break; 15740800ce71896ccd7f49b37861a8cfbc21b6b10022Bill Wendling case 16: Align = 0x02; break; 15750800ce71896ccd7f49b37861a8cfbc21b6b10022Bill Wendling case 32: Align = 0x03; break; 1576d9aa7d30aa277fba319ee4bcdb862cd79f1aabe5Owen Anderson } 15770800ce71896ccd7f49b37861a8cfbc21b6b10022Bill Wendling 1578d9aa7d30aa277fba319ee4bcdb862cd79f1aabe5Owen Anderson return RegNo | (Align << 4); 1579d9aa7d30aa277fba319ee4bcdb862cd79f1aabe5Owen Anderson} 1580d9aa7d30aa277fba319ee4bcdb862cd79f1aabe5Owen Anderson 1581183c627d89be5d0e8f3255ab7f6d1204c2fabedfMon P Wang/// getAddrMode6OneLane32AddressOpValue - Encode an addrmode6 register number 1582183c627d89be5d0e8f3255ab7f6d1204c2fabedfMon P Wang/// along with the alignment operand for use in VST1 and VLD1 with size 32. 1583183c627d89be5d0e8f3255ab7f6d1204c2fabedfMon P Wangunsigned ARMMCCodeEmitter:: 1584183c627d89be5d0e8f3255ab7f6d1204c2fabedfMon P WanggetAddrMode6OneLane32AddressOpValue(const MCInst &MI, unsigned Op, 158536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines SmallVectorImpl<MCFixup> &Fixups, 158636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines const MCSubtargetInfo &STI) const { 1587183c627d89be5d0e8f3255ab7f6d1204c2fabedfMon P Wang const MCOperand &Reg = MI.getOperand(Op); 1588183c627d89be5d0e8f3255ab7f6d1204c2fabedfMon P Wang const MCOperand &Imm = MI.getOperand(Op + 1); 1589183c627d89be5d0e8f3255ab7f6d1204c2fabedfMon P Wang 159099cb622041a0839c7dfcf0263c5102a305a0fdb5Bill Wendling unsigned RegNo = CTX.getRegisterInfo()->getEncodingValue(Reg.getReg()); 1591183c627d89be5d0e8f3255ab7f6d1204c2fabedfMon P Wang unsigned Align = 0; 1592183c627d89be5d0e8f3255ab7f6d1204c2fabedfMon P Wang 1593183c627d89be5d0e8f3255ab7f6d1204c2fabedfMon P Wang switch (Imm.getImm()) { 1594183c627d89be5d0e8f3255ab7f6d1204c2fabedfMon P Wang default: break; 1595183c627d89be5d0e8f3255ab7f6d1204c2fabedfMon P Wang case 8: 1596eeaf1c1636c664c707fd9ecc96916fd20ddf137aJim Grosbach case 16: 1597eeaf1c1636c664c707fd9ecc96916fd20ddf137aJim Grosbach case 32: // Default '0' value for invalid alignments of 8, 16, 32 bytes. 1598eeaf1c1636c664c707fd9ecc96916fd20ddf137aJim Grosbach case 2: Align = 0x00; break; 1599eeaf1c1636c664c707fd9ecc96916fd20ddf137aJim Grosbach case 4: Align = 0x03; break; 1600183c627d89be5d0e8f3255ab7f6d1204c2fabedfMon P Wang } 1601183c627d89be5d0e8f3255ab7f6d1204c2fabedfMon P Wang 1602183c627d89be5d0e8f3255ab7f6d1204c2fabedfMon P Wang return RegNo | (Align << 4); 1603183c627d89be5d0e8f3255ab7f6d1204c2fabedfMon P Wang} 1604183c627d89be5d0e8f3255ab7f6d1204c2fabedfMon P Wang 1605183c627d89be5d0e8f3255ab7f6d1204c2fabedfMon P Wang 16068e0c7b52877983b4838e54e233449912fc1a2325Bob Wilson/// getAddrMode6DupAddressOpValue - Encode an addrmode6 register number and 16078e0c7b52877983b4838e54e233449912fc1a2325Bob Wilson/// alignment operand for use in VLD-dup instructions. This is the same as 16088e0c7b52877983b4838e54e233449912fc1a2325Bob Wilson/// getAddrMode6AddressOpValue except for the alignment encoding, which is 16098e0c7b52877983b4838e54e233449912fc1a2325Bob Wilson/// different for VLD4-dup. 16108e0c7b52877983b4838e54e233449912fc1a2325Bob Wilsonunsigned ARMMCCodeEmitter:: 16118e0c7b52877983b4838e54e233449912fc1a2325Bob WilsongetAddrMode6DupAddressOpValue(const MCInst &MI, unsigned Op, 161236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines SmallVectorImpl<MCFixup> &Fixups, 161336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines const MCSubtargetInfo &STI) const { 16148e0c7b52877983b4838e54e233449912fc1a2325Bob Wilson const MCOperand &Reg = MI.getOperand(Op); 16158e0c7b52877983b4838e54e233449912fc1a2325Bob Wilson const MCOperand &Imm = MI.getOperand(Op + 1); 16168e0c7b52877983b4838e54e233449912fc1a2325Bob Wilson 161799cb622041a0839c7dfcf0263c5102a305a0fdb5Bill Wendling unsigned RegNo = CTX.getRegisterInfo()->getEncodingValue(Reg.getReg()); 16188e0c7b52877983b4838e54e233449912fc1a2325Bob Wilson unsigned Align = 0; 16198e0c7b52877983b4838e54e233449912fc1a2325Bob Wilson 16208e0c7b52877983b4838e54e233449912fc1a2325Bob Wilson switch (Imm.getImm()) { 16218e0c7b52877983b4838e54e233449912fc1a2325Bob Wilson default: break; 16228e0c7b52877983b4838e54e233449912fc1a2325Bob Wilson case 2: 16238e0c7b52877983b4838e54e233449912fc1a2325Bob Wilson case 4: 16248e0c7b52877983b4838e54e233449912fc1a2325Bob Wilson case 8: Align = 0x01; break; 16258e0c7b52877983b4838e54e233449912fc1a2325Bob Wilson case 16: Align = 0x03; break; 16268e0c7b52877983b4838e54e233449912fc1a2325Bob Wilson } 16278e0c7b52877983b4838e54e233449912fc1a2325Bob Wilson 16288e0c7b52877983b4838e54e233449912fc1a2325Bob Wilson return RegNo | (Align << 4); 16298e0c7b52877983b4838e54e233449912fc1a2325Bob Wilson} 16308e0c7b52877983b4838e54e233449912fc1a2325Bob Wilson 1631806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbachunsigned ARMMCCodeEmitter:: 1632806e80ef42bdb416f409142a1ff1d4e8752baac8Jim GrosbachgetAddrMode6OffsetOpValue(const MCInst &MI, unsigned Op, 163336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines SmallVectorImpl<MCFixup> &Fixups, 163436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines const MCSubtargetInfo &STI) const { 16350800ce71896ccd7f49b37861a8cfbc21b6b10022Bill Wendling const MCOperand &MO = MI.getOperand(Op); 16360800ce71896ccd7f49b37861a8cfbc21b6b10022Bill Wendling if (MO.getReg() == 0) return 0x0D; 163799cb622041a0839c7dfcf0263c5102a305a0fdb5Bill Wendling return CTX.getRegisterInfo()->getEncodingValue(MO.getReg()); 1638a656b63ee4d5b0e3f4d26a55dd4cc69795746684Bill Wendling} 1639a656b63ee4d5b0e3f4d26a55dd4cc69795746684Bill Wendling 1640a656b63ee4d5b0e3f4d26a55dd4cc69795746684Bill Wendlingunsigned ARMMCCodeEmitter:: 16413116dce33840a115130c5f8ffcb9679d023496d6Bill WendlinggetShiftRight8Imm(const MCInst &MI, unsigned Op, 164236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines SmallVectorImpl<MCFixup> &Fixups, 164336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines const MCSubtargetInfo &STI) const { 1644a656b63ee4d5b0e3f4d26a55dd4cc69795746684Bill Wendling return 8 - MI.getOperand(Op).getImm(); 1645a656b63ee4d5b0e3f4d26a55dd4cc69795746684Bill Wendling} 1646a656b63ee4d5b0e3f4d26a55dd4cc69795746684Bill Wendling 1647a656b63ee4d5b0e3f4d26a55dd4cc69795746684Bill Wendlingunsigned ARMMCCodeEmitter:: 16483116dce33840a115130c5f8ffcb9679d023496d6Bill WendlinggetShiftRight16Imm(const MCInst &MI, unsigned Op, 164936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines SmallVectorImpl<MCFixup> &Fixups, 165036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines const MCSubtargetInfo &STI) const { 1651a656b63ee4d5b0e3f4d26a55dd4cc69795746684Bill Wendling return 16 - MI.getOperand(Op).getImm(); 1652a656b63ee4d5b0e3f4d26a55dd4cc69795746684Bill Wendling} 1653a656b63ee4d5b0e3f4d26a55dd4cc69795746684Bill Wendling 1654a656b63ee4d5b0e3f4d26a55dd4cc69795746684Bill Wendlingunsigned ARMMCCodeEmitter:: 16553116dce33840a115130c5f8ffcb9679d023496d6Bill WendlinggetShiftRight32Imm(const MCInst &MI, unsigned Op, 165636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines SmallVectorImpl<MCFixup> &Fixups, 165736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines const MCSubtargetInfo &STI) const { 1658a656b63ee4d5b0e3f4d26a55dd4cc69795746684Bill Wendling return 32 - MI.getOperand(Op).getImm(); 16593116dce33840a115130c5f8ffcb9679d023496d6Bill Wendling} 16603116dce33840a115130c5f8ffcb9679d023496d6Bill Wendling 16613116dce33840a115130c5f8ffcb9679d023496d6Bill Wendlingunsigned ARMMCCodeEmitter:: 16623116dce33840a115130c5f8ffcb9679d023496d6Bill WendlinggetShiftRight64Imm(const MCInst &MI, unsigned Op, 166336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines SmallVectorImpl<MCFixup> &Fixups, 166436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines const MCSubtargetInfo &STI) const { 16653116dce33840a115130c5f8ffcb9679d023496d6Bill Wendling return 64 - MI.getOperand(Op).getImm(); 1666cf667be17b479fe276fd606b8fd72ccfa3065bb8Owen Anderson} 1667cf667be17b479fe276fd606b8fd72ccfa3065bb8Owen Anderson 1668568eeedea72c274abbba1310c18a31eef78e14a4Jim Grosbachvoid ARMMCCodeEmitter:: 1669568eeedea72c274abbba1310c18a31eef78e14a4Jim GrosbachEncodeInstruction(const MCInst &MI, raw_ostream &OS, 167036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines SmallVectorImpl<MCFixup> &Fixups, 167136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines const MCSubtargetInfo &STI) const { 1672d6d4b42ba473657b6d30242962f0d0fb23fe126eJim Grosbach // Pseudo instructions don't get encoded. 167359ee62d2418df8db499eca1ae17f5900dc2dcbbaEvan Cheng const MCInstrDesc &Desc = MCII.get(MI.getOpcode()); 1674e50e6bcd901ebb1cfc42fe9ca0796ae303d7f1a1Jim Grosbach uint64_t TSFlags = Desc.TSFlags; 1675e50e6bcd901ebb1cfc42fe9ca0796ae303d7f1a1Jim Grosbach if ((TSFlags & ARMII::FormMask) == ARMII::Pseudo) 1676d6d4b42ba473657b6d30242962f0d0fb23fe126eJim Grosbach return; 167716884415db751c75f2133bd04921393c792b1158Owen Anderson 1678e50e6bcd901ebb1cfc42fe9ca0796ae303d7f1a1Jim Grosbach int Size; 167916884415db751c75f2133bd04921393c792b1158Owen Anderson if (Desc.getSize() == 2 || Desc.getSize() == 4) 168016884415db751c75f2133bd04921393c792b1158Owen Anderson Size = Desc.getSize(); 168116884415db751c75f2133bd04921393c792b1158Owen Anderson else 168216884415db751c75f2133bd04921393c792b1158Owen Anderson llvm_unreachable("Unexpected instruction size!"); 168310096dbdef22a10a6a4444437c935ab428545525Owen Anderson 168436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines uint32_t Binary = getBinaryCodeForInstr(MI, Fixups, STI); 16857597212abced110723f2fee985a7d60557c092ecEvan Cheng // Thumb 32-bit wide instructions need to emit the high order halfword 16867597212abced110723f2fee985a7d60557c092ecEvan Cheng // first. 168736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (isThumb(STI) && Size == 4) { 1688d91f4e40e6312304c60c83c3dd93f769a39a9772Jim Grosbach EmitConstant(Binary >> 16, 2, OS); 1689d91f4e40e6312304c60c83c3dd93f769a39a9772Jim Grosbach EmitConstant(Binary & 0xffff, 2, OS); 1690d91f4e40e6312304c60c83c3dd93f769a39a9772Jim Grosbach } else 1691d91f4e40e6312304c60c83c3dd93f769a39a9772Jim Grosbach EmitConstant(Binary, Size, OS); 16927292e0a6564bb24707eff1c49da9044dd5eaec78Bill Wendling ++MCNumEmitted; // Keep track of the # of mi's emitted. 1693568eeedea72c274abbba1310c18a31eef78e14a4Jim Grosbach} 16949af82ba42b53905f580f8c4270626946e3548654Jim Grosbach 1695806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbach#include "ARMGenMCCodeEmitter.inc" 1696