ARMMCCodeEmitter.cpp revision 6d74631062e4464326eb5c680a4d62d340fa42eb
1568eeedea72c274abbba1310c18a31eef78e14a4Jim Grosbach//===-- ARM/ARMMCCodeEmitter.cpp - Convert ARM code to machine code -------===// 2568eeedea72c274abbba1310c18a31eef78e14a4Jim Grosbach// 3568eeedea72c274abbba1310c18a31eef78e14a4Jim Grosbach// The LLVM Compiler Infrastructure 4568eeedea72c274abbba1310c18a31eef78e14a4Jim Grosbach// 5568eeedea72c274abbba1310c18a31eef78e14a4Jim Grosbach// This file is distributed under the University of Illinois Open Source 6568eeedea72c274abbba1310c18a31eef78e14a4Jim Grosbach// License. See LICENSE.TXT for details. 7568eeedea72c274abbba1310c18a31eef78e14a4Jim Grosbach// 8568eeedea72c274abbba1310c18a31eef78e14a4Jim Grosbach//===----------------------------------------------------------------------===// 9568eeedea72c274abbba1310c18a31eef78e14a4Jim Grosbach// 10568eeedea72c274abbba1310c18a31eef78e14a4Jim Grosbach// This file implements the ARMMCCodeEmitter class. 11568eeedea72c274abbba1310c18a31eef78e14a4Jim Grosbach// 12568eeedea72c274abbba1310c18a31eef78e14a4Jim Grosbach//===----------------------------------------------------------------------===// 13568eeedea72c274abbba1310c18a31eef78e14a4Jim Grosbach 142ac190238e88b21e716e2853900b5076c9013410Chris Lattner#define DEBUG_TYPE "mccodeemitter" 15ee04a6d3a40c3017124e3fd89a0db473a2824498Evan Cheng#include "MCTargetDesc/ARMAddressingModes.h" 16be74029f44c32efc09274a16cbff588ad10dc5eaEvan Cheng#include "MCTargetDesc/ARMBaseInfo.h" 17be74029f44c32efc09274a16cbff588ad10dc5eaEvan Cheng#include "MCTargetDesc/ARMFixupKinds.h" 18ee04a6d3a40c3017124e3fd89a0db473a2824498Evan Cheng#include "MCTargetDesc/ARMMCExpr.h" 19be74029f44c32efc09274a16cbff588ad10dc5eaEvan Cheng#include "MCTargetDesc/ARMMCTargetDesc.h" 20568eeedea72c274abbba1310c18a31eef78e14a4Jim Grosbach#include "llvm/MC/MCCodeEmitter.h" 21568eeedea72c274abbba1310c18a31eef78e14a4Jim Grosbach#include "llvm/MC/MCExpr.h" 22568eeedea72c274abbba1310c18a31eef78e14a4Jim Grosbach#include "llvm/MC/MCInst.h" 2359ee62d2418df8db499eca1ae17f5900dc2dcbbaEvan Cheng#include "llvm/MC/MCInstrInfo.h" 24be74029f44c32efc09274a16cbff588ad10dc5eaEvan Cheng#include "llvm/MC/MCRegisterInfo.h" 2559ee62d2418df8db499eca1ae17f5900dc2dcbbaEvan Cheng#include "llvm/MC/MCSubtargetInfo.h" 26ee04a6d3a40c3017124e3fd89a0db473a2824498Evan Cheng#include "llvm/ADT/APFloat.h" 27d6d4b42ba473657b6d30242962f0d0fb23fe126eJim Grosbach#include "llvm/ADT/Statistic.h" 28568eeedea72c274abbba1310c18a31eef78e14a4Jim Grosbach#include "llvm/Support/raw_ostream.h" 2959ee62d2418df8db499eca1ae17f5900dc2dcbbaEvan Cheng 30568eeedea72c274abbba1310c18a31eef78e14a4Jim Grosbachusing namespace llvm; 31568eeedea72c274abbba1310c18a31eef78e14a4Jim Grosbach 3270933266ae73c891d9d1c2f0de72ecd1db8f86dfJim GrosbachSTATISTIC(MCNumEmitted, "Number of MC instructions emitted."); 3370933266ae73c891d9d1c2f0de72ecd1db8f86dfJim GrosbachSTATISTIC(MCNumCPRelocations, "Number of constant pool relocations created."); 34d6d4b42ba473657b6d30242962f0d0fb23fe126eJim Grosbach 35568eeedea72c274abbba1310c18a31eef78e14a4Jim Grosbachnamespace { 36568eeedea72c274abbba1310c18a31eef78e14a4Jim Grosbachclass ARMMCCodeEmitter : public MCCodeEmitter { 37568eeedea72c274abbba1310c18a31eef78e14a4Jim Grosbach ARMMCCodeEmitter(const ARMMCCodeEmitter &); // DO NOT IMPLEMENT 38568eeedea72c274abbba1310c18a31eef78e14a4Jim Grosbach void operator=(const ARMMCCodeEmitter &); // DO NOT IMPLEMENT 3959ee62d2418df8db499eca1ae17f5900dc2dcbbaEvan Cheng const MCInstrInfo &MCII; 4059ee62d2418df8db499eca1ae17f5900dc2dcbbaEvan Cheng const MCSubtargetInfo &STI; 41568eeedea72c274abbba1310c18a31eef78e14a4Jim Grosbach 42568eeedea72c274abbba1310c18a31eef78e14a4Jim Grosbachpublic: 4359ee62d2418df8db499eca1ae17f5900dc2dcbbaEvan Cheng ARMMCCodeEmitter(const MCInstrInfo &mcii, const MCSubtargetInfo &sti, 4459ee62d2418df8db499eca1ae17f5900dc2dcbbaEvan Cheng MCContext &ctx) 45af0a2e6730ffb59405352269e1500b6e83e42d6aEvan Cheng : MCII(mcii), STI(sti) { 46568eeedea72c274abbba1310c18a31eef78e14a4Jim Grosbach } 47568eeedea72c274abbba1310c18a31eef78e14a4Jim Grosbach 48568eeedea72c274abbba1310c18a31eef78e14a4Jim Grosbach ~ARMMCCodeEmitter() {} 49568eeedea72c274abbba1310c18a31eef78e14a4Jim Grosbach 5059ee62d2418df8db499eca1ae17f5900dc2dcbbaEvan Cheng bool isThumb() const { 5159ee62d2418df8db499eca1ae17f5900dc2dcbbaEvan Cheng // FIXME: Can tablegen auto-generate this? 5259ee62d2418df8db499eca1ae17f5900dc2dcbbaEvan Cheng return (STI.getFeatureBits() & ARM::ModeThumb) != 0; 5359ee62d2418df8db499eca1ae17f5900dc2dcbbaEvan Cheng } 5459ee62d2418df8db499eca1ae17f5900dc2dcbbaEvan Cheng bool isThumb2() const { 5559ee62d2418df8db499eca1ae17f5900dc2dcbbaEvan Cheng return isThumb() && (STI.getFeatureBits() & ARM::FeatureThumb2) != 0; 5659ee62d2418df8db499eca1ae17f5900dc2dcbbaEvan Cheng } 5759ee62d2418df8db499eca1ae17f5900dc2dcbbaEvan Cheng bool isTargetDarwin() const { 5859ee62d2418df8db499eca1ae17f5900dc2dcbbaEvan Cheng Triple TT(STI.getTargetTriple()); 5959ee62d2418df8db499eca1ae17f5900dc2dcbbaEvan Cheng Triple::OSType OS = TT.getOS(); 6059ee62d2418df8db499eca1ae17f5900dc2dcbbaEvan Cheng return OS == Triple::Darwin || OS == Triple::MacOSX || OS == Triple::IOS; 6159ee62d2418df8db499eca1ae17f5900dc2dcbbaEvan Cheng } 6259ee62d2418df8db499eca1ae17f5900dc2dcbbaEvan Cheng 630de6ab3c43ed2143d661115dddf1480545236c91Jim Grosbach unsigned getMachineSoImmOpValue(unsigned SoImm) const; 640de6ab3c43ed2143d661115dddf1480545236c91Jim Grosbach 659af82ba42b53905f580f8c4270626946e3548654Jim Grosbach // getBinaryCodeForInstr - TableGen'erated function for getting the 669af82ba42b53905f580f8c4270626946e3548654Jim Grosbach // binary encoding for an instruction. 67806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbach unsigned getBinaryCodeForInstr(const MCInst &MI, 68806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbach SmallVectorImpl<MCFixup> &Fixups) const; 699af82ba42b53905f580f8c4270626946e3548654Jim Grosbach 709af82ba42b53905f580f8c4270626946e3548654Jim Grosbach /// getMachineOpValue - Return binary encoding of operand. If the machine 719af82ba42b53905f580f8c4270626946e3548654Jim Grosbach /// operand requires relocation, record the relocation and return zero. 72806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbach unsigned getMachineOpValue(const MCInst &MI,const MCOperand &MO, 73806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbach SmallVectorImpl<MCFixup> &Fixups) const; 749af82ba42b53905f580f8c4270626946e3548654Jim Grosbach 757597212abced110723f2fee985a7d60557c092ecEvan Cheng /// getHiLo16ImmOpValue - Return the encoding for the hi / low 16-bit of 76971b83b67a9812556cdb97bb58aa96fb37af458dOwen Anderson /// the specified operand. This is used for operands with :lower16: and 777597212abced110723f2fee985a7d60557c092ecEvan Cheng /// :upper16: prefixes. 787597212abced110723f2fee985a7d60557c092ecEvan Cheng uint32_t getHiLo16ImmOpValue(const MCInst &MI, unsigned OpIdx, 797597212abced110723f2fee985a7d60557c092ecEvan Cheng SmallVectorImpl<MCFixup> &Fixups) const; 80837caa9313e1f9480721f232f89f5c7b1b9c9d09Jason W Kim 8192b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling bool EncodeAddrModeOpValues(const MCInst &MI, unsigned OpIdx, 82806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbach unsigned &Reg, unsigned &Imm, 83806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbach SmallVectorImpl<MCFixup> &Fixups) const; 8492b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling 85662a816e89a9d77bf75e1328b09cf9235b4682aaJim Grosbach /// getThumbBLTargetOpValue - Return encoding info for Thumb immediate 8609aa3f0ef35d9241c92439d74b8d5e9a81d814c2Bill Wendling /// BL branch target. 87662a816e89a9d77bf75e1328b09cf9235b4682aaJim Grosbach uint32_t getThumbBLTargetOpValue(const MCInst &MI, unsigned OpIdx, 88662a816e89a9d77bf75e1328b09cf9235b4682aaJim Grosbach SmallVectorImpl<MCFixup> &Fixups) const; 89662a816e89a9d77bf75e1328b09cf9235b4682aaJim Grosbach 9009aa3f0ef35d9241c92439d74b8d5e9a81d814c2Bill Wendling /// getThumbBLXTargetOpValue - Return encoding info for Thumb immediate 9109aa3f0ef35d9241c92439d74b8d5e9a81d814c2Bill Wendling /// BLX branch target. 9209aa3f0ef35d9241c92439d74b8d5e9a81d814c2Bill Wendling uint32_t getThumbBLXTargetOpValue(const MCInst &MI, unsigned OpIdx, 9309aa3f0ef35d9241c92439d74b8d5e9a81d814c2Bill Wendling SmallVectorImpl<MCFixup> &Fixups) const; 9409aa3f0ef35d9241c92439d74b8d5e9a81d814c2Bill Wendling 95e246717c3a36a913fd4200776ed621649bb2b624Jim Grosbach /// getThumbBRTargetOpValue - Return encoding info for Thumb branch target. 96e246717c3a36a913fd4200776ed621649bb2b624Jim Grosbach uint32_t getThumbBRTargetOpValue(const MCInst &MI, unsigned OpIdx, 97e246717c3a36a913fd4200776ed621649bb2b624Jim Grosbach SmallVectorImpl<MCFixup> &Fixups) const; 98e246717c3a36a913fd4200776ed621649bb2b624Jim Grosbach 9901086451393ef33e82b6fad623989dd97dd70edfJim Grosbach /// getThumbBCCTargetOpValue - Return encoding info for Thumb branch target. 10001086451393ef33e82b6fad623989dd97dd70edfJim Grosbach uint32_t getThumbBCCTargetOpValue(const MCInst &MI, unsigned OpIdx, 10101086451393ef33e82b6fad623989dd97dd70edfJim Grosbach SmallVectorImpl<MCFixup> &Fixups) const; 10201086451393ef33e82b6fad623989dd97dd70edfJim Grosbach 103027d6e8d1ca04e4096fb3a27579b861d861466c5Jim Grosbach /// getThumbCBTargetOpValue - Return encoding info for Thumb branch target. 104027d6e8d1ca04e4096fb3a27579b861d861466c5Jim Grosbach uint32_t getThumbCBTargetOpValue(const MCInst &MI, unsigned OpIdx, 105dff2f7151f695b86db8c4b0c6604463bdb8a63eaBill Wendling SmallVectorImpl<MCFixup> &Fixups) const; 106dff2f7151f695b86db8c4b0c6604463bdb8a63eaBill Wendling 107c466b937dbdbaabeef0097fe340de1b8f49a3508Jim Grosbach /// getBranchTargetOpValue - Return encoding info for 24-bit immediate 108c466b937dbdbaabeef0097fe340de1b8f49a3508Jim Grosbach /// branch target. 109c466b937dbdbaabeef0097fe340de1b8f49a3508Jim Grosbach uint32_t getBranchTargetOpValue(const MCInst &MI, unsigned OpIdx, 110c466b937dbdbaabeef0097fe340de1b8f49a3508Jim Grosbach SmallVectorImpl<MCFixup> &Fixups) const; 111c466b937dbdbaabeef0097fe340de1b8f49a3508Jim Grosbach 112c266600bec4b5ba0ee93ffdfeaafcab8f1295145Owen Anderson /// getUnconditionalBranchTargetOpValue - Return encoding info for 24-bit 113c266600bec4b5ba0ee93ffdfeaafcab8f1295145Owen Anderson /// immediate Thumb2 direct branch target. 114c266600bec4b5ba0ee93ffdfeaafcab8f1295145Owen Anderson uint32_t getUnconditionalBranchTargetOpValue(const MCInst &MI, unsigned OpIdx, 115c266600bec4b5ba0ee93ffdfeaafcab8f1295145Owen Anderson SmallVectorImpl<MCFixup> &Fixups) const; 116c266600bec4b5ba0ee93ffdfeaafcab8f1295145Owen Anderson 117685c350ae76b588e1f00c01a511fe8bd57f18394Jason W Kim /// getARMBranchTargetOpValue - Return encoding info for 24-bit immediate 118685c350ae76b588e1f00c01a511fe8bd57f18394Jason W Kim /// branch target. 119685c350ae76b588e1f00c01a511fe8bd57f18394Jason W Kim uint32_t getARMBranchTargetOpValue(const MCInst &MI, unsigned OpIdx, 120685c350ae76b588e1f00c01a511fe8bd57f18394Jason W Kim SmallVectorImpl<MCFixup> &Fixups) const; 121c266600bec4b5ba0ee93ffdfeaafcab8f1295145Owen Anderson 1225d14f9be7ba64162c7b996f36d419b11d8cdbe9aJim Grosbach /// getAdrLabelOpValue - Return encoding info for 12-bit immediate 1235d14f9be7ba64162c7b996f36d419b11d8cdbe9aJim Grosbach /// ADR label target. 1245d14f9be7ba64162c7b996f36d419b11d8cdbe9aJim Grosbach uint32_t getAdrLabelOpValue(const MCInst &MI, unsigned OpIdx, 1255d14f9be7ba64162c7b996f36d419b11d8cdbe9aJim Grosbach SmallVectorImpl<MCFixup> &Fixups) const; 126d40963c4065432ec7e47879d3ca665a54ee903b6Jim Grosbach uint32_t getThumbAdrLabelOpValue(const MCInst &MI, unsigned OpIdx, 127d40963c4065432ec7e47879d3ca665a54ee903b6Jim Grosbach SmallVectorImpl<MCFixup> &Fixups) const; 128a838a25d59838adfa91463f6a918ae3adeb352c1Owen Anderson uint32_t getT2AdrLabelOpValue(const MCInst &MI, unsigned OpIdx, 129a838a25d59838adfa91463f6a918ae3adeb352c1Owen Anderson SmallVectorImpl<MCFixup> &Fixups) const; 130971b83b67a9812556cdb97bb58aa96fb37af458dOwen Anderson 1315d14f9be7ba64162c7b996f36d419b11d8cdbe9aJim Grosbach 13292b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling /// getAddrModeImm12OpValue - Return encoding info for 'reg +/- imm12' 13392b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling /// operand. 134806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbach uint32_t getAddrModeImm12OpValue(const MCInst &MI, unsigned OpIdx, 135806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbach SmallVectorImpl<MCFixup> &Fixups) const; 13692b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling 137f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling /// getThumbAddrModeRegRegOpValue - Return encoding for 'reg + reg' operand. 138f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling uint32_t getThumbAddrModeRegRegOpValue(const MCInst &MI, unsigned OpIdx, 139f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling SmallVectorImpl<MCFixup> &Fixups)const; 1400f4b60d43a289671082deee3bd56a3a055afb16aOwen Anderson 1419d63d90de5e57ad96f467b270544443a9284eb2bOwen Anderson /// getT2AddrModeImm8s4OpValue - Return encoding info for 'reg +/- imm8<<2' 1429d63d90de5e57ad96f467b270544443a9284eb2bOwen Anderson /// operand. 1439d63d90de5e57ad96f467b270544443a9284eb2bOwen Anderson uint32_t getT2AddrModeImm8s4OpValue(const MCInst &MI, unsigned OpIdx, 1449d63d90de5e57ad96f467b270544443a9284eb2bOwen Anderson SmallVectorImpl<MCFixup> &Fixups) const; 1459d63d90de5e57ad96f467b270544443a9284eb2bOwen Anderson 1469d63d90de5e57ad96f467b270544443a9284eb2bOwen Anderson 14754fea632b161f98e96ec7275922e35102bcecc5dJim Grosbach /// getLdStSORegOpValue - Return encoding info for 'reg +/- reg shop imm' 14854fea632b161f98e96ec7275922e35102bcecc5dJim Grosbach /// operand as needed by load/store instructions. 14954fea632b161f98e96ec7275922e35102bcecc5dJim Grosbach uint32_t getLdStSORegOpValue(const MCInst &MI, unsigned OpIdx, 15054fea632b161f98e96ec7275922e35102bcecc5dJim Grosbach SmallVectorImpl<MCFixup> &Fixups) const; 15154fea632b161f98e96ec7275922e35102bcecc5dJim Grosbach 1525d5eb9e3817a2765297e6dd5649ecb9b8b03e334Jim Grosbach /// getLdStmModeOpValue - Return encoding for load/store multiple mode. 1535d5eb9e3817a2765297e6dd5649ecb9b8b03e334Jim Grosbach uint32_t getLdStmModeOpValue(const MCInst &MI, unsigned OpIdx, 1545d5eb9e3817a2765297e6dd5649ecb9b8b03e334Jim Grosbach SmallVectorImpl<MCFixup> &Fixups) const { 1555d5eb9e3817a2765297e6dd5649ecb9b8b03e334Jim Grosbach ARM_AM::AMSubMode Mode = (ARM_AM::AMSubMode)MI.getOperand(OpIdx).getImm(); 1565d5eb9e3817a2765297e6dd5649ecb9b8b03e334Jim Grosbach switch (Mode) { 1575f8a917b6558f8fdf31b4a6fa591b396e16b9ff2Matt Beaumont-Gay default: assert(0 && "Unknown addressing sub-mode!"); 1585d5eb9e3817a2765297e6dd5649ecb9b8b03e334Jim Grosbach case ARM_AM::da: return 0; 1595d5eb9e3817a2765297e6dd5649ecb9b8b03e334Jim Grosbach case ARM_AM::ia: return 1; 1605d5eb9e3817a2765297e6dd5649ecb9b8b03e334Jim Grosbach case ARM_AM::db: return 2; 1615d5eb9e3817a2765297e6dd5649ecb9b8b03e334Jim Grosbach case ARM_AM::ib: return 3; 1625d5eb9e3817a2765297e6dd5649ecb9b8b03e334Jim Grosbach } 1635d5eb9e3817a2765297e6dd5649ecb9b8b03e334Jim Grosbach } 16499f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach /// getShiftOp - Return the shift opcode (bit[6:5]) of the immediate value. 16599f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach /// 16699f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach unsigned getShiftOp(ARM_AM::ShiftOpc ShOpc) const { 16799f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach switch (ShOpc) { 16899f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach default: llvm_unreachable("Unknown shift opc!"); 16999f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach case ARM_AM::no_shift: 17099f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach case ARM_AM::lsl: return 0; 17199f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach case ARM_AM::lsr: return 1; 17299f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach case ARM_AM::asr: return 2; 17399f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach case ARM_AM::ror: 17499f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach case ARM_AM::rrx: return 3; 17599f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach } 17699f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach return 0; 17799f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach } 17899f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach 17999f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach /// getAddrMode2OpValue - Return encoding for addrmode2 operands. 18099f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach uint32_t getAddrMode2OpValue(const MCInst &MI, unsigned OpIdx, 18199f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach SmallVectorImpl<MCFixup> &Fixups) const; 18299f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach 18399f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach /// getAddrMode2OffsetOpValue - Return encoding for am2offset operands. 18499f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach uint32_t getAddrMode2OffsetOpValue(const MCInst &MI, unsigned OpIdx, 18599f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach SmallVectorImpl<MCFixup> &Fixups) const; 18699f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach 1877ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach /// getPostIdxRegOpValue - Return encoding for postidx_reg operands. 1887ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach uint32_t getPostIdxRegOpValue(const MCInst &MI, unsigned OpIdx, 1897ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach SmallVectorImpl<MCFixup> &Fixups) const; 1907ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach 1917eab97f260ba0f56d1d4a82f3a4eb2c979452011Jim Grosbach /// getAddrMode3OffsetOpValue - Return encoding for am3offset operands. 1927eab97f260ba0f56d1d4a82f3a4eb2c979452011Jim Grosbach uint32_t getAddrMode3OffsetOpValue(const MCInst &MI, unsigned OpIdx, 1937eab97f260ba0f56d1d4a82f3a4eb2c979452011Jim Grosbach SmallVectorImpl<MCFixup> &Fixups) const; 1947eab97f260ba0f56d1d4a82f3a4eb2c979452011Jim Grosbach 195570a9226913ebe1af04832b8fb3273c70b4ee152Jim Grosbach /// getAddrMode3OpValue - Return encoding for addrmode3 operands. 196570a9226913ebe1af04832b8fb3273c70b4ee152Jim Grosbach uint32_t getAddrMode3OpValue(const MCInst &MI, unsigned OpIdx, 197570a9226913ebe1af04832b8fb3273c70b4ee152Jim Grosbach SmallVectorImpl<MCFixup> &Fixups) const; 1985d5eb9e3817a2765297e6dd5649ecb9b8b03e334Jim Grosbach 199d967cd096ae87accf2f1df86b2dfac969d9c9da2Jim Grosbach /// getAddrModeThumbSPOpValue - Return encoding info for 'reg +/- imm12' 200d967cd096ae87accf2f1df86b2dfac969d9c9da2Jim Grosbach /// operand. 201d967cd096ae87accf2f1df86b2dfac969d9c9da2Jim Grosbach uint32_t getAddrModeThumbSPOpValue(const MCInst &MI, unsigned OpIdx, 202d967cd096ae87accf2f1df86b2dfac969d9c9da2Jim Grosbach SmallVectorImpl<MCFixup> &Fixups) const; 203d967cd096ae87accf2f1df86b2dfac969d9c9da2Jim Grosbach 204f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling /// getAddrModeISOpValue - Encode the t_addrmode_is# operands. 205f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling uint32_t getAddrModeISOpValue(const MCInst &MI, unsigned OpIdx, 20622447ae54bcb8ca94ed994cad103074a24e66781Bill Wendling SmallVectorImpl<MCFixup> &Fixups) const; 2071fd374e9c1c074c1681336bef31e65f0170b0f7eBill Wendling 208b8958b031ec5163261f490f131780c5dc3d823d6Bill Wendling /// getAddrModePCOpValue - Return encoding for t_addrmode_pc operands. 209b8958b031ec5163261f490f131780c5dc3d823d6Bill Wendling uint32_t getAddrModePCOpValue(const MCInst &MI, unsigned OpIdx, 210b8958b031ec5163261f490f131780c5dc3d823d6Bill Wendling SmallVectorImpl<MCFixup> &Fixups) const; 211b8958b031ec5163261f490f131780c5dc3d823d6Bill Wendling 21292b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling /// getAddrMode5OpValue - Return encoding info for 'reg +/- imm8' operand. 213806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbach uint32_t getAddrMode5OpValue(const MCInst &MI, unsigned OpIdx, 214806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbach SmallVectorImpl<MCFixup> &Fixups) const; 2153e5561247202bae994dd259a2d8dc4eff8f799f3Jim Grosbach 21608bd54987f4ae482de13436e7254ff08b23f825fJim Grosbach /// getCCOutOpValue - Return encoding of the 's' bit. 217806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbach unsigned getCCOutOpValue(const MCInst &MI, unsigned Op, 218806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbach SmallVectorImpl<MCFixup> &Fixups) const { 21908bd54987f4ae482de13436e7254ff08b23f825fJim Grosbach // The operand is either reg0 or CPSR. The 's' bit is encoded as '0' or 22008bd54987f4ae482de13436e7254ff08b23f825fJim Grosbach // '1' respectively. 22108bd54987f4ae482de13436e7254ff08b23f825fJim Grosbach return MI.getOperand(Op).getReg() == ARM::CPSR; 22208bd54987f4ae482de13436e7254ff08b23f825fJim Grosbach } 223ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach 2242a6a93d5425b38546de2b6674719d52f565171d8Jim Grosbach /// getSOImmOpValue - Return an encoded 12-bit shifted-immediate value. 225806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbach unsigned getSOImmOpValue(const MCInst &MI, unsigned Op, 226806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbach SmallVectorImpl<MCFixup> &Fixups) const { 2272a6a93d5425b38546de2b6674719d52f565171d8Jim Grosbach unsigned SoImm = MI.getOperand(Op).getImm(); 2282a6a93d5425b38546de2b6674719d52f565171d8Jim Grosbach int SoImmVal = ARM_AM::getSOImmVal(SoImm); 2292a6a93d5425b38546de2b6674719d52f565171d8Jim Grosbach assert(SoImmVal != -1 && "Not a valid so_imm value!"); 2302a6a93d5425b38546de2b6674719d52f565171d8Jim Grosbach 2312a6a93d5425b38546de2b6674719d52f565171d8Jim Grosbach // Encode rotate_imm. 2322a6a93d5425b38546de2b6674719d52f565171d8Jim Grosbach unsigned Binary = (ARM_AM::getSOImmValRot((unsigned)SoImmVal) >> 1) 2332a6a93d5425b38546de2b6674719d52f565171d8Jim Grosbach << ARMII::SoRotImmShift; 2342a6a93d5425b38546de2b6674719d52f565171d8Jim Grosbach 2352a6a93d5425b38546de2b6674719d52f565171d8Jim Grosbach // Encode immed_8. 2362a6a93d5425b38546de2b6674719d52f565171d8Jim Grosbach Binary |= ARM_AM::getSOImmValImm((unsigned)SoImmVal); 2372a6a93d5425b38546de2b6674719d52f565171d8Jim Grosbach return Binary; 2382a6a93d5425b38546de2b6674719d52f565171d8Jim Grosbach } 2397bf4c02789f97e32225fc248dff6622b994a15eeJim Grosbach 2405de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson /// getT2SOImmOpValue - Return an encoded 12-bit shifted-immediate value. 2415de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson unsigned getT2SOImmOpValue(const MCInst &MI, unsigned Op, 2425de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson SmallVectorImpl<MCFixup> &Fixups) const { 2435de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson unsigned SoImm = MI.getOperand(Op).getImm(); 2445de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson unsigned Encoded = ARM_AM::getT2SOImmVal(SoImm); 2455de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson assert(Encoded != ~0U && "Not a Thumb2 so_imm value?"); 2465de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson return Encoded; 2475de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson } 24808bd54987f4ae482de13436e7254ff08b23f825fJim Grosbach 24975579f739fbc99a92a15f3ce75bbd7628ba00f8cOwen Anderson unsigned getT2AddrModeSORegOpValue(const MCInst &MI, unsigned OpNum, 25075579f739fbc99a92a15f3ce75bbd7628ba00f8cOwen Anderson SmallVectorImpl<MCFixup> &Fixups) const; 25175579f739fbc99a92a15f3ce75bbd7628ba00f8cOwen Anderson unsigned getT2AddrModeImm8OpValue(const MCInst &MI, unsigned OpNum, 25275579f739fbc99a92a15f3ce75bbd7628ba00f8cOwen Anderson SmallVectorImpl<MCFixup> &Fixups) const; 2536af50f7dd12d82f0a80f3158102180eee4c921aaOwen Anderson unsigned getT2AddrModeImm8OffsetOpValue(const MCInst &MI, unsigned OpNum, 2546af50f7dd12d82f0a80f3158102180eee4c921aaOwen Anderson SmallVectorImpl<MCFixup> &Fixups) const; 2550e1bcdf4f7547bb5f47ed5ff5f2409a8f72f3609Owen Anderson unsigned getT2AddrModeImm12OffsetOpValue(const MCInst &MI, unsigned OpNum, 2560e1bcdf4f7547bb5f47ed5ff5f2409a8f72f3609Owen Anderson SmallVectorImpl<MCFixup> &Fixups) const; 25775579f739fbc99a92a15f3ce75bbd7628ba00f8cOwen Anderson 258ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach /// getSORegOpValue - Return an encoded so_reg shifted register value. 259152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson unsigned getSORegRegOpValue(const MCInst &MI, unsigned Op, 260152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson SmallVectorImpl<MCFixup> &Fixups) const; 261152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson unsigned getSORegImmOpValue(const MCInst &MI, unsigned Op, 262806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbach SmallVectorImpl<MCFixup> &Fixups) const; 2635de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson unsigned getT2SORegOpValue(const MCInst &MI, unsigned Op, 2645de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson SmallVectorImpl<MCFixup> &Fixups) const; 265ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach 266806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbach unsigned getNEONVcvtImm32OpValue(const MCInst &MI, unsigned Op, 267806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbach SmallVectorImpl<MCFixup> &Fixups) const { 268498ec20703c89d0c2890b0967791f0f5f2b59a2fOwen Anderson return 64 - MI.getOperand(Op).getImm(); 269498ec20703c89d0c2890b0967791f0f5f2b59a2fOwen Anderson } 2708abe32af38b66bf4577526b23b6af6ec7eb6c155Jim Grosbach 271806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbach unsigned getBitfieldInvertedMaskOpValue(const MCInst &MI, unsigned Op, 272806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbach SmallVectorImpl<MCFixup> &Fixups) const; 2733fea19105d4929ad694f0b6272de31924c9f9f09Jim Grosbach 274a461d4222877f43588da38c466145f38dd74e229Bruno Cardoso Lopes unsigned getMsbOpValue(const MCInst &MI, unsigned Op, 275a461d4222877f43588da38c466145f38dd74e229Bruno Cardoso Lopes SmallVectorImpl<MCFixup> &Fixups) const; 276a461d4222877f43588da38c466145f38dd74e229Bruno Cardoso Lopes 277806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbach unsigned getRegisterListOpValue(const MCInst &MI, unsigned Op, 278806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbach SmallVectorImpl<MCFixup> &Fixups) const; 279806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbach unsigned getAddrMode6AddressOpValue(const MCInst &MI, unsigned Op, 280806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbach SmallVectorImpl<MCFixup> &Fixups) const; 281183c627d89be5d0e8f3255ab7f6d1204c2fabedfMon P Wang unsigned getAddrMode6OneLane32AddressOpValue(const MCInst &MI, unsigned Op, 282183c627d89be5d0e8f3255ab7f6d1204c2fabedfMon P Wang SmallVectorImpl<MCFixup> &Fixups) const; 2838e0c7b52877983b4838e54e233449912fc1a2325Bob Wilson unsigned getAddrMode6DupAddressOpValue(const MCInst &MI, unsigned Op, 2848e0c7b52877983b4838e54e233449912fc1a2325Bob Wilson SmallVectorImpl<MCFixup> &Fixups) const; 285806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbach unsigned getAddrMode6OffsetOpValue(const MCInst &MI, unsigned Op, 286806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbach SmallVectorImpl<MCFixup> &Fixups) const; 2876b5252db2db5eeeadec4602329ac56beb6dea54aJim Grosbach 2883116dce33840a115130c5f8ffcb9679d023496d6Bill Wendling unsigned getShiftRight8Imm(const MCInst &MI, unsigned Op, 2893116dce33840a115130c5f8ffcb9679d023496d6Bill Wendling SmallVectorImpl<MCFixup> &Fixups) const; 2903116dce33840a115130c5f8ffcb9679d023496d6Bill Wendling unsigned getShiftRight16Imm(const MCInst &MI, unsigned Op, 2913116dce33840a115130c5f8ffcb9679d023496d6Bill Wendling SmallVectorImpl<MCFixup> &Fixups) const; 2923116dce33840a115130c5f8ffcb9679d023496d6Bill Wendling unsigned getShiftRight32Imm(const MCInst &MI, unsigned Op, 2933116dce33840a115130c5f8ffcb9679d023496d6Bill Wendling SmallVectorImpl<MCFixup> &Fixups) const; 2943116dce33840a115130c5f8ffcb9679d023496d6Bill Wendling unsigned getShiftRight64Imm(const MCInst &MI, unsigned Op, 2953116dce33840a115130c5f8ffcb9679d023496d6Bill Wendling SmallVectorImpl<MCFixup> &Fixups) const; 296a656b63ee4d5b0e3f4d26a55dd4cc69795746684Bill Wendling 2976d74631062e4464326eb5c680a4d62d340fa42ebOwen Anderson unsigned getThumbSRImmOpValue(const MCInst &MI, unsigned Op, 2986d74631062e4464326eb5c680a4d62d340fa42ebOwen Anderson SmallVectorImpl<MCFixup> &Fixups) const; 2996d74631062e4464326eb5c680a4d62d340fa42ebOwen Anderson 300c7139a6f0d3acd198ab9eb536ea1ec52e61ff130Owen Anderson unsigned NEONThumb2DataIPostEncoder(const MCInst &MI, 301c7139a6f0d3acd198ab9eb536ea1ec52e61ff130Owen Anderson unsigned EncodedValue) const; 30257dac88f775c1191a98cff89abd1f7ad33df5e29Owen Anderson unsigned NEONThumb2LoadStorePostEncoder(const MCInst &MI, 303cf590263cd5c24ccf1d08cef612738d99cd980d9Bill Wendling unsigned EncodedValue) const; 3048f143913141991baaa535ca0da7c8a81606d6392Owen Anderson unsigned NEONThumb2DupPostEncoder(const MCInst &MI, 305cf590263cd5c24ccf1d08cef612738d99cd980d9Bill Wendling unsigned EncodedValue) const; 306cf590263cd5c24ccf1d08cef612738d99cd980d9Bill Wendling 307cf590263cd5c24ccf1d08cef612738d99cd980d9Bill Wendling unsigned VFPThumb2PostEncoder(const MCInst &MI, 308cf590263cd5c24ccf1d08cef612738d99cd980d9Bill Wendling unsigned EncodedValue) const; 309c7139a6f0d3acd198ab9eb536ea1ec52e61ff130Owen Anderson 31070933266ae73c891d9d1c2f0de72ecd1db8f86dfJim Grosbach void EmitByte(unsigned char C, raw_ostream &OS) const { 311568eeedea72c274abbba1310c18a31eef78e14a4Jim Grosbach OS << (char)C; 312568eeedea72c274abbba1310c18a31eef78e14a4Jim Grosbach } 313568eeedea72c274abbba1310c18a31eef78e14a4Jim Grosbach 31470933266ae73c891d9d1c2f0de72ecd1db8f86dfJim Grosbach void EmitConstant(uint64_t Val, unsigned Size, raw_ostream &OS) const { 315568eeedea72c274abbba1310c18a31eef78e14a4Jim Grosbach // Output the constant in little endian byte order. 316568eeedea72c274abbba1310c18a31eef78e14a4Jim Grosbach for (unsigned i = 0; i != Size; ++i) { 31770933266ae73c891d9d1c2f0de72ecd1db8f86dfJim Grosbach EmitByte(Val & 255, OS); 318568eeedea72c274abbba1310c18a31eef78e14a4Jim Grosbach Val >>= 8; 319568eeedea72c274abbba1310c18a31eef78e14a4Jim Grosbach } 320568eeedea72c274abbba1310c18a31eef78e14a4Jim Grosbach } 321568eeedea72c274abbba1310c18a31eef78e14a4Jim Grosbach 322568eeedea72c274abbba1310c18a31eef78e14a4Jim Grosbach void EncodeInstruction(const MCInst &MI, raw_ostream &OS, 323568eeedea72c274abbba1310c18a31eef78e14a4Jim Grosbach SmallVectorImpl<MCFixup> &Fixups) const; 324568eeedea72c274abbba1310c18a31eef78e14a4Jim Grosbach}; 325568eeedea72c274abbba1310c18a31eef78e14a4Jim Grosbach 326568eeedea72c274abbba1310c18a31eef78e14a4Jim Grosbach} // end anonymous namespace 327568eeedea72c274abbba1310c18a31eef78e14a4Jim Grosbach 32859ee62d2418df8db499eca1ae17f5900dc2dcbbaEvan ChengMCCodeEmitter *llvm::createARMMCCodeEmitter(const MCInstrInfo &MCII, 32959ee62d2418df8db499eca1ae17f5900dc2dcbbaEvan Cheng const MCSubtargetInfo &STI, 3300800ce71896ccd7f49b37861a8cfbc21b6b10022Bill Wendling MCContext &Ctx) { 33159ee62d2418df8db499eca1ae17f5900dc2dcbbaEvan Cheng return new ARMMCCodeEmitter(MCII, STI, Ctx); 332568eeedea72c274abbba1310c18a31eef78e14a4Jim Grosbach} 333568eeedea72c274abbba1310c18a31eef78e14a4Jim Grosbach 3347bf4c02789f97e32225fc248dff6622b994a15eeJim Grosbach/// NEONThumb2DataIPostEncoder - Post-process encoded NEON data-processing 3357bf4c02789f97e32225fc248dff6622b994a15eeJim Grosbach/// instructions, and rewrite them to their Thumb2 form if we are currently in 336c7139a6f0d3acd198ab9eb536ea1ec52e61ff130Owen Anderson/// Thumb2 mode. 337c7139a6f0d3acd198ab9eb536ea1ec52e61ff130Owen Andersonunsigned ARMMCCodeEmitter::NEONThumb2DataIPostEncoder(const MCInst &MI, 338c7139a6f0d3acd198ab9eb536ea1ec52e61ff130Owen Anderson unsigned EncodedValue) const { 33959ee62d2418df8db499eca1ae17f5900dc2dcbbaEvan Cheng if (isThumb2()) { 3407bf4c02789f97e32225fc248dff6622b994a15eeJim Grosbach // NEON Thumb2 data-processsing encodings are very simple: bit 24 is moved 341c7139a6f0d3acd198ab9eb536ea1ec52e61ff130Owen Anderson // to bit 12 of the high half-word (i.e. bit 28), and bits 27-24 are 342c7139a6f0d3acd198ab9eb536ea1ec52e61ff130Owen Anderson // set to 1111. 343c7139a6f0d3acd198ab9eb536ea1ec52e61ff130Owen Anderson unsigned Bit24 = EncodedValue & 0x01000000; 344c7139a6f0d3acd198ab9eb536ea1ec52e61ff130Owen Anderson unsigned Bit28 = Bit24 << 4; 345c7139a6f0d3acd198ab9eb536ea1ec52e61ff130Owen Anderson EncodedValue &= 0xEFFFFFFF; 346c7139a6f0d3acd198ab9eb536ea1ec52e61ff130Owen Anderson EncodedValue |= Bit28; 347c7139a6f0d3acd198ab9eb536ea1ec52e61ff130Owen Anderson EncodedValue |= 0x0F000000; 348c7139a6f0d3acd198ab9eb536ea1ec52e61ff130Owen Anderson } 3497bf4c02789f97e32225fc248dff6622b994a15eeJim Grosbach 350c7139a6f0d3acd198ab9eb536ea1ec52e61ff130Owen Anderson return EncodedValue; 351c7139a6f0d3acd198ab9eb536ea1ec52e61ff130Owen Anderson} 352c7139a6f0d3acd198ab9eb536ea1ec52e61ff130Owen Anderson 35357dac88f775c1191a98cff89abd1f7ad33df5e29Owen Anderson/// NEONThumb2LoadStorePostEncoder - Post-process encoded NEON load/store 3547bf4c02789f97e32225fc248dff6622b994a15eeJim Grosbach/// instructions, and rewrite them to their Thumb2 form if we are currently in 35557dac88f775c1191a98cff89abd1f7ad33df5e29Owen Anderson/// Thumb2 mode. 35657dac88f775c1191a98cff89abd1f7ad33df5e29Owen Andersonunsigned ARMMCCodeEmitter::NEONThumb2LoadStorePostEncoder(const MCInst &MI, 35757dac88f775c1191a98cff89abd1f7ad33df5e29Owen Anderson unsigned EncodedValue) const { 35859ee62d2418df8db499eca1ae17f5900dc2dcbbaEvan Cheng if (isThumb2()) { 35957dac88f775c1191a98cff89abd1f7ad33df5e29Owen Anderson EncodedValue &= 0xF0FFFFFF; 36057dac88f775c1191a98cff89abd1f7ad33df5e29Owen Anderson EncodedValue |= 0x09000000; 36157dac88f775c1191a98cff89abd1f7ad33df5e29Owen Anderson } 3627bf4c02789f97e32225fc248dff6622b994a15eeJim Grosbach 36357dac88f775c1191a98cff89abd1f7ad33df5e29Owen Anderson return EncodedValue; 36457dac88f775c1191a98cff89abd1f7ad33df5e29Owen Anderson} 36557dac88f775c1191a98cff89abd1f7ad33df5e29Owen Anderson 3668f143913141991baaa535ca0da7c8a81606d6392Owen Anderson/// NEONThumb2DupPostEncoder - Post-process encoded NEON vdup 3677bf4c02789f97e32225fc248dff6622b994a15eeJim Grosbach/// instructions, and rewrite them to their Thumb2 form if we are currently in 3688f143913141991baaa535ca0da7c8a81606d6392Owen Anderson/// Thumb2 mode. 3698f143913141991baaa535ca0da7c8a81606d6392Owen Andersonunsigned ARMMCCodeEmitter::NEONThumb2DupPostEncoder(const MCInst &MI, 3708f143913141991baaa535ca0da7c8a81606d6392Owen Anderson unsigned EncodedValue) const { 37159ee62d2418df8db499eca1ae17f5900dc2dcbbaEvan Cheng if (isThumb2()) { 3728f143913141991baaa535ca0da7c8a81606d6392Owen Anderson EncodedValue &= 0x00FFFFFF; 3738f143913141991baaa535ca0da7c8a81606d6392Owen Anderson EncodedValue |= 0xEE000000; 3748f143913141991baaa535ca0da7c8a81606d6392Owen Anderson } 3757bf4c02789f97e32225fc248dff6622b994a15eeJim Grosbach 3768f143913141991baaa535ca0da7c8a81606d6392Owen Anderson return EncodedValue; 3778f143913141991baaa535ca0da7c8a81606d6392Owen Anderson} 3788f143913141991baaa535ca0da7c8a81606d6392Owen Anderson 379cf590263cd5c24ccf1d08cef612738d99cd980d9Bill Wendling/// VFPThumb2PostEncoder - Post-process encoded VFP instructions and rewrite 380cf590263cd5c24ccf1d08cef612738d99cd980d9Bill Wendling/// them to their Thumb2 form if we are currently in Thumb2 mode. 381cf590263cd5c24ccf1d08cef612738d99cd980d9Bill Wendlingunsigned ARMMCCodeEmitter:: 382cf590263cd5c24ccf1d08cef612738d99cd980d9Bill WendlingVFPThumb2PostEncoder(const MCInst &MI, unsigned EncodedValue) const { 38359ee62d2418df8db499eca1ae17f5900dc2dcbbaEvan Cheng if (isThumb2()) { 384cf590263cd5c24ccf1d08cef612738d99cd980d9Bill Wendling EncodedValue &= 0x0FFFFFFF; 385cf590263cd5c24ccf1d08cef612738d99cd980d9Bill Wendling EncodedValue |= 0xE0000000; 386cf590263cd5c24ccf1d08cef612738d99cd980d9Bill Wendling } 387cf590263cd5c24ccf1d08cef612738d99cd980d9Bill Wendling return EncodedValue; 388cf590263cd5c24ccf1d08cef612738d99cd980d9Bill Wendling} 38957dac88f775c1191a98cff89abd1f7ad33df5e29Owen Anderson 39056ac907c57fcfddfd650238f03c856a9d55987e5Jim Grosbach/// getMachineOpValue - Return binary encoding of operand. If the machine 39156ac907c57fcfddfd650238f03c856a9d55987e5Jim Grosbach/// operand requires relocation, record the relocation and return zero. 392806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbachunsigned ARMMCCodeEmitter:: 393806e80ef42bdb416f409142a1ff1d4e8752baac8Jim GrosbachgetMachineOpValue(const MCInst &MI, const MCOperand &MO, 394806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbach SmallVectorImpl<MCFixup> &Fixups) const { 395bbbdcd453d22258cb4dd217eddf016668fcebf84Bill Wendling if (MO.isReg()) { 3960800ce71896ccd7f49b37861a8cfbc21b6b10022Bill Wendling unsigned Reg = MO.getReg(); 3970800ce71896ccd7f49b37861a8cfbc21b6b10022Bill Wendling unsigned RegNo = getARMRegisterNumbering(Reg); 398d8a11c25fa64c152628cfcf5f9d36eb60242b302Jim Grosbach 399b0708d292bbe04cfcfe0c5cb5e27d8a872c9839aJim Grosbach // Q registers are encoded as 2x their register number. 4000800ce71896ccd7f49b37861a8cfbc21b6b10022Bill Wendling switch (Reg) { 4010800ce71896ccd7f49b37861a8cfbc21b6b10022Bill Wendling default: 4020800ce71896ccd7f49b37861a8cfbc21b6b10022Bill Wendling return RegNo; 4030800ce71896ccd7f49b37861a8cfbc21b6b10022Bill Wendling case ARM::Q0: case ARM::Q1: case ARM::Q2: case ARM::Q3: 4040800ce71896ccd7f49b37861a8cfbc21b6b10022Bill Wendling case ARM::Q4: case ARM::Q5: case ARM::Q6: case ARM::Q7: 4050800ce71896ccd7f49b37861a8cfbc21b6b10022Bill Wendling case ARM::Q8: case ARM::Q9: case ARM::Q10: case ARM::Q11: 4060800ce71896ccd7f49b37861a8cfbc21b6b10022Bill Wendling case ARM::Q12: case ARM::Q13: case ARM::Q14: case ARM::Q15: 4070800ce71896ccd7f49b37861a8cfbc21b6b10022Bill Wendling return 2 * RegNo; 40890d4cf931477b497553a9f2d0ed53377dd5dd88cOwen Anderson } 409bbbdcd453d22258cb4dd217eddf016668fcebf84Bill Wendling } else if (MO.isImm()) { 41056ac907c57fcfddfd650238f03c856a9d55987e5Jim Grosbach return static_cast<unsigned>(MO.getImm()); 411bbbdcd453d22258cb4dd217eddf016668fcebf84Bill Wendling } else if (MO.isFPImm()) { 412bbbdcd453d22258cb4dd217eddf016668fcebf84Bill Wendling return static_cast<unsigned>(APFloat(MO.getFPImm()) 413bbbdcd453d22258cb4dd217eddf016668fcebf84Bill Wendling .bitcastToAPInt().getHiBits(32).getLimitedValue()); 4140800ce71896ccd7f49b37861a8cfbc21b6b10022Bill Wendling } 4150800ce71896ccd7f49b37861a8cfbc21b6b10022Bill Wendling 416817c1a6dddadb4664738777d224bc7eae6e62cf3Jim Grosbach llvm_unreachable("Unable to encode MCOperand!"); 41756ac907c57fcfddfd650238f03c856a9d55987e5Jim Grosbach return 0; 41856ac907c57fcfddfd650238f03c856a9d55987e5Jim Grosbach} 41956ac907c57fcfddfd650238f03c856a9d55987e5Jim Grosbach 4205df0e0a61d6ac0e8dcf1a600bdc28d3e4a8db0adBill Wendling/// getAddrModeImmOpValue - Return encoding info for 'reg +/- imm' operand. 421806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbachbool ARMMCCodeEmitter:: 422806e80ef42bdb416f409142a1ff1d4e8752baac8Jim GrosbachEncodeAddrModeOpValues(const MCInst &MI, unsigned OpIdx, unsigned &Reg, 423806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbach unsigned &Imm, SmallVectorImpl<MCFixup> &Fixups) const { 4243e5561247202bae994dd259a2d8dc4eff8f799f3Jim Grosbach const MCOperand &MO = MI.getOperand(OpIdx); 4253e5561247202bae994dd259a2d8dc4eff8f799f3Jim Grosbach const MCOperand &MO1 = MI.getOperand(OpIdx + 1); 4269af3d1c0dc2250793ada1ca6cfa98e9f1253f7f9Jim Grosbach 42792b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling Reg = getARMRegisterNumbering(MO.getReg()); 42892b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling 42992b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling int32_t SImm = MO1.getImm(); 43092b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling bool isAdd = true; 4315df0e0a61d6ac0e8dcf1a600bdc28d3e4a8db0adBill Wendling 432ab682a2090f795d0b67f29889622da0a74cd97c3Jim Grosbach // Special value for #-0 43392b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling if (SImm == INT32_MIN) 43492b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling SImm = 0; 4355df0e0a61d6ac0e8dcf1a600bdc28d3e4a8db0adBill Wendling 436ab682a2090f795d0b67f29889622da0a74cd97c3Jim Grosbach // Immediate is always encoded as positive. The 'U' bit controls add vs sub. 43792b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling if (SImm < 0) { 43892b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling SImm = -SImm; 43992b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling isAdd = false; 44092b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling } 44192b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling 44292b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling Imm = SImm; 44392b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling return isAdd; 44492b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling} 4455df0e0a61d6ac0e8dcf1a600bdc28d3e4a8db0adBill Wendling 4466d74631062e4464326eb5c680a4d62d340fa42ebOwen Andersonuint32_t ARMMCCodeEmitter:: 4476d74631062e4464326eb5c680a4d62d340fa42ebOwen AndersongetThumbSRImmOpValue(const MCInst &MI, unsigned OpIdx, 4486d74631062e4464326eb5c680a4d62d340fa42ebOwen Anderson SmallVectorImpl<MCFixup> &Fixups) const { 4496d74631062e4464326eb5c680a4d62d340fa42ebOwen Anderson const MCOperand &MO = MI.getOperand(OpIdx); 4506d74631062e4464326eb5c680a4d62d340fa42ebOwen Anderson assert(MO.isImm() && "Expected constant shift!"); 4516d74631062e4464326eb5c680a4d62d340fa42ebOwen Anderson int val = MO.getImm(); 4526d74631062e4464326eb5c680a4d62d340fa42ebOwen Anderson return (val == 32) ? 0 : val; 4536d74631062e4464326eb5c680a4d62d340fa42ebOwen Anderson} 4546d74631062e4464326eb5c680a4d62d340fa42ebOwen Anderson 4556d74631062e4464326eb5c680a4d62d340fa42ebOwen Anderson 456dff2f7151f695b86db8c4b0c6604463bdb8a63eaBill Wendling/// getBranchTargetOpValue - Helper function to get the branch target operand, 457dff2f7151f695b86db8c4b0c6604463bdb8a63eaBill Wendling/// which is either an immediate or requires a fixup. 458dff2f7151f695b86db8c4b0c6604463bdb8a63eaBill Wendlingstatic uint32_t getBranchTargetOpValue(const MCInst &MI, unsigned OpIdx, 459dff2f7151f695b86db8c4b0c6604463bdb8a63eaBill Wendling unsigned FixupKind, 460dff2f7151f695b86db8c4b0c6604463bdb8a63eaBill Wendling SmallVectorImpl<MCFixup> &Fixups) { 461662a816e89a9d77bf75e1328b09cf9235b4682aaJim Grosbach const MCOperand &MO = MI.getOperand(OpIdx); 462662a816e89a9d77bf75e1328b09cf9235b4682aaJim Grosbach 463662a816e89a9d77bf75e1328b09cf9235b4682aaJim Grosbach // If the destination is an immediate, we have nothing to do. 464662a816e89a9d77bf75e1328b09cf9235b4682aaJim Grosbach if (MO.isImm()) return MO.getImm(); 465dff2f7151f695b86db8c4b0c6604463bdb8a63eaBill Wendling assert(MO.isExpr() && "Unexpected branch target type!"); 466662a816e89a9d77bf75e1328b09cf9235b4682aaJim Grosbach const MCExpr *Expr = MO.getExpr(); 467dff2f7151f695b86db8c4b0c6604463bdb8a63eaBill Wendling MCFixupKind Kind = MCFixupKind(FixupKind); 468662a816e89a9d77bf75e1328b09cf9235b4682aaJim Grosbach Fixups.push_back(MCFixup::Create(0, Expr, Kind)); 469662a816e89a9d77bf75e1328b09cf9235b4682aaJim Grosbach 470662a816e89a9d77bf75e1328b09cf9235b4682aaJim Grosbach // All of the information is in the fixup. 471662a816e89a9d77bf75e1328b09cf9235b4682aaJim Grosbach return 0; 472662a816e89a9d77bf75e1328b09cf9235b4682aaJim Grosbach} 473662a816e89a9d77bf75e1328b09cf9235b4682aaJim Grosbach 474dff2f7151f695b86db8c4b0c6604463bdb8a63eaBill Wendling/// getThumbBLTargetOpValue - Return encoding info for immediate branch target. 475c466b937dbdbaabeef0097fe340de1b8f49a3508Jim Grosbachuint32_t ARMMCCodeEmitter:: 476dff2f7151f695b86db8c4b0c6604463bdb8a63eaBill WendlinggetThumbBLTargetOpValue(const MCInst &MI, unsigned OpIdx, 477c466b937dbdbaabeef0097fe340de1b8f49a3508Jim Grosbach SmallVectorImpl<MCFixup> &Fixups) const { 478dff2f7151f695b86db8c4b0c6604463bdb8a63eaBill Wendling return ::getBranchTargetOpValue(MI, OpIdx, ARM::fixup_arm_thumb_bl, Fixups); 479dff2f7151f695b86db8c4b0c6604463bdb8a63eaBill Wendling} 480c466b937dbdbaabeef0097fe340de1b8f49a3508Jim Grosbach 48109aa3f0ef35d9241c92439d74b8d5e9a81d814c2Bill Wendling/// getThumbBLXTargetOpValue - Return encoding info for Thumb immediate 48209aa3f0ef35d9241c92439d74b8d5e9a81d814c2Bill Wendling/// BLX branch target. 48309aa3f0ef35d9241c92439d74b8d5e9a81d814c2Bill Wendlinguint32_t ARMMCCodeEmitter:: 48409aa3f0ef35d9241c92439d74b8d5e9a81d814c2Bill WendlinggetThumbBLXTargetOpValue(const MCInst &MI, unsigned OpIdx, 48509aa3f0ef35d9241c92439d74b8d5e9a81d814c2Bill Wendling SmallVectorImpl<MCFixup> &Fixups) const { 48609aa3f0ef35d9241c92439d74b8d5e9a81d814c2Bill Wendling return ::getBranchTargetOpValue(MI, OpIdx, ARM::fixup_arm_thumb_blx, Fixups); 48709aa3f0ef35d9241c92439d74b8d5e9a81d814c2Bill Wendling} 48809aa3f0ef35d9241c92439d74b8d5e9a81d814c2Bill Wendling 489e246717c3a36a913fd4200776ed621649bb2b624Jim Grosbach/// getThumbBRTargetOpValue - Return encoding info for Thumb branch target. 490e246717c3a36a913fd4200776ed621649bb2b624Jim Grosbachuint32_t ARMMCCodeEmitter:: 491e246717c3a36a913fd4200776ed621649bb2b624Jim GrosbachgetThumbBRTargetOpValue(const MCInst &MI, unsigned OpIdx, 492e246717c3a36a913fd4200776ed621649bb2b624Jim Grosbach SmallVectorImpl<MCFixup> &Fixups) const { 493e246717c3a36a913fd4200776ed621649bb2b624Jim Grosbach return ::getBranchTargetOpValue(MI, OpIdx, ARM::fixup_arm_thumb_br, Fixups); 494e246717c3a36a913fd4200776ed621649bb2b624Jim Grosbach} 495e246717c3a36a913fd4200776ed621649bb2b624Jim Grosbach 49601086451393ef33e82b6fad623989dd97dd70edfJim Grosbach/// getThumbBCCTargetOpValue - Return encoding info for Thumb branch target. 49701086451393ef33e82b6fad623989dd97dd70edfJim Grosbachuint32_t ARMMCCodeEmitter:: 49801086451393ef33e82b6fad623989dd97dd70edfJim GrosbachgetThumbBCCTargetOpValue(const MCInst &MI, unsigned OpIdx, 499e246717c3a36a913fd4200776ed621649bb2b624Jim Grosbach SmallVectorImpl<MCFixup> &Fixups) const { 50001086451393ef33e82b6fad623989dd97dd70edfJim Grosbach return ::getBranchTargetOpValue(MI, OpIdx, ARM::fixup_arm_thumb_bcc, Fixups); 50101086451393ef33e82b6fad623989dd97dd70edfJim Grosbach} 50201086451393ef33e82b6fad623989dd97dd70edfJim Grosbach 503027d6e8d1ca04e4096fb3a27579b861d861466c5Jim Grosbach/// getThumbCBTargetOpValue - Return encoding info for Thumb branch target. 504dff2f7151f695b86db8c4b0c6604463bdb8a63eaBill Wendlinguint32_t ARMMCCodeEmitter:: 505027d6e8d1ca04e4096fb3a27579b861d861466c5Jim GrosbachgetThumbCBTargetOpValue(const MCInst &MI, unsigned OpIdx, 506dff2f7151f695b86db8c4b0c6604463bdb8a63eaBill Wendling SmallVectorImpl<MCFixup> &Fixups) const { 507b492a7c2134d3886f545f1b5ea55115d71529a10Jim Grosbach return ::getBranchTargetOpValue(MI, OpIdx, ARM::fixup_arm_thumb_cb, Fixups); 508dff2f7151f695b86db8c4b0c6604463bdb8a63eaBill Wendling} 509c466b937dbdbaabeef0097fe340de1b8f49a3508Jim Grosbach 510685c350ae76b588e1f00c01a511fe8bd57f18394Jason W Kim/// Return true if this branch has a non-always predication 511685c350ae76b588e1f00c01a511fe8bd57f18394Jason W Kimstatic bool HasConditionalBranch(const MCInst &MI) { 512685c350ae76b588e1f00c01a511fe8bd57f18394Jason W Kim int NumOp = MI.getNumOperands(); 513685c350ae76b588e1f00c01a511fe8bd57f18394Jason W Kim if (NumOp >= 2) { 514685c350ae76b588e1f00c01a511fe8bd57f18394Jason W Kim for (int i = 0; i < NumOp-1; ++i) { 515685c350ae76b588e1f00c01a511fe8bd57f18394Jason W Kim const MCOperand &MCOp1 = MI.getOperand(i); 516685c350ae76b588e1f00c01a511fe8bd57f18394Jason W Kim const MCOperand &MCOp2 = MI.getOperand(i + 1); 517685c350ae76b588e1f00c01a511fe8bd57f18394Jason W Kim if (MCOp1.isImm() && MCOp2.isReg() && 518685c350ae76b588e1f00c01a511fe8bd57f18394Jason W Kim (MCOp2.getReg() == 0 || MCOp2.getReg() == ARM::CPSR)) { 519685c350ae76b588e1f00c01a511fe8bd57f18394Jason W Kim if (ARMCC::CondCodes(MCOp1.getImm()) != ARMCC::AL) 520685c350ae76b588e1f00c01a511fe8bd57f18394Jason W Kim return true; 521685c350ae76b588e1f00c01a511fe8bd57f18394Jason W Kim } 522685c350ae76b588e1f00c01a511fe8bd57f18394Jason W Kim } 523685c350ae76b588e1f00c01a511fe8bd57f18394Jason W Kim } 524685c350ae76b588e1f00c01a511fe8bd57f18394Jason W Kim return false; 525685c350ae76b588e1f00c01a511fe8bd57f18394Jason W Kim} 526685c350ae76b588e1f00c01a511fe8bd57f18394Jason W Kim 527dff2f7151f695b86db8c4b0c6604463bdb8a63eaBill Wendling/// getBranchTargetOpValue - Return encoding info for 24-bit immediate branch 528dff2f7151f695b86db8c4b0c6604463bdb8a63eaBill Wendling/// target. 529dff2f7151f695b86db8c4b0c6604463bdb8a63eaBill Wendlinguint32_t ARMMCCodeEmitter:: 530dff2f7151f695b86db8c4b0c6604463bdb8a63eaBill WendlinggetBranchTargetOpValue(const MCInst &MI, unsigned OpIdx, 531dff2f7151f695b86db8c4b0c6604463bdb8a63eaBill Wendling SmallVectorImpl<MCFixup> &Fixups) const { 532092e2cd5693114a4f1d93eb5b72f3e194de27236Jim Grosbach // FIXME: This really, really shouldn't use TargetMachine. We don't want 533092e2cd5693114a4f1d93eb5b72f3e194de27236Jim Grosbach // coupling between MC and TM anywhere we can help it. 53459ee62d2418df8db499eca1ae17f5900dc2dcbbaEvan Cheng if (isThumb2()) 535c266600bec4b5ba0ee93ffdfeaafcab8f1295145Owen Anderson return 536c266600bec4b5ba0ee93ffdfeaafcab8f1295145Owen Anderson ::getBranchTargetOpValue(MI, OpIdx, ARM::fixup_t2_condbranch, Fixups); 537685c350ae76b588e1f00c01a511fe8bd57f18394Jason W Kim return getARMBranchTargetOpValue(MI, OpIdx, Fixups); 538685c350ae76b588e1f00c01a511fe8bd57f18394Jason W Kim} 539685c350ae76b588e1f00c01a511fe8bd57f18394Jason W Kim 540685c350ae76b588e1f00c01a511fe8bd57f18394Jason W Kim/// getBranchTargetOpValue - Return encoding info for 24-bit immediate branch 541685c350ae76b588e1f00c01a511fe8bd57f18394Jason W Kim/// target. 542685c350ae76b588e1f00c01a511fe8bd57f18394Jason W Kimuint32_t ARMMCCodeEmitter:: 543685c350ae76b588e1f00c01a511fe8bd57f18394Jason W KimgetARMBranchTargetOpValue(const MCInst &MI, unsigned OpIdx, 544685c350ae76b588e1f00c01a511fe8bd57f18394Jason W Kim SmallVectorImpl<MCFixup> &Fixups) const { 545685c350ae76b588e1f00c01a511fe8bd57f18394Jason W Kim if (HasConditionalBranch(MI)) 546685c350ae76b588e1f00c01a511fe8bd57f18394Jason W Kim return ::getBranchTargetOpValue(MI, OpIdx, 547685c350ae76b588e1f00c01a511fe8bd57f18394Jason W Kim ARM::fixup_arm_condbranch, Fixups); 548685c350ae76b588e1f00c01a511fe8bd57f18394Jason W Kim return ::getBranchTargetOpValue(MI, OpIdx, 549685c350ae76b588e1f00c01a511fe8bd57f18394Jason W Kim ARM::fixup_arm_uncondbranch, Fixups); 550c466b937dbdbaabeef0097fe340de1b8f49a3508Jim Grosbach} 551c466b937dbdbaabeef0097fe340de1b8f49a3508Jim Grosbach 552685c350ae76b588e1f00c01a511fe8bd57f18394Jason W Kim 553685c350ae76b588e1f00c01a511fe8bd57f18394Jason W Kim 554685c350ae76b588e1f00c01a511fe8bd57f18394Jason W Kim 555c266600bec4b5ba0ee93ffdfeaafcab8f1295145Owen Anderson/// getUnconditionalBranchTargetOpValue - Return encoding info for 24-bit 556c266600bec4b5ba0ee93ffdfeaafcab8f1295145Owen Anderson/// immediate branch target. 557c266600bec4b5ba0ee93ffdfeaafcab8f1295145Owen Andersonuint32_t ARMMCCodeEmitter:: 558c266600bec4b5ba0ee93ffdfeaafcab8f1295145Owen AndersongetUnconditionalBranchTargetOpValue(const MCInst &MI, unsigned OpIdx, 559c266600bec4b5ba0ee93ffdfeaafcab8f1295145Owen Anderson SmallVectorImpl<MCFixup> &Fixups) const { 560c266600bec4b5ba0ee93ffdfeaafcab8f1295145Owen Anderson unsigned Val = 561c266600bec4b5ba0ee93ffdfeaafcab8f1295145Owen Anderson ::getBranchTargetOpValue(MI, OpIdx, ARM::fixup_t2_uncondbranch, Fixups); 562c266600bec4b5ba0ee93ffdfeaafcab8f1295145Owen Anderson bool I = (Val & 0x800000); 563c266600bec4b5ba0ee93ffdfeaafcab8f1295145Owen Anderson bool J1 = (Val & 0x400000); 564c266600bec4b5ba0ee93ffdfeaafcab8f1295145Owen Anderson bool J2 = (Val & 0x200000); 565c266600bec4b5ba0ee93ffdfeaafcab8f1295145Owen Anderson if (I ^ J1) 566c266600bec4b5ba0ee93ffdfeaafcab8f1295145Owen Anderson Val &= ~0x400000; 567c266600bec4b5ba0ee93ffdfeaafcab8f1295145Owen Anderson else 568c266600bec4b5ba0ee93ffdfeaafcab8f1295145Owen Anderson Val |= 0x400000; 569971b83b67a9812556cdb97bb58aa96fb37af458dOwen Anderson 570c266600bec4b5ba0ee93ffdfeaafcab8f1295145Owen Anderson if (I ^ J2) 571c266600bec4b5ba0ee93ffdfeaafcab8f1295145Owen Anderson Val &= ~0x200000; 572c266600bec4b5ba0ee93ffdfeaafcab8f1295145Owen Anderson else 573c266600bec4b5ba0ee93ffdfeaafcab8f1295145Owen Anderson Val |= 0x200000; 574971b83b67a9812556cdb97bb58aa96fb37af458dOwen Anderson 575c266600bec4b5ba0ee93ffdfeaafcab8f1295145Owen Anderson return Val; 576c266600bec4b5ba0ee93ffdfeaafcab8f1295145Owen Anderson} 577c266600bec4b5ba0ee93ffdfeaafcab8f1295145Owen Anderson 578dff2f7151f695b86db8c4b0c6604463bdb8a63eaBill Wendling/// getAdrLabelOpValue - Return encoding info for 12-bit immediate ADR label 579dff2f7151f695b86db8c4b0c6604463bdb8a63eaBill Wendling/// target. 5805d14f9be7ba64162c7b996f36d419b11d8cdbe9aJim Grosbachuint32_t ARMMCCodeEmitter:: 5815d14f9be7ba64162c7b996f36d419b11d8cdbe9aJim GrosbachgetAdrLabelOpValue(const MCInst &MI, unsigned OpIdx, 5825d14f9be7ba64162c7b996f36d419b11d8cdbe9aJim Grosbach SmallVectorImpl<MCFixup> &Fixups) const { 583dff2f7151f695b86db8c4b0c6604463bdb8a63eaBill Wendling assert(MI.getOperand(OpIdx).isExpr() && "Unexpected adr target type!"); 584dff2f7151f695b86db8c4b0c6604463bdb8a63eaBill Wendling return ::getBranchTargetOpValue(MI, OpIdx, ARM::fixup_arm_adr_pcrel_12, 585dff2f7151f695b86db8c4b0c6604463bdb8a63eaBill Wendling Fixups); 5865d14f9be7ba64162c7b996f36d419b11d8cdbe9aJim Grosbach} 5875d14f9be7ba64162c7b996f36d419b11d8cdbe9aJim Grosbach 588a838a25d59838adfa91463f6a918ae3adeb352c1Owen Anderson/// getAdrLabelOpValue - Return encoding info for 12-bit immediate ADR label 589a838a25d59838adfa91463f6a918ae3adeb352c1Owen Anderson/// target. 590a838a25d59838adfa91463f6a918ae3adeb352c1Owen Andersonuint32_t ARMMCCodeEmitter:: 591a838a25d59838adfa91463f6a918ae3adeb352c1Owen AndersongetT2AdrLabelOpValue(const MCInst &MI, unsigned OpIdx, 592a838a25d59838adfa91463f6a918ae3adeb352c1Owen Anderson SmallVectorImpl<MCFixup> &Fixups) const { 593a838a25d59838adfa91463f6a918ae3adeb352c1Owen Anderson assert(MI.getOperand(OpIdx).isExpr() && "Unexpected adr target type!"); 594a838a25d59838adfa91463f6a918ae3adeb352c1Owen Anderson return ::getBranchTargetOpValue(MI, OpIdx, ARM::fixup_t2_adr_pcrel_12, 595a838a25d59838adfa91463f6a918ae3adeb352c1Owen Anderson Fixups); 596a838a25d59838adfa91463f6a918ae3adeb352c1Owen Anderson} 597a838a25d59838adfa91463f6a918ae3adeb352c1Owen Anderson 598d40963c4065432ec7e47879d3ca665a54ee903b6Jim Grosbach/// getAdrLabelOpValue - Return encoding info for 8-bit immediate ADR label 599d40963c4065432ec7e47879d3ca665a54ee903b6Jim Grosbach/// target. 600d40963c4065432ec7e47879d3ca665a54ee903b6Jim Grosbachuint32_t ARMMCCodeEmitter:: 601d40963c4065432ec7e47879d3ca665a54ee903b6Jim GrosbachgetThumbAdrLabelOpValue(const MCInst &MI, unsigned OpIdx, 602d40963c4065432ec7e47879d3ca665a54ee903b6Jim Grosbach SmallVectorImpl<MCFixup> &Fixups) const { 603d40963c4065432ec7e47879d3ca665a54ee903b6Jim Grosbach assert(MI.getOperand(OpIdx).isExpr() && "Unexpected adr target type!"); 604d40963c4065432ec7e47879d3ca665a54ee903b6Jim Grosbach return ::getBranchTargetOpValue(MI, OpIdx, ARM::fixup_thumb_adr_pcrel_10, 605d40963c4065432ec7e47879d3ca665a54ee903b6Jim Grosbach Fixups); 606d40963c4065432ec7e47879d3ca665a54ee903b6Jim Grosbach} 607d40963c4065432ec7e47879d3ca665a54ee903b6Jim Grosbach 608f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling/// getThumbAddrModeRegRegOpValue - Return encoding info for 'reg + reg' 609f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling/// operand. 6100f4b60d43a289671082deee3bd56a3a055afb16aOwen Andersonuint32_t ARMMCCodeEmitter:: 611f4caf69720d807573c50d41aa06bcec1c99bdbbdBill WendlinggetThumbAddrModeRegRegOpValue(const MCInst &MI, unsigned OpIdx, 612f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling SmallVectorImpl<MCFixup> &) const { 613f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling // [Rn, Rm] 614f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling // {5-3} = Rm 615f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling // {2-0} = Rn 6160f4b60d43a289671082deee3bd56a3a055afb16aOwen Anderson const MCOperand &MO1 = MI.getOperand(OpIdx); 617f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling const MCOperand &MO2 = MI.getOperand(OpIdx + 1); 6180f4b60d43a289671082deee3bd56a3a055afb16aOwen Anderson unsigned Rn = getARMRegisterNumbering(MO1.getReg()); 6190f4b60d43a289671082deee3bd56a3a055afb16aOwen Anderson unsigned Rm = getARMRegisterNumbering(MO2.getReg()); 6200f4b60d43a289671082deee3bd56a3a055afb16aOwen Anderson return (Rm << 3) | Rn; 6210f4b60d43a289671082deee3bd56a3a055afb16aOwen Anderson} 6220f4b60d43a289671082deee3bd56a3a055afb16aOwen Anderson 62392b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling/// getAddrModeImm12OpValue - Return encoding info for 'reg +/- imm12' operand. 624806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbachuint32_t ARMMCCodeEmitter:: 625806e80ef42bdb416f409142a1ff1d4e8752baac8Jim GrosbachgetAddrModeImm12OpValue(const MCInst &MI, unsigned OpIdx, 626806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbach SmallVectorImpl<MCFixup> &Fixups) const { 62792b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling // {17-13} = reg 62892b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling // {12} = (U)nsigned (add == '1', sub == '0') 62992b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling // {11-0} = imm12 63092b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling unsigned Reg, Imm12; 63170933266ae73c891d9d1c2f0de72ecd1db8f86dfJim Grosbach bool isAdd = true; 63270933266ae73c891d9d1c2f0de72ecd1db8f86dfJim Grosbach // If The first operand isn't a register, we have a label reference. 63370933266ae73c891d9d1c2f0de72ecd1db8f86dfJim Grosbach const MCOperand &MO = MI.getOperand(OpIdx); 634971b83b67a9812556cdb97bb58aa96fb37af458dOwen Anderson if (!MO.isReg()) { 635679cbd3b215b1769a6035e334f9009aeeb940dddJim Grosbach Reg = getARMRegisterNumbering(ARM::PC); // Rn is PC. 63670933266ae73c891d9d1c2f0de72ecd1db8f86dfJim Grosbach Imm12 = 0; 63797dd28fb89dc4c4caa3c60890335dc99489981a6Jim Grosbach isAdd = false ; // 'U' bit is set as part of the fixup. 63870933266ae73c891d9d1c2f0de72ecd1db8f86dfJim Grosbach 639971b83b67a9812556cdb97bb58aa96fb37af458dOwen Anderson assert(MO.isExpr() && "Unexpected machine operand type!"); 640971b83b67a9812556cdb97bb58aa96fb37af458dOwen Anderson const MCExpr *Expr = MO.getExpr(); 6417bf4c02789f97e32225fc248dff6622b994a15eeJim Grosbach 642d7b3f5870d9d04351d9cd363d9d6af01482a2eb8Owen Anderson MCFixupKind Kind; 64359ee62d2418df8db499eca1ae17f5900dc2dcbbaEvan Cheng if (isThumb2()) 644d7b3f5870d9d04351d9cd363d9d6af01482a2eb8Owen Anderson Kind = MCFixupKind(ARM::fixup_t2_ldst_pcrel_12); 645d7b3f5870d9d04351d9cd363d9d6af01482a2eb8Owen Anderson else 646d7b3f5870d9d04351d9cd363d9d6af01482a2eb8Owen Anderson Kind = MCFixupKind(ARM::fixup_arm_ldst_pcrel_12); 64770933266ae73c891d9d1c2f0de72ecd1db8f86dfJim Grosbach Fixups.push_back(MCFixup::Create(0, Expr, Kind)); 64870933266ae73c891d9d1c2f0de72ecd1db8f86dfJim Grosbach 64970933266ae73c891d9d1c2f0de72ecd1db8f86dfJim Grosbach ++MCNumCPRelocations; 65070933266ae73c891d9d1c2f0de72ecd1db8f86dfJim Grosbach } else 65170933266ae73c891d9d1c2f0de72ecd1db8f86dfJim Grosbach isAdd = EncodeAddrModeOpValues(MI, OpIdx, Reg, Imm12, Fixups); 65292b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling 65392b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling uint32_t Binary = Imm12 & 0xfff; 65492b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling // Immediate is always encoded as positive. The 'U' bit controls add vs sub. 655ab682a2090f795d0b67f29889622da0a74cd97c3Jim Grosbach if (isAdd) 65692b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling Binary |= (1 << 12); 65792b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling Binary |= (Reg << 13); 65892b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling return Binary; 65992b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling} 66092b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling 6619d63d90de5e57ad96f467b270544443a9284eb2bOwen Anderson/// getT2AddrModeImm8s4OpValue - Return encoding info for 6629d63d90de5e57ad96f467b270544443a9284eb2bOwen Anderson/// 'reg +/- imm8<<2' operand. 6639d63d90de5e57ad96f467b270544443a9284eb2bOwen Andersonuint32_t ARMMCCodeEmitter:: 6649d63d90de5e57ad96f467b270544443a9284eb2bOwen AndersongetT2AddrModeImm8s4OpValue(const MCInst &MI, unsigned OpIdx, 6659d63d90de5e57ad96f467b270544443a9284eb2bOwen Anderson SmallVectorImpl<MCFixup> &Fixups) const { 66690cc533fda9742f5c67203f97e69e5efd270c676Jim Grosbach // {12-9} = reg 66790cc533fda9742f5c67203f97e69e5efd270c676Jim Grosbach // {8} = (U)nsigned (add == '1', sub == '0') 66890cc533fda9742f5c67203f97e69e5efd270c676Jim Grosbach // {7-0} = imm8 6699d63d90de5e57ad96f467b270544443a9284eb2bOwen Anderson unsigned Reg, Imm8; 6709d63d90de5e57ad96f467b270544443a9284eb2bOwen Anderson bool isAdd = true; 6719d63d90de5e57ad96f467b270544443a9284eb2bOwen Anderson // If The first operand isn't a register, we have a label reference. 6729d63d90de5e57ad96f467b270544443a9284eb2bOwen Anderson const MCOperand &MO = MI.getOperand(OpIdx); 6739d63d90de5e57ad96f467b270544443a9284eb2bOwen Anderson if (!MO.isReg()) { 6749d63d90de5e57ad96f467b270544443a9284eb2bOwen Anderson Reg = getARMRegisterNumbering(ARM::PC); // Rn is PC. 6759d63d90de5e57ad96f467b270544443a9284eb2bOwen Anderson Imm8 = 0; 6769d63d90de5e57ad96f467b270544443a9284eb2bOwen Anderson isAdd = false ; // 'U' bit is set as part of the fixup. 6779d63d90de5e57ad96f467b270544443a9284eb2bOwen Anderson 6789d63d90de5e57ad96f467b270544443a9284eb2bOwen Anderson assert(MO.isExpr() && "Unexpected machine operand type!"); 6799d63d90de5e57ad96f467b270544443a9284eb2bOwen Anderson const MCExpr *Expr = MO.getExpr(); 6809d63d90de5e57ad96f467b270544443a9284eb2bOwen Anderson MCFixupKind Kind = MCFixupKind(ARM::fixup_arm_pcrel_10); 6819d63d90de5e57ad96f467b270544443a9284eb2bOwen Anderson Fixups.push_back(MCFixup::Create(0, Expr, Kind)); 6829d63d90de5e57ad96f467b270544443a9284eb2bOwen Anderson 6839d63d90de5e57ad96f467b270544443a9284eb2bOwen Anderson ++MCNumCPRelocations; 6849d63d90de5e57ad96f467b270544443a9284eb2bOwen Anderson } else 6859d63d90de5e57ad96f467b270544443a9284eb2bOwen Anderson isAdd = EncodeAddrModeOpValues(MI, OpIdx, Reg, Imm8, Fixups); 6869d63d90de5e57ad96f467b270544443a9284eb2bOwen Anderson 6879d63d90de5e57ad96f467b270544443a9284eb2bOwen Anderson uint32_t Binary = (Imm8 >> 2) & 0xff; 6889d63d90de5e57ad96f467b270544443a9284eb2bOwen Anderson // Immediate is always encoded as positive. The 'U' bit controls add vs sub. 6899d63d90de5e57ad96f467b270544443a9284eb2bOwen Anderson if (isAdd) 69090cc533fda9742f5c67203f97e69e5efd270c676Jim Grosbach Binary |= (1 << 8); 6919d63d90de5e57ad96f467b270544443a9284eb2bOwen Anderson Binary |= (Reg << 9); 6929d63d90de5e57ad96f467b270544443a9284eb2bOwen Anderson return Binary; 6939d63d90de5e57ad96f467b270544443a9284eb2bOwen Anderson} 6949d63d90de5e57ad96f467b270544443a9284eb2bOwen Anderson 69586a97f2e4d0cde5e992f52ac287da0de687e0110Jason W Kim// FIXME: This routine assumes that a binary 69686a97f2e4d0cde5e992f52ac287da0de687e0110Jason W Kim// expression will always result in a PCRel expression 69786a97f2e4d0cde5e992f52ac287da0de687e0110Jason W Kim// In reality, its only true if one or more subexpressions 69886a97f2e4d0cde5e992f52ac287da0de687e0110Jason W Kim// is itself a PCRel (i.e. "." in asm or some other pcrel construct) 69986a97f2e4d0cde5e992f52ac287da0de687e0110Jason W Kim// but this is good enough for now. 70086a97f2e4d0cde5e992f52ac287da0de687e0110Jason W Kimstatic bool EvaluateAsPCRel(const MCExpr *Expr) { 70186a97f2e4d0cde5e992f52ac287da0de687e0110Jason W Kim switch (Expr->getKind()) { 7025f8a917b6558f8fdf31b4a6fa591b396e16b9ff2Matt Beaumont-Gay default: assert(0 && "Unexpected expression type"); 70386a97f2e4d0cde5e992f52ac287da0de687e0110Jason W Kim case MCExpr::SymbolRef: return false; 70486a97f2e4d0cde5e992f52ac287da0de687e0110Jason W Kim case MCExpr::Binary: return true; 70586a97f2e4d0cde5e992f52ac287da0de687e0110Jason W Kim } 70686a97f2e4d0cde5e992f52ac287da0de687e0110Jason W Kim} 70786a97f2e4d0cde5e992f52ac287da0de687e0110Jason W Kim 7087597212abced110723f2fee985a7d60557c092ecEvan Chenguint32_t 7097597212abced110723f2fee985a7d60557c092ecEvan ChengARMMCCodeEmitter::getHiLo16ImmOpValue(const MCInst &MI, unsigned OpIdx, 7107597212abced110723f2fee985a7d60557c092ecEvan Cheng SmallVectorImpl<MCFixup> &Fixups) const { 711837caa9313e1f9480721f232f89f5c7b1b9c9d09Jason W Kim // {20-16} = imm{15-12} 712837caa9313e1f9480721f232f89f5c7b1b9c9d09Jason W Kim // {11-0} = imm{11-0} 7137bf4c02789f97e32225fc248dff6622b994a15eeJim Grosbach const MCOperand &MO = MI.getOperand(OpIdx); 7147597212abced110723f2fee985a7d60557c092ecEvan Cheng if (MO.isImm()) 7157597212abced110723f2fee985a7d60557c092ecEvan Cheng // Hi / lo 16 bits already extracted during earlier passes. 716837caa9313e1f9480721f232f89f5c7b1b9c9d09Jason W Kim return static_cast<unsigned>(MO.getImm()); 7177597212abced110723f2fee985a7d60557c092ecEvan Cheng 7187597212abced110723f2fee985a7d60557c092ecEvan Cheng // Handle :upper16: and :lower16: assembly prefixes. 7197597212abced110723f2fee985a7d60557c092ecEvan Cheng const MCExpr *E = MO.getExpr(); 7207597212abced110723f2fee985a7d60557c092ecEvan Cheng if (E->getKind() == MCExpr::Target) { 7217597212abced110723f2fee985a7d60557c092ecEvan Cheng const ARMMCExpr *ARM16Expr = cast<ARMMCExpr>(E); 7227597212abced110723f2fee985a7d60557c092ecEvan Cheng E = ARM16Expr->getSubExpr(); 7237597212abced110723f2fee985a7d60557c092ecEvan Cheng 724837caa9313e1f9480721f232f89f5c7b1b9c9d09Jason W Kim MCFixupKind Kind; 7257597212abced110723f2fee985a7d60557c092ecEvan Cheng switch (ARM16Expr->getKind()) { 7265f8a917b6558f8fdf31b4a6fa591b396e16b9ff2Matt Beaumont-Gay default: assert(0 && "Unsupported ARMFixup"); 7277597212abced110723f2fee985a7d60557c092ecEvan Cheng case ARMMCExpr::VK_ARM_HI16: 72859ee62d2418df8db499eca1ae17f5900dc2dcbbaEvan Cheng if (!isTargetDarwin() && EvaluateAsPCRel(E)) 72959ee62d2418df8db499eca1ae17f5900dc2dcbbaEvan Cheng Kind = MCFixupKind(isThumb2() 730f3eb3bba1614a7935b44fc963a805088d71267f3Evan Cheng ? ARM::fixup_t2_movt_hi16_pcrel 731f3eb3bba1614a7935b44fc963a805088d71267f3Evan Cheng : ARM::fixup_arm_movt_hi16_pcrel); 732f3eb3bba1614a7935b44fc963a805088d71267f3Evan Cheng else 73359ee62d2418df8db499eca1ae17f5900dc2dcbbaEvan Cheng Kind = MCFixupKind(isThumb2() 734f3eb3bba1614a7935b44fc963a805088d71267f3Evan Cheng ? ARM::fixup_t2_movt_hi16 735f3eb3bba1614a7935b44fc963a805088d71267f3Evan Cheng : ARM::fixup_arm_movt_hi16); 736837caa9313e1f9480721f232f89f5c7b1b9c9d09Jason W Kim break; 7377597212abced110723f2fee985a7d60557c092ecEvan Cheng case ARMMCExpr::VK_ARM_LO16: 73859ee62d2418df8db499eca1ae17f5900dc2dcbbaEvan Cheng if (!isTargetDarwin() && EvaluateAsPCRel(E)) 73959ee62d2418df8db499eca1ae17f5900dc2dcbbaEvan Cheng Kind = MCFixupKind(isThumb2() 740f3eb3bba1614a7935b44fc963a805088d71267f3Evan Cheng ? ARM::fixup_t2_movw_lo16_pcrel 741f3eb3bba1614a7935b44fc963a805088d71267f3Evan Cheng : ARM::fixup_arm_movw_lo16_pcrel); 742f3eb3bba1614a7935b44fc963a805088d71267f3Evan Cheng else 74359ee62d2418df8db499eca1ae17f5900dc2dcbbaEvan Cheng Kind = MCFixupKind(isThumb2() 744f3eb3bba1614a7935b44fc963a805088d71267f3Evan Cheng ? ARM::fixup_t2_movw_lo16 745f3eb3bba1614a7935b44fc963a805088d71267f3Evan Cheng : ARM::fixup_arm_movw_lo16); 746837caa9313e1f9480721f232f89f5c7b1b9c9d09Jason W Kim break; 747837caa9313e1f9480721f232f89f5c7b1b9c9d09Jason W Kim } 7487597212abced110723f2fee985a7d60557c092ecEvan Cheng Fixups.push_back(MCFixup::Create(0, E, Kind)); 749837caa9313e1f9480721f232f89f5c7b1b9c9d09Jason W Kim return 0; 750817c1a6dddadb4664738777d224bc7eae6e62cf3Jim Grosbach }; 7517597212abced110723f2fee985a7d60557c092ecEvan Cheng 752817c1a6dddadb4664738777d224bc7eae6e62cf3Jim Grosbach llvm_unreachable("Unsupported MCExpr type in MCOperand!"); 753837caa9313e1f9480721f232f89f5c7b1b9c9d09Jason W Kim return 0; 754837caa9313e1f9480721f232f89f5c7b1b9c9d09Jason W Kim} 755837caa9313e1f9480721f232f89f5c7b1b9c9d09Jason W Kim 756837caa9313e1f9480721f232f89f5c7b1b9c9d09Jason W Kimuint32_t ARMMCCodeEmitter:: 75754fea632b161f98e96ec7275922e35102bcecc5dJim GrosbachgetLdStSORegOpValue(const MCInst &MI, unsigned OpIdx, 75854fea632b161f98e96ec7275922e35102bcecc5dJim Grosbach SmallVectorImpl<MCFixup> &Fixups) const { 75954fea632b161f98e96ec7275922e35102bcecc5dJim Grosbach const MCOperand &MO = MI.getOperand(OpIdx); 76054fea632b161f98e96ec7275922e35102bcecc5dJim Grosbach const MCOperand &MO1 = MI.getOperand(OpIdx+1); 76154fea632b161f98e96ec7275922e35102bcecc5dJim Grosbach const MCOperand &MO2 = MI.getOperand(OpIdx+2); 76254fea632b161f98e96ec7275922e35102bcecc5dJim Grosbach unsigned Rn = getARMRegisterNumbering(MO.getReg()); 76354fea632b161f98e96ec7275922e35102bcecc5dJim Grosbach unsigned Rm = getARMRegisterNumbering(MO1.getReg()); 76454fea632b161f98e96ec7275922e35102bcecc5dJim Grosbach unsigned ShImm = ARM_AM::getAM2Offset(MO2.getImm()); 76554fea632b161f98e96ec7275922e35102bcecc5dJim Grosbach bool isAdd = ARM_AM::getAM2Op(MO2.getImm()) == ARM_AM::add; 76699f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach ARM_AM::ShiftOpc ShOp = ARM_AM::getAM2ShiftOpc(MO2.getImm()); 76799f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach unsigned SBits = getShiftOp(ShOp); 76854fea632b161f98e96ec7275922e35102bcecc5dJim Grosbach 76954fea632b161f98e96ec7275922e35102bcecc5dJim Grosbach // {16-13} = Rn 77054fea632b161f98e96ec7275922e35102bcecc5dJim Grosbach // {12} = isAdd 77154fea632b161f98e96ec7275922e35102bcecc5dJim Grosbach // {11-0} = shifter 77254fea632b161f98e96ec7275922e35102bcecc5dJim Grosbach // {3-0} = Rm 77354fea632b161f98e96ec7275922e35102bcecc5dJim Grosbach // {4} = 0 77454fea632b161f98e96ec7275922e35102bcecc5dJim Grosbach // {6-5} = type 77554fea632b161f98e96ec7275922e35102bcecc5dJim Grosbach // {11-7} = imm 776570a9226913ebe1af04832b8fb3273c70b4ee152Jim Grosbach uint32_t Binary = Rm; 77754fea632b161f98e96ec7275922e35102bcecc5dJim Grosbach Binary |= Rn << 13; 77854fea632b161f98e96ec7275922e35102bcecc5dJim Grosbach Binary |= SBits << 5; 77954fea632b161f98e96ec7275922e35102bcecc5dJim Grosbach Binary |= ShImm << 7; 78054fea632b161f98e96ec7275922e35102bcecc5dJim Grosbach if (isAdd) 78154fea632b161f98e96ec7275922e35102bcecc5dJim Grosbach Binary |= 1 << 12; 78254fea632b161f98e96ec7275922e35102bcecc5dJim Grosbach return Binary; 78354fea632b161f98e96ec7275922e35102bcecc5dJim Grosbach} 78454fea632b161f98e96ec7275922e35102bcecc5dJim Grosbach 785570a9226913ebe1af04832b8fb3273c70b4ee152Jim Grosbachuint32_t ARMMCCodeEmitter:: 78699f53d13efc259b47c93dc0d90a5db763cbe371aJim GrosbachgetAddrMode2OpValue(const MCInst &MI, unsigned OpIdx, 78799f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach SmallVectorImpl<MCFixup> &Fixups) const { 78899f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach // {17-14} Rn 78999f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach // {13} 1 == imm12, 0 == Rm 79099f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach // {12} isAdd 79199f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach // {11-0} imm12/Rm 79299f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach const MCOperand &MO = MI.getOperand(OpIdx); 79399f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach unsigned Rn = getARMRegisterNumbering(MO.getReg()); 79499f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach uint32_t Binary = getAddrMode2OffsetOpValue(MI, OpIdx + 1, Fixups); 79599f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach Binary |= Rn << 14; 79699f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach return Binary; 79799f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach} 79899f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach 79999f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbachuint32_t ARMMCCodeEmitter:: 80099f53d13efc259b47c93dc0d90a5db763cbe371aJim GrosbachgetAddrMode2OffsetOpValue(const MCInst &MI, unsigned OpIdx, 80199f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach SmallVectorImpl<MCFixup> &Fixups) const { 80299f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach // {13} 1 == imm12, 0 == Rm 80399f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach // {12} isAdd 80499f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach // {11-0} imm12/Rm 80599f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach const MCOperand &MO = MI.getOperand(OpIdx); 80699f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach const MCOperand &MO1 = MI.getOperand(OpIdx+1); 80799f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach unsigned Imm = MO1.getImm(); 80899f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach bool isAdd = ARM_AM::getAM2Op(Imm) == ARM_AM::add; 80999f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach bool isReg = MO.getReg() != 0; 81099f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach uint32_t Binary = ARM_AM::getAM2Offset(Imm); 81199f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach // if reg +/- reg, Rm will be non-zero. Otherwise, we have reg +/- imm12 81299f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach if (isReg) { 81399f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach ARM_AM::ShiftOpc ShOp = ARM_AM::getAM2ShiftOpc(Imm); 81499f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach Binary <<= 7; // Shift amount is bits [11:7] 81599f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach Binary |= getShiftOp(ShOp) << 5; // Shift type is bits [6:5] 81699f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach Binary |= getARMRegisterNumbering(MO.getReg()); // Rm is bits [3:0] 81799f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach } 81899f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach return Binary | (isAdd << 12) | (isReg << 13); 81999f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach} 82099f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach 82199f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbachuint32_t ARMMCCodeEmitter:: 8227ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim GrosbachgetPostIdxRegOpValue(const MCInst &MI, unsigned OpIdx, 8237ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach SmallVectorImpl<MCFixup> &Fixups) const { 8247ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // {4} isAdd 8257ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // {3-0} Rm 8267ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach const MCOperand &MO = MI.getOperand(OpIdx); 8277ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach const MCOperand &MO1 = MI.getOperand(OpIdx+1); 82816578b50889329eb62774148091ba0f38b681a09Jim Grosbach bool isAdd = MO1.getImm() != 0; 8297ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return getARMRegisterNumbering(MO.getReg()) | (isAdd << 4); 8307ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach} 8317ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach 8327ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbachuint32_t ARMMCCodeEmitter:: 8337eab97f260ba0f56d1d4a82f3a4eb2c979452011Jim GrosbachgetAddrMode3OffsetOpValue(const MCInst &MI, unsigned OpIdx, 8347eab97f260ba0f56d1d4a82f3a4eb2c979452011Jim Grosbach SmallVectorImpl<MCFixup> &Fixups) const { 8357eab97f260ba0f56d1d4a82f3a4eb2c979452011Jim Grosbach // {9} 1 == imm8, 0 == Rm 8367eab97f260ba0f56d1d4a82f3a4eb2c979452011Jim Grosbach // {8} isAdd 8377eab97f260ba0f56d1d4a82f3a4eb2c979452011Jim Grosbach // {7-4} imm7_4/zero 8387eab97f260ba0f56d1d4a82f3a4eb2c979452011Jim Grosbach // {3-0} imm3_0/Rm 8397eab97f260ba0f56d1d4a82f3a4eb2c979452011Jim Grosbach const MCOperand &MO = MI.getOperand(OpIdx); 8407eab97f260ba0f56d1d4a82f3a4eb2c979452011Jim Grosbach const MCOperand &MO1 = MI.getOperand(OpIdx+1); 8417eab97f260ba0f56d1d4a82f3a4eb2c979452011Jim Grosbach unsigned Imm = MO1.getImm(); 8427eab97f260ba0f56d1d4a82f3a4eb2c979452011Jim Grosbach bool isAdd = ARM_AM::getAM3Op(Imm) == ARM_AM::add; 8437eab97f260ba0f56d1d4a82f3a4eb2c979452011Jim Grosbach bool isImm = MO.getReg() == 0; 8447eab97f260ba0f56d1d4a82f3a4eb2c979452011Jim Grosbach uint32_t Imm8 = ARM_AM::getAM3Offset(Imm); 8457eab97f260ba0f56d1d4a82f3a4eb2c979452011Jim Grosbach // if reg +/- reg, Rm will be non-zero. Otherwise, we have reg +/- imm8 8467eab97f260ba0f56d1d4a82f3a4eb2c979452011Jim Grosbach if (!isImm) 8477eab97f260ba0f56d1d4a82f3a4eb2c979452011Jim Grosbach Imm8 = getARMRegisterNumbering(MO.getReg()); 8487eab97f260ba0f56d1d4a82f3a4eb2c979452011Jim Grosbach return Imm8 | (isAdd << 8) | (isImm << 9); 8497eab97f260ba0f56d1d4a82f3a4eb2c979452011Jim Grosbach} 8507eab97f260ba0f56d1d4a82f3a4eb2c979452011Jim Grosbach 8517eab97f260ba0f56d1d4a82f3a4eb2c979452011Jim Grosbachuint32_t ARMMCCodeEmitter:: 852570a9226913ebe1af04832b8fb3273c70b4ee152Jim GrosbachgetAddrMode3OpValue(const MCInst &MI, unsigned OpIdx, 853570a9226913ebe1af04832b8fb3273c70b4ee152Jim Grosbach SmallVectorImpl<MCFixup> &Fixups) const { 854570a9226913ebe1af04832b8fb3273c70b4ee152Jim Grosbach // {13} 1 == imm8, 0 == Rm 855570a9226913ebe1af04832b8fb3273c70b4ee152Jim Grosbach // {12-9} Rn 856570a9226913ebe1af04832b8fb3273c70b4ee152Jim Grosbach // {8} isAdd 857570a9226913ebe1af04832b8fb3273c70b4ee152Jim Grosbach // {7-4} imm7_4/zero 858570a9226913ebe1af04832b8fb3273c70b4ee152Jim Grosbach // {3-0} imm3_0/Rm 859570a9226913ebe1af04832b8fb3273c70b4ee152Jim Grosbach const MCOperand &MO = MI.getOperand(OpIdx); 860570a9226913ebe1af04832b8fb3273c70b4ee152Jim Grosbach const MCOperand &MO1 = MI.getOperand(OpIdx+1); 861570a9226913ebe1af04832b8fb3273c70b4ee152Jim Grosbach const MCOperand &MO2 = MI.getOperand(OpIdx+2); 862570a9226913ebe1af04832b8fb3273c70b4ee152Jim Grosbach unsigned Rn = getARMRegisterNumbering(MO.getReg()); 863570a9226913ebe1af04832b8fb3273c70b4ee152Jim Grosbach unsigned Imm = MO2.getImm(); 864570a9226913ebe1af04832b8fb3273c70b4ee152Jim Grosbach bool isAdd = ARM_AM::getAM3Op(Imm) == ARM_AM::add; 865570a9226913ebe1af04832b8fb3273c70b4ee152Jim Grosbach bool isImm = MO1.getReg() == 0; 866570a9226913ebe1af04832b8fb3273c70b4ee152Jim Grosbach uint32_t Imm8 = ARM_AM::getAM3Offset(Imm); 867570a9226913ebe1af04832b8fb3273c70b4ee152Jim Grosbach // if reg +/- reg, Rm will be non-zero. Otherwise, we have reg +/- imm8 868570a9226913ebe1af04832b8fb3273c70b4ee152Jim Grosbach if (!isImm) 869570a9226913ebe1af04832b8fb3273c70b4ee152Jim Grosbach Imm8 = getARMRegisterNumbering(MO1.getReg()); 870570a9226913ebe1af04832b8fb3273c70b4ee152Jim Grosbach return (Rn << 9) | Imm8 | (isAdd << 8) | (isImm << 13); 871570a9226913ebe1af04832b8fb3273c70b4ee152Jim Grosbach} 872570a9226913ebe1af04832b8fb3273c70b4ee152Jim Grosbach 873b8958b031ec5163261f490f131780c5dc3d823d6Bill Wendling/// getAddrModeThumbSPOpValue - Encode the t_addrmode_sp operands. 874d967cd096ae87accf2f1df86b2dfac969d9c9da2Jim Grosbachuint32_t ARMMCCodeEmitter:: 875d967cd096ae87accf2f1df86b2dfac969d9c9da2Jim GrosbachgetAddrModeThumbSPOpValue(const MCInst &MI, unsigned OpIdx, 876d967cd096ae87accf2f1df86b2dfac969d9c9da2Jim Grosbach SmallVectorImpl<MCFixup> &Fixups) const { 877d967cd096ae87accf2f1df86b2dfac969d9c9da2Jim Grosbach // [SP, #imm] 878d967cd096ae87accf2f1df86b2dfac969d9c9da2Jim Grosbach // {7-0} = imm8 879d967cd096ae87accf2f1df86b2dfac969d9c9da2Jim Grosbach const MCOperand &MO1 = MI.getOperand(OpIdx + 1); 880b8958b031ec5163261f490f131780c5dc3d823d6Bill Wendling assert(MI.getOperand(OpIdx).getReg() == ARM::SP && 881b8958b031ec5163261f490f131780c5dc3d823d6Bill Wendling "Unexpected base register!"); 8827a905a82f7425d1a10b828c8bb3365b2ebc15833Bill Wendling 883d967cd096ae87accf2f1df86b2dfac969d9c9da2Jim Grosbach // The immediate is already shifted for the implicit zeroes, so no change 884d967cd096ae87accf2f1df86b2dfac969d9c9da2Jim Grosbach // here. 885d967cd096ae87accf2f1df86b2dfac969d9c9da2Jim Grosbach return MO1.getImm() & 0xff; 886d967cd096ae87accf2f1df86b2dfac969d9c9da2Jim Grosbach} 887d967cd096ae87accf2f1df86b2dfac969d9c9da2Jim Grosbach 888f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling/// getAddrModeISOpValue - Encode the t_addrmode_is# operands. 889272df516d7a9b1f0f69174276abaa759816ee456Bill Wendlinguint32_t ARMMCCodeEmitter:: 890f4caf69720d807573c50d41aa06bcec1c99bdbbdBill WendlinggetAddrModeISOpValue(const MCInst &MI, unsigned OpIdx, 89122447ae54bcb8ca94ed994cad103074a24e66781Bill Wendling SmallVectorImpl<MCFixup> &Fixups) const { 892ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling // [Rn, #imm] 893ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling // {7-3} = imm5 894ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling // {2-0} = Rn 895ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling const MCOperand &MO = MI.getOperand(OpIdx); 896ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling const MCOperand &MO1 = MI.getOperand(OpIdx + 1); 897ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling unsigned Rn = getARMRegisterNumbering(MO.getReg()); 898656b3d22f70c2d1c8a5286f7270cb380df862565Matt Beaumont-Gay unsigned Imm5 = MO1.getImm(); 899272df516d7a9b1f0f69174276abaa759816ee456Bill Wendling return ((Imm5 & 0x1f) << 3) | Rn; 9001fd374e9c1c074c1681336bef31e65f0170b0f7eBill Wendling} 9011fd374e9c1c074c1681336bef31e65f0170b0f7eBill Wendling 902b8958b031ec5163261f490f131780c5dc3d823d6Bill Wendling/// getAddrModePCOpValue - Return encoding for t_addrmode_pc operands. 903b8958b031ec5163261f490f131780c5dc3d823d6Bill Wendlinguint32_t ARMMCCodeEmitter:: 904b8958b031ec5163261f490f131780c5dc3d823d6Bill WendlinggetAddrModePCOpValue(const MCInst &MI, unsigned OpIdx, 905b8958b031ec5163261f490f131780c5dc3d823d6Bill Wendling SmallVectorImpl<MCFixup> &Fixups) const { 90609aa3f0ef35d9241c92439d74b8d5e9a81d814c2Bill Wendling return ::getBranchTargetOpValue(MI, OpIdx, ARM::fixup_arm_thumb_cp, Fixups); 907b8958b031ec5163261f490f131780c5dc3d823d6Bill Wendling} 908b8958b031ec5163261f490f131780c5dc3d823d6Bill Wendling 9095177f79c378b47e38bed5ac05ba4b597f31b864eJim Grosbach/// getAddrMode5OpValue - Return encoding info for 'reg +/- imm10' operand. 910806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbachuint32_t ARMMCCodeEmitter:: 911806e80ef42bdb416f409142a1ff1d4e8752baac8Jim GrosbachgetAddrMode5OpValue(const MCInst &MI, unsigned OpIdx, 912806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbach SmallVectorImpl<MCFixup> &Fixups) const { 91392b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling // {12-9} = reg 91492b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling // {8} = (U)nsigned (add == '1', sub == '0') 91592b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling // {7-0} = imm8 91692b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling unsigned Reg, Imm8; 91797dd28fb89dc4c4caa3c60890335dc99489981a6Jim Grosbach bool isAdd; 91870933266ae73c891d9d1c2f0de72ecd1db8f86dfJim Grosbach // If The first operand isn't a register, we have a label reference. 91970933266ae73c891d9d1c2f0de72ecd1db8f86dfJim Grosbach const MCOperand &MO = MI.getOperand(OpIdx); 92070933266ae73c891d9d1c2f0de72ecd1db8f86dfJim Grosbach if (!MO.isReg()) { 921679cbd3b215b1769a6035e334f9009aeeb940dddJim Grosbach Reg = getARMRegisterNumbering(ARM::PC); // Rn is PC. 92270933266ae73c891d9d1c2f0de72ecd1db8f86dfJim Grosbach Imm8 = 0; 92397dd28fb89dc4c4caa3c60890335dc99489981a6Jim Grosbach isAdd = false; // 'U' bit is handled as part of the fixup. 92470933266ae73c891d9d1c2f0de72ecd1db8f86dfJim Grosbach 92570933266ae73c891d9d1c2f0de72ecd1db8f86dfJim Grosbach assert(MO.isExpr() && "Unexpected machine operand type!"); 92670933266ae73c891d9d1c2f0de72ecd1db8f86dfJim Grosbach const MCExpr *Expr = MO.getExpr(); 927d8e351b96f5fd7007fbdd636acaa1fc9f6e18f3cOwen Anderson MCFixupKind Kind; 92859ee62d2418df8db499eca1ae17f5900dc2dcbbaEvan Cheng if (isThumb2()) 929d8e351b96f5fd7007fbdd636acaa1fc9f6e18f3cOwen Anderson Kind = MCFixupKind(ARM::fixup_t2_pcrel_10); 930d8e351b96f5fd7007fbdd636acaa1fc9f6e18f3cOwen Anderson else 931d8e351b96f5fd7007fbdd636acaa1fc9f6e18f3cOwen Anderson Kind = MCFixupKind(ARM::fixup_arm_pcrel_10); 93270933266ae73c891d9d1c2f0de72ecd1db8f86dfJim Grosbach Fixups.push_back(MCFixup::Create(0, Expr, Kind)); 93370933266ae73c891d9d1c2f0de72ecd1db8f86dfJim Grosbach 93470933266ae73c891d9d1c2f0de72ecd1db8f86dfJim Grosbach ++MCNumCPRelocations; 93597dd28fb89dc4c4caa3c60890335dc99489981a6Jim Grosbach } else { 93670933266ae73c891d9d1c2f0de72ecd1db8f86dfJim Grosbach EncodeAddrModeOpValues(MI, OpIdx, Reg, Imm8, Fixups); 93797dd28fb89dc4c4caa3c60890335dc99489981a6Jim Grosbach isAdd = ARM_AM::getAM5Op(Imm8) == ARM_AM::add; 93897dd28fb89dc4c4caa3c60890335dc99489981a6Jim Grosbach } 93992b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling 94092b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling uint32_t Binary = ARM_AM::getAM5Offset(Imm8); 94192b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling // Immediate is always encoded as positive. The 'U' bit controls add vs sub. 94297dd28fb89dc4c4caa3c60890335dc99489981a6Jim Grosbach if (isAdd) 94392b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling Binary |= (1 << 8); 94492b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling Binary |= (Reg << 9); 9453e5561247202bae994dd259a2d8dc4eff8f799f3Jim Grosbach return Binary; 9463e5561247202bae994dd259a2d8dc4eff8f799f3Jim Grosbach} 9473e5561247202bae994dd259a2d8dc4eff8f799f3Jim Grosbach 948806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbachunsigned ARMMCCodeEmitter:: 949152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen AndersongetSORegRegOpValue(const MCInst &MI, unsigned OpIdx, 950806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbach SmallVectorImpl<MCFixup> &Fixups) const { 9510800ce71896ccd7f49b37861a8cfbc21b6b10022Bill Wendling // Sub-operands are [reg, reg, imm]. The first register is Rm, the reg to be 952354712c5a506449676e6fcac6b623af4092e7100Owen Anderson // shifted. The second is Rs, the amount to shift by, and the third specifies 953354712c5a506449676e6fcac6b623af4092e7100Owen Anderson // the type of the shift. 95435b2de012d9404e3e9e4373e45f41711f752dd3aJim Grosbach // 955ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach // {3-0} = Rm. 956354712c5a506449676e6fcac6b623af4092e7100Owen Anderson // {4} = 1 957ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach // {6-5} = type 958354712c5a506449676e6fcac6b623af4092e7100Owen Anderson // {11-8} = Rs 959354712c5a506449676e6fcac6b623af4092e7100Owen Anderson // {7} = 0 960ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach 961ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach const MCOperand &MO = MI.getOperand(OpIdx); 962ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach const MCOperand &MO1 = MI.getOperand(OpIdx + 1); 963ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach const MCOperand &MO2 = MI.getOperand(OpIdx + 2); 964ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach ARM_AM::ShiftOpc SOpc = ARM_AM::getSORegShOp(MO2.getImm()); 965ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach 966ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach // Encode Rm. 967ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach unsigned Binary = getARMRegisterNumbering(MO.getReg()); 968ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach 969ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach // Encode the shift opcode. 970ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach unsigned SBits = 0; 971ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach unsigned Rs = MO1.getReg(); 972ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach if (Rs) { 973ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach // Set shift operand (bit[7:4]). 974ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach // LSL - 0001 975ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach // LSR - 0011 976ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach // ASR - 0101 977ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach // ROR - 0111 978ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach switch (SOpc) { 979ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach default: llvm_unreachable("Unknown shift opc!"); 980ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach case ARM_AM::lsl: SBits = 0x1; break; 981ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach case ARM_AM::lsr: SBits = 0x3; break; 982ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach case ARM_AM::asr: SBits = 0x5; break; 983ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach case ARM_AM::ror: SBits = 0x7; break; 984ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach } 985ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach } 9860800ce71896ccd7f49b37861a8cfbc21b6b10022Bill Wendling 987ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach Binary |= SBits << 4; 988ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach 989354712c5a506449676e6fcac6b623af4092e7100Owen Anderson // Encode the shift operation Rs. 990152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson // Encode Rs bit[11:8]. 991152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson assert(ARM_AM::getSORegOffset(MO2.getImm()) == 0); 992152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson return Binary | (getARMRegisterNumbering(Rs) << ARMII::RegRsShift); 993152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson} 994152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson 995152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Andersonunsigned ARMMCCodeEmitter:: 996152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen AndersongetSORegImmOpValue(const MCInst &MI, unsigned OpIdx, 997152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson SmallVectorImpl<MCFixup> &Fixups) const { 998354712c5a506449676e6fcac6b623af4092e7100Owen Anderson // Sub-operands are [reg, imm]. The first register is Rm, the reg to be 999354712c5a506449676e6fcac6b623af4092e7100Owen Anderson // shifted. The second is the amount to shift by. 1000152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson // 1001152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson // {3-0} = Rm. 1002354712c5a506449676e6fcac6b623af4092e7100Owen Anderson // {4} = 0 1003152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson // {6-5} = type 1004354712c5a506449676e6fcac6b623af4092e7100Owen Anderson // {11-7} = imm 1005152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson 1006152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson const MCOperand &MO = MI.getOperand(OpIdx); 1007152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson const MCOperand &MO1 = MI.getOperand(OpIdx + 1); 1008152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson ARM_AM::ShiftOpc SOpc = ARM_AM::getSORegShOp(MO1.getImm()); 1009152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson 1010152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson // Encode Rm. 1011152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson unsigned Binary = getARMRegisterNumbering(MO.getReg()); 1012152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson 1013152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson // Encode the shift opcode. 1014152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson unsigned SBits = 0; 1015152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson 1016152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson // Set shift operand (bit[6:4]). 1017152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson // LSL - 000 1018152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson // LSR - 010 1019152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson // ASR - 100 1020152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson // ROR - 110 1021152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson // RRX - 110 and bit[11:8] clear. 1022152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson switch (SOpc) { 1023152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson default: llvm_unreachable("Unknown shift opc!"); 1024152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson case ARM_AM::lsl: SBits = 0x0; break; 1025152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson case ARM_AM::lsr: SBits = 0x2; break; 1026152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson case ARM_AM::asr: SBits = 0x4; break; 1027152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson case ARM_AM::ror: SBits = 0x6; break; 1028152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson case ARM_AM::rrx: 1029152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson Binary |= 0x60; 1030152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson return Binary; 1031ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach } 1032ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach 1033ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach // Encode shift_imm bit[11:7]. 1034152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson Binary |= SBits << 4; 1035152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson return Binary | ARM_AM::getSORegOffset(MO1.getImm()) << 7; 1036ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach} 1037ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach 1038152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson 1039806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbachunsigned ARMMCCodeEmitter:: 104075579f739fbc99a92a15f3ce75bbd7628ba00f8cOwen AndersongetT2AddrModeSORegOpValue(const MCInst &MI, unsigned OpNum, 104175579f739fbc99a92a15f3ce75bbd7628ba00f8cOwen Anderson SmallVectorImpl<MCFixup> &Fixups) const { 104275579f739fbc99a92a15f3ce75bbd7628ba00f8cOwen Anderson const MCOperand &MO1 = MI.getOperand(OpNum); 104375579f739fbc99a92a15f3ce75bbd7628ba00f8cOwen Anderson const MCOperand &MO2 = MI.getOperand(OpNum+1); 10447bf4c02789f97e32225fc248dff6622b994a15eeJim Grosbach const MCOperand &MO3 = MI.getOperand(OpNum+2); 10457bf4c02789f97e32225fc248dff6622b994a15eeJim Grosbach 104675579f739fbc99a92a15f3ce75bbd7628ba00f8cOwen Anderson // Encoded as [Rn, Rm, imm]. 104775579f739fbc99a92a15f3ce75bbd7628ba00f8cOwen Anderson // FIXME: Needs fixup support. 104875579f739fbc99a92a15f3ce75bbd7628ba00f8cOwen Anderson unsigned Value = getARMRegisterNumbering(MO1.getReg()); 104975579f739fbc99a92a15f3ce75bbd7628ba00f8cOwen Anderson Value <<= 4; 105075579f739fbc99a92a15f3ce75bbd7628ba00f8cOwen Anderson Value |= getARMRegisterNumbering(MO2.getReg()); 105175579f739fbc99a92a15f3ce75bbd7628ba00f8cOwen Anderson Value <<= 2; 105275579f739fbc99a92a15f3ce75bbd7628ba00f8cOwen Anderson Value |= MO3.getImm(); 10537bf4c02789f97e32225fc248dff6622b994a15eeJim Grosbach 105475579f739fbc99a92a15f3ce75bbd7628ba00f8cOwen Anderson return Value; 105575579f739fbc99a92a15f3ce75bbd7628ba00f8cOwen Anderson} 105675579f739fbc99a92a15f3ce75bbd7628ba00f8cOwen Anderson 105775579f739fbc99a92a15f3ce75bbd7628ba00f8cOwen Andersonunsigned ARMMCCodeEmitter:: 105875579f739fbc99a92a15f3ce75bbd7628ba00f8cOwen AndersongetT2AddrModeImm8OpValue(const MCInst &MI, unsigned OpNum, 105975579f739fbc99a92a15f3ce75bbd7628ba00f8cOwen Anderson SmallVectorImpl<MCFixup> &Fixups) const { 106075579f739fbc99a92a15f3ce75bbd7628ba00f8cOwen Anderson const MCOperand &MO1 = MI.getOperand(OpNum); 106175579f739fbc99a92a15f3ce75bbd7628ba00f8cOwen Anderson const MCOperand &MO2 = MI.getOperand(OpNum+1); 106275579f739fbc99a92a15f3ce75bbd7628ba00f8cOwen Anderson 106375579f739fbc99a92a15f3ce75bbd7628ba00f8cOwen Anderson // FIXME: Needs fixup support. 106475579f739fbc99a92a15f3ce75bbd7628ba00f8cOwen Anderson unsigned Value = getARMRegisterNumbering(MO1.getReg()); 10657bf4c02789f97e32225fc248dff6622b994a15eeJim Grosbach 106675579f739fbc99a92a15f3ce75bbd7628ba00f8cOwen Anderson // Even though the immediate is 8 bits long, we need 9 bits in order 106775579f739fbc99a92a15f3ce75bbd7628ba00f8cOwen Anderson // to represent the (inverse of the) sign bit. 106875579f739fbc99a92a15f3ce75bbd7628ba00f8cOwen Anderson Value <<= 9; 10696af50f7dd12d82f0a80f3158102180eee4c921aaOwen Anderson int32_t tmp = (int32_t)MO2.getImm(); 10706af50f7dd12d82f0a80f3158102180eee4c921aaOwen Anderson if (tmp < 0) 10716af50f7dd12d82f0a80f3158102180eee4c921aaOwen Anderson tmp = abs(tmp); 10726af50f7dd12d82f0a80f3158102180eee4c921aaOwen Anderson else 10736af50f7dd12d82f0a80f3158102180eee4c921aaOwen Anderson Value |= 256; // Set the ADD bit 10746af50f7dd12d82f0a80f3158102180eee4c921aaOwen Anderson Value |= tmp & 255; 10756af50f7dd12d82f0a80f3158102180eee4c921aaOwen Anderson return Value; 10766af50f7dd12d82f0a80f3158102180eee4c921aaOwen Anderson} 10776af50f7dd12d82f0a80f3158102180eee4c921aaOwen Anderson 10786af50f7dd12d82f0a80f3158102180eee4c921aaOwen Andersonunsigned ARMMCCodeEmitter:: 10796af50f7dd12d82f0a80f3158102180eee4c921aaOwen AndersongetT2AddrModeImm8OffsetOpValue(const MCInst &MI, unsigned OpNum, 10806af50f7dd12d82f0a80f3158102180eee4c921aaOwen Anderson SmallVectorImpl<MCFixup> &Fixups) const { 10816af50f7dd12d82f0a80f3158102180eee4c921aaOwen Anderson const MCOperand &MO1 = MI.getOperand(OpNum); 10826af50f7dd12d82f0a80f3158102180eee4c921aaOwen Anderson 10836af50f7dd12d82f0a80f3158102180eee4c921aaOwen Anderson // FIXME: Needs fixup support. 10846af50f7dd12d82f0a80f3158102180eee4c921aaOwen Anderson unsigned Value = 0; 10856af50f7dd12d82f0a80f3158102180eee4c921aaOwen Anderson int32_t tmp = (int32_t)MO1.getImm(); 10866af50f7dd12d82f0a80f3158102180eee4c921aaOwen Anderson if (tmp < 0) 10876af50f7dd12d82f0a80f3158102180eee4c921aaOwen Anderson tmp = abs(tmp); 10886af50f7dd12d82f0a80f3158102180eee4c921aaOwen Anderson else 10896af50f7dd12d82f0a80f3158102180eee4c921aaOwen Anderson Value |= 256; // Set the ADD bit 10906af50f7dd12d82f0a80f3158102180eee4c921aaOwen Anderson Value |= tmp & 255; 109175579f739fbc99a92a15f3ce75bbd7628ba00f8cOwen Anderson return Value; 109275579f739fbc99a92a15f3ce75bbd7628ba00f8cOwen Anderson} 109375579f739fbc99a92a15f3ce75bbd7628ba00f8cOwen Anderson 109475579f739fbc99a92a15f3ce75bbd7628ba00f8cOwen Andersonunsigned ARMMCCodeEmitter:: 10950e1bcdf4f7547bb5f47ed5ff5f2409a8f72f3609Owen AndersongetT2AddrModeImm12OffsetOpValue(const MCInst &MI, unsigned OpNum, 10960e1bcdf4f7547bb5f47ed5ff5f2409a8f72f3609Owen Anderson SmallVectorImpl<MCFixup> &Fixups) const { 10970e1bcdf4f7547bb5f47ed5ff5f2409a8f72f3609Owen Anderson const MCOperand &MO1 = MI.getOperand(OpNum); 10980e1bcdf4f7547bb5f47ed5ff5f2409a8f72f3609Owen Anderson 10990e1bcdf4f7547bb5f47ed5ff5f2409a8f72f3609Owen Anderson // FIXME: Needs fixup support. 11000e1bcdf4f7547bb5f47ed5ff5f2409a8f72f3609Owen Anderson unsigned Value = 0; 11010e1bcdf4f7547bb5f47ed5ff5f2409a8f72f3609Owen Anderson int32_t tmp = (int32_t)MO1.getImm(); 11020e1bcdf4f7547bb5f47ed5ff5f2409a8f72f3609Owen Anderson if (tmp < 0) 11030e1bcdf4f7547bb5f47ed5ff5f2409a8f72f3609Owen Anderson tmp = abs(tmp); 11040e1bcdf4f7547bb5f47ed5ff5f2409a8f72f3609Owen Anderson else 11050e1bcdf4f7547bb5f47ed5ff5f2409a8f72f3609Owen Anderson Value |= 4096; // Set the ADD bit 11060e1bcdf4f7547bb5f47ed5ff5f2409a8f72f3609Owen Anderson Value |= tmp & 4095; 11070e1bcdf4f7547bb5f47ed5ff5f2409a8f72f3609Owen Anderson return Value; 11080e1bcdf4f7547bb5f47ed5ff5f2409a8f72f3609Owen Anderson} 11090e1bcdf4f7547bb5f47ed5ff5f2409a8f72f3609Owen Anderson 11100e1bcdf4f7547bb5f47ed5ff5f2409a8f72f3609Owen Andersonunsigned ARMMCCodeEmitter:: 11115de6d841a5116152793dcab35a2e534a6a9aaa7aOwen AndersongetT2SORegOpValue(const MCInst &MI, unsigned OpIdx, 11125de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson SmallVectorImpl<MCFixup> &Fixups) const { 11135de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson // Sub-operands are [reg, imm]. The first register is Rm, the reg to be 11145de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson // shifted. The second is the amount to shift by. 11155de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson // 11165de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson // {3-0} = Rm. 11175de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson // {4} = 0 11185de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson // {6-5} = type 11195de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson // {11-7} = imm 11205de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson 11215de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson const MCOperand &MO = MI.getOperand(OpIdx); 11225de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson const MCOperand &MO1 = MI.getOperand(OpIdx + 1); 11235de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson ARM_AM::ShiftOpc SOpc = ARM_AM::getSORegShOp(MO1.getImm()); 11245de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson 11255de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson // Encode Rm. 11265de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson unsigned Binary = getARMRegisterNumbering(MO.getReg()); 11275de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson 11285de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson // Encode the shift opcode. 11295de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson unsigned SBits = 0; 11305de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson // Set shift operand (bit[6:4]). 11315de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson // LSL - 000 11325de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson // LSR - 010 11335de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson // ASR - 100 11345de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson // ROR - 110 11355de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson switch (SOpc) { 11365de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson default: llvm_unreachable("Unknown shift opc!"); 11375de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson case ARM_AM::lsl: SBits = 0x0; break; 11385de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson case ARM_AM::lsr: SBits = 0x2; break; 11395de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson case ARM_AM::asr: SBits = 0x4; break; 11405de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson case ARM_AM::ror: SBits = 0x6; break; 11415de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson } 11425de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson 11435de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson Binary |= SBits << 4; 11445de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson if (SOpc == ARM_AM::rrx) 11455de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson return Binary; 11465de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson 11475de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson // Encode shift_imm bit[11:7]. 11485de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson return Binary | ARM_AM::getSORegOffset(MO1.getImm()) << 7; 11495de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson} 11505de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson 11515de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Andersonunsigned ARMMCCodeEmitter:: 1152806e80ef42bdb416f409142a1ff1d4e8752baac8Jim GrosbachgetBitfieldInvertedMaskOpValue(const MCInst &MI, unsigned Op, 1153806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbach SmallVectorImpl<MCFixup> &Fixups) const { 11543fea19105d4929ad694f0b6272de31924c9f9f09Jim Grosbach // 10 bits. lower 5 bits are are the lsb of the mask, high five bits are the 11553fea19105d4929ad694f0b6272de31924c9f9f09Jim Grosbach // msb of the mask. 11563fea19105d4929ad694f0b6272de31924c9f9f09Jim Grosbach const MCOperand &MO = MI.getOperand(Op); 11573fea19105d4929ad694f0b6272de31924c9f9f09Jim Grosbach uint32_t v = ~MO.getImm(); 11583fea19105d4929ad694f0b6272de31924c9f9f09Jim Grosbach uint32_t lsb = CountTrailingZeros_32(v); 11593fea19105d4929ad694f0b6272de31924c9f9f09Jim Grosbach uint32_t msb = (32 - CountLeadingZeros_32 (v)) - 1; 11603fea19105d4929ad694f0b6272de31924c9f9f09Jim Grosbach assert (v != 0 && lsb < 32 && msb < 32 && "Illegal bitfield mask!"); 11613fea19105d4929ad694f0b6272de31924c9f9f09Jim Grosbach return lsb | (msb << 5); 11623fea19105d4929ad694f0b6272de31924c9f9f09Jim Grosbach} 11633fea19105d4929ad694f0b6272de31924c9f9f09Jim Grosbach 1164806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbachunsigned ARMMCCodeEmitter:: 1165a461d4222877f43588da38c466145f38dd74e229Bruno Cardoso LopesgetMsbOpValue(const MCInst &MI, unsigned Op, 1166a461d4222877f43588da38c466145f38dd74e229Bruno Cardoso Lopes SmallVectorImpl<MCFixup> &Fixups) const { 1167a461d4222877f43588da38c466145f38dd74e229Bruno Cardoso Lopes // MSB - 5 bits. 1168a461d4222877f43588da38c466145f38dd74e229Bruno Cardoso Lopes uint32_t lsb = MI.getOperand(Op-1).getImm(); 1169a461d4222877f43588da38c466145f38dd74e229Bruno Cardoso Lopes uint32_t width = MI.getOperand(Op).getImm(); 1170a461d4222877f43588da38c466145f38dd74e229Bruno Cardoso Lopes uint32_t msb = lsb+width-1; 1171a461d4222877f43588da38c466145f38dd74e229Bruno Cardoso Lopes assert (width != 0 && msb < 32 && "Illegal bit width!"); 1172a461d4222877f43588da38c466145f38dd74e229Bruno Cardoso Lopes return msb; 1173a461d4222877f43588da38c466145f38dd74e229Bruno Cardoso Lopes} 1174a461d4222877f43588da38c466145f38dd74e229Bruno Cardoso Lopes 1175a461d4222877f43588da38c466145f38dd74e229Bruno Cardoso Lopesunsigned ARMMCCodeEmitter:: 1176806e80ef42bdb416f409142a1ff1d4e8752baac8Jim GrosbachgetRegisterListOpValue(const MCInst &MI, unsigned Op, 11775e559a22c18166508a01fbd65471ec4e752726f9Bill Wendling SmallVectorImpl<MCFixup> &Fixups) const { 11786bc105a7b9282a0b5beb9d06267b31a3054fb3faBill Wendling // VLDM/VSTM: 11796bc105a7b9282a0b5beb9d06267b31a3054fb3faBill Wendling // {12-8} = Vd 11806bc105a7b9282a0b5beb9d06267b31a3054fb3faBill Wendling // {7-0} = Number of registers 11816bc105a7b9282a0b5beb9d06267b31a3054fb3faBill Wendling // 11826bc105a7b9282a0b5beb9d06267b31a3054fb3faBill Wendling // LDM/STM: 11836bc105a7b9282a0b5beb9d06267b31a3054fb3faBill Wendling // {15-0} = Bitfield of GPRs. 11846bc105a7b9282a0b5beb9d06267b31a3054fb3faBill Wendling unsigned Reg = MI.getOperand(Op).getReg(); 1185be74029f44c32efc09274a16cbff588ad10dc5eaEvan Cheng bool SPRRegs = llvm::ARMMCRegisterClasses[ARM::SPRRegClassID].contains(Reg); 1186be74029f44c32efc09274a16cbff588ad10dc5eaEvan Cheng bool DPRRegs = llvm::ARMMCRegisterClasses[ARM::DPRRegClassID].contains(Reg); 11876bc105a7b9282a0b5beb9d06267b31a3054fb3faBill Wendling 11885e559a22c18166508a01fbd65471ec4e752726f9Bill Wendling unsigned Binary = 0; 11896bc105a7b9282a0b5beb9d06267b31a3054fb3faBill Wendling 11906bc105a7b9282a0b5beb9d06267b31a3054fb3faBill Wendling if (SPRRegs || DPRRegs) { 11916bc105a7b9282a0b5beb9d06267b31a3054fb3faBill Wendling // VLDM/VSTM 11926bc105a7b9282a0b5beb9d06267b31a3054fb3faBill Wendling unsigned RegNo = getARMRegisterNumbering(Reg); 11936bc105a7b9282a0b5beb9d06267b31a3054fb3faBill Wendling unsigned NumRegs = (MI.getNumOperands() - Op) & 0xff; 11946bc105a7b9282a0b5beb9d06267b31a3054fb3faBill Wendling Binary |= (RegNo & 0x1f) << 8; 11956bc105a7b9282a0b5beb9d06267b31a3054fb3faBill Wendling if (SPRRegs) 11966bc105a7b9282a0b5beb9d06267b31a3054fb3faBill Wendling Binary |= NumRegs; 11976bc105a7b9282a0b5beb9d06267b31a3054fb3faBill Wendling else 11986bc105a7b9282a0b5beb9d06267b31a3054fb3faBill Wendling Binary |= NumRegs * 2; 11996bc105a7b9282a0b5beb9d06267b31a3054fb3faBill Wendling } else { 12006bc105a7b9282a0b5beb9d06267b31a3054fb3faBill Wendling for (unsigned I = Op, E = MI.getNumOperands(); I < E; ++I) { 12016bc105a7b9282a0b5beb9d06267b31a3054fb3faBill Wendling unsigned RegNo = getARMRegisterNumbering(MI.getOperand(I).getReg()); 12026bc105a7b9282a0b5beb9d06267b31a3054fb3faBill Wendling Binary |= 1 << RegNo; 12036bc105a7b9282a0b5beb9d06267b31a3054fb3faBill Wendling } 12045e559a22c18166508a01fbd65471ec4e752726f9Bill Wendling } 12056bc105a7b9282a0b5beb9d06267b31a3054fb3faBill Wendling 12066b5252db2db5eeeadec4602329ac56beb6dea54aJim Grosbach return Binary; 12076b5252db2db5eeeadec4602329ac56beb6dea54aJim Grosbach} 12086b5252db2db5eeeadec4602329ac56beb6dea54aJim Grosbach 12098e0c7b52877983b4838e54e233449912fc1a2325Bob Wilson/// getAddrMode6AddressOpValue - Encode an addrmode6 register number along 12108e0c7b52877983b4838e54e233449912fc1a2325Bob Wilson/// with the alignment operand. 1211806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbachunsigned ARMMCCodeEmitter:: 1212806e80ef42bdb416f409142a1ff1d4e8752baac8Jim GrosbachgetAddrMode6AddressOpValue(const MCInst &MI, unsigned Op, 1213806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbach SmallVectorImpl<MCFixup> &Fixups) const { 1214d9aa7d30aa277fba319ee4bcdb862cd79f1aabe5Owen Anderson const MCOperand &Reg = MI.getOperand(Op); 12150800ce71896ccd7f49b37861a8cfbc21b6b10022Bill Wendling const MCOperand &Imm = MI.getOperand(Op + 1); 121635b2de012d9404e3e9e4373e45f41711f752dd3aJim Grosbach 1217d9aa7d30aa277fba319ee4bcdb862cd79f1aabe5Owen Anderson unsigned RegNo = getARMRegisterNumbering(Reg.getReg()); 12180800ce71896ccd7f49b37861a8cfbc21b6b10022Bill Wendling unsigned Align = 0; 12190800ce71896ccd7f49b37861a8cfbc21b6b10022Bill Wendling 12200800ce71896ccd7f49b37861a8cfbc21b6b10022Bill Wendling switch (Imm.getImm()) { 12210800ce71896ccd7f49b37861a8cfbc21b6b10022Bill Wendling default: break; 12220800ce71896ccd7f49b37861a8cfbc21b6b10022Bill Wendling case 2: 12230800ce71896ccd7f49b37861a8cfbc21b6b10022Bill Wendling case 4: 12240800ce71896ccd7f49b37861a8cfbc21b6b10022Bill Wendling case 8: Align = 0x01; break; 12250800ce71896ccd7f49b37861a8cfbc21b6b10022Bill Wendling case 16: Align = 0x02; break; 12260800ce71896ccd7f49b37861a8cfbc21b6b10022Bill Wendling case 32: Align = 0x03; break; 1227d9aa7d30aa277fba319ee4bcdb862cd79f1aabe5Owen Anderson } 12280800ce71896ccd7f49b37861a8cfbc21b6b10022Bill Wendling 1229d9aa7d30aa277fba319ee4bcdb862cd79f1aabe5Owen Anderson return RegNo | (Align << 4); 1230d9aa7d30aa277fba319ee4bcdb862cd79f1aabe5Owen Anderson} 1231d9aa7d30aa277fba319ee4bcdb862cd79f1aabe5Owen Anderson 1232183c627d89be5d0e8f3255ab7f6d1204c2fabedfMon P Wang/// getAddrMode6OneLane32AddressOpValue - Encode an addrmode6 register number 1233183c627d89be5d0e8f3255ab7f6d1204c2fabedfMon P Wang/// along with the alignment operand for use in VST1 and VLD1 with size 32. 1234183c627d89be5d0e8f3255ab7f6d1204c2fabedfMon P Wangunsigned ARMMCCodeEmitter:: 1235183c627d89be5d0e8f3255ab7f6d1204c2fabedfMon P WanggetAddrMode6OneLane32AddressOpValue(const MCInst &MI, unsigned Op, 1236183c627d89be5d0e8f3255ab7f6d1204c2fabedfMon P Wang SmallVectorImpl<MCFixup> &Fixups) const { 1237183c627d89be5d0e8f3255ab7f6d1204c2fabedfMon P Wang const MCOperand &Reg = MI.getOperand(Op); 1238183c627d89be5d0e8f3255ab7f6d1204c2fabedfMon P Wang const MCOperand &Imm = MI.getOperand(Op + 1); 1239183c627d89be5d0e8f3255ab7f6d1204c2fabedfMon P Wang 1240183c627d89be5d0e8f3255ab7f6d1204c2fabedfMon P Wang unsigned RegNo = getARMRegisterNumbering(Reg.getReg()); 1241183c627d89be5d0e8f3255ab7f6d1204c2fabedfMon P Wang unsigned Align = 0; 1242183c627d89be5d0e8f3255ab7f6d1204c2fabedfMon P Wang 1243183c627d89be5d0e8f3255ab7f6d1204c2fabedfMon P Wang switch (Imm.getImm()) { 1244183c627d89be5d0e8f3255ab7f6d1204c2fabedfMon P Wang default: break; 1245183c627d89be5d0e8f3255ab7f6d1204c2fabedfMon P Wang case 2: 1246183c627d89be5d0e8f3255ab7f6d1204c2fabedfMon P Wang case 4: 1247183c627d89be5d0e8f3255ab7f6d1204c2fabedfMon P Wang case 8: 1248183c627d89be5d0e8f3255ab7f6d1204c2fabedfMon P Wang case 16: Align = 0x00; break; 1249183c627d89be5d0e8f3255ab7f6d1204c2fabedfMon P Wang case 32: Align = 0x03; break; 1250183c627d89be5d0e8f3255ab7f6d1204c2fabedfMon P Wang } 1251183c627d89be5d0e8f3255ab7f6d1204c2fabedfMon P Wang 1252183c627d89be5d0e8f3255ab7f6d1204c2fabedfMon P Wang return RegNo | (Align << 4); 1253183c627d89be5d0e8f3255ab7f6d1204c2fabedfMon P Wang} 1254183c627d89be5d0e8f3255ab7f6d1204c2fabedfMon P Wang 1255183c627d89be5d0e8f3255ab7f6d1204c2fabedfMon P Wang 12568e0c7b52877983b4838e54e233449912fc1a2325Bob Wilson/// getAddrMode6DupAddressOpValue - Encode an addrmode6 register number and 12578e0c7b52877983b4838e54e233449912fc1a2325Bob Wilson/// alignment operand for use in VLD-dup instructions. This is the same as 12588e0c7b52877983b4838e54e233449912fc1a2325Bob Wilson/// getAddrMode6AddressOpValue except for the alignment encoding, which is 12598e0c7b52877983b4838e54e233449912fc1a2325Bob Wilson/// different for VLD4-dup. 12608e0c7b52877983b4838e54e233449912fc1a2325Bob Wilsonunsigned ARMMCCodeEmitter:: 12618e0c7b52877983b4838e54e233449912fc1a2325Bob WilsongetAddrMode6DupAddressOpValue(const MCInst &MI, unsigned Op, 12628e0c7b52877983b4838e54e233449912fc1a2325Bob Wilson SmallVectorImpl<MCFixup> &Fixups) const { 12638e0c7b52877983b4838e54e233449912fc1a2325Bob Wilson const MCOperand &Reg = MI.getOperand(Op); 12648e0c7b52877983b4838e54e233449912fc1a2325Bob Wilson const MCOperand &Imm = MI.getOperand(Op + 1); 12658e0c7b52877983b4838e54e233449912fc1a2325Bob Wilson 12668e0c7b52877983b4838e54e233449912fc1a2325Bob Wilson unsigned RegNo = getARMRegisterNumbering(Reg.getReg()); 12678e0c7b52877983b4838e54e233449912fc1a2325Bob Wilson unsigned Align = 0; 12688e0c7b52877983b4838e54e233449912fc1a2325Bob Wilson 12698e0c7b52877983b4838e54e233449912fc1a2325Bob Wilson switch (Imm.getImm()) { 12708e0c7b52877983b4838e54e233449912fc1a2325Bob Wilson default: break; 12718e0c7b52877983b4838e54e233449912fc1a2325Bob Wilson case 2: 12728e0c7b52877983b4838e54e233449912fc1a2325Bob Wilson case 4: 12738e0c7b52877983b4838e54e233449912fc1a2325Bob Wilson case 8: Align = 0x01; break; 12748e0c7b52877983b4838e54e233449912fc1a2325Bob Wilson case 16: Align = 0x03; break; 12758e0c7b52877983b4838e54e233449912fc1a2325Bob Wilson } 12768e0c7b52877983b4838e54e233449912fc1a2325Bob Wilson 12778e0c7b52877983b4838e54e233449912fc1a2325Bob Wilson return RegNo | (Align << 4); 12788e0c7b52877983b4838e54e233449912fc1a2325Bob Wilson} 12798e0c7b52877983b4838e54e233449912fc1a2325Bob Wilson 1280806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbachunsigned ARMMCCodeEmitter:: 1281806e80ef42bdb416f409142a1ff1d4e8752baac8Jim GrosbachgetAddrMode6OffsetOpValue(const MCInst &MI, unsigned Op, 1282806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbach SmallVectorImpl<MCFixup> &Fixups) const { 12830800ce71896ccd7f49b37861a8cfbc21b6b10022Bill Wendling const MCOperand &MO = MI.getOperand(Op); 12840800ce71896ccd7f49b37861a8cfbc21b6b10022Bill Wendling if (MO.getReg() == 0) return 0x0D; 12850800ce71896ccd7f49b37861a8cfbc21b6b10022Bill Wendling return MO.getReg(); 1286a656b63ee4d5b0e3f4d26a55dd4cc69795746684Bill Wendling} 1287a656b63ee4d5b0e3f4d26a55dd4cc69795746684Bill Wendling 1288a656b63ee4d5b0e3f4d26a55dd4cc69795746684Bill Wendlingunsigned ARMMCCodeEmitter:: 12893116dce33840a115130c5f8ffcb9679d023496d6Bill WendlinggetShiftRight8Imm(const MCInst &MI, unsigned Op, 12903116dce33840a115130c5f8ffcb9679d023496d6Bill Wendling SmallVectorImpl<MCFixup> &Fixups) const { 1291a656b63ee4d5b0e3f4d26a55dd4cc69795746684Bill Wendling return 8 - MI.getOperand(Op).getImm(); 1292a656b63ee4d5b0e3f4d26a55dd4cc69795746684Bill Wendling} 1293a656b63ee4d5b0e3f4d26a55dd4cc69795746684Bill Wendling 1294a656b63ee4d5b0e3f4d26a55dd4cc69795746684Bill Wendlingunsigned ARMMCCodeEmitter:: 12953116dce33840a115130c5f8ffcb9679d023496d6Bill WendlinggetShiftRight16Imm(const MCInst &MI, unsigned Op, 12963116dce33840a115130c5f8ffcb9679d023496d6Bill Wendling SmallVectorImpl<MCFixup> &Fixups) const { 1297a656b63ee4d5b0e3f4d26a55dd4cc69795746684Bill Wendling return 16 - MI.getOperand(Op).getImm(); 1298a656b63ee4d5b0e3f4d26a55dd4cc69795746684Bill Wendling} 1299a656b63ee4d5b0e3f4d26a55dd4cc69795746684Bill Wendling 1300a656b63ee4d5b0e3f4d26a55dd4cc69795746684Bill Wendlingunsigned ARMMCCodeEmitter:: 13013116dce33840a115130c5f8ffcb9679d023496d6Bill WendlinggetShiftRight32Imm(const MCInst &MI, unsigned Op, 13023116dce33840a115130c5f8ffcb9679d023496d6Bill Wendling SmallVectorImpl<MCFixup> &Fixups) const { 1303a656b63ee4d5b0e3f4d26a55dd4cc69795746684Bill Wendling return 32 - MI.getOperand(Op).getImm(); 13043116dce33840a115130c5f8ffcb9679d023496d6Bill Wendling} 13053116dce33840a115130c5f8ffcb9679d023496d6Bill Wendling 13063116dce33840a115130c5f8ffcb9679d023496d6Bill Wendlingunsigned ARMMCCodeEmitter:: 13073116dce33840a115130c5f8ffcb9679d023496d6Bill WendlinggetShiftRight64Imm(const MCInst &MI, unsigned Op, 13083116dce33840a115130c5f8ffcb9679d023496d6Bill Wendling SmallVectorImpl<MCFixup> &Fixups) const { 13093116dce33840a115130c5f8ffcb9679d023496d6Bill Wendling return 64 - MI.getOperand(Op).getImm(); 1310cf667be17b479fe276fd606b8fd72ccfa3065bb8Owen Anderson} 1311cf667be17b479fe276fd606b8fd72ccfa3065bb8Owen Anderson 1312568eeedea72c274abbba1310c18a31eef78e14a4Jim Grosbachvoid ARMMCCodeEmitter:: 1313568eeedea72c274abbba1310c18a31eef78e14a4Jim GrosbachEncodeInstruction(const MCInst &MI, raw_ostream &OS, 1314806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbach SmallVectorImpl<MCFixup> &Fixups) const { 1315d6d4b42ba473657b6d30242962f0d0fb23fe126eJim Grosbach // Pseudo instructions don't get encoded. 131659ee62d2418df8db499eca1ae17f5900dc2dcbbaEvan Cheng const MCInstrDesc &Desc = MCII.get(MI.getOpcode()); 1317e50e6bcd901ebb1cfc42fe9ca0796ae303d7f1a1Jim Grosbach uint64_t TSFlags = Desc.TSFlags; 1318e50e6bcd901ebb1cfc42fe9ca0796ae303d7f1a1Jim Grosbach if ((TSFlags & ARMII::FormMask) == ARMII::Pseudo) 1319d6d4b42ba473657b6d30242962f0d0fb23fe126eJim Grosbach return; 132016884415db751c75f2133bd04921393c792b1158Owen Anderson 1321e50e6bcd901ebb1cfc42fe9ca0796ae303d7f1a1Jim Grosbach int Size; 132216884415db751c75f2133bd04921393c792b1158Owen Anderson if (Desc.getSize() == 2 || Desc.getSize() == 4) 132316884415db751c75f2133bd04921393c792b1158Owen Anderson Size = Desc.getSize(); 132416884415db751c75f2133bd04921393c792b1158Owen Anderson else 132516884415db751c75f2133bd04921393c792b1158Owen Anderson llvm_unreachable("Unexpected instruction size!"); 132616884415db751c75f2133bd04921393c792b1158Owen Anderson 1327d91f4e40e6312304c60c83c3dd93f769a39a9772Jim Grosbach uint32_t Binary = getBinaryCodeForInstr(MI, Fixups); 13287597212abced110723f2fee985a7d60557c092ecEvan Cheng // Thumb 32-bit wide instructions need to emit the high order halfword 13297597212abced110723f2fee985a7d60557c092ecEvan Cheng // first. 133059ee62d2418df8db499eca1ae17f5900dc2dcbbaEvan Cheng if (isThumb() && Size == 4) { 1331d91f4e40e6312304c60c83c3dd93f769a39a9772Jim Grosbach EmitConstant(Binary >> 16, 2, OS); 1332d91f4e40e6312304c60c83c3dd93f769a39a9772Jim Grosbach EmitConstant(Binary & 0xffff, 2, OS); 1333d91f4e40e6312304c60c83c3dd93f769a39a9772Jim Grosbach } else 1334d91f4e40e6312304c60c83c3dd93f769a39a9772Jim Grosbach EmitConstant(Binary, Size, OS); 13357292e0a6564bb24707eff1c49da9044dd5eaec78Bill Wendling ++MCNumEmitted; // Keep track of the # of mi's emitted. 1336568eeedea72c274abbba1310c18a31eef78e14a4Jim Grosbach} 13379af82ba42b53905f580f8c4270626946e3548654Jim Grosbach 1338806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbach#include "ARMGenMCCodeEmitter.inc" 1339