1226584Sdim//===-- ARM/ARMMCCodeEmitter.cpp - Convert ARM code to machine code -------===// 2226584Sdim// 3226584Sdim// The LLVM Compiler Infrastructure 4226584Sdim// 5226584Sdim// This file is distributed under the University of Illinois Open Source 6226584Sdim// License. See LICENSE.TXT for details. 7226584Sdim// 8226584Sdim//===----------------------------------------------------------------------===// 9226584Sdim// 10226584Sdim// This file implements the ARMMCCodeEmitter class. 11226584Sdim// 12226584Sdim//===----------------------------------------------------------------------===// 13226584Sdim 14249423Sdim#include "MCTargetDesc/ARMMCTargetDesc.h" 15226584Sdim#include "MCTargetDesc/ARMAddressingModes.h" 16226584Sdim#include "MCTargetDesc/ARMBaseInfo.h" 17226584Sdim#include "MCTargetDesc/ARMFixupKinds.h" 18226584Sdim#include "MCTargetDesc/ARMMCExpr.h" 19249423Sdim#include "llvm/ADT/APFloat.h" 20249423Sdim#include "llvm/ADT/Statistic.h" 21226584Sdim#include "llvm/MC/MCCodeEmitter.h" 22239462Sdim#include "llvm/MC/MCContext.h" 23226584Sdim#include "llvm/MC/MCExpr.h" 24226584Sdim#include "llvm/MC/MCInst.h" 25226584Sdim#include "llvm/MC/MCInstrInfo.h" 26226584Sdim#include "llvm/MC/MCRegisterInfo.h" 27226584Sdim#include "llvm/MC/MCSubtargetInfo.h" 28276479Sdim#include "llvm/Support/ErrorHandling.h" 29226584Sdim#include "llvm/Support/raw_ostream.h" 30226584Sdim 31226584Sdimusing namespace llvm; 32226584Sdim 33276479Sdim#define DEBUG_TYPE "mccodeemitter" 34276479Sdim 35226584SdimSTATISTIC(MCNumEmitted, "Number of MC instructions emitted."); 36226584SdimSTATISTIC(MCNumCPRelocations, "Number of constant pool relocations created."); 37226584Sdim 38226584Sdimnamespace { 39226584Sdimclass ARMMCCodeEmitter : public MCCodeEmitter { 40288943Sdim ARMMCCodeEmitter(const ARMMCCodeEmitter &) = delete; 41288943Sdim void operator=(const ARMMCCodeEmitter &) = delete; 42226584Sdim const MCInstrInfo &MCII; 43239462Sdim const MCContext &CTX; 44276479Sdim bool IsLittleEndian; 45226584Sdim 46226584Sdimpublic: 47276479Sdim ARMMCCodeEmitter(const MCInstrInfo &mcii, MCContext &ctx, bool IsLittle) 48276479Sdim : MCII(mcii), CTX(ctx), IsLittleEndian(IsLittle) { 49226584Sdim } 50226584Sdim 51288943Sdim ~ARMMCCodeEmitter() override {} 52226584Sdim 53276479Sdim bool isThumb(const MCSubtargetInfo &STI) const { 54288943Sdim return STI.getFeatureBits()[ARM::ModeThumb]; 55226584Sdim } 56276479Sdim bool isThumb2(const MCSubtargetInfo &STI) const { 57288943Sdim return isThumb(STI) && STI.getFeatureBits()[ARM::FeatureThumb2]; 58226584Sdim } 59276479Sdim bool isTargetMachO(const MCSubtargetInfo &STI) const { 60288943Sdim const Triple &TT = STI.getTargetTriple(); 61276479Sdim return TT.isOSBinFormatMachO(); 62226584Sdim } 63226584Sdim 64226584Sdim unsigned getMachineSoImmOpValue(unsigned SoImm) const; 65226584Sdim 66226584Sdim // getBinaryCodeForInstr - TableGen'erated function for getting the 67226584Sdim // binary encoding for an instruction. 68234353Sdim uint64_t getBinaryCodeForInstr(const MCInst &MI, 69276479Sdim SmallVectorImpl<MCFixup> &Fixups, 70276479Sdim const MCSubtargetInfo &STI) const; 71226584Sdim 72226584Sdim /// getMachineOpValue - Return binary encoding of operand. If the machine 73226584Sdim /// operand requires relocation, record the relocation and return zero. 74226584Sdim unsigned getMachineOpValue(const MCInst &MI,const MCOperand &MO, 75276479Sdim SmallVectorImpl<MCFixup> &Fixups, 76276479Sdim const MCSubtargetInfo &STI) const; 77226584Sdim 78226584Sdim /// getHiLo16ImmOpValue - Return the encoding for the hi / low 16-bit of 79226584Sdim /// the specified operand. This is used for operands with :lower16: and 80226584Sdim /// :upper16: prefixes. 81226584Sdim uint32_t getHiLo16ImmOpValue(const MCInst &MI, unsigned OpIdx, 82276479Sdim SmallVectorImpl<MCFixup> &Fixups, 83276479Sdim const MCSubtargetInfo &STI) const; 84226584Sdim 85226584Sdim bool EncodeAddrModeOpValues(const MCInst &MI, unsigned OpIdx, 86226584Sdim unsigned &Reg, unsigned &Imm, 87276479Sdim SmallVectorImpl<MCFixup> &Fixups, 88276479Sdim const MCSubtargetInfo &STI) const; 89226584Sdim 90226584Sdim /// getThumbBLTargetOpValue - Return encoding info for Thumb immediate 91226584Sdim /// BL branch target. 92226584Sdim uint32_t getThumbBLTargetOpValue(const MCInst &MI, unsigned OpIdx, 93276479Sdim SmallVectorImpl<MCFixup> &Fixups, 94276479Sdim const MCSubtargetInfo &STI) const; 95226584Sdim 96226584Sdim /// getThumbBLXTargetOpValue - Return encoding info for Thumb immediate 97226584Sdim /// BLX branch target. 98226584Sdim uint32_t getThumbBLXTargetOpValue(const MCInst &MI, unsigned OpIdx, 99276479Sdim SmallVectorImpl<MCFixup> &Fixups, 100276479Sdim const MCSubtargetInfo &STI) const; 101226584Sdim 102226584Sdim /// getThumbBRTargetOpValue - Return encoding info for Thumb branch target. 103226584Sdim uint32_t getThumbBRTargetOpValue(const MCInst &MI, unsigned OpIdx, 104276479Sdim SmallVectorImpl<MCFixup> &Fixups, 105276479Sdim const MCSubtargetInfo &STI) const; 106226584Sdim 107226584Sdim /// getThumbBCCTargetOpValue - Return encoding info for Thumb branch target. 108226584Sdim uint32_t getThumbBCCTargetOpValue(const MCInst &MI, unsigned OpIdx, 109276479Sdim SmallVectorImpl<MCFixup> &Fixups, 110276479Sdim const MCSubtargetInfo &STI) const; 111226584Sdim 112226584Sdim /// getThumbCBTargetOpValue - Return encoding info for Thumb branch target. 113226584Sdim uint32_t getThumbCBTargetOpValue(const MCInst &MI, unsigned OpIdx, 114276479Sdim SmallVectorImpl<MCFixup> &Fixups, 115276479Sdim const MCSubtargetInfo &STI) const; 116226584Sdim 117226584Sdim /// getBranchTargetOpValue - Return encoding info for 24-bit immediate 118226584Sdim /// branch target. 119226584Sdim uint32_t getBranchTargetOpValue(const MCInst &MI, unsigned OpIdx, 120276479Sdim SmallVectorImpl<MCFixup> &Fixups, 121276479Sdim const MCSubtargetInfo &STI) const; 122226584Sdim 123226584Sdim /// getUnconditionalBranchTargetOpValue - Return encoding info for 24-bit 124226584Sdim /// immediate Thumb2 direct branch target. 125226584Sdim uint32_t getUnconditionalBranchTargetOpValue(const MCInst &MI, unsigned OpIdx, 126276479Sdim SmallVectorImpl<MCFixup> &Fixups, 127276479Sdim const MCSubtargetInfo &STI) const; 128226584Sdim 129226584Sdim /// getARMBranchTargetOpValue - Return encoding info for 24-bit immediate 130226584Sdim /// branch target. 131226584Sdim uint32_t getARMBranchTargetOpValue(const MCInst &MI, unsigned OpIdx, 132276479Sdim SmallVectorImpl<MCFixup> &Fixups, 133276479Sdim const MCSubtargetInfo &STI) const; 134234353Sdim uint32_t getARMBLTargetOpValue(const MCInst &MI, unsigned OpIdx, 135276479Sdim SmallVectorImpl<MCFixup> &Fixups, 136276479Sdim const MCSubtargetInfo &STI) const; 137226584Sdim uint32_t getARMBLXTargetOpValue(const MCInst &MI, unsigned OpIdx, 138276479Sdim SmallVectorImpl<MCFixup> &Fixups, 139276479Sdim const MCSubtargetInfo &STI) const; 140226584Sdim 141226584Sdim /// getAdrLabelOpValue - Return encoding info for 12-bit immediate 142226584Sdim /// ADR label target. 143226584Sdim uint32_t getAdrLabelOpValue(const MCInst &MI, unsigned OpIdx, 144276479Sdim SmallVectorImpl<MCFixup> &Fixups, 145276479Sdim const MCSubtargetInfo &STI) const; 146226584Sdim uint32_t getThumbAdrLabelOpValue(const MCInst &MI, unsigned OpIdx, 147276479Sdim SmallVectorImpl<MCFixup> &Fixups, 148276479Sdim const MCSubtargetInfo &STI) const; 149226584Sdim uint32_t getT2AdrLabelOpValue(const MCInst &MI, unsigned OpIdx, 150276479Sdim SmallVectorImpl<MCFixup> &Fixups, 151276479Sdim const MCSubtargetInfo &STI) const; 152226584Sdim 153226584Sdim 154226584Sdim /// getAddrModeImm12OpValue - Return encoding info for 'reg +/- imm12' 155226584Sdim /// operand. 156226584Sdim uint32_t getAddrModeImm12OpValue(const MCInst &MI, unsigned OpIdx, 157276479Sdim SmallVectorImpl<MCFixup> &Fixups, 158276479Sdim const MCSubtargetInfo &STI) const; 159226584Sdim 160226584Sdim /// getThumbAddrModeRegRegOpValue - Return encoding for 'reg + reg' operand. 161226584Sdim uint32_t getThumbAddrModeRegRegOpValue(const MCInst &MI, unsigned OpIdx, 162276479Sdim SmallVectorImpl<MCFixup> &Fixups, 163276479Sdim const MCSubtargetInfo &STI) const; 164226584Sdim 165226584Sdim /// getT2AddrModeImm8s4OpValue - Return encoding info for 'reg +/- imm8<<2' 166226584Sdim /// operand. 167226584Sdim uint32_t getT2AddrModeImm8s4OpValue(const MCInst &MI, unsigned OpIdx, 168276479Sdim SmallVectorImpl<MCFixup> &Fixups, 169276479Sdim const MCSubtargetInfo &STI) const; 170226584Sdim 171226584Sdim /// getT2AddrModeImm0_1020s4OpValue - Return encoding info for 'reg + imm8<<2' 172226584Sdim /// operand. 173226584Sdim uint32_t getT2AddrModeImm0_1020s4OpValue(const MCInst &MI, unsigned OpIdx, 174276479Sdim SmallVectorImpl<MCFixup> &Fixups, 175276479Sdim const MCSubtargetInfo &STI) const; 176226584Sdim 177226584Sdim /// getT2Imm8s4OpValue - Return encoding info for '+/- imm8<<2' 178226584Sdim /// operand. 179226584Sdim uint32_t getT2Imm8s4OpValue(const MCInst &MI, unsigned OpIdx, 180276479Sdim SmallVectorImpl<MCFixup> &Fixups, 181276479Sdim const MCSubtargetInfo &STI) const; 182226584Sdim 183226584Sdim 184226584Sdim /// getLdStSORegOpValue - Return encoding info for 'reg +/- reg shop imm' 185226584Sdim /// operand as needed by load/store instructions. 186226584Sdim uint32_t getLdStSORegOpValue(const MCInst &MI, unsigned OpIdx, 187276479Sdim SmallVectorImpl<MCFixup> &Fixups, 188276479Sdim const MCSubtargetInfo &STI) const; 189226584Sdim 190226584Sdim /// getLdStmModeOpValue - Return encoding for load/store multiple mode. 191226584Sdim uint32_t getLdStmModeOpValue(const MCInst &MI, unsigned OpIdx, 192276479Sdim SmallVectorImpl<MCFixup> &Fixups, 193276479Sdim const MCSubtargetInfo &STI) const { 194226584Sdim ARM_AM::AMSubMode Mode = (ARM_AM::AMSubMode)MI.getOperand(OpIdx).getImm(); 195226584Sdim switch (Mode) { 196234353Sdim default: llvm_unreachable("Unknown addressing sub-mode!"); 197226584Sdim case ARM_AM::da: return 0; 198226584Sdim case ARM_AM::ia: return 1; 199226584Sdim case ARM_AM::db: return 2; 200226584Sdim case ARM_AM::ib: return 3; 201226584Sdim } 202226584Sdim } 203226584Sdim /// getShiftOp - Return the shift opcode (bit[6:5]) of the immediate value. 204226584Sdim /// 205226584Sdim unsigned getShiftOp(ARM_AM::ShiftOpc ShOpc) const { 206226584Sdim switch (ShOpc) { 207226584Sdim case ARM_AM::no_shift: 208226584Sdim case ARM_AM::lsl: return 0; 209226584Sdim case ARM_AM::lsr: return 1; 210226584Sdim case ARM_AM::asr: return 2; 211226584Sdim case ARM_AM::ror: 212226584Sdim case ARM_AM::rrx: return 3; 213226584Sdim } 214234353Sdim llvm_unreachable("Invalid ShiftOpc!"); 215226584Sdim } 216226584Sdim 217226584Sdim /// getAddrMode2OpValue - Return encoding for addrmode2 operands. 218226584Sdim uint32_t getAddrMode2OpValue(const MCInst &MI, unsigned OpIdx, 219276479Sdim SmallVectorImpl<MCFixup> &Fixups, 220276479Sdim const MCSubtargetInfo &STI) const; 221226584Sdim 222226584Sdim /// getAddrMode2OffsetOpValue - Return encoding for am2offset operands. 223226584Sdim uint32_t getAddrMode2OffsetOpValue(const MCInst &MI, unsigned OpIdx, 224276479Sdim SmallVectorImpl<MCFixup> &Fixups, 225276479Sdim const MCSubtargetInfo &STI) const; 226226584Sdim 227226584Sdim /// getPostIdxRegOpValue - Return encoding for postidx_reg operands. 228226584Sdim uint32_t getPostIdxRegOpValue(const MCInst &MI, unsigned OpIdx, 229276479Sdim SmallVectorImpl<MCFixup> &Fixups, 230276479Sdim const MCSubtargetInfo &STI) const; 231226584Sdim 232226584Sdim /// getAddrMode3OffsetOpValue - Return encoding for am3offset operands. 233226584Sdim uint32_t getAddrMode3OffsetOpValue(const MCInst &MI, unsigned OpIdx, 234276479Sdim SmallVectorImpl<MCFixup> &Fixups, 235276479Sdim const MCSubtargetInfo &STI) const; 236226584Sdim 237226584Sdim /// getAddrMode3OpValue - Return encoding for addrmode3 operands. 238226584Sdim uint32_t getAddrMode3OpValue(const MCInst &MI, unsigned OpIdx, 239276479Sdim SmallVectorImpl<MCFixup> &Fixups, 240276479Sdim const MCSubtargetInfo &STI) const; 241226584Sdim 242226584Sdim /// getAddrModeThumbSPOpValue - Return encoding info for 'reg +/- imm12' 243226584Sdim /// operand. 244226584Sdim uint32_t getAddrModeThumbSPOpValue(const MCInst &MI, unsigned OpIdx, 245276479Sdim SmallVectorImpl<MCFixup> &Fixups, 246276479Sdim const MCSubtargetInfo &STI) const; 247226584Sdim 248226584Sdim /// getAddrModeISOpValue - Encode the t_addrmode_is# operands. 249226584Sdim uint32_t getAddrModeISOpValue(const MCInst &MI, unsigned OpIdx, 250276479Sdim SmallVectorImpl<MCFixup> &Fixups, 251276479Sdim const MCSubtargetInfo &STI) const; 252226584Sdim 253226584Sdim /// getAddrModePCOpValue - Return encoding for t_addrmode_pc operands. 254226584Sdim uint32_t getAddrModePCOpValue(const MCInst &MI, unsigned OpIdx, 255276479Sdim SmallVectorImpl<MCFixup> &Fixups, 256276479Sdim const MCSubtargetInfo &STI) const; 257226584Sdim 258226584Sdim /// getAddrMode5OpValue - Return encoding info for 'reg +/- imm8' operand. 259226584Sdim uint32_t getAddrMode5OpValue(const MCInst &MI, unsigned OpIdx, 260276479Sdim SmallVectorImpl<MCFixup> &Fixups, 261276479Sdim const MCSubtargetInfo &STI) const; 262226584Sdim 263226584Sdim /// getCCOutOpValue - Return encoding of the 's' bit. 264226584Sdim unsigned getCCOutOpValue(const MCInst &MI, unsigned Op, 265276479Sdim SmallVectorImpl<MCFixup> &Fixups, 266276479Sdim const MCSubtargetInfo &STI) const { 267226584Sdim // The operand is either reg0 or CPSR. The 's' bit is encoded as '0' or 268226584Sdim // '1' respectively. 269226584Sdim return MI.getOperand(Op).getReg() == ARM::CPSR; 270226584Sdim } 271226584Sdim 272226584Sdim /// getSOImmOpValue - Return an encoded 12-bit shifted-immediate value. 273226584Sdim unsigned getSOImmOpValue(const MCInst &MI, unsigned Op, 274276479Sdim SmallVectorImpl<MCFixup> &Fixups, 275276479Sdim const MCSubtargetInfo &STI) const { 276276479Sdim 277276479Sdim const MCOperand &MO = MI.getOperand(Op); 278276479Sdim 279276479Sdim // We expect MO to be an immediate or an expression, 280276479Sdim // if it is an immediate - that's fine, just encode the value. 281276479Sdim // Otherwise - create a Fixup. 282276479Sdim if (MO.isExpr()) { 283276479Sdim const MCExpr *Expr = MO.getExpr(); 284276479Sdim // In instruction code this value always encoded as lowest 12 bits, 285276479Sdim // so we don't have to perform any specific adjustments. 286276479Sdim // Due to requirements of relocatable records we have to use FK_Data_4. 287276479Sdim // See ARMELFObjectWriter::ExplicitRelSym and 288276479Sdim // ARMELFObjectWriter::GetRelocTypeInner for more details. 289276479Sdim MCFixupKind Kind = MCFixupKind(FK_Data_4); 290288943Sdim Fixups.push_back(MCFixup::create(0, Expr, Kind, MI.getLoc())); 291276479Sdim return 0; 292276479Sdim } 293276479Sdim 294276479Sdim unsigned SoImm = MO.getImm(); 295226584Sdim int SoImmVal = ARM_AM::getSOImmVal(SoImm); 296226584Sdim assert(SoImmVal != -1 && "Not a valid so_imm value!"); 297226584Sdim 298226584Sdim // Encode rotate_imm. 299226584Sdim unsigned Binary = (ARM_AM::getSOImmValRot((unsigned)SoImmVal) >> 1) 300226584Sdim << ARMII::SoRotImmShift; 301226584Sdim 302226584Sdim // Encode immed_8. 303226584Sdim Binary |= ARM_AM::getSOImmValImm((unsigned)SoImmVal); 304226584Sdim return Binary; 305226584Sdim } 306226584Sdim 307280031Sdim unsigned getModImmOpValue(const MCInst &MI, unsigned Op, 308280031Sdim SmallVectorImpl<MCFixup> &Fixups, 309280031Sdim const MCSubtargetInfo &ST) const { 310280031Sdim const MCOperand &MO = MI.getOperand(Op); 311280031Sdim 312280031Sdim // Support for fixups (MCFixup) 313280031Sdim if (MO.isExpr()) { 314280031Sdim const MCExpr *Expr = MO.getExpr(); 315304690Sdim // Fixups resolve to plain values that need to be encoded. 316304690Sdim MCFixupKind Kind = MCFixupKind(ARM::fixup_arm_mod_imm); 317288943Sdim Fixups.push_back(MCFixup::create(0, Expr, Kind, MI.getLoc())); 318280031Sdim return 0; 319280031Sdim } 320280031Sdim 321280031Sdim // Immediate is already in its encoded format 322280031Sdim return MO.getImm(); 323280031Sdim } 324280031Sdim 325226584Sdim /// getT2SOImmOpValue - Return an encoded 12-bit shifted-immediate value. 326226584Sdim unsigned getT2SOImmOpValue(const MCInst &MI, unsigned Op, 327276479Sdim SmallVectorImpl<MCFixup> &Fixups, 328276479Sdim const MCSubtargetInfo &STI) const { 329226584Sdim unsigned SoImm = MI.getOperand(Op).getImm(); 330226584Sdim unsigned Encoded = ARM_AM::getT2SOImmVal(SoImm); 331226584Sdim assert(Encoded != ~0U && "Not a Thumb2 so_imm value?"); 332226584Sdim return Encoded; 333226584Sdim } 334226584Sdim 335226584Sdim unsigned getT2AddrModeSORegOpValue(const MCInst &MI, unsigned OpNum, 336276479Sdim SmallVectorImpl<MCFixup> &Fixups, 337276479Sdim const MCSubtargetInfo &STI) const; 338226584Sdim unsigned getT2AddrModeImm8OpValue(const MCInst &MI, unsigned OpNum, 339276479Sdim SmallVectorImpl<MCFixup> &Fixups, 340276479Sdim const MCSubtargetInfo &STI) const; 341226584Sdim unsigned getT2AddrModeImm8OffsetOpValue(const MCInst &MI, unsigned OpNum, 342276479Sdim SmallVectorImpl<MCFixup> &Fixups, 343276479Sdim const MCSubtargetInfo &STI) const; 344226584Sdim unsigned getT2AddrModeImm12OffsetOpValue(const MCInst &MI, unsigned OpNum, 345276479Sdim SmallVectorImpl<MCFixup> &Fixups, 346276479Sdim const MCSubtargetInfo &STI) const; 347226584Sdim 348226584Sdim /// getSORegOpValue - Return an encoded so_reg shifted register value. 349226584Sdim unsigned getSORegRegOpValue(const MCInst &MI, unsigned Op, 350276479Sdim SmallVectorImpl<MCFixup> &Fixups, 351276479Sdim const MCSubtargetInfo &STI) const; 352226584Sdim unsigned getSORegImmOpValue(const MCInst &MI, unsigned Op, 353276479Sdim SmallVectorImpl<MCFixup> &Fixups, 354276479Sdim const MCSubtargetInfo &STI) const; 355226584Sdim unsigned getT2SORegOpValue(const MCInst &MI, unsigned Op, 356276479Sdim SmallVectorImpl<MCFixup> &Fixups, 357276479Sdim const MCSubtargetInfo &STI) const; 358226584Sdim 359226584Sdim unsigned getNEONVcvtImm32OpValue(const MCInst &MI, unsigned Op, 360276479Sdim SmallVectorImpl<MCFixup> &Fixups, 361276479Sdim const MCSubtargetInfo &STI) const { 362226584Sdim return 64 - MI.getOperand(Op).getImm(); 363226584Sdim } 364226584Sdim 365226584Sdim unsigned getBitfieldInvertedMaskOpValue(const MCInst &MI, unsigned Op, 366276479Sdim SmallVectorImpl<MCFixup> &Fixups, 367276479Sdim const MCSubtargetInfo &STI) const; 368226584Sdim 369226584Sdim unsigned getRegisterListOpValue(const MCInst &MI, unsigned Op, 370276479Sdim SmallVectorImpl<MCFixup> &Fixups, 371276479Sdim const MCSubtargetInfo &STI) const; 372226584Sdim unsigned getAddrMode6AddressOpValue(const MCInst &MI, unsigned Op, 373276479Sdim SmallVectorImpl<MCFixup> &Fixups, 374276479Sdim const MCSubtargetInfo &STI) const; 375226584Sdim unsigned getAddrMode6OneLane32AddressOpValue(const MCInst &MI, unsigned Op, 376276479Sdim SmallVectorImpl<MCFixup> &Fixups, 377276479Sdim const MCSubtargetInfo &STI) const; 378226584Sdim unsigned getAddrMode6DupAddressOpValue(const MCInst &MI, unsigned Op, 379276479Sdim SmallVectorImpl<MCFixup> &Fixups, 380276479Sdim const MCSubtargetInfo &STI) const; 381226584Sdim unsigned getAddrMode6OffsetOpValue(const MCInst &MI, unsigned Op, 382276479Sdim SmallVectorImpl<MCFixup> &Fixups, 383276479Sdim const MCSubtargetInfo &STI) const; 384226584Sdim 385226584Sdim unsigned getShiftRight8Imm(const MCInst &MI, unsigned Op, 386276479Sdim SmallVectorImpl<MCFixup> &Fixups, 387276479Sdim const MCSubtargetInfo &STI) const; 388226584Sdim unsigned getShiftRight16Imm(const MCInst &MI, unsigned Op, 389276479Sdim SmallVectorImpl<MCFixup> &Fixups, 390276479Sdim const MCSubtargetInfo &STI) const; 391226584Sdim unsigned getShiftRight32Imm(const MCInst &MI, unsigned Op, 392276479Sdim SmallVectorImpl<MCFixup> &Fixups, 393276479Sdim const MCSubtargetInfo &STI) const; 394226584Sdim unsigned getShiftRight64Imm(const MCInst &MI, unsigned Op, 395276479Sdim SmallVectorImpl<MCFixup> &Fixups, 396276479Sdim const MCSubtargetInfo &STI) const; 397226584Sdim 398226584Sdim unsigned getThumbSRImmOpValue(const MCInst &MI, unsigned Op, 399276479Sdim SmallVectorImpl<MCFixup> &Fixups, 400276479Sdim const MCSubtargetInfo &STI) const; 401226584Sdim 402226584Sdim unsigned NEONThumb2DataIPostEncoder(const MCInst &MI, 403276479Sdim unsigned EncodedValue, 404276479Sdim const MCSubtargetInfo &STI) const; 405226584Sdim unsigned NEONThumb2LoadStorePostEncoder(const MCInst &MI, 406276479Sdim unsigned EncodedValue, 407276479Sdim const MCSubtargetInfo &STI) const; 408226584Sdim unsigned NEONThumb2DupPostEncoder(const MCInst &MI, 409276479Sdim unsigned EncodedValue, 410276479Sdim const MCSubtargetInfo &STI) const; 411261991Sdim unsigned NEONThumb2V8PostEncoder(const MCInst &MI, 412276479Sdim unsigned EncodedValue, 413276479Sdim const MCSubtargetInfo &STI) const; 414226584Sdim 415226584Sdim unsigned VFPThumb2PostEncoder(const MCInst &MI, 416276479Sdim unsigned EncodedValue, 417276479Sdim const MCSubtargetInfo &STI) const; 418226584Sdim 419226584Sdim void EmitByte(unsigned char C, raw_ostream &OS) const { 420226584Sdim OS << (char)C; 421226584Sdim } 422226584Sdim 423226584Sdim void EmitConstant(uint64_t Val, unsigned Size, raw_ostream &OS) const { 424226584Sdim // Output the constant in little endian byte order. 425226584Sdim for (unsigned i = 0; i != Size; ++i) { 426276479Sdim unsigned Shift = IsLittleEndian ? i * 8 : (Size - 1 - i) * 8; 427276479Sdim EmitByte((Val >> Shift) & 0xff, OS); 428226584Sdim } 429226584Sdim } 430226584Sdim 431288943Sdim void encodeInstruction(const MCInst &MI, raw_ostream &OS, 432276479Sdim SmallVectorImpl<MCFixup> &Fixups, 433276479Sdim const MCSubtargetInfo &STI) const override; 434226584Sdim}; 435226584Sdim 436226584Sdim} // end anonymous namespace 437226584Sdim 438276479SdimMCCodeEmitter *llvm::createARMLEMCCodeEmitter(const MCInstrInfo &MCII, 439276479Sdim const MCRegisterInfo &MRI, 440276479Sdim MCContext &Ctx) { 441276479Sdim return new ARMMCCodeEmitter(MCII, Ctx, true); 442226584Sdim} 443226584Sdim 444276479SdimMCCodeEmitter *llvm::createARMBEMCCodeEmitter(const MCInstrInfo &MCII, 445276479Sdim const MCRegisterInfo &MRI, 446276479Sdim MCContext &Ctx) { 447276479Sdim return new ARMMCCodeEmitter(MCII, Ctx, false); 448276479Sdim} 449276479Sdim 450226584Sdim/// NEONThumb2DataIPostEncoder - Post-process encoded NEON data-processing 451226584Sdim/// instructions, and rewrite them to their Thumb2 form if we are currently in 452226584Sdim/// Thumb2 mode. 453226584Sdimunsigned ARMMCCodeEmitter::NEONThumb2DataIPostEncoder(const MCInst &MI, 454276479Sdim unsigned EncodedValue, 455276479Sdim const MCSubtargetInfo &STI) const { 456276479Sdim if (isThumb2(STI)) { 457226584Sdim // NEON Thumb2 data-processsing encodings are very simple: bit 24 is moved 458226584Sdim // to bit 12 of the high half-word (i.e. bit 28), and bits 27-24 are 459226584Sdim // set to 1111. 460226584Sdim unsigned Bit24 = EncodedValue & 0x01000000; 461226584Sdim unsigned Bit28 = Bit24 << 4; 462226584Sdim EncodedValue &= 0xEFFFFFFF; 463226584Sdim EncodedValue |= Bit28; 464226584Sdim EncodedValue |= 0x0F000000; 465226584Sdim } 466226584Sdim 467226584Sdim return EncodedValue; 468226584Sdim} 469226584Sdim 470226584Sdim/// NEONThumb2LoadStorePostEncoder - Post-process encoded NEON load/store 471226584Sdim/// instructions, and rewrite them to their Thumb2 form if we are currently in 472226584Sdim/// Thumb2 mode. 473226584Sdimunsigned ARMMCCodeEmitter::NEONThumb2LoadStorePostEncoder(const MCInst &MI, 474276479Sdim unsigned EncodedValue, 475276479Sdim const MCSubtargetInfo &STI) const { 476276479Sdim if (isThumb2(STI)) { 477226584Sdim EncodedValue &= 0xF0FFFFFF; 478226584Sdim EncodedValue |= 0x09000000; 479226584Sdim } 480226584Sdim 481226584Sdim return EncodedValue; 482226584Sdim} 483226584Sdim 484226584Sdim/// NEONThumb2DupPostEncoder - Post-process encoded NEON vdup 485226584Sdim/// instructions, and rewrite them to their Thumb2 form if we are currently in 486226584Sdim/// Thumb2 mode. 487226584Sdimunsigned ARMMCCodeEmitter::NEONThumb2DupPostEncoder(const MCInst &MI, 488276479Sdim unsigned EncodedValue, 489276479Sdim const MCSubtargetInfo &STI) const { 490276479Sdim if (isThumb2(STI)) { 491226584Sdim EncodedValue &= 0x00FFFFFF; 492226584Sdim EncodedValue |= 0xEE000000; 493226584Sdim } 494226584Sdim 495226584Sdim return EncodedValue; 496226584Sdim} 497226584Sdim 498261991Sdim/// Post-process encoded NEON v8 instructions, and rewrite them to Thumb2 form 499261991Sdim/// if we are in Thumb2. 500261991Sdimunsigned ARMMCCodeEmitter::NEONThumb2V8PostEncoder(const MCInst &MI, 501276479Sdim unsigned EncodedValue, 502276479Sdim const MCSubtargetInfo &STI) const { 503276479Sdim if (isThumb2(STI)) { 504261991Sdim EncodedValue |= 0xC000000; // Set bits 27-26 505261991Sdim } 506261991Sdim 507261991Sdim return EncodedValue; 508261991Sdim} 509261991Sdim 510226584Sdim/// VFPThumb2PostEncoder - Post-process encoded VFP instructions and rewrite 511226584Sdim/// them to their Thumb2 form if we are currently in Thumb2 mode. 512226584Sdimunsigned ARMMCCodeEmitter:: 513276479SdimVFPThumb2PostEncoder(const MCInst &MI, unsigned EncodedValue, 514276479Sdim const MCSubtargetInfo &STI) const { 515276479Sdim if (isThumb2(STI)) { 516226584Sdim EncodedValue &= 0x0FFFFFFF; 517226584Sdim EncodedValue |= 0xE0000000; 518226584Sdim } 519226584Sdim return EncodedValue; 520226584Sdim} 521226584Sdim 522226584Sdim/// getMachineOpValue - Return binary encoding of operand. If the machine 523226584Sdim/// operand requires relocation, record the relocation and return zero. 524226584Sdimunsigned ARMMCCodeEmitter:: 525226584SdimgetMachineOpValue(const MCInst &MI, const MCOperand &MO, 526276479Sdim SmallVectorImpl<MCFixup> &Fixups, 527276479Sdim const MCSubtargetInfo &STI) const { 528226584Sdim if (MO.isReg()) { 529226584Sdim unsigned Reg = MO.getReg(); 530261991Sdim unsigned RegNo = CTX.getRegisterInfo()->getEncodingValue(Reg); 531226584Sdim 532226584Sdim // Q registers are encoded as 2x their register number. 533226584Sdim switch (Reg) { 534226584Sdim default: 535226584Sdim return RegNo; 536226584Sdim case ARM::Q0: case ARM::Q1: case ARM::Q2: case ARM::Q3: 537226584Sdim case ARM::Q4: case ARM::Q5: case ARM::Q6: case ARM::Q7: 538226584Sdim case ARM::Q8: case ARM::Q9: case ARM::Q10: case ARM::Q11: 539226584Sdim case ARM::Q12: case ARM::Q13: case ARM::Q14: case ARM::Q15: 540226584Sdim return 2 * RegNo; 541226584Sdim } 542226584Sdim } else if (MO.isImm()) { 543226584Sdim return static_cast<unsigned>(MO.getImm()); 544226584Sdim } else if (MO.isFPImm()) { 545226584Sdim return static_cast<unsigned>(APFloat(MO.getFPImm()) 546226584Sdim .bitcastToAPInt().getHiBits(32).getLimitedValue()); 547226584Sdim } 548226584Sdim 549226584Sdim llvm_unreachable("Unable to encode MCOperand!"); 550226584Sdim} 551226584Sdim 552226584Sdim/// getAddrModeImmOpValue - Return encoding info for 'reg +/- imm' operand. 553226584Sdimbool ARMMCCodeEmitter:: 554226584SdimEncodeAddrModeOpValues(const MCInst &MI, unsigned OpIdx, unsigned &Reg, 555276479Sdim unsigned &Imm, SmallVectorImpl<MCFixup> &Fixups, 556276479Sdim const MCSubtargetInfo &STI) const { 557226584Sdim const MCOperand &MO = MI.getOperand(OpIdx); 558226584Sdim const MCOperand &MO1 = MI.getOperand(OpIdx + 1); 559226584Sdim 560261991Sdim Reg = CTX.getRegisterInfo()->getEncodingValue(MO.getReg()); 561226584Sdim 562226584Sdim int32_t SImm = MO1.getImm(); 563226584Sdim bool isAdd = true; 564226584Sdim 565226584Sdim // Special value for #-0 566226584Sdim if (SImm == INT32_MIN) { 567226584Sdim SImm = 0; 568226584Sdim isAdd = false; 569226584Sdim } 570226584Sdim 571226584Sdim // Immediate is always encoded as positive. The 'U' bit controls add vs sub. 572226584Sdim if (SImm < 0) { 573226584Sdim SImm = -SImm; 574226584Sdim isAdd = false; 575226584Sdim } 576226584Sdim 577226584Sdim Imm = SImm; 578226584Sdim return isAdd; 579226584Sdim} 580226584Sdim 581226584Sdim/// getBranchTargetOpValue - Helper function to get the branch target operand, 582226584Sdim/// which is either an immediate or requires a fixup. 583226584Sdimstatic uint32_t getBranchTargetOpValue(const MCInst &MI, unsigned OpIdx, 584226584Sdim unsigned FixupKind, 585276479Sdim SmallVectorImpl<MCFixup> &Fixups, 586276479Sdim const MCSubtargetInfo &STI) { 587226584Sdim const MCOperand &MO = MI.getOperand(OpIdx); 588226584Sdim 589226584Sdim // If the destination is an immediate, we have nothing to do. 590226584Sdim if (MO.isImm()) return MO.getImm(); 591226584Sdim assert(MO.isExpr() && "Unexpected branch target type!"); 592226584Sdim const MCExpr *Expr = MO.getExpr(); 593226584Sdim MCFixupKind Kind = MCFixupKind(FixupKind); 594288943Sdim Fixups.push_back(MCFixup::create(0, Expr, Kind, MI.getLoc())); 595226584Sdim 596226584Sdim // All of the information is in the fixup. 597226584Sdim return 0; 598226584Sdim} 599226584Sdim 600226584Sdim// Thumb BL and BLX use a strange offset encoding where bits 22 and 21 are 601226584Sdim// determined by negating them and XOR'ing them with bit 23. 602226584Sdimstatic int32_t encodeThumbBLOffset(int32_t offset) { 603226584Sdim offset >>= 1; 604226584Sdim uint32_t S = (offset & 0x800000) >> 23; 605226584Sdim uint32_t J1 = (offset & 0x400000) >> 22; 606226584Sdim uint32_t J2 = (offset & 0x200000) >> 21; 607226584Sdim J1 = (~J1 & 0x1); 608226584Sdim J2 = (~J2 & 0x1); 609226584Sdim J1 ^= S; 610226584Sdim J2 ^= S; 611226584Sdim 612226584Sdim offset &= ~0x600000; 613226584Sdim offset |= J1 << 22; 614226584Sdim offset |= J2 << 21; 615226584Sdim 616226584Sdim return offset; 617226584Sdim} 618226584Sdim 619226584Sdim/// getThumbBLTargetOpValue - Return encoding info for immediate branch target. 620226584Sdimuint32_t ARMMCCodeEmitter:: 621226584SdimgetThumbBLTargetOpValue(const MCInst &MI, unsigned OpIdx, 622276479Sdim SmallVectorImpl<MCFixup> &Fixups, 623276479Sdim const MCSubtargetInfo &STI) const { 624226584Sdim const MCOperand MO = MI.getOperand(OpIdx); 625226584Sdim if (MO.isExpr()) 626226584Sdim return ::getBranchTargetOpValue(MI, OpIdx, ARM::fixup_arm_thumb_bl, 627276479Sdim Fixups, STI); 628226584Sdim return encodeThumbBLOffset(MO.getImm()); 629226584Sdim} 630226584Sdim 631226584Sdim/// getThumbBLXTargetOpValue - Return encoding info for Thumb immediate 632226584Sdim/// BLX branch target. 633226584Sdimuint32_t ARMMCCodeEmitter:: 634226584SdimgetThumbBLXTargetOpValue(const MCInst &MI, unsigned OpIdx, 635276479Sdim SmallVectorImpl<MCFixup> &Fixups, 636276479Sdim const MCSubtargetInfo &STI) const { 637226584Sdim const MCOperand MO = MI.getOperand(OpIdx); 638226584Sdim if (MO.isExpr()) 639226584Sdim return ::getBranchTargetOpValue(MI, OpIdx, ARM::fixup_arm_thumb_blx, 640276479Sdim Fixups, STI); 641226584Sdim return encodeThumbBLOffset(MO.getImm()); 642226584Sdim} 643226584Sdim 644226584Sdim/// getThumbBRTargetOpValue - Return encoding info for Thumb branch target. 645226584Sdimuint32_t ARMMCCodeEmitter:: 646226584SdimgetThumbBRTargetOpValue(const MCInst &MI, unsigned OpIdx, 647276479Sdim SmallVectorImpl<MCFixup> &Fixups, 648276479Sdim const MCSubtargetInfo &STI) const { 649226584Sdim const MCOperand MO = MI.getOperand(OpIdx); 650226584Sdim if (MO.isExpr()) 651226584Sdim return ::getBranchTargetOpValue(MI, OpIdx, ARM::fixup_arm_thumb_br, 652276479Sdim Fixups, STI); 653226584Sdim return (MO.getImm() >> 1); 654226584Sdim} 655226584Sdim 656226584Sdim/// getThumbBCCTargetOpValue - Return encoding info for Thumb branch target. 657226584Sdimuint32_t ARMMCCodeEmitter:: 658226584SdimgetThumbBCCTargetOpValue(const MCInst &MI, unsigned OpIdx, 659276479Sdim SmallVectorImpl<MCFixup> &Fixups, 660276479Sdim const MCSubtargetInfo &STI) const { 661226584Sdim const MCOperand MO = MI.getOperand(OpIdx); 662226584Sdim if (MO.isExpr()) 663226584Sdim return ::getBranchTargetOpValue(MI, OpIdx, ARM::fixup_arm_thumb_bcc, 664276479Sdim Fixups, STI); 665226584Sdim return (MO.getImm() >> 1); 666226584Sdim} 667226584Sdim 668226584Sdim/// getThumbCBTargetOpValue - Return encoding info for Thumb branch target. 669226584Sdimuint32_t ARMMCCodeEmitter:: 670226584SdimgetThumbCBTargetOpValue(const MCInst &MI, unsigned OpIdx, 671276479Sdim SmallVectorImpl<MCFixup> &Fixups, 672276479Sdim const MCSubtargetInfo &STI) const { 673226584Sdim const MCOperand MO = MI.getOperand(OpIdx); 674226584Sdim if (MO.isExpr()) 675276479Sdim return ::getBranchTargetOpValue(MI, OpIdx, ARM::fixup_arm_thumb_cb, Fixups, STI); 676226584Sdim return (MO.getImm() >> 1); 677226584Sdim} 678226584Sdim 679226584Sdim/// Return true if this branch has a non-always predication 680226584Sdimstatic bool HasConditionalBranch(const MCInst &MI) { 681226584Sdim int NumOp = MI.getNumOperands(); 682226584Sdim if (NumOp >= 2) { 683226584Sdim for (int i = 0; i < NumOp-1; ++i) { 684226584Sdim const MCOperand &MCOp1 = MI.getOperand(i); 685226584Sdim const MCOperand &MCOp2 = MI.getOperand(i + 1); 686226584Sdim if (MCOp1.isImm() && MCOp2.isReg() && 687226584Sdim (MCOp2.getReg() == 0 || MCOp2.getReg() == ARM::CPSR)) { 688226584Sdim if (ARMCC::CondCodes(MCOp1.getImm()) != ARMCC::AL) 689226584Sdim return true; 690226584Sdim } 691226584Sdim } 692226584Sdim } 693226584Sdim return false; 694226584Sdim} 695226584Sdim 696226584Sdim/// getBranchTargetOpValue - Return encoding info for 24-bit immediate branch 697226584Sdim/// target. 698226584Sdimuint32_t ARMMCCodeEmitter:: 699226584SdimgetBranchTargetOpValue(const MCInst &MI, unsigned OpIdx, 700276479Sdim SmallVectorImpl<MCFixup> &Fixups, 701276479Sdim const MCSubtargetInfo &STI) const { 702226584Sdim // FIXME: This really, really shouldn't use TargetMachine. We don't want 703226584Sdim // coupling between MC and TM anywhere we can help it. 704276479Sdim if (isThumb2(STI)) 705226584Sdim return 706276479Sdim ::getBranchTargetOpValue(MI, OpIdx, ARM::fixup_t2_condbranch, Fixups, STI); 707276479Sdim return getARMBranchTargetOpValue(MI, OpIdx, Fixups, STI); 708226584Sdim} 709226584Sdim 710226584Sdim/// getBranchTargetOpValue - Return encoding info for 24-bit immediate branch 711226584Sdim/// target. 712226584Sdimuint32_t ARMMCCodeEmitter:: 713226584SdimgetARMBranchTargetOpValue(const MCInst &MI, unsigned OpIdx, 714276479Sdim SmallVectorImpl<MCFixup> &Fixups, 715276479Sdim const MCSubtargetInfo &STI) const { 716226584Sdim const MCOperand MO = MI.getOperand(OpIdx); 717226584Sdim if (MO.isExpr()) { 718226584Sdim if (HasConditionalBranch(MI)) 719226584Sdim return ::getBranchTargetOpValue(MI, OpIdx, 720276479Sdim ARM::fixup_arm_condbranch, Fixups, STI); 721226584Sdim return ::getBranchTargetOpValue(MI, OpIdx, 722276479Sdim ARM::fixup_arm_uncondbranch, Fixups, STI); 723226584Sdim } 724226584Sdim 725226584Sdim return MO.getImm() >> 2; 726226584Sdim} 727226584Sdim 728226584Sdimuint32_t ARMMCCodeEmitter:: 729234353SdimgetARMBLTargetOpValue(const MCInst &MI, unsigned OpIdx, 730276479Sdim SmallVectorImpl<MCFixup> &Fixups, 731276479Sdim const MCSubtargetInfo &STI) const { 732226584Sdim const MCOperand MO = MI.getOperand(OpIdx); 733226584Sdim if (MO.isExpr()) { 734226584Sdim if (HasConditionalBranch(MI)) 735234353Sdim return ::getBranchTargetOpValue(MI, OpIdx, 736276479Sdim ARM::fixup_arm_condbl, Fixups, STI); 737276479Sdim return ::getBranchTargetOpValue(MI, OpIdx, ARM::fixup_arm_uncondbl, Fixups, STI); 738226584Sdim } 739226584Sdim 740234353Sdim return MO.getImm() >> 2; 741234353Sdim} 742234353Sdim 743234353Sdimuint32_t ARMMCCodeEmitter:: 744234353SdimgetARMBLXTargetOpValue(const MCInst &MI, unsigned OpIdx, 745276479Sdim SmallVectorImpl<MCFixup> &Fixups, 746276479Sdim const MCSubtargetInfo &STI) const { 747234353Sdim const MCOperand MO = MI.getOperand(OpIdx); 748234353Sdim if (MO.isExpr()) 749276479Sdim return ::getBranchTargetOpValue(MI, OpIdx, ARM::fixup_arm_blx, Fixups, STI); 750234353Sdim 751226584Sdim return MO.getImm() >> 1; 752226584Sdim} 753226584Sdim 754226584Sdim/// getUnconditionalBranchTargetOpValue - Return encoding info for 24-bit 755226584Sdim/// immediate branch target. 756226584Sdimuint32_t ARMMCCodeEmitter:: 757226584SdimgetUnconditionalBranchTargetOpValue(const MCInst &MI, unsigned OpIdx, 758276479Sdim SmallVectorImpl<MCFixup> &Fixups, 759276479Sdim const MCSubtargetInfo &STI) const { 760261991Sdim unsigned Val = 0; 761261991Sdim const MCOperand MO = MI.getOperand(OpIdx); 762261991Sdim 763261991Sdim if(MO.isExpr()) 764276479Sdim return ::getBranchTargetOpValue(MI, OpIdx, ARM::fixup_t2_uncondbranch, Fixups, STI); 765261991Sdim else 766261991Sdim Val = MO.getImm() >> 1; 767261991Sdim 768226584Sdim bool I = (Val & 0x800000); 769226584Sdim bool J1 = (Val & 0x400000); 770226584Sdim bool J2 = (Val & 0x200000); 771226584Sdim if (I ^ J1) 772226584Sdim Val &= ~0x400000; 773226584Sdim else 774226584Sdim Val |= 0x400000; 775226584Sdim 776226584Sdim if (I ^ J2) 777226584Sdim Val &= ~0x200000; 778226584Sdim else 779226584Sdim Val |= 0x200000; 780226584Sdim 781226584Sdim return Val; 782226584Sdim} 783226584Sdim 784239462Sdim/// getAdrLabelOpValue - Return encoding info for 12-bit shifted-immediate 785239462Sdim/// ADR label target. 786226584Sdimuint32_t ARMMCCodeEmitter:: 787226584SdimgetAdrLabelOpValue(const MCInst &MI, unsigned OpIdx, 788276479Sdim SmallVectorImpl<MCFixup> &Fixups, 789276479Sdim const MCSubtargetInfo &STI) const { 790226584Sdim const MCOperand MO = MI.getOperand(OpIdx); 791226584Sdim if (MO.isExpr()) 792226584Sdim return ::getBranchTargetOpValue(MI, OpIdx, ARM::fixup_arm_adr_pcrel_12, 793276479Sdim Fixups, STI); 794261991Sdim int64_t offset = MO.getImm(); 795226584Sdim uint32_t Val = 0x2000; 796239462Sdim 797249423Sdim int SoImmVal; 798239462Sdim if (offset == INT32_MIN) { 799226584Sdim Val = 0x1000; 800249423Sdim SoImmVal = 0; 801239462Sdim } else if (offset < 0) { 802239462Sdim Val = 0x1000; 803226584Sdim offset *= -1; 804249423Sdim SoImmVal = ARM_AM::getSOImmVal(offset); 805249423Sdim if(SoImmVal == -1) { 806249423Sdim Val = 0x2000; 807249423Sdim offset *= -1; 808249423Sdim SoImmVal = ARM_AM::getSOImmVal(offset); 809249423Sdim } 810249423Sdim } else { 811249423Sdim SoImmVal = ARM_AM::getSOImmVal(offset); 812249423Sdim if(SoImmVal == -1) { 813249423Sdim Val = 0x1000; 814249423Sdim offset *= -1; 815249423Sdim SoImmVal = ARM_AM::getSOImmVal(offset); 816249423Sdim } 817226584Sdim } 818239462Sdim 819239462Sdim assert(SoImmVal != -1 && "Not a valid so_imm value!"); 820239462Sdim 821239462Sdim Val |= SoImmVal; 822226584Sdim return Val; 823226584Sdim} 824226584Sdim 825239462Sdim/// getT2AdrLabelOpValue - Return encoding info for 12-bit immediate ADR label 826226584Sdim/// target. 827226584Sdimuint32_t ARMMCCodeEmitter:: 828226584SdimgetT2AdrLabelOpValue(const MCInst &MI, unsigned OpIdx, 829276479Sdim SmallVectorImpl<MCFixup> &Fixups, 830276479Sdim const MCSubtargetInfo &STI) const { 831226584Sdim const MCOperand MO = MI.getOperand(OpIdx); 832226584Sdim if (MO.isExpr()) 833226584Sdim return ::getBranchTargetOpValue(MI, OpIdx, ARM::fixup_t2_adr_pcrel_12, 834276479Sdim Fixups, STI); 835226584Sdim int32_t Val = MO.getImm(); 836239462Sdim if (Val == INT32_MIN) 837239462Sdim Val = 0x1000; 838239462Sdim else if (Val < 0) { 839226584Sdim Val *= -1; 840226584Sdim Val |= 0x1000; 841226584Sdim } 842226584Sdim return Val; 843226584Sdim} 844226584Sdim 845239462Sdim/// getThumbAdrLabelOpValue - Return encoding info for 8-bit immediate ADR label 846226584Sdim/// target. 847226584Sdimuint32_t ARMMCCodeEmitter:: 848226584SdimgetThumbAdrLabelOpValue(const MCInst &MI, unsigned OpIdx, 849276479Sdim SmallVectorImpl<MCFixup> &Fixups, 850276479Sdim const MCSubtargetInfo &STI) const { 851226584Sdim const MCOperand MO = MI.getOperand(OpIdx); 852226584Sdim if (MO.isExpr()) 853226584Sdim return ::getBranchTargetOpValue(MI, OpIdx, ARM::fixup_thumb_adr_pcrel_10, 854276479Sdim Fixups, STI); 855226584Sdim return MO.getImm(); 856226584Sdim} 857226584Sdim 858226584Sdim/// getThumbAddrModeRegRegOpValue - Return encoding info for 'reg + reg' 859226584Sdim/// operand. 860226584Sdimuint32_t ARMMCCodeEmitter:: 861226584SdimgetThumbAddrModeRegRegOpValue(const MCInst &MI, unsigned OpIdx, 862276479Sdim SmallVectorImpl<MCFixup> &, 863276479Sdim const MCSubtargetInfo &STI) const { 864226584Sdim // [Rn, Rm] 865226584Sdim // {5-3} = Rm 866226584Sdim // {2-0} = Rn 867226584Sdim const MCOperand &MO1 = MI.getOperand(OpIdx); 868226584Sdim const MCOperand &MO2 = MI.getOperand(OpIdx + 1); 869261991Sdim unsigned Rn = CTX.getRegisterInfo()->getEncodingValue(MO1.getReg()); 870261991Sdim unsigned Rm = CTX.getRegisterInfo()->getEncodingValue(MO2.getReg()); 871226584Sdim return (Rm << 3) | Rn; 872226584Sdim} 873226584Sdim 874226584Sdim/// getAddrModeImm12OpValue - Return encoding info for 'reg +/- imm12' operand. 875226584Sdimuint32_t ARMMCCodeEmitter:: 876226584SdimgetAddrModeImm12OpValue(const MCInst &MI, unsigned OpIdx, 877276479Sdim SmallVectorImpl<MCFixup> &Fixups, 878276479Sdim const MCSubtargetInfo &STI) const { 879226584Sdim // {17-13} = reg 880226584Sdim // {12} = (U)nsigned (add == '1', sub == '0') 881226584Sdim // {11-0} = imm12 882226584Sdim unsigned Reg, Imm12; 883226584Sdim bool isAdd = true; 884226584Sdim // If The first operand isn't a register, we have a label reference. 885226584Sdim const MCOperand &MO = MI.getOperand(OpIdx); 886226584Sdim if (!MO.isReg()) { 887261991Sdim Reg = CTX.getRegisterInfo()->getEncodingValue(ARM::PC); // Rn is PC. 888226584Sdim Imm12 = 0; 889226584Sdim 890226584Sdim if (MO.isExpr()) { 891226584Sdim const MCExpr *Expr = MO.getExpr(); 892261991Sdim isAdd = false ; // 'U' bit is set as part of the fixup. 893226584Sdim 894226584Sdim MCFixupKind Kind; 895276479Sdim if (isThumb2(STI)) 896226584Sdim Kind = MCFixupKind(ARM::fixup_t2_ldst_pcrel_12); 897226584Sdim else 898226584Sdim Kind = MCFixupKind(ARM::fixup_arm_ldst_pcrel_12); 899288943Sdim Fixups.push_back(MCFixup::create(0, Expr, Kind, MI.getLoc())); 900226584Sdim 901226584Sdim ++MCNumCPRelocations; 902226584Sdim } else { 903226584Sdim Reg = ARM::PC; 904226584Sdim int32_t Offset = MO.getImm(); 905261991Sdim if (Offset == INT32_MIN) { 906261991Sdim Offset = 0; 907261991Sdim isAdd = false; 908261991Sdim } else if (Offset < 0) { 909226584Sdim Offset *= -1; 910226584Sdim isAdd = false; 911226584Sdim } 912226584Sdim Imm12 = Offset; 913226584Sdim } 914226584Sdim } else 915276479Sdim isAdd = EncodeAddrModeOpValues(MI, OpIdx, Reg, Imm12, Fixups, STI); 916226584Sdim 917226584Sdim uint32_t Binary = Imm12 & 0xfff; 918226584Sdim // Immediate is always encoded as positive. The 'U' bit controls add vs sub. 919226584Sdim if (isAdd) 920226584Sdim Binary |= (1 << 12); 921226584Sdim Binary |= (Reg << 13); 922226584Sdim return Binary; 923226584Sdim} 924226584Sdim 925226584Sdim/// getT2Imm8s4OpValue - Return encoding info for 926226584Sdim/// '+/- imm8<<2' operand. 927226584Sdimuint32_t ARMMCCodeEmitter:: 928226584SdimgetT2Imm8s4OpValue(const MCInst &MI, unsigned OpIdx, 929276479Sdim SmallVectorImpl<MCFixup> &Fixups, 930276479Sdim const MCSubtargetInfo &STI) const { 931226584Sdim // FIXME: The immediate operand should have already been encoded like this 932226584Sdim // before ever getting here. The encoder method should just need to combine 933226584Sdim // the MI operands for the register and the offset into a single 934226584Sdim // representation for the complex operand in the .td file. This isn't just 935226584Sdim // style, unfortunately. As-is, we can't represent the distinct encoding 936226584Sdim // for #-0. 937226584Sdim 938226584Sdim // {8} = (U)nsigned (add == '1', sub == '0') 939226584Sdim // {7-0} = imm8 940226584Sdim int32_t Imm8 = MI.getOperand(OpIdx).getImm(); 941226584Sdim bool isAdd = Imm8 >= 0; 942226584Sdim 943226584Sdim // Immediate is always encoded as positive. The 'U' bit controls add vs sub. 944226584Sdim if (Imm8 < 0) 945243830Sdim Imm8 = -(uint32_t)Imm8; 946226584Sdim 947226584Sdim // Scaled by 4. 948226584Sdim Imm8 /= 4; 949226584Sdim 950226584Sdim uint32_t Binary = Imm8 & 0xff; 951226584Sdim // Immediate is always encoded as positive. The 'U' bit controls add vs sub. 952226584Sdim if (isAdd) 953226584Sdim Binary |= (1 << 8); 954226584Sdim return Binary; 955226584Sdim} 956226584Sdim 957226584Sdim/// getT2AddrModeImm8s4OpValue - Return encoding info for 958226584Sdim/// 'reg +/- imm8<<2' operand. 959226584Sdimuint32_t ARMMCCodeEmitter:: 960226584SdimgetT2AddrModeImm8s4OpValue(const MCInst &MI, unsigned OpIdx, 961276479Sdim SmallVectorImpl<MCFixup> &Fixups, 962276479Sdim const MCSubtargetInfo &STI) const { 963226584Sdim // {12-9} = reg 964226584Sdim // {8} = (U)nsigned (add == '1', sub == '0') 965226584Sdim // {7-0} = imm8 966226584Sdim unsigned Reg, Imm8; 967226584Sdim bool isAdd = true; 968226584Sdim // If The first operand isn't a register, we have a label reference. 969226584Sdim const MCOperand &MO = MI.getOperand(OpIdx); 970226584Sdim if (!MO.isReg()) { 971261991Sdim Reg = CTX.getRegisterInfo()->getEncodingValue(ARM::PC); // Rn is PC. 972226584Sdim Imm8 = 0; 973226584Sdim isAdd = false ; // 'U' bit is set as part of the fixup. 974226584Sdim 975226584Sdim assert(MO.isExpr() && "Unexpected machine operand type!"); 976226584Sdim const MCExpr *Expr = MO.getExpr(); 977234353Sdim MCFixupKind Kind = MCFixupKind(ARM::fixup_t2_pcrel_10); 978288943Sdim Fixups.push_back(MCFixup::create(0, Expr, Kind, MI.getLoc())); 979226584Sdim 980226584Sdim ++MCNumCPRelocations; 981226584Sdim } else 982276479Sdim isAdd = EncodeAddrModeOpValues(MI, OpIdx, Reg, Imm8, Fixups, STI); 983226584Sdim 984226584Sdim // FIXME: The immediate operand should have already been encoded like this 985226584Sdim // before ever getting here. The encoder method should just need to combine 986226584Sdim // the MI operands for the register and the offset into a single 987226584Sdim // representation for the complex operand in the .td file. This isn't just 988226584Sdim // style, unfortunately. As-is, we can't represent the distinct encoding 989226584Sdim // for #-0. 990226584Sdim uint32_t Binary = (Imm8 >> 2) & 0xff; 991226584Sdim // Immediate is always encoded as positive. The 'U' bit controls add vs sub. 992226584Sdim if (isAdd) 993226584Sdim Binary |= (1 << 8); 994226584Sdim Binary |= (Reg << 9); 995226584Sdim return Binary; 996226584Sdim} 997226584Sdim 998226584Sdim/// getT2AddrModeImm0_1020s4OpValue - Return encoding info for 999226584Sdim/// 'reg + imm8<<2' operand. 1000226584Sdimuint32_t ARMMCCodeEmitter:: 1001226584SdimgetT2AddrModeImm0_1020s4OpValue(const MCInst &MI, unsigned OpIdx, 1002276479Sdim SmallVectorImpl<MCFixup> &Fixups, 1003276479Sdim const MCSubtargetInfo &STI) const { 1004226584Sdim // {11-8} = reg 1005226584Sdim // {7-0} = imm8 1006226584Sdim const MCOperand &MO = MI.getOperand(OpIdx); 1007226584Sdim const MCOperand &MO1 = MI.getOperand(OpIdx + 1); 1008261991Sdim unsigned Reg = CTX.getRegisterInfo()->getEncodingValue(MO.getReg()); 1009226584Sdim unsigned Imm8 = MO1.getImm(); 1010226584Sdim return (Reg << 8) | Imm8; 1011226584Sdim} 1012226584Sdim 1013226584Sdimuint32_t 1014226584SdimARMMCCodeEmitter::getHiLo16ImmOpValue(const MCInst &MI, unsigned OpIdx, 1015276479Sdim SmallVectorImpl<MCFixup> &Fixups, 1016276479Sdim const MCSubtargetInfo &STI) const { 1017226584Sdim // {20-16} = imm{15-12} 1018226584Sdim // {11-0} = imm{11-0} 1019226584Sdim const MCOperand &MO = MI.getOperand(OpIdx); 1020226584Sdim if (MO.isImm()) 1021226584Sdim // Hi / lo 16 bits already extracted during earlier passes. 1022226584Sdim return static_cast<unsigned>(MO.getImm()); 1023226584Sdim 1024226584Sdim // Handle :upper16: and :lower16: assembly prefixes. 1025226584Sdim const MCExpr *E = MO.getExpr(); 1026239462Sdim MCFixupKind Kind; 1027226584Sdim if (E->getKind() == MCExpr::Target) { 1028226584Sdim const ARMMCExpr *ARM16Expr = cast<ARMMCExpr>(E); 1029226584Sdim E = ARM16Expr->getSubExpr(); 1030226584Sdim 1031276479Sdim if (const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(E)) { 1032276479Sdim const int64_t Value = MCE->getValue(); 1033276479Sdim if (Value > UINT32_MAX) 1034276479Sdim report_fatal_error("constant value truncated (limited to 32-bit)"); 1035276479Sdim 1036276479Sdim switch (ARM16Expr->getKind()) { 1037276479Sdim case ARMMCExpr::VK_ARM_HI16: 1038276479Sdim return (int32_t(Value) & 0xffff0000) >> 16; 1039276479Sdim case ARMMCExpr::VK_ARM_LO16: 1040276479Sdim return (int32_t(Value) & 0x0000ffff); 1041276479Sdim default: llvm_unreachable("Unsupported ARMFixup"); 1042276479Sdim } 1043276479Sdim } 1044276479Sdim 1045226584Sdim switch (ARM16Expr->getKind()) { 1046234353Sdim default: llvm_unreachable("Unsupported ARMFixup"); 1047226584Sdim case ARMMCExpr::VK_ARM_HI16: 1048276479Sdim Kind = MCFixupKind(isThumb2(STI) ? ARM::fixup_t2_movt_hi16 1049276479Sdim : ARM::fixup_arm_movt_hi16); 1050226584Sdim break; 1051226584Sdim case ARMMCExpr::VK_ARM_LO16: 1052276479Sdim Kind = MCFixupKind(isThumb2(STI) ? ARM::fixup_t2_movw_lo16 1053276479Sdim : ARM::fixup_arm_movw_lo16); 1054226584Sdim break; 1055226584Sdim } 1056276479Sdim 1057288943Sdim Fixups.push_back(MCFixup::create(0, E, Kind, MI.getLoc())); 1058226584Sdim return 0; 1059239462Sdim } 1060239462Sdim // If the expression doesn't have :upper16: or :lower16: on it, 1061276479Sdim // it's just a plain immediate expression, previously those evaluated to 1062239462Sdim // the lower 16 bits of the expression regardless of whether 1063276479Sdim // we have a movt or a movw, but that led to misleadingly results. 1064288943Sdim // This is disallowed in the AsmParser in validateInstruction() 1065276479Sdim // so this should never happen. 1066276479Sdim llvm_unreachable("expression without :upper16: or :lower16:"); 1067226584Sdim} 1068226584Sdim 1069226584Sdimuint32_t ARMMCCodeEmitter:: 1070226584SdimgetLdStSORegOpValue(const MCInst &MI, unsigned OpIdx, 1071276479Sdim SmallVectorImpl<MCFixup> &Fixups, 1072276479Sdim const MCSubtargetInfo &STI) const { 1073226584Sdim const MCOperand &MO = MI.getOperand(OpIdx); 1074226584Sdim const MCOperand &MO1 = MI.getOperand(OpIdx+1); 1075226584Sdim const MCOperand &MO2 = MI.getOperand(OpIdx+2); 1076261991Sdim unsigned Rn = CTX.getRegisterInfo()->getEncodingValue(MO.getReg()); 1077261991Sdim unsigned Rm = CTX.getRegisterInfo()->getEncodingValue(MO1.getReg()); 1078226584Sdim unsigned ShImm = ARM_AM::getAM2Offset(MO2.getImm()); 1079226584Sdim bool isAdd = ARM_AM::getAM2Op(MO2.getImm()) == ARM_AM::add; 1080226584Sdim ARM_AM::ShiftOpc ShOp = ARM_AM::getAM2ShiftOpc(MO2.getImm()); 1081226584Sdim unsigned SBits = getShiftOp(ShOp); 1082226584Sdim 1083243830Sdim // While "lsr #32" and "asr #32" exist, they are encoded with a 0 in the shift 1084243830Sdim // amount. However, it would be an easy mistake to make so check here. 1085243830Sdim assert((ShImm & ~0x1f) == 0 && "Out of range shift amount"); 1086243830Sdim 1087226584Sdim // {16-13} = Rn 1088226584Sdim // {12} = isAdd 1089226584Sdim // {11-0} = shifter 1090226584Sdim // {3-0} = Rm 1091226584Sdim // {4} = 0 1092226584Sdim // {6-5} = type 1093226584Sdim // {11-7} = imm 1094226584Sdim uint32_t Binary = Rm; 1095226584Sdim Binary |= Rn << 13; 1096226584Sdim Binary |= SBits << 5; 1097226584Sdim Binary |= ShImm << 7; 1098226584Sdim if (isAdd) 1099226584Sdim Binary |= 1 << 12; 1100226584Sdim return Binary; 1101226584Sdim} 1102226584Sdim 1103226584Sdimuint32_t ARMMCCodeEmitter:: 1104226584SdimgetAddrMode2OpValue(const MCInst &MI, unsigned OpIdx, 1105276479Sdim SmallVectorImpl<MCFixup> &Fixups, 1106276479Sdim const MCSubtargetInfo &STI) const { 1107226584Sdim // {17-14} Rn 1108226584Sdim // {13} 1 == imm12, 0 == Rm 1109226584Sdim // {12} isAdd 1110226584Sdim // {11-0} imm12/Rm 1111226584Sdim const MCOperand &MO = MI.getOperand(OpIdx); 1112261991Sdim unsigned Rn = CTX.getRegisterInfo()->getEncodingValue(MO.getReg()); 1113276479Sdim uint32_t Binary = getAddrMode2OffsetOpValue(MI, OpIdx + 1, Fixups, STI); 1114226584Sdim Binary |= Rn << 14; 1115226584Sdim return Binary; 1116226584Sdim} 1117226584Sdim 1118226584Sdimuint32_t ARMMCCodeEmitter:: 1119226584SdimgetAddrMode2OffsetOpValue(const MCInst &MI, unsigned OpIdx, 1120276479Sdim SmallVectorImpl<MCFixup> &Fixups, 1121276479Sdim const MCSubtargetInfo &STI) const { 1122226584Sdim // {13} 1 == imm12, 0 == Rm 1123226584Sdim // {12} isAdd 1124226584Sdim // {11-0} imm12/Rm 1125226584Sdim const MCOperand &MO = MI.getOperand(OpIdx); 1126226584Sdim const MCOperand &MO1 = MI.getOperand(OpIdx+1); 1127226584Sdim unsigned Imm = MO1.getImm(); 1128226584Sdim bool isAdd = ARM_AM::getAM2Op(Imm) == ARM_AM::add; 1129226584Sdim bool isReg = MO.getReg() != 0; 1130226584Sdim uint32_t Binary = ARM_AM::getAM2Offset(Imm); 1131226584Sdim // if reg +/- reg, Rm will be non-zero. Otherwise, we have reg +/- imm12 1132226584Sdim if (isReg) { 1133226584Sdim ARM_AM::ShiftOpc ShOp = ARM_AM::getAM2ShiftOpc(Imm); 1134226584Sdim Binary <<= 7; // Shift amount is bits [11:7] 1135226584Sdim Binary |= getShiftOp(ShOp) << 5; // Shift type is bits [6:5] 1136261991Sdim Binary |= CTX.getRegisterInfo()->getEncodingValue(MO.getReg()); // Rm is bits [3:0] 1137226584Sdim } 1138226584Sdim return Binary | (isAdd << 12) | (isReg << 13); 1139226584Sdim} 1140226584Sdim 1141226584Sdimuint32_t ARMMCCodeEmitter:: 1142226584SdimgetPostIdxRegOpValue(const MCInst &MI, unsigned OpIdx, 1143276479Sdim SmallVectorImpl<MCFixup> &Fixups, 1144276479Sdim const MCSubtargetInfo &STI) const { 1145226584Sdim // {4} isAdd 1146226584Sdim // {3-0} Rm 1147226584Sdim const MCOperand &MO = MI.getOperand(OpIdx); 1148226584Sdim const MCOperand &MO1 = MI.getOperand(OpIdx+1); 1149226584Sdim bool isAdd = MO1.getImm() != 0; 1150261991Sdim return CTX.getRegisterInfo()->getEncodingValue(MO.getReg()) | (isAdd << 4); 1151226584Sdim} 1152226584Sdim 1153226584Sdimuint32_t ARMMCCodeEmitter:: 1154226584SdimgetAddrMode3OffsetOpValue(const MCInst &MI, unsigned OpIdx, 1155276479Sdim SmallVectorImpl<MCFixup> &Fixups, 1156276479Sdim const MCSubtargetInfo &STI) const { 1157226584Sdim // {9} 1 == imm8, 0 == Rm 1158226584Sdim // {8} isAdd 1159226584Sdim // {7-4} imm7_4/zero 1160226584Sdim // {3-0} imm3_0/Rm 1161226584Sdim const MCOperand &MO = MI.getOperand(OpIdx); 1162226584Sdim const MCOperand &MO1 = MI.getOperand(OpIdx+1); 1163226584Sdim unsigned Imm = MO1.getImm(); 1164226584Sdim bool isAdd = ARM_AM::getAM3Op(Imm) == ARM_AM::add; 1165226584Sdim bool isImm = MO.getReg() == 0; 1166226584Sdim uint32_t Imm8 = ARM_AM::getAM3Offset(Imm); 1167226584Sdim // if reg +/- reg, Rm will be non-zero. Otherwise, we have reg +/- imm8 1168226584Sdim if (!isImm) 1169261991Sdim Imm8 = CTX.getRegisterInfo()->getEncodingValue(MO.getReg()); 1170226584Sdim return Imm8 | (isAdd << 8) | (isImm << 9); 1171226584Sdim} 1172226584Sdim 1173226584Sdimuint32_t ARMMCCodeEmitter:: 1174226584SdimgetAddrMode3OpValue(const MCInst &MI, unsigned OpIdx, 1175276479Sdim SmallVectorImpl<MCFixup> &Fixups, 1176276479Sdim const MCSubtargetInfo &STI) const { 1177226584Sdim // {13} 1 == imm8, 0 == Rm 1178226584Sdim // {12-9} Rn 1179226584Sdim // {8} isAdd 1180226584Sdim // {7-4} imm7_4/zero 1181226584Sdim // {3-0} imm3_0/Rm 1182226584Sdim const MCOperand &MO = MI.getOperand(OpIdx); 1183226584Sdim const MCOperand &MO1 = MI.getOperand(OpIdx+1); 1184226584Sdim const MCOperand &MO2 = MI.getOperand(OpIdx+2); 1185234353Sdim 1186234353Sdim // If The first operand isn't a register, we have a label reference. 1187234353Sdim if (!MO.isReg()) { 1188261991Sdim unsigned Rn = CTX.getRegisterInfo()->getEncodingValue(ARM::PC); // Rn is PC. 1189234353Sdim 1190234353Sdim assert(MO.isExpr() && "Unexpected machine operand type!"); 1191234353Sdim const MCExpr *Expr = MO.getExpr(); 1192234353Sdim MCFixupKind Kind = MCFixupKind(ARM::fixup_arm_pcrel_10_unscaled); 1193288943Sdim Fixups.push_back(MCFixup::create(0, Expr, Kind, MI.getLoc())); 1194234353Sdim 1195234353Sdim ++MCNumCPRelocations; 1196234353Sdim return (Rn << 9) | (1 << 13); 1197234353Sdim } 1198261991Sdim unsigned Rn = CTX.getRegisterInfo()->getEncodingValue(MO.getReg()); 1199226584Sdim unsigned Imm = MO2.getImm(); 1200226584Sdim bool isAdd = ARM_AM::getAM3Op(Imm) == ARM_AM::add; 1201226584Sdim bool isImm = MO1.getReg() == 0; 1202226584Sdim uint32_t Imm8 = ARM_AM::getAM3Offset(Imm); 1203226584Sdim // if reg +/- reg, Rm will be non-zero. Otherwise, we have reg +/- imm8 1204226584Sdim if (!isImm) 1205261991Sdim Imm8 = CTX.getRegisterInfo()->getEncodingValue(MO1.getReg()); 1206226584Sdim return (Rn << 9) | Imm8 | (isAdd << 8) | (isImm << 13); 1207226584Sdim} 1208226584Sdim 1209226584Sdim/// getAddrModeThumbSPOpValue - Encode the t_addrmode_sp operands. 1210226584Sdimuint32_t ARMMCCodeEmitter:: 1211226584SdimgetAddrModeThumbSPOpValue(const MCInst &MI, unsigned OpIdx, 1212276479Sdim SmallVectorImpl<MCFixup> &Fixups, 1213276479Sdim const MCSubtargetInfo &STI) const { 1214226584Sdim // [SP, #imm] 1215226584Sdim // {7-0} = imm8 1216226584Sdim const MCOperand &MO1 = MI.getOperand(OpIdx + 1); 1217226584Sdim assert(MI.getOperand(OpIdx).getReg() == ARM::SP && 1218226584Sdim "Unexpected base register!"); 1219226584Sdim 1220226584Sdim // The immediate is already shifted for the implicit zeroes, so no change 1221226584Sdim // here. 1222226584Sdim return MO1.getImm() & 0xff; 1223226584Sdim} 1224226584Sdim 1225226584Sdim/// getAddrModeISOpValue - Encode the t_addrmode_is# operands. 1226226584Sdimuint32_t ARMMCCodeEmitter:: 1227226584SdimgetAddrModeISOpValue(const MCInst &MI, unsigned OpIdx, 1228276479Sdim SmallVectorImpl<MCFixup> &Fixups, 1229276479Sdim const MCSubtargetInfo &STI) const { 1230226584Sdim // [Rn, #imm] 1231226584Sdim // {7-3} = imm5 1232226584Sdim // {2-0} = Rn 1233226584Sdim const MCOperand &MO = MI.getOperand(OpIdx); 1234226584Sdim const MCOperand &MO1 = MI.getOperand(OpIdx + 1); 1235261991Sdim unsigned Rn = CTX.getRegisterInfo()->getEncodingValue(MO.getReg()); 1236226584Sdim unsigned Imm5 = MO1.getImm(); 1237226584Sdim return ((Imm5 & 0x1f) << 3) | Rn; 1238226584Sdim} 1239226584Sdim 1240226584Sdim/// getAddrModePCOpValue - Return encoding for t_addrmode_pc operands. 1241226584Sdimuint32_t ARMMCCodeEmitter:: 1242226584SdimgetAddrModePCOpValue(const MCInst &MI, unsigned OpIdx, 1243276479Sdim SmallVectorImpl<MCFixup> &Fixups, 1244276479Sdim const MCSubtargetInfo &STI) const { 1245226584Sdim const MCOperand MO = MI.getOperand(OpIdx); 1246226584Sdim if (MO.isExpr()) 1247276479Sdim return ::getBranchTargetOpValue(MI, OpIdx, ARM::fixup_arm_thumb_cp, Fixups, STI); 1248226584Sdim return (MO.getImm() >> 2); 1249226584Sdim} 1250226584Sdim 1251226584Sdim/// getAddrMode5OpValue - Return encoding info for 'reg +/- imm10' operand. 1252226584Sdimuint32_t ARMMCCodeEmitter:: 1253226584SdimgetAddrMode5OpValue(const MCInst &MI, unsigned OpIdx, 1254276479Sdim SmallVectorImpl<MCFixup> &Fixups, 1255276479Sdim const MCSubtargetInfo &STI) const { 1256226584Sdim // {12-9} = reg 1257226584Sdim // {8} = (U)nsigned (add == '1', sub == '0') 1258226584Sdim // {7-0} = imm8 1259226584Sdim unsigned Reg, Imm8; 1260226584Sdim bool isAdd; 1261226584Sdim // If The first operand isn't a register, we have a label reference. 1262226584Sdim const MCOperand &MO = MI.getOperand(OpIdx); 1263226584Sdim if (!MO.isReg()) { 1264261991Sdim Reg = CTX.getRegisterInfo()->getEncodingValue(ARM::PC); // Rn is PC. 1265226584Sdim Imm8 = 0; 1266226584Sdim isAdd = false; // 'U' bit is handled as part of the fixup. 1267226584Sdim 1268226584Sdim assert(MO.isExpr() && "Unexpected machine operand type!"); 1269226584Sdim const MCExpr *Expr = MO.getExpr(); 1270226584Sdim MCFixupKind Kind; 1271276479Sdim if (isThumb2(STI)) 1272226584Sdim Kind = MCFixupKind(ARM::fixup_t2_pcrel_10); 1273226584Sdim else 1274226584Sdim Kind = MCFixupKind(ARM::fixup_arm_pcrel_10); 1275288943Sdim Fixups.push_back(MCFixup::create(0, Expr, Kind, MI.getLoc())); 1276226584Sdim 1277226584Sdim ++MCNumCPRelocations; 1278226584Sdim } else { 1279276479Sdim EncodeAddrModeOpValues(MI, OpIdx, Reg, Imm8, Fixups, STI); 1280226584Sdim isAdd = ARM_AM::getAM5Op(Imm8) == ARM_AM::add; 1281226584Sdim } 1282226584Sdim 1283226584Sdim uint32_t Binary = ARM_AM::getAM5Offset(Imm8); 1284226584Sdim // Immediate is always encoded as positive. The 'U' bit controls add vs sub. 1285226584Sdim if (isAdd) 1286226584Sdim Binary |= (1 << 8); 1287226584Sdim Binary |= (Reg << 9); 1288226584Sdim return Binary; 1289226584Sdim} 1290226584Sdim 1291226584Sdimunsigned ARMMCCodeEmitter:: 1292226584SdimgetSORegRegOpValue(const MCInst &MI, unsigned OpIdx, 1293276479Sdim SmallVectorImpl<MCFixup> &Fixups, 1294276479Sdim const MCSubtargetInfo &STI) const { 1295226584Sdim // Sub-operands are [reg, reg, imm]. The first register is Rm, the reg to be 1296226584Sdim // shifted. The second is Rs, the amount to shift by, and the third specifies 1297226584Sdim // the type of the shift. 1298226584Sdim // 1299226584Sdim // {3-0} = Rm. 1300226584Sdim // {4} = 1 1301226584Sdim // {6-5} = type 1302226584Sdim // {11-8} = Rs 1303226584Sdim // {7} = 0 1304226584Sdim 1305226584Sdim const MCOperand &MO = MI.getOperand(OpIdx); 1306226584Sdim const MCOperand &MO1 = MI.getOperand(OpIdx + 1); 1307226584Sdim const MCOperand &MO2 = MI.getOperand(OpIdx + 2); 1308226584Sdim ARM_AM::ShiftOpc SOpc = ARM_AM::getSORegShOp(MO2.getImm()); 1309226584Sdim 1310226584Sdim // Encode Rm. 1311261991Sdim unsigned Binary = CTX.getRegisterInfo()->getEncodingValue(MO.getReg()); 1312226584Sdim 1313226584Sdim // Encode the shift opcode. 1314226584Sdim unsigned SBits = 0; 1315226584Sdim unsigned Rs = MO1.getReg(); 1316226584Sdim if (Rs) { 1317226584Sdim // Set shift operand (bit[7:4]). 1318226584Sdim // LSL - 0001 1319226584Sdim // LSR - 0011 1320226584Sdim // ASR - 0101 1321226584Sdim // ROR - 0111 1322226584Sdim switch (SOpc) { 1323226584Sdim default: llvm_unreachable("Unknown shift opc!"); 1324226584Sdim case ARM_AM::lsl: SBits = 0x1; break; 1325226584Sdim case ARM_AM::lsr: SBits = 0x3; break; 1326226584Sdim case ARM_AM::asr: SBits = 0x5; break; 1327226584Sdim case ARM_AM::ror: SBits = 0x7; break; 1328226584Sdim } 1329226584Sdim } 1330226584Sdim 1331226584Sdim Binary |= SBits << 4; 1332226584Sdim 1333226584Sdim // Encode the shift operation Rs. 1334226584Sdim // Encode Rs bit[11:8]. 1335226584Sdim assert(ARM_AM::getSORegOffset(MO2.getImm()) == 0); 1336261991Sdim return Binary | (CTX.getRegisterInfo()->getEncodingValue(Rs) << ARMII::RegRsShift); 1337226584Sdim} 1338226584Sdim 1339226584Sdimunsigned ARMMCCodeEmitter:: 1340226584SdimgetSORegImmOpValue(const MCInst &MI, unsigned OpIdx, 1341276479Sdim SmallVectorImpl<MCFixup> &Fixups, 1342276479Sdim const MCSubtargetInfo &STI) const { 1343226584Sdim // Sub-operands are [reg, imm]. The first register is Rm, the reg to be 1344226584Sdim // shifted. The second is the amount to shift by. 1345226584Sdim // 1346226584Sdim // {3-0} = Rm. 1347226584Sdim // {4} = 0 1348226584Sdim // {6-5} = type 1349226584Sdim // {11-7} = imm 1350226584Sdim 1351226584Sdim const MCOperand &MO = MI.getOperand(OpIdx); 1352226584Sdim const MCOperand &MO1 = MI.getOperand(OpIdx + 1); 1353226584Sdim ARM_AM::ShiftOpc SOpc = ARM_AM::getSORegShOp(MO1.getImm()); 1354226584Sdim 1355226584Sdim // Encode Rm. 1356261991Sdim unsigned Binary = CTX.getRegisterInfo()->getEncodingValue(MO.getReg()); 1357226584Sdim 1358226584Sdim // Encode the shift opcode. 1359226584Sdim unsigned SBits = 0; 1360226584Sdim 1361226584Sdim // Set shift operand (bit[6:4]). 1362226584Sdim // LSL - 000 1363226584Sdim // LSR - 010 1364226584Sdim // ASR - 100 1365226584Sdim // ROR - 110 1366226584Sdim // RRX - 110 and bit[11:8] clear. 1367226584Sdim switch (SOpc) { 1368226584Sdim default: llvm_unreachable("Unknown shift opc!"); 1369226584Sdim case ARM_AM::lsl: SBits = 0x0; break; 1370226584Sdim case ARM_AM::lsr: SBits = 0x2; break; 1371226584Sdim case ARM_AM::asr: SBits = 0x4; break; 1372226584Sdim case ARM_AM::ror: SBits = 0x6; break; 1373226584Sdim case ARM_AM::rrx: 1374226584Sdim Binary |= 0x60; 1375226584Sdim return Binary; 1376226584Sdim } 1377226584Sdim 1378226584Sdim // Encode shift_imm bit[11:7]. 1379226584Sdim Binary |= SBits << 4; 1380226584Sdim unsigned Offset = ARM_AM::getSORegOffset(MO1.getImm()); 1381239462Sdim assert(Offset < 32 && "Offset must be in range 0-31!"); 1382226584Sdim return Binary | (Offset << 7); 1383226584Sdim} 1384226584Sdim 1385226584Sdim 1386226584Sdimunsigned ARMMCCodeEmitter:: 1387226584SdimgetT2AddrModeSORegOpValue(const MCInst &MI, unsigned OpNum, 1388276479Sdim SmallVectorImpl<MCFixup> &Fixups, 1389276479Sdim const MCSubtargetInfo &STI) const { 1390226584Sdim const MCOperand &MO1 = MI.getOperand(OpNum); 1391226584Sdim const MCOperand &MO2 = MI.getOperand(OpNum+1); 1392226584Sdim const MCOperand &MO3 = MI.getOperand(OpNum+2); 1393226584Sdim 1394226584Sdim // Encoded as [Rn, Rm, imm]. 1395226584Sdim // FIXME: Needs fixup support. 1396261991Sdim unsigned Value = CTX.getRegisterInfo()->getEncodingValue(MO1.getReg()); 1397226584Sdim Value <<= 4; 1398261991Sdim Value |= CTX.getRegisterInfo()->getEncodingValue(MO2.getReg()); 1399226584Sdim Value <<= 2; 1400226584Sdim Value |= MO3.getImm(); 1401226584Sdim 1402226584Sdim return Value; 1403226584Sdim} 1404226584Sdim 1405226584Sdimunsigned ARMMCCodeEmitter:: 1406226584SdimgetT2AddrModeImm8OpValue(const MCInst &MI, unsigned OpNum, 1407276479Sdim SmallVectorImpl<MCFixup> &Fixups, 1408276479Sdim const MCSubtargetInfo &STI) const { 1409226584Sdim const MCOperand &MO1 = MI.getOperand(OpNum); 1410226584Sdim const MCOperand &MO2 = MI.getOperand(OpNum+1); 1411226584Sdim 1412226584Sdim // FIXME: Needs fixup support. 1413261991Sdim unsigned Value = CTX.getRegisterInfo()->getEncodingValue(MO1.getReg()); 1414226584Sdim 1415226584Sdim // Even though the immediate is 8 bits long, we need 9 bits in order 1416226584Sdim // to represent the (inverse of the) sign bit. 1417226584Sdim Value <<= 9; 1418226584Sdim int32_t tmp = (int32_t)MO2.getImm(); 1419226584Sdim if (tmp < 0) 1420226584Sdim tmp = abs(tmp); 1421226584Sdim else 1422226584Sdim Value |= 256; // Set the ADD bit 1423226584Sdim Value |= tmp & 255; 1424226584Sdim return Value; 1425226584Sdim} 1426226584Sdim 1427226584Sdimunsigned ARMMCCodeEmitter:: 1428226584SdimgetT2AddrModeImm8OffsetOpValue(const MCInst &MI, unsigned OpNum, 1429276479Sdim SmallVectorImpl<MCFixup> &Fixups, 1430276479Sdim const MCSubtargetInfo &STI) const { 1431226584Sdim const MCOperand &MO1 = MI.getOperand(OpNum); 1432226584Sdim 1433226584Sdim // FIXME: Needs fixup support. 1434226584Sdim unsigned Value = 0; 1435226584Sdim int32_t tmp = (int32_t)MO1.getImm(); 1436226584Sdim if (tmp < 0) 1437226584Sdim tmp = abs(tmp); 1438226584Sdim else 1439226584Sdim Value |= 256; // Set the ADD bit 1440226584Sdim Value |= tmp & 255; 1441226584Sdim return Value; 1442226584Sdim} 1443226584Sdim 1444226584Sdimunsigned ARMMCCodeEmitter:: 1445226584SdimgetT2AddrModeImm12OffsetOpValue(const MCInst &MI, unsigned OpNum, 1446276479Sdim SmallVectorImpl<MCFixup> &Fixups, 1447276479Sdim const MCSubtargetInfo &STI) const { 1448226584Sdim const MCOperand &MO1 = MI.getOperand(OpNum); 1449226584Sdim 1450226584Sdim // FIXME: Needs fixup support. 1451226584Sdim unsigned Value = 0; 1452226584Sdim int32_t tmp = (int32_t)MO1.getImm(); 1453226584Sdim if (tmp < 0) 1454226584Sdim tmp = abs(tmp); 1455226584Sdim else 1456226584Sdim Value |= 4096; // Set the ADD bit 1457226584Sdim Value |= tmp & 4095; 1458226584Sdim return Value; 1459226584Sdim} 1460226584Sdim 1461226584Sdimunsigned ARMMCCodeEmitter:: 1462226584SdimgetT2SORegOpValue(const MCInst &MI, unsigned OpIdx, 1463276479Sdim SmallVectorImpl<MCFixup> &Fixups, 1464276479Sdim const MCSubtargetInfo &STI) const { 1465226584Sdim // Sub-operands are [reg, imm]. The first register is Rm, the reg to be 1466226584Sdim // shifted. The second is the amount to shift by. 1467226584Sdim // 1468226584Sdim // {3-0} = Rm. 1469226584Sdim // {4} = 0 1470226584Sdim // {6-5} = type 1471226584Sdim // {11-7} = imm 1472226584Sdim 1473226584Sdim const MCOperand &MO = MI.getOperand(OpIdx); 1474226584Sdim const MCOperand &MO1 = MI.getOperand(OpIdx + 1); 1475226584Sdim ARM_AM::ShiftOpc SOpc = ARM_AM::getSORegShOp(MO1.getImm()); 1476226584Sdim 1477226584Sdim // Encode Rm. 1478261991Sdim unsigned Binary = CTX.getRegisterInfo()->getEncodingValue(MO.getReg()); 1479226584Sdim 1480226584Sdim // Encode the shift opcode. 1481226584Sdim unsigned SBits = 0; 1482226584Sdim // Set shift operand (bit[6:4]). 1483226584Sdim // LSL - 000 1484226584Sdim // LSR - 010 1485226584Sdim // ASR - 100 1486226584Sdim // ROR - 110 1487226584Sdim switch (SOpc) { 1488226584Sdim default: llvm_unreachable("Unknown shift opc!"); 1489226584Sdim case ARM_AM::lsl: SBits = 0x0; break; 1490226584Sdim case ARM_AM::lsr: SBits = 0x2; break; 1491226584Sdim case ARM_AM::asr: SBits = 0x4; break; 1492226584Sdim case ARM_AM::rrx: // FALLTHROUGH 1493226584Sdim case ARM_AM::ror: SBits = 0x6; break; 1494226584Sdim } 1495226584Sdim 1496226584Sdim Binary |= SBits << 4; 1497226584Sdim if (SOpc == ARM_AM::rrx) 1498226584Sdim return Binary; 1499226584Sdim 1500226584Sdim // Encode shift_imm bit[11:7]. 1501226584Sdim return Binary | ARM_AM::getSORegOffset(MO1.getImm()) << 7; 1502226584Sdim} 1503226584Sdim 1504226584Sdimunsigned ARMMCCodeEmitter:: 1505226584SdimgetBitfieldInvertedMaskOpValue(const MCInst &MI, unsigned Op, 1506276479Sdim SmallVectorImpl<MCFixup> &Fixups, 1507276479Sdim const MCSubtargetInfo &STI) const { 1508226584Sdim // 10 bits. lower 5 bits are are the lsb of the mask, high five bits are the 1509226584Sdim // msb of the mask. 1510226584Sdim const MCOperand &MO = MI.getOperand(Op); 1511226584Sdim uint32_t v = ~MO.getImm(); 1512261991Sdim uint32_t lsb = countTrailingZeros(v); 1513261991Sdim uint32_t msb = (32 - countLeadingZeros (v)) - 1; 1514226584Sdim assert (v != 0 && lsb < 32 && msb < 32 && "Illegal bitfield mask!"); 1515226584Sdim return lsb | (msb << 5); 1516226584Sdim} 1517226584Sdim 1518226584Sdimunsigned ARMMCCodeEmitter:: 1519226584SdimgetRegisterListOpValue(const MCInst &MI, unsigned Op, 1520276479Sdim SmallVectorImpl<MCFixup> &Fixups, 1521276479Sdim const MCSubtargetInfo &STI) const { 1522226584Sdim // VLDM/VSTM: 1523226584Sdim // {12-8} = Vd 1524226584Sdim // {7-0} = Number of registers 1525226584Sdim // 1526226584Sdim // LDM/STM: 1527226584Sdim // {15-0} = Bitfield of GPRs. 1528226584Sdim unsigned Reg = MI.getOperand(Op).getReg(); 1529234353Sdim bool SPRRegs = ARMMCRegisterClasses[ARM::SPRRegClassID].contains(Reg); 1530234353Sdim bool DPRRegs = ARMMCRegisterClasses[ARM::DPRRegClassID].contains(Reg); 1531226584Sdim 1532226584Sdim unsigned Binary = 0; 1533226584Sdim 1534226584Sdim if (SPRRegs || DPRRegs) { 1535226584Sdim // VLDM/VSTM 1536261991Sdim unsigned RegNo = CTX.getRegisterInfo()->getEncodingValue(Reg); 1537226584Sdim unsigned NumRegs = (MI.getNumOperands() - Op) & 0xff; 1538226584Sdim Binary |= (RegNo & 0x1f) << 8; 1539226584Sdim if (SPRRegs) 1540226584Sdim Binary |= NumRegs; 1541226584Sdim else 1542226584Sdim Binary |= NumRegs * 2; 1543226584Sdim } else { 1544226584Sdim for (unsigned I = Op, E = MI.getNumOperands(); I < E; ++I) { 1545261991Sdim unsigned RegNo = CTX.getRegisterInfo()->getEncodingValue(MI.getOperand(I).getReg()); 1546226584Sdim Binary |= 1 << RegNo; 1547226584Sdim } 1548226584Sdim } 1549226584Sdim 1550226584Sdim return Binary; 1551226584Sdim} 1552226584Sdim 1553226584Sdim/// getAddrMode6AddressOpValue - Encode an addrmode6 register number along 1554226584Sdim/// with the alignment operand. 1555226584Sdimunsigned ARMMCCodeEmitter:: 1556226584SdimgetAddrMode6AddressOpValue(const MCInst &MI, unsigned Op, 1557276479Sdim SmallVectorImpl<MCFixup> &Fixups, 1558276479Sdim const MCSubtargetInfo &STI) const { 1559226584Sdim const MCOperand &Reg = MI.getOperand(Op); 1560226584Sdim const MCOperand &Imm = MI.getOperand(Op + 1); 1561226584Sdim 1562261991Sdim unsigned RegNo = CTX.getRegisterInfo()->getEncodingValue(Reg.getReg()); 1563226584Sdim unsigned Align = 0; 1564226584Sdim 1565226584Sdim switch (Imm.getImm()) { 1566226584Sdim default: break; 1567226584Sdim case 2: 1568226584Sdim case 4: 1569226584Sdim case 8: Align = 0x01; break; 1570226584Sdim case 16: Align = 0x02; break; 1571226584Sdim case 32: Align = 0x03; break; 1572226584Sdim } 1573226584Sdim 1574226584Sdim return RegNo | (Align << 4); 1575226584Sdim} 1576226584Sdim 1577226584Sdim/// getAddrMode6OneLane32AddressOpValue - Encode an addrmode6 register number 1578226584Sdim/// along with the alignment operand for use in VST1 and VLD1 with size 32. 1579226584Sdimunsigned ARMMCCodeEmitter:: 1580226584SdimgetAddrMode6OneLane32AddressOpValue(const MCInst &MI, unsigned Op, 1581276479Sdim SmallVectorImpl<MCFixup> &Fixups, 1582276479Sdim const MCSubtargetInfo &STI) const { 1583226584Sdim const MCOperand &Reg = MI.getOperand(Op); 1584226584Sdim const MCOperand &Imm = MI.getOperand(Op + 1); 1585226584Sdim 1586261991Sdim unsigned RegNo = CTX.getRegisterInfo()->getEncodingValue(Reg.getReg()); 1587226584Sdim unsigned Align = 0; 1588226584Sdim 1589226584Sdim switch (Imm.getImm()) { 1590226584Sdim default: break; 1591226584Sdim case 8: 1592234353Sdim case 16: 1593234353Sdim case 32: // Default '0' value for invalid alignments of 8, 16, 32 bytes. 1594234353Sdim case 2: Align = 0x00; break; 1595234353Sdim case 4: Align = 0x03; break; 1596226584Sdim } 1597226584Sdim 1598226584Sdim return RegNo | (Align << 4); 1599226584Sdim} 1600226584Sdim 1601226584Sdim 1602226584Sdim/// getAddrMode6DupAddressOpValue - Encode an addrmode6 register number and 1603226584Sdim/// alignment operand for use in VLD-dup instructions. This is the same as 1604226584Sdim/// getAddrMode6AddressOpValue except for the alignment encoding, which is 1605226584Sdim/// different for VLD4-dup. 1606226584Sdimunsigned ARMMCCodeEmitter:: 1607226584SdimgetAddrMode6DupAddressOpValue(const MCInst &MI, unsigned Op, 1608276479Sdim SmallVectorImpl<MCFixup> &Fixups, 1609276479Sdim const MCSubtargetInfo &STI) const { 1610226584Sdim const MCOperand &Reg = MI.getOperand(Op); 1611226584Sdim const MCOperand &Imm = MI.getOperand(Op + 1); 1612226584Sdim 1613261991Sdim unsigned RegNo = CTX.getRegisterInfo()->getEncodingValue(Reg.getReg()); 1614226584Sdim unsigned Align = 0; 1615226584Sdim 1616226584Sdim switch (Imm.getImm()) { 1617226584Sdim default: break; 1618226584Sdim case 2: 1619226584Sdim case 4: 1620226584Sdim case 8: Align = 0x01; break; 1621226584Sdim case 16: Align = 0x03; break; 1622226584Sdim } 1623226584Sdim 1624226584Sdim return RegNo | (Align << 4); 1625226584Sdim} 1626226584Sdim 1627226584Sdimunsigned ARMMCCodeEmitter:: 1628226584SdimgetAddrMode6OffsetOpValue(const MCInst &MI, unsigned Op, 1629276479Sdim SmallVectorImpl<MCFixup> &Fixups, 1630276479Sdim const MCSubtargetInfo &STI) const { 1631226584Sdim const MCOperand &MO = MI.getOperand(Op); 1632226584Sdim if (MO.getReg() == 0) return 0x0D; 1633261991Sdim return CTX.getRegisterInfo()->getEncodingValue(MO.getReg()); 1634226584Sdim} 1635226584Sdim 1636226584Sdimunsigned ARMMCCodeEmitter:: 1637226584SdimgetShiftRight8Imm(const MCInst &MI, unsigned Op, 1638276479Sdim SmallVectorImpl<MCFixup> &Fixups, 1639276479Sdim const MCSubtargetInfo &STI) const { 1640226584Sdim return 8 - MI.getOperand(Op).getImm(); 1641226584Sdim} 1642226584Sdim 1643226584Sdimunsigned ARMMCCodeEmitter:: 1644226584SdimgetShiftRight16Imm(const MCInst &MI, unsigned Op, 1645276479Sdim SmallVectorImpl<MCFixup> &Fixups, 1646276479Sdim const MCSubtargetInfo &STI) const { 1647226584Sdim return 16 - MI.getOperand(Op).getImm(); 1648226584Sdim} 1649226584Sdim 1650226584Sdimunsigned ARMMCCodeEmitter:: 1651226584SdimgetShiftRight32Imm(const MCInst &MI, unsigned Op, 1652276479Sdim SmallVectorImpl<MCFixup> &Fixups, 1653276479Sdim const MCSubtargetInfo &STI) const { 1654226584Sdim return 32 - MI.getOperand(Op).getImm(); 1655226584Sdim} 1656226584Sdim 1657226584Sdimunsigned ARMMCCodeEmitter:: 1658226584SdimgetShiftRight64Imm(const MCInst &MI, unsigned Op, 1659276479Sdim SmallVectorImpl<MCFixup> &Fixups, 1660276479Sdim const MCSubtargetInfo &STI) const { 1661226584Sdim return 64 - MI.getOperand(Op).getImm(); 1662226584Sdim} 1663226584Sdim 1664226584Sdimvoid ARMMCCodeEmitter:: 1665288943SdimencodeInstruction(const MCInst &MI, raw_ostream &OS, 1666276479Sdim SmallVectorImpl<MCFixup> &Fixups, 1667276479Sdim const MCSubtargetInfo &STI) const { 1668226584Sdim // Pseudo instructions don't get encoded. 1669226584Sdim const MCInstrDesc &Desc = MCII.get(MI.getOpcode()); 1670226584Sdim uint64_t TSFlags = Desc.TSFlags; 1671226584Sdim if ((TSFlags & ARMII::FormMask) == ARMII::Pseudo) 1672226584Sdim return; 1673226584Sdim 1674226584Sdim int Size; 1675226584Sdim if (Desc.getSize() == 2 || Desc.getSize() == 4) 1676226584Sdim Size = Desc.getSize(); 1677226584Sdim else 1678226584Sdim llvm_unreachable("Unexpected instruction size!"); 1679226584Sdim 1680276479Sdim uint32_t Binary = getBinaryCodeForInstr(MI, Fixups, STI); 1681226584Sdim // Thumb 32-bit wide instructions need to emit the high order halfword 1682226584Sdim // first. 1683276479Sdim if (isThumb(STI) && Size == 4) { 1684226584Sdim EmitConstant(Binary >> 16, 2, OS); 1685226584Sdim EmitConstant(Binary & 0xffff, 2, OS); 1686226584Sdim } else 1687226584Sdim EmitConstant(Binary, Size, OS); 1688226584Sdim ++MCNumEmitted; // Keep track of the # of mi's emitted. 1689226584Sdim} 1690226584Sdim 1691226584Sdim#include "ARMGenMCCodeEmitter.inc" 1692