1235633Sdim//===-- X86MCCodeEmitter.cpp - Convert X86 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 X86MCCodeEmitter class. 11226584Sdim// 12226584Sdim//===----------------------------------------------------------------------===// 13226584Sdim 14226584Sdim#define DEBUG_TYPE "mccodeemitter" 15226584Sdim#include "MCTargetDesc/X86MCTargetDesc.h" 16226584Sdim#include "MCTargetDesc/X86BaseInfo.h" 17226584Sdim#include "MCTargetDesc/X86FixupKinds.h" 18226584Sdim#include "llvm/MC/MCCodeEmitter.h" 19245431Sdim#include "llvm/MC/MCContext.h" 20226584Sdim#include "llvm/MC/MCExpr.h" 21226584Sdim#include "llvm/MC/MCInst.h" 22226584Sdim#include "llvm/MC/MCInstrInfo.h" 23226584Sdim#include "llvm/MC/MCRegisterInfo.h" 24226584Sdim#include "llvm/MC/MCSubtargetInfo.h" 25226584Sdim#include "llvm/MC/MCSymbol.h" 26226584Sdim#include "llvm/Support/raw_ostream.h" 27226584Sdim 28226584Sdimusing namespace llvm; 29226584Sdim 30226584Sdimnamespace { 31226584Sdimclass X86MCCodeEmitter : public MCCodeEmitter { 32245431Sdim X86MCCodeEmitter(const X86MCCodeEmitter &) LLVM_DELETED_FUNCTION; 33245431Sdim void operator=(const X86MCCodeEmitter &) LLVM_DELETED_FUNCTION; 34226584Sdim const MCInstrInfo &MCII; 35226584Sdim const MCSubtargetInfo &STI; 36226584Sdim MCContext &Ctx; 37226584Sdimpublic: 38226584Sdim X86MCCodeEmitter(const MCInstrInfo &mcii, const MCSubtargetInfo &sti, 39226584Sdim MCContext &ctx) 40226584Sdim : MCII(mcii), STI(sti), Ctx(ctx) { 41226584Sdim } 42226584Sdim 43226584Sdim ~X86MCCodeEmitter() {} 44226584Sdim 45226584Sdim bool is64BitMode() const { 46226584Sdim // FIXME: Can tablegen auto-generate this? 47226584Sdim return (STI.getFeatureBits() & X86::Mode64Bit) != 0; 48226584Sdim } 49226584Sdim 50235633Sdim bool is32BitMode() const { 51235633Sdim // FIXME: Can tablegen auto-generate this? 52235633Sdim return (STI.getFeatureBits() & X86::Mode64Bit) == 0; 53235633Sdim } 54235633Sdim 55245431Sdim unsigned GetX86RegNum(const MCOperand &MO) const { 56263509Sdim return Ctx.getRegisterInfo()->getEncodingValue(MO.getReg()) & 0x7; 57226584Sdim } 58226584Sdim 59226584Sdim // On regular x86, both XMM0-XMM7 and XMM8-XMM15 are encoded in the range 60226584Sdim // 0-7 and the difference between the 2 groups is given by the REX prefix. 61226584Sdim // In the VEX prefix, registers are seen sequencially from 0-15 and encoded 62226584Sdim // in 1's complement form, example: 63226584Sdim // 64226584Sdim // ModRM field => XMM9 => 1 65226584Sdim // VEX.VVVV => XMM9 => ~9 66226584Sdim // 67226584Sdim // See table 4-35 of Intel AVX Programming Reference for details. 68245431Sdim unsigned char getVEXRegisterEncoding(const MCInst &MI, 69245431Sdim unsigned OpNum) const { 70226584Sdim unsigned SrcReg = MI.getOperand(OpNum).getReg(); 71226584Sdim unsigned SrcRegNum = GetX86RegNum(MI.getOperand(OpNum)); 72235633Sdim if (X86II::isX86_64ExtendedReg(SrcReg)) 73235633Sdim SrcRegNum |= 8; 74226584Sdim 75226584Sdim // The registers represented through VEX_VVVV should 76226584Sdim // be encoded in 1's complement form. 77226584Sdim return (~SrcRegNum) & 0xf; 78226584Sdim } 79226584Sdim 80263509Sdim unsigned char getWriteMaskRegisterEncoding(const MCInst &MI, 81263509Sdim unsigned OpNum) const { 82263509Sdim assert(X86::K0 != MI.getOperand(OpNum).getReg() && 83263509Sdim "Invalid mask register as write-mask!"); 84263509Sdim unsigned MaskRegNum = GetX86RegNum(MI.getOperand(OpNum)); 85263509Sdim return MaskRegNum; 86263509Sdim } 87263509Sdim 88226584Sdim void EmitByte(unsigned char C, unsigned &CurByte, raw_ostream &OS) const { 89226584Sdim OS << (char)C; 90226584Sdim ++CurByte; 91226584Sdim } 92226584Sdim 93226584Sdim void EmitConstant(uint64_t Val, unsigned Size, unsigned &CurByte, 94226584Sdim raw_ostream &OS) const { 95226584Sdim // Output the constant in little endian byte order. 96226584Sdim for (unsigned i = 0; i != Size; ++i) { 97226584Sdim EmitByte(Val & 255, CurByte, OS); 98226584Sdim Val >>= 8; 99226584Sdim } 100226584Sdim } 101226584Sdim 102235633Sdim void EmitImmediate(const MCOperand &Disp, SMLoc Loc, 103226584Sdim unsigned ImmSize, MCFixupKind FixupKind, 104226584Sdim unsigned &CurByte, raw_ostream &OS, 105226584Sdim SmallVectorImpl<MCFixup> &Fixups, 106226584Sdim int ImmOffset = 0) const; 107226584Sdim 108226584Sdim inline static unsigned char ModRMByte(unsigned Mod, unsigned RegOpcode, 109226584Sdim unsigned RM) { 110226584Sdim assert(Mod < 4 && RegOpcode < 8 && RM < 8 && "ModRM Fields out of range!"); 111226584Sdim return RM | (RegOpcode << 3) | (Mod << 6); 112226584Sdim } 113226584Sdim 114226584Sdim void EmitRegModRMByte(const MCOperand &ModRMReg, unsigned RegOpcodeFld, 115226584Sdim unsigned &CurByte, raw_ostream &OS) const { 116226584Sdim EmitByte(ModRMByte(3, RegOpcodeFld, GetX86RegNum(ModRMReg)), CurByte, OS); 117226584Sdim } 118226584Sdim 119226584Sdim void EmitSIBByte(unsigned SS, unsigned Index, unsigned Base, 120226584Sdim unsigned &CurByte, raw_ostream &OS) const { 121226584Sdim // SIB byte is in the same format as the ModRMByte. 122226584Sdim EmitByte(ModRMByte(SS, Index, Base), CurByte, OS); 123226584Sdim } 124226584Sdim 125226584Sdim 126226584Sdim void EmitMemModRMByte(const MCInst &MI, unsigned Op, 127226584Sdim unsigned RegOpcodeField, 128226584Sdim uint64_t TSFlags, unsigned &CurByte, raw_ostream &OS, 129226584Sdim SmallVectorImpl<MCFixup> &Fixups) const; 130226584Sdim 131226584Sdim void EncodeInstruction(const MCInst &MI, raw_ostream &OS, 132226584Sdim SmallVectorImpl<MCFixup> &Fixups) const; 133226584Sdim 134226584Sdim void EmitVEXOpcodePrefix(uint64_t TSFlags, unsigned &CurByte, int MemOperand, 135226584Sdim const MCInst &MI, const MCInstrDesc &Desc, 136226584Sdim raw_ostream &OS) const; 137226584Sdim 138226584Sdim void EmitSegmentOverridePrefix(uint64_t TSFlags, unsigned &CurByte, 139226584Sdim int MemOperand, const MCInst &MI, 140226584Sdim raw_ostream &OS) const; 141226584Sdim 142226584Sdim void EmitOpcodePrefix(uint64_t TSFlags, unsigned &CurByte, int MemOperand, 143226584Sdim const MCInst &MI, const MCInstrDesc &Desc, 144226584Sdim raw_ostream &OS) const; 145226584Sdim}; 146226584Sdim 147226584Sdim} // end anonymous namespace 148226584Sdim 149226584Sdim 150226584SdimMCCodeEmitter *llvm::createX86MCCodeEmitter(const MCInstrInfo &MCII, 151245431Sdim const MCRegisterInfo &MRI, 152226584Sdim const MCSubtargetInfo &STI, 153226584Sdim MCContext &Ctx) { 154226584Sdim return new X86MCCodeEmitter(MCII, STI, Ctx); 155226584Sdim} 156226584Sdim 157226584Sdim/// isDisp8 - Return true if this signed displacement fits in a 8-bit 158226584Sdim/// sign-extended field. 159226584Sdimstatic bool isDisp8(int Value) { 160226584Sdim return Value == (signed char)Value; 161226584Sdim} 162226584Sdim 163263509Sdim/// isCDisp8 - Return true if this signed displacement fits in a 8-bit 164263509Sdim/// compressed dispacement field. 165263509Sdimstatic bool isCDisp8(uint64_t TSFlags, int Value, int& CValue) { 166263509Sdim assert(((TSFlags >> X86II::VEXShift) & X86II::EVEX) && 167263509Sdim "Compressed 8-bit displacement is only valid for EVEX inst."); 168263509Sdim 169263509Sdim unsigned CD8E = (TSFlags >> X86II::EVEX_CD8EShift) & X86II::EVEX_CD8EMask; 170263509Sdim unsigned CD8V = (TSFlags >> X86II::EVEX_CD8VShift) & X86II::EVEX_CD8VMask; 171263509Sdim 172263509Sdim if (CD8V == 0 && CD8E == 0) { 173263509Sdim CValue = Value; 174263509Sdim return isDisp8(Value); 175263509Sdim } 176263509Sdim 177263509Sdim unsigned MemObjSize = 1U << CD8E; 178263509Sdim if (CD8V & 4) { 179263509Sdim // Fixed vector length 180263509Sdim MemObjSize *= 1U << (CD8V & 0x3); 181263509Sdim } else { 182263509Sdim // Modified vector length 183263509Sdim bool EVEX_b = (TSFlags >> X86II::VEXShift) & X86II::EVEX_B; 184263509Sdim if (!EVEX_b) { 185263509Sdim unsigned EVEX_LL = ((TSFlags >> X86II::VEXShift) & X86II::VEX_L) ? 1 : 0; 186263509Sdim EVEX_LL += ((TSFlags >> X86II::VEXShift) & X86II::EVEX_L2) ? 2 : 0; 187263509Sdim assert(EVEX_LL < 3 && ""); 188263509Sdim 189263509Sdim unsigned NumElems = (1U << (EVEX_LL + 4)) / MemObjSize; 190263509Sdim NumElems /= 1U << (CD8V & 0x3); 191263509Sdim 192263509Sdim MemObjSize *= NumElems; 193263509Sdim } 194263509Sdim } 195263509Sdim 196263509Sdim unsigned MemObjMask = MemObjSize - 1; 197263509Sdim assert((MemObjSize & MemObjMask) == 0 && "Invalid memory object size."); 198263509Sdim 199263509Sdim if (Value & MemObjMask) // Unaligned offset 200263509Sdim return false; 201263509Sdim Value /= MemObjSize; 202263509Sdim bool Ret = (Value == (signed char)Value); 203263509Sdim 204263509Sdim if (Ret) 205263509Sdim CValue = Value; 206263509Sdim return Ret; 207263509Sdim} 208263509Sdim 209226584Sdim/// getImmFixupKind - Return the appropriate fixup kind to use for an immediate 210226584Sdim/// in an instruction with the specified TSFlags. 211226584Sdimstatic MCFixupKind getImmFixupKind(uint64_t TSFlags) { 212226584Sdim unsigned Size = X86II::getSizeOfImm(TSFlags); 213226584Sdim bool isPCRel = X86II::isImmPCRel(TSFlags); 214226584Sdim 215226584Sdim return MCFixup::getKindForSize(Size, isPCRel); 216226584Sdim} 217226584Sdim 218235633Sdim/// Is32BitMemOperand - Return true if the specified instruction has 219235633Sdim/// a 32-bit memory operand. Op specifies the operand # of the memoperand. 220226584Sdimstatic bool Is32BitMemOperand(const MCInst &MI, unsigned Op) { 221226584Sdim const MCOperand &BaseReg = MI.getOperand(Op+X86::AddrBaseReg); 222226584Sdim const MCOperand &IndexReg = MI.getOperand(Op+X86::AddrIndexReg); 223226584Sdim 224226584Sdim if ((BaseReg.getReg() != 0 && 225226584Sdim X86MCRegisterClasses[X86::GR32RegClassID].contains(BaseReg.getReg())) || 226226584Sdim (IndexReg.getReg() != 0 && 227226584Sdim X86MCRegisterClasses[X86::GR32RegClassID].contains(IndexReg.getReg()))) 228226584Sdim return true; 229226584Sdim return false; 230226584Sdim} 231226584Sdim 232235633Sdim/// Is64BitMemOperand - Return true if the specified instruction has 233235633Sdim/// a 64-bit memory operand. Op specifies the operand # of the memoperand. 234235633Sdim#ifndef NDEBUG 235235633Sdimstatic bool Is64BitMemOperand(const MCInst &MI, unsigned Op) { 236235633Sdim const MCOperand &BaseReg = MI.getOperand(Op+X86::AddrBaseReg); 237235633Sdim const MCOperand &IndexReg = MI.getOperand(Op+X86::AddrIndexReg); 238235633Sdim 239235633Sdim if ((BaseReg.getReg() != 0 && 240235633Sdim X86MCRegisterClasses[X86::GR64RegClassID].contains(BaseReg.getReg())) || 241235633Sdim (IndexReg.getReg() != 0 && 242235633Sdim X86MCRegisterClasses[X86::GR64RegClassID].contains(IndexReg.getReg()))) 243235633Sdim return true; 244235633Sdim return false; 245235633Sdim} 246235633Sdim#endif 247235633Sdim 248235633Sdim/// Is16BitMemOperand - Return true if the specified instruction has 249235633Sdim/// a 16-bit memory operand. Op specifies the operand # of the memoperand. 250235633Sdimstatic bool Is16BitMemOperand(const MCInst &MI, unsigned Op) { 251235633Sdim const MCOperand &BaseReg = MI.getOperand(Op+X86::AddrBaseReg); 252235633Sdim const MCOperand &IndexReg = MI.getOperand(Op+X86::AddrIndexReg); 253235633Sdim 254235633Sdim if ((BaseReg.getReg() != 0 && 255235633Sdim X86MCRegisterClasses[X86::GR16RegClassID].contains(BaseReg.getReg())) || 256235633Sdim (IndexReg.getReg() != 0 && 257235633Sdim X86MCRegisterClasses[X86::GR16RegClassID].contains(IndexReg.getReg()))) 258235633Sdim return true; 259235633Sdim return false; 260235633Sdim} 261235633Sdim 262235633Sdim/// StartsWithGlobalOffsetTable - Check if this expression starts with 263235633Sdim/// _GLOBAL_OFFSET_TABLE_ and if it is of the form 264235633Sdim/// _GLOBAL_OFFSET_TABLE_-symbol. This is needed to support PIC on ELF 265235633Sdim/// i386 as _GLOBAL_OFFSET_TABLE_ is magical. We check only simple case that 266226584Sdim/// are know to be used: _GLOBAL_OFFSET_TABLE_ by itself or at the start 267226584Sdim/// of a binary expression. 268235633Sdimenum GlobalOffsetTableExprKind { 269235633Sdim GOT_None, 270235633Sdim GOT_Normal, 271235633Sdim GOT_SymDiff 272235633Sdim}; 273235633Sdimstatic GlobalOffsetTableExprKind 274235633SdimStartsWithGlobalOffsetTable(const MCExpr *Expr) { 275235633Sdim const MCExpr *RHS = 0; 276226584Sdim if (Expr->getKind() == MCExpr::Binary) { 277226584Sdim const MCBinaryExpr *BE = static_cast<const MCBinaryExpr *>(Expr); 278226584Sdim Expr = BE->getLHS(); 279235633Sdim RHS = BE->getRHS(); 280226584Sdim } 281226584Sdim 282226584Sdim if (Expr->getKind() != MCExpr::SymbolRef) 283235633Sdim return GOT_None; 284226584Sdim 285226584Sdim const MCSymbolRefExpr *Ref = static_cast<const MCSymbolRefExpr*>(Expr); 286226584Sdim const MCSymbol &S = Ref->getSymbol(); 287235633Sdim if (S.getName() != "_GLOBAL_OFFSET_TABLE_") 288235633Sdim return GOT_None; 289235633Sdim if (RHS && RHS->getKind() == MCExpr::SymbolRef) 290235633Sdim return GOT_SymDiff; 291235633Sdim return GOT_Normal; 292226584Sdim} 293226584Sdim 294252723Sdimstatic bool HasSecRelSymbolRef(const MCExpr *Expr) { 295252723Sdim if (Expr->getKind() == MCExpr::SymbolRef) { 296252723Sdim const MCSymbolRefExpr *Ref = static_cast<const MCSymbolRefExpr*>(Expr); 297252723Sdim return Ref->getKind() == MCSymbolRefExpr::VK_SECREL; 298252723Sdim } 299252723Sdim return false; 300252723Sdim} 301252723Sdim 302226584Sdimvoid X86MCCodeEmitter:: 303235633SdimEmitImmediate(const MCOperand &DispOp, SMLoc Loc, unsigned Size, 304235633Sdim MCFixupKind FixupKind, unsigned &CurByte, raw_ostream &OS, 305226584Sdim SmallVectorImpl<MCFixup> &Fixups, int ImmOffset) const { 306226584Sdim const MCExpr *Expr = NULL; 307226584Sdim if (DispOp.isImm()) { 308226584Sdim // If this is a simple integer displacement that doesn't require a 309226584Sdim // relocation, emit it now. 310226584Sdim if (FixupKind != FK_PCRel_1 && 311226584Sdim FixupKind != FK_PCRel_2 && 312226584Sdim FixupKind != FK_PCRel_4) { 313226584Sdim EmitConstant(DispOp.getImm()+ImmOffset, Size, CurByte, OS); 314226584Sdim return; 315226584Sdim } 316226584Sdim Expr = MCConstantExpr::Create(DispOp.getImm(), Ctx); 317226584Sdim } else { 318226584Sdim Expr = DispOp.getExpr(); 319226584Sdim } 320226584Sdim 321226584Sdim // If we have an immoffset, add it to the expression. 322226584Sdim if ((FixupKind == FK_Data_4 || 323235633Sdim FixupKind == FK_Data_8 || 324235633Sdim FixupKind == MCFixupKind(X86::reloc_signed_4byte))) { 325235633Sdim GlobalOffsetTableExprKind Kind = StartsWithGlobalOffsetTable(Expr); 326235633Sdim if (Kind != GOT_None) { 327235633Sdim assert(ImmOffset == 0); 328226584Sdim 329235633Sdim FixupKind = MCFixupKind(X86::reloc_global_offset_table); 330235633Sdim if (Kind == GOT_Normal) 331235633Sdim ImmOffset = CurByte; 332235633Sdim } else if (Expr->getKind() == MCExpr::SymbolRef) { 333252723Sdim if (HasSecRelSymbolRef(Expr)) { 334235633Sdim FixupKind = MCFixupKind(FK_SecRel_4); 335235633Sdim } 336252723Sdim } else if (Expr->getKind() == MCExpr::Binary) { 337252723Sdim const MCBinaryExpr *Bin = static_cast<const MCBinaryExpr*>(Expr); 338252723Sdim if (HasSecRelSymbolRef(Bin->getLHS()) 339252723Sdim || HasSecRelSymbolRef(Bin->getRHS())) { 340252723Sdim FixupKind = MCFixupKind(FK_SecRel_4); 341252723Sdim } 342235633Sdim } 343226584Sdim } 344226584Sdim 345226584Sdim // If the fixup is pc-relative, we need to bias the value to be relative to 346226584Sdim // the start of the field, not the end of the field. 347226584Sdim if (FixupKind == FK_PCRel_4 || 348226584Sdim FixupKind == MCFixupKind(X86::reloc_riprel_4byte) || 349226584Sdim FixupKind == MCFixupKind(X86::reloc_riprel_4byte_movq_load)) 350226584Sdim ImmOffset -= 4; 351226584Sdim if (FixupKind == FK_PCRel_2) 352226584Sdim ImmOffset -= 2; 353226584Sdim if (FixupKind == FK_PCRel_1) 354226584Sdim ImmOffset -= 1; 355226584Sdim 356226584Sdim if (ImmOffset) 357226584Sdim Expr = MCBinaryExpr::CreateAdd(Expr, MCConstantExpr::Create(ImmOffset, Ctx), 358226584Sdim Ctx); 359226584Sdim 360226584Sdim // Emit a symbolic constant as a fixup and 4 zeros. 361235633Sdim Fixups.push_back(MCFixup::Create(CurByte, Expr, FixupKind, Loc)); 362226584Sdim EmitConstant(0, Size, CurByte, OS); 363226584Sdim} 364226584Sdim 365226584Sdimvoid X86MCCodeEmitter::EmitMemModRMByte(const MCInst &MI, unsigned Op, 366226584Sdim unsigned RegOpcodeField, 367226584Sdim uint64_t TSFlags, unsigned &CurByte, 368226584Sdim raw_ostream &OS, 369226584Sdim SmallVectorImpl<MCFixup> &Fixups) const{ 370226584Sdim const MCOperand &Disp = MI.getOperand(Op+X86::AddrDisp); 371226584Sdim const MCOperand &Base = MI.getOperand(Op+X86::AddrBaseReg); 372226584Sdim const MCOperand &Scale = MI.getOperand(Op+X86::AddrScaleAmt); 373226584Sdim const MCOperand &IndexReg = MI.getOperand(Op+X86::AddrIndexReg); 374226584Sdim unsigned BaseReg = Base.getReg(); 375263509Sdim bool HasEVEX = (TSFlags >> X86II::VEXShift) & X86II::EVEX; 376226584Sdim 377226584Sdim // Handle %rip relative addressing. 378226584Sdim if (BaseReg == X86::RIP) { // [disp32+RIP] in X86-64 mode 379226584Sdim assert(is64BitMode() && "Rip-relative addressing requires 64-bit mode"); 380226584Sdim assert(IndexReg.getReg() == 0 && "Invalid rip-relative address"); 381226584Sdim EmitByte(ModRMByte(0, RegOpcodeField, 5), CurByte, OS); 382226584Sdim 383226584Sdim unsigned FixupKind = X86::reloc_riprel_4byte; 384226584Sdim 385226584Sdim // movq loads are handled with a special relocation form which allows the 386226584Sdim // linker to eliminate some loads for GOT references which end up in the 387226584Sdim // same linkage unit. 388226584Sdim if (MI.getOpcode() == X86::MOV64rm) 389226584Sdim FixupKind = X86::reloc_riprel_4byte_movq_load; 390226584Sdim 391226584Sdim // rip-relative addressing is actually relative to the *next* instruction. 392226584Sdim // Since an immediate can follow the mod/rm byte for an instruction, this 393226584Sdim // means that we need to bias the immediate field of the instruction with 394226584Sdim // the size of the immediate field. If we have this case, add it into the 395226584Sdim // expression to emit. 396226584Sdim int ImmSize = X86II::hasImm(TSFlags) ? X86II::getSizeOfImm(TSFlags) : 0; 397226584Sdim 398235633Sdim EmitImmediate(Disp, MI.getLoc(), 4, MCFixupKind(FixupKind), 399226584Sdim CurByte, OS, Fixups, -ImmSize); 400226584Sdim return; 401226584Sdim } 402226584Sdim 403226584Sdim unsigned BaseRegNo = BaseReg ? GetX86RegNum(Base) : -1U; 404226584Sdim 405226584Sdim // Determine whether a SIB byte is needed. 406226584Sdim // If no BaseReg, issue a RIP relative instruction only if the MCE can 407226584Sdim // resolve addresses on-the-fly, otherwise use SIB (Intel Manual 2A, table 408226584Sdim // 2-7) and absolute references. 409226584Sdim 410226584Sdim if (// The SIB byte must be used if there is an index register. 411226584Sdim IndexReg.getReg() == 0 && 412226584Sdim // The SIB byte must be used if the base is ESP/RSP/R12, all of which 413226584Sdim // encode to an R/M value of 4, which indicates that a SIB byte is 414226584Sdim // present. 415226584Sdim BaseRegNo != N86::ESP && 416226584Sdim // If there is no base register and we're in 64-bit mode, we need a SIB 417226584Sdim // byte to emit an addr that is just 'disp32' (the non-RIP relative form). 418226584Sdim (!is64BitMode() || BaseReg != 0)) { 419226584Sdim 420226584Sdim if (BaseReg == 0) { // [disp32] in X86-32 mode 421226584Sdim EmitByte(ModRMByte(0, RegOpcodeField, 5), CurByte, OS); 422235633Sdim EmitImmediate(Disp, MI.getLoc(), 4, FK_Data_4, CurByte, OS, Fixups); 423226584Sdim return; 424226584Sdim } 425226584Sdim 426226584Sdim // If the base is not EBP/ESP and there is no displacement, use simple 427226584Sdim // indirect register encoding, this handles addresses like [EAX]. The 428226584Sdim // encoding for [EBP] with no displacement means [disp32] so we handle it 429226584Sdim // by emitting a displacement of 0 below. 430226584Sdim if (Disp.isImm() && Disp.getImm() == 0 && BaseRegNo != N86::EBP) { 431226584Sdim EmitByte(ModRMByte(0, RegOpcodeField, BaseRegNo), CurByte, OS); 432226584Sdim return; 433226584Sdim } 434226584Sdim 435226584Sdim // Otherwise, if the displacement fits in a byte, encode as [REG+disp8]. 436263509Sdim if (Disp.isImm()) { 437263509Sdim if (!HasEVEX && isDisp8(Disp.getImm())) { 438263509Sdim EmitByte(ModRMByte(1, RegOpcodeField, BaseRegNo), CurByte, OS); 439263509Sdim EmitImmediate(Disp, MI.getLoc(), 1, FK_Data_1, CurByte, OS, Fixups); 440263509Sdim return; 441263509Sdim } 442263509Sdim // Try EVEX compressed 8-bit displacement first; if failed, fall back to 443263509Sdim // 32-bit displacement. 444263509Sdim int CDisp8 = 0; 445263509Sdim if (HasEVEX && isCDisp8(TSFlags, Disp.getImm(), CDisp8)) { 446263509Sdim EmitByte(ModRMByte(1, RegOpcodeField, BaseRegNo), CurByte, OS); 447263509Sdim EmitImmediate(Disp, MI.getLoc(), 1, FK_Data_1, CurByte, OS, Fixups, 448263509Sdim CDisp8 - Disp.getImm()); 449263509Sdim return; 450263509Sdim } 451226584Sdim } 452226584Sdim 453226584Sdim // Otherwise, emit the most general non-SIB encoding: [REG+disp32] 454226584Sdim EmitByte(ModRMByte(2, RegOpcodeField, BaseRegNo), CurByte, OS); 455235633Sdim EmitImmediate(Disp, MI.getLoc(), 4, MCFixupKind(X86::reloc_signed_4byte), CurByte, OS, 456226584Sdim Fixups); 457226584Sdim return; 458226584Sdim } 459226584Sdim 460226584Sdim // We need a SIB byte, so start by outputting the ModR/M byte first 461226584Sdim assert(IndexReg.getReg() != X86::ESP && 462226584Sdim IndexReg.getReg() != X86::RSP && "Cannot use ESP as index reg!"); 463226584Sdim 464226584Sdim bool ForceDisp32 = false; 465226584Sdim bool ForceDisp8 = false; 466263509Sdim int CDisp8 = 0; 467263509Sdim int ImmOffset = 0; 468226584Sdim if (BaseReg == 0) { 469226584Sdim // If there is no base register, we emit the special case SIB byte with 470226584Sdim // MOD=0, BASE=5, to JUST get the index, scale, and displacement. 471226584Sdim EmitByte(ModRMByte(0, RegOpcodeField, 4), CurByte, OS); 472226584Sdim ForceDisp32 = true; 473226584Sdim } else if (!Disp.isImm()) { 474226584Sdim // Emit the normal disp32 encoding. 475226584Sdim EmitByte(ModRMByte(2, RegOpcodeField, 4), CurByte, OS); 476226584Sdim ForceDisp32 = true; 477226584Sdim } else if (Disp.getImm() == 0 && 478226584Sdim // Base reg can't be anything that ends up with '5' as the base 479226584Sdim // reg, it is the magic [*] nomenclature that indicates no base. 480226584Sdim BaseRegNo != N86::EBP) { 481226584Sdim // Emit no displacement ModR/M byte 482226584Sdim EmitByte(ModRMByte(0, RegOpcodeField, 4), CurByte, OS); 483263509Sdim } else if (!HasEVEX && isDisp8(Disp.getImm())) { 484226584Sdim // Emit the disp8 encoding. 485226584Sdim EmitByte(ModRMByte(1, RegOpcodeField, 4), CurByte, OS); 486226584Sdim ForceDisp8 = true; // Make sure to force 8 bit disp if Base=EBP 487263509Sdim } else if (HasEVEX && isCDisp8(TSFlags, Disp.getImm(), CDisp8)) { 488263509Sdim // Emit the disp8 encoding. 489263509Sdim EmitByte(ModRMByte(1, RegOpcodeField, 4), CurByte, OS); 490263509Sdim ForceDisp8 = true; // Make sure to force 8 bit disp if Base=EBP 491263509Sdim ImmOffset = CDisp8 - Disp.getImm(); 492226584Sdim } else { 493226584Sdim // Emit the normal disp32 encoding. 494226584Sdim EmitByte(ModRMByte(2, RegOpcodeField, 4), CurByte, OS); 495226584Sdim } 496226584Sdim 497226584Sdim // Calculate what the SS field value should be... 498226584Sdim static const unsigned SSTable[] = { ~0U, 0, 1, ~0U, 2, ~0U, ~0U, ~0U, 3 }; 499226584Sdim unsigned SS = SSTable[Scale.getImm()]; 500226584Sdim 501226584Sdim if (BaseReg == 0) { 502226584Sdim // Handle the SIB byte for the case where there is no base, see Intel 503226584Sdim // Manual 2A, table 2-7. The displacement has already been output. 504226584Sdim unsigned IndexRegNo; 505226584Sdim if (IndexReg.getReg()) 506226584Sdim IndexRegNo = GetX86RegNum(IndexReg); 507226584Sdim else // Examples: [ESP+1*<noreg>+4] or [scaled idx]+disp32 (MOD=0,BASE=5) 508226584Sdim IndexRegNo = 4; 509226584Sdim EmitSIBByte(SS, IndexRegNo, 5, CurByte, OS); 510226584Sdim } else { 511226584Sdim unsigned IndexRegNo; 512226584Sdim if (IndexReg.getReg()) 513226584Sdim IndexRegNo = GetX86RegNum(IndexReg); 514226584Sdim else 515226584Sdim IndexRegNo = 4; // For example [ESP+1*<noreg>+4] 516226584Sdim EmitSIBByte(SS, IndexRegNo, GetX86RegNum(Base), CurByte, OS); 517226584Sdim } 518226584Sdim 519226584Sdim // Do we need to output a displacement? 520226584Sdim if (ForceDisp8) 521263509Sdim EmitImmediate(Disp, MI.getLoc(), 1, FK_Data_1, CurByte, OS, Fixups, ImmOffset); 522226584Sdim else if (ForceDisp32 || Disp.getImm() != 0) 523235633Sdim EmitImmediate(Disp, MI.getLoc(), 4, MCFixupKind(X86::reloc_signed_4byte), 524235633Sdim CurByte, OS, Fixups); 525226584Sdim} 526226584Sdim 527226584Sdim/// EmitVEXOpcodePrefix - AVX instructions are encoded using a opcode prefix 528226584Sdim/// called VEX. 529226584Sdimvoid X86MCCodeEmitter::EmitVEXOpcodePrefix(uint64_t TSFlags, unsigned &CurByte, 530226584Sdim int MemOperand, const MCInst &MI, 531226584Sdim const MCInstrDesc &Desc, 532226584Sdim raw_ostream &OS) const { 533263509Sdim bool HasEVEX = (TSFlags >> X86II::VEXShift) & X86II::EVEX; 534263509Sdim bool HasEVEX_K = HasEVEX && ((TSFlags >> X86II::VEXShift) & X86II::EVEX_K); 535235633Sdim bool HasVEX_4V = (TSFlags >> X86II::VEXShift) & X86II::VEX_4V; 536235633Sdim bool HasVEX_4VOp3 = (TSFlags >> X86II::VEXShift) & X86II::VEX_4VOp3; 537252723Sdim bool HasMemOp4 = (TSFlags >> X86II::VEXShift) & X86II::MemOp4; 538226584Sdim 539226584Sdim // VEX_R: opcode externsion equivalent to REX.R in 540226584Sdim // 1's complement (inverted) form 541226584Sdim // 542226584Sdim // 1: Same as REX_R=0 (must be 1 in 32-bit mode) 543226584Sdim // 0: Same as REX_R=1 (64 bit mode only) 544226584Sdim // 545226584Sdim unsigned char VEX_R = 0x1; 546263509Sdim unsigned char EVEX_R2 = 0x1; 547226584Sdim 548226584Sdim // VEX_X: equivalent to REX.X, only used when a 549226584Sdim // register is used for index in SIB Byte. 550226584Sdim // 551226584Sdim // 1: Same as REX.X=0 (must be 1 in 32-bit mode) 552226584Sdim // 0: Same as REX.X=1 (64-bit mode only) 553226584Sdim unsigned char VEX_X = 0x1; 554226584Sdim 555226584Sdim // VEX_B: 556226584Sdim // 557226584Sdim // 1: Same as REX_B=0 (ignored in 32-bit mode) 558226584Sdim // 0: Same as REX_B=1 (64 bit mode only) 559226584Sdim // 560226584Sdim unsigned char VEX_B = 0x1; 561226584Sdim 562226584Sdim // VEX_W: opcode specific (use like REX.W, or used for 563226584Sdim // opcode extension, or ignored, depending on the opcode byte) 564226584Sdim unsigned char VEX_W = 0; 565226584Sdim 566235633Sdim // XOP: Use XOP prefix byte 0x8f instead of VEX. 567263509Sdim bool XOP = false; 568235633Sdim 569226584Sdim // VEX_5M (VEX m-mmmmm field): 570226584Sdim // 571226584Sdim // 0b00000: Reserved for future use 572226584Sdim // 0b00001: implied 0F leading opcode 573226584Sdim // 0b00010: implied 0F 38 leading opcode bytes 574226584Sdim // 0b00011: implied 0F 3A leading opcode bytes 575226584Sdim // 0b00100-0b11111: Reserved for future use 576235633Sdim // 0b01000: XOP map select - 08h instructions with imm byte 577263509Sdim // 0b01001: XOP map select - 09h instructions with no imm byte 578263509Sdim // 0b01010: XOP map select - 0Ah instructions with imm dword 579226584Sdim unsigned char VEX_5M = 0x1; 580226584Sdim 581226584Sdim // VEX_4V (VEX vvvv field): a register specifier 582226584Sdim // (in 1's complement form) or 1111 if unused. 583226584Sdim unsigned char VEX_4V = 0xf; 584263509Sdim unsigned char EVEX_V2 = 0x1; 585226584Sdim 586226584Sdim // VEX_L (Vector Length): 587226584Sdim // 588226584Sdim // 0: scalar or 128-bit vector 589226584Sdim // 1: 256-bit vector 590226584Sdim // 591226584Sdim unsigned char VEX_L = 0; 592263509Sdim unsigned char EVEX_L2 = 0; 593226584Sdim 594226584Sdim // VEX_PP: opcode extension providing equivalent 595226584Sdim // functionality of a SIMD prefix 596226584Sdim // 597226584Sdim // 0b00: None 598226584Sdim // 0b01: 66 599226584Sdim // 0b10: F3 600226584Sdim // 0b11: F2 601226584Sdim // 602226584Sdim unsigned char VEX_PP = 0; 603226584Sdim 604263509Sdim // EVEX_U 605263509Sdim unsigned char EVEX_U = 1; // Always '1' so far 606263509Sdim 607263509Sdim // EVEX_z 608263509Sdim unsigned char EVEX_z = 0; 609263509Sdim 610263509Sdim // EVEX_b 611263509Sdim unsigned char EVEX_b = 0; 612263509Sdim 613263509Sdim // EVEX_aaa 614263509Sdim unsigned char EVEX_aaa = 0; 615263509Sdim 616226584Sdim // Encode the operand size opcode prefix as needed. 617226584Sdim if (TSFlags & X86II::OpSize) 618226584Sdim VEX_PP = 0x01; 619226584Sdim 620226584Sdim if ((TSFlags >> X86II::VEXShift) & X86II::VEX_W) 621226584Sdim VEX_W = 1; 622226584Sdim 623235633Sdim if ((TSFlags >> X86II::VEXShift) & X86II::XOP) 624263509Sdim XOP = true; 625235633Sdim 626226584Sdim if ((TSFlags >> X86II::VEXShift) & X86II::VEX_L) 627226584Sdim VEX_L = 1; 628263509Sdim if (HasEVEX && ((TSFlags >> X86II::VEXShift) & X86II::EVEX_L2)) 629263509Sdim EVEX_L2 = 1; 630226584Sdim 631263509Sdim if (HasEVEX_K && ((TSFlags >> X86II::VEXShift) & X86II::EVEX_Z)) 632263509Sdim EVEX_z = 1; 633263509Sdim 634263509Sdim if (HasEVEX && ((TSFlags >> X86II::VEXShift) & X86II::EVEX_B)) 635263509Sdim EVEX_b = 1; 636263509Sdim 637226584Sdim switch (TSFlags & X86II::Op0Mask) { 638235633Sdim default: llvm_unreachable("Invalid prefix!"); 639226584Sdim case X86II::T8: // 0F 38 640226584Sdim VEX_5M = 0x2; 641226584Sdim break; 642226584Sdim case X86II::TA: // 0F 3A 643226584Sdim VEX_5M = 0x3; 644226584Sdim break; 645235633Sdim case X86II::T8XS: // F3 0F 38 646235633Sdim VEX_PP = 0x2; 647235633Sdim VEX_5M = 0x2; 648235633Sdim break; 649235633Sdim case X86II::T8XD: // F2 0F 38 650226584Sdim VEX_PP = 0x3; 651226584Sdim VEX_5M = 0x2; 652226584Sdim break; 653235633Sdim case X86II::TAXD: // F2 0F 3A 654235633Sdim VEX_PP = 0x3; 655235633Sdim VEX_5M = 0x3; 656235633Sdim break; 657226584Sdim case X86II::XS: // F3 0F 658226584Sdim VEX_PP = 0x2; 659226584Sdim break; 660226584Sdim case X86II::XD: // F2 0F 661226584Sdim VEX_PP = 0x3; 662226584Sdim break; 663235633Sdim case X86II::XOP8: 664235633Sdim VEX_5M = 0x8; 665235633Sdim break; 666235633Sdim case X86II::XOP9: 667235633Sdim VEX_5M = 0x9; 668235633Sdim break; 669263509Sdim case X86II::XOPA: 670263509Sdim VEX_5M = 0xA; 671263509Sdim break; 672263509Sdim case X86II::TB: // VEX_5M/VEX_PP already correct 673263509Sdim break; 674226584Sdim } 675226584Sdim 676235633Sdim 677245431Sdim // Classify VEX_B, VEX_4V, VEX_R, VEX_X 678245431Sdim unsigned NumOps = Desc.getNumOperands(); 679245431Sdim unsigned CurOp = 0; 680245431Sdim if (NumOps > 1 && Desc.getOperandConstraint(1, MCOI::TIED_TO) == 0) 681245431Sdim ++CurOp; 682263509Sdim else if (NumOps > 3 && Desc.getOperandConstraint(2, MCOI::TIED_TO) == 0 && 683263509Sdim Desc.getOperandConstraint(3, MCOI::TIED_TO) == 1) 684263509Sdim // Special case for AVX-512 GATHER with 2 TIED_TO operands 685263509Sdim // Skip the first 2 operands: dst, mask_wb 686263509Sdim CurOp += 2; 687263509Sdim else if (NumOps > 3 && Desc.getOperandConstraint(2, MCOI::TIED_TO) == 0 && 688263509Sdim Desc.getOperandConstraint(NumOps - 1, MCOI::TIED_TO) == 1) 689245431Sdim // Special case for GATHER with 2 TIED_TO operands 690245431Sdim // Skip the first 2 operands: dst, mask_wb 691245431Sdim CurOp += 2; 692263509Sdim else if (NumOps > 2 && Desc.getOperandConstraint(NumOps - 2, MCOI::TIED_TO) == 0) 693263509Sdim // SCATTER 694263509Sdim ++CurOp; 695226584Sdim 696226584Sdim switch (TSFlags & X86II::FormMask) { 697235633Sdim case X86II::MRMInitReg: llvm_unreachable("FIXME: Remove this!"); 698226584Sdim case X86II::MRMDestMem: { 699226584Sdim // MRMDestMem instructions forms: 700226584Sdim // MemAddr, src1(ModR/M) 701226584Sdim // MemAddr, src1(VEX_4V), src2(ModR/M) 702226584Sdim // MemAddr, src1(ModR/M), imm8 703226584Sdim // 704263509Sdim if (X86II::isX86_64ExtendedReg(MI.getOperand(MemOperand + 705263509Sdim X86::AddrBaseReg).getReg())) 706226584Sdim VEX_B = 0x0; 707263509Sdim if (X86II::isX86_64ExtendedReg(MI.getOperand(MemOperand + 708263509Sdim X86::AddrIndexReg).getReg())) 709226584Sdim VEX_X = 0x0; 710263509Sdim if (HasEVEX && X86II::is32ExtendedReg(MI.getOperand(MemOperand + 711263509Sdim X86::AddrIndexReg).getReg())) 712263509Sdim EVEX_V2 = 0x0; 713226584Sdim 714263509Sdim CurOp += X86::AddrNumOperands; 715226584Sdim 716263509Sdim if (HasEVEX_K) 717263509Sdim EVEX_aaa = getWriteMaskRegisterEncoding(MI, CurOp++); 718263509Sdim 719263509Sdim if (HasVEX_4V) { 720263509Sdim VEX_4V = getVEXRegisterEncoding(MI, CurOp); 721263509Sdim if (HasEVEX && X86II::is32ExtendedReg(MI.getOperand(CurOp).getReg())) 722263509Sdim EVEX_V2 = 0x0; 723263509Sdim CurOp++; 724263509Sdim } 725263509Sdim 726226584Sdim const MCOperand &MO = MI.getOperand(CurOp); 727263509Sdim if (MO.isReg()) { 728263509Sdim if (X86II::isX86_64ExtendedReg(MO.getReg())) 729263509Sdim VEX_R = 0x0; 730263509Sdim if (HasEVEX && X86II::is32ExtendedReg(MO.getReg())) 731263509Sdim EVEX_R2 = 0x0; 732263509Sdim } 733226584Sdim break; 734226584Sdim } 735235633Sdim case X86II::MRMSrcMem: 736226584Sdim // MRMSrcMem instructions forms: 737226584Sdim // src1(ModR/M), MemAddr 738226584Sdim // src1(ModR/M), src2(VEX_4V), MemAddr 739226584Sdim // src1(ModR/M), MemAddr, imm8 740226584Sdim // src1(ModR/M), MemAddr, src2(VEX_I8IMM) 741226584Sdim // 742235633Sdim // FMA4: 743235633Sdim // dst(ModR/M.reg), src1(VEX_4V), src2(ModR/M), src3(VEX_I8IMM) 744235633Sdim // dst(ModR/M.reg), src1(VEX_4V), src2(VEX_I8IMM), src3(ModR/M), 745263509Sdim if (X86II::isX86_64ExtendedReg(MI.getOperand(CurOp).getReg())) 746226584Sdim VEX_R = 0x0; 747263509Sdim if (HasEVEX && X86II::is32ExtendedReg(MI.getOperand(CurOp).getReg())) 748263509Sdim EVEX_R2 = 0x0; 749263509Sdim CurOp++; 750226584Sdim 751263509Sdim if (HasEVEX_K) 752263509Sdim EVEX_aaa = getWriteMaskRegisterEncoding(MI, CurOp++); 753263509Sdim 754263509Sdim if (HasVEX_4V) { 755245431Sdim VEX_4V = getVEXRegisterEncoding(MI, CurOp); 756263509Sdim if (HasEVEX && X86II::is32ExtendedReg(MI.getOperand(CurOp).getReg())) 757263509Sdim EVEX_V2 = 0x0; 758263509Sdim CurOp++; 759263509Sdim } 760226584Sdim 761226584Sdim if (X86II::isX86_64ExtendedReg( 762235633Sdim MI.getOperand(MemOperand+X86::AddrBaseReg).getReg())) 763226584Sdim VEX_B = 0x0; 764226584Sdim if (X86II::isX86_64ExtendedReg( 765235633Sdim MI.getOperand(MemOperand+X86::AddrIndexReg).getReg())) 766226584Sdim VEX_X = 0x0; 767263509Sdim if (HasEVEX && X86II::is32ExtendedReg(MI.getOperand(MemOperand + 768263509Sdim X86::AddrIndexReg).getReg())) 769263509Sdim EVEX_V2 = 0x0; 770235633Sdim 771235633Sdim if (HasVEX_4VOp3) 772245431Sdim // Instruction format for 4VOp3: 773245431Sdim // src1(ModR/M), MemAddr, src3(VEX_4V) 774245431Sdim // CurOp points to start of the MemoryOperand, 775245431Sdim // it skips TIED_TO operands if exist, then increments past src1. 776245431Sdim // CurOp + X86::AddrNumOperands will point to src3. 777245431Sdim VEX_4V = getVEXRegisterEncoding(MI, CurOp+X86::AddrNumOperands); 778226584Sdim break; 779226584Sdim case X86II::MRM0m: case X86II::MRM1m: 780226584Sdim case X86II::MRM2m: case X86II::MRM3m: 781226584Sdim case X86II::MRM4m: case X86II::MRM5m: 782235633Sdim case X86II::MRM6m: case X86II::MRM7m: { 783226584Sdim // MRM[0-9]m instructions forms: 784226584Sdim // MemAddr 785235633Sdim // src1(VEX_4V), MemAddr 786263509Sdim if (HasVEX_4V) { 787263509Sdim VEX_4V = getVEXRegisterEncoding(MI, CurOp); 788263509Sdim if (HasEVEX && X86II::is32ExtendedReg(MI.getOperand(CurOp).getReg())) 789263509Sdim EVEX_V2 = 0x0; 790263509Sdim CurOp++; 791263509Sdim } 792235633Sdim 793263509Sdim if (HasEVEX_K) 794263509Sdim EVEX_aaa = getWriteMaskRegisterEncoding(MI, CurOp++); 795263509Sdim 796235633Sdim if (X86II::isX86_64ExtendedReg( 797235633Sdim MI.getOperand(MemOperand+X86::AddrBaseReg).getReg())) 798226584Sdim VEX_B = 0x0; 799235633Sdim if (X86II::isX86_64ExtendedReg( 800235633Sdim MI.getOperand(MemOperand+X86::AddrIndexReg).getReg())) 801226584Sdim VEX_X = 0x0; 802226584Sdim break; 803235633Sdim } 804226584Sdim case X86II::MRMSrcReg: 805226584Sdim // MRMSrcReg instructions forms: 806226584Sdim // dst(ModR/M), src1(VEX_4V), src2(ModR/M), src3(VEX_I8IMM) 807226584Sdim // dst(ModR/M), src1(ModR/M) 808226584Sdim // dst(ModR/M), src1(ModR/M), imm8 809226584Sdim // 810252723Sdim // FMA4: 811252723Sdim // dst(ModR/M.reg), src1(VEX_4V), src2(ModR/M), src3(VEX_I8IMM) 812252723Sdim // dst(ModR/M.reg), src1(VEX_4V), src2(VEX_I8IMM), src3(ModR/M), 813226584Sdim if (X86II::isX86_64ExtendedReg(MI.getOperand(CurOp).getReg())) 814226584Sdim VEX_R = 0x0; 815263509Sdim if (HasEVEX && X86II::is32ExtendedReg(MI.getOperand(CurOp).getReg())) 816263509Sdim EVEX_R2 = 0x0; 817226584Sdim CurOp++; 818226584Sdim 819263509Sdim if (HasEVEX_K) 820263509Sdim EVEX_aaa = getWriteMaskRegisterEncoding(MI, CurOp++); 821252723Sdim 822263509Sdim if (HasVEX_4V) { 823263509Sdim VEX_4V = getVEXRegisterEncoding(MI, CurOp); 824263509Sdim if (HasEVEX && X86II::is32ExtendedReg(MI.getOperand(CurOp).getReg())) 825263509Sdim EVEX_V2 = 0x0; 826263509Sdim CurOp++; 827263509Sdim } 828263509Sdim 829252723Sdim if (HasMemOp4) // Skip second register source (encoded in I8IMM) 830252723Sdim CurOp++; 831252723Sdim 832226584Sdim if (X86II::isX86_64ExtendedReg(MI.getOperand(CurOp).getReg())) 833226584Sdim VEX_B = 0x0; 834263509Sdim if (HasEVEX && X86II::is32ExtendedReg(MI.getOperand(CurOp).getReg())) 835263509Sdim VEX_X = 0x0; 836235633Sdim CurOp++; 837235633Sdim if (HasVEX_4VOp3) 838235633Sdim VEX_4V = getVEXRegisterEncoding(MI, CurOp); 839226584Sdim break; 840226584Sdim case X86II::MRMDestReg: 841226584Sdim // MRMDestReg instructions forms: 842226584Sdim // dst(ModR/M), src(ModR/M) 843226584Sdim // dst(ModR/M), src(ModR/M), imm8 844252723Sdim // dst(ModR/M), src1(VEX_4V), src2(ModR/M) 845252723Sdim if (X86II::isX86_64ExtendedReg(MI.getOperand(CurOp).getReg())) 846226584Sdim VEX_B = 0x0; 847263509Sdim if (HasEVEX && X86II::is32ExtendedReg(MI.getOperand(CurOp).getReg())) 848263509Sdim VEX_X = 0x0; 849252723Sdim CurOp++; 850252723Sdim 851263509Sdim if (HasEVEX_K) 852263509Sdim EVEX_aaa = getWriteMaskRegisterEncoding(MI, CurOp++); 853252723Sdim 854263509Sdim if (HasVEX_4V) { 855263509Sdim VEX_4V = getVEXRegisterEncoding(MI, CurOp); 856263509Sdim if (HasEVEX && X86II::is32ExtendedReg(MI.getOperand(CurOp).getReg())) 857263509Sdim EVEX_V2 = 0x0; 858263509Sdim CurOp++; 859263509Sdim } 860263509Sdim 861252723Sdim if (X86II::isX86_64ExtendedReg(MI.getOperand(CurOp).getReg())) 862226584Sdim VEX_R = 0x0; 863263509Sdim if (HasEVEX && X86II::is32ExtendedReg(MI.getOperand(CurOp).getReg())) 864263509Sdim EVEX_R2 = 0x0; 865226584Sdim break; 866226584Sdim case X86II::MRM0r: case X86II::MRM1r: 867226584Sdim case X86II::MRM2r: case X86II::MRM3r: 868226584Sdim case X86II::MRM4r: case X86II::MRM5r: 869226584Sdim case X86II::MRM6r: case X86II::MRM7r: 870226584Sdim // MRM0r-MRM7r instructions forms: 871226584Sdim // dst(VEX_4V), src(ModR/M), imm8 872263509Sdim if (HasVEX_4V) { 873263509Sdim VEX_4V = getVEXRegisterEncoding(MI, CurOp); 874263509Sdim if (HasEVEX && X86II::is32ExtendedReg(MI.getOperand(CurOp).getReg())) 875263509Sdim EVEX_V2 = 0x0; 876263509Sdim CurOp++; 877263509Sdim } 878263509Sdim if (HasEVEX_K) 879263509Sdim EVEX_aaa = getWriteMaskRegisterEncoding(MI, CurOp++); 880263509Sdim 881263509Sdim if (X86II::isX86_64ExtendedReg(MI.getOperand(CurOp).getReg())) 882226584Sdim VEX_B = 0x0; 883263509Sdim if (HasEVEX && X86II::is32ExtendedReg(MI.getOperand(CurOp).getReg())) 884263509Sdim VEX_X = 0x0; 885226584Sdim break; 886226584Sdim default: // RawFrm 887226584Sdim break; 888226584Sdim } 889226584Sdim 890226584Sdim // Emit segment override opcode prefix as needed. 891226584Sdim EmitSegmentOverridePrefix(TSFlags, CurByte, MemOperand, MI, OS); 892226584Sdim 893263509Sdim if (!HasEVEX) { 894263509Sdim // VEX opcode prefix can have 2 or 3 bytes 895263509Sdim // 896263509Sdim // 3 bytes: 897263509Sdim // +-----+ +--------------+ +-------------------+ 898263509Sdim // | C4h | | RXB | m-mmmm | | W | vvvv | L | pp | 899263509Sdim // +-----+ +--------------+ +-------------------+ 900263509Sdim // 2 bytes: 901263509Sdim // +-----+ +-------------------+ 902263509Sdim // | C5h | | R | vvvv | L | pp | 903263509Sdim // +-----+ +-------------------+ 904263509Sdim // 905263509Sdim unsigned char LastByte = VEX_PP | (VEX_L << 2) | (VEX_4V << 3); 906226584Sdim 907263509Sdim if (VEX_B && VEX_X && !VEX_W && !XOP && (VEX_5M == 1)) { // 2 byte VEX prefix 908263509Sdim EmitByte(0xC5, CurByte, OS); 909263509Sdim EmitByte(LastByte | (VEX_R << 7), CurByte, OS); 910263509Sdim return; 911263509Sdim } 912263509Sdim 913263509Sdim // 3 byte VEX prefix 914263509Sdim EmitByte(XOP ? 0x8F : 0xC4, CurByte, OS); 915263509Sdim EmitByte(VEX_R << 7 | VEX_X << 6 | VEX_B << 5 | VEX_5M, CurByte, OS); 916263509Sdim EmitByte(LastByte | (VEX_W << 7), CurByte, OS); 917263509Sdim } else { 918263509Sdim // EVEX opcode prefix can have 4 bytes 919263509Sdim // 920263509Sdim // +-----+ +--------------+ +-------------------+ +------------------------+ 921263509Sdim // | 62h | | RXBR' | 00mm | | W | vvvv | U | pp | | z | L'L | b | v' | aaa | 922263509Sdim // +-----+ +--------------+ +-------------------+ +------------------------+ 923263509Sdim assert((VEX_5M & 0x3) == VEX_5M 924263509Sdim && "More than 2 significant bits in VEX.m-mmmm fields for EVEX!"); 925263509Sdim 926263509Sdim VEX_5M &= 0x3; 927263509Sdim 928263509Sdim EmitByte(0x62, CurByte, OS); 929263509Sdim EmitByte((VEX_R << 7) | 930263509Sdim (VEX_X << 6) | 931263509Sdim (VEX_B << 5) | 932263509Sdim (EVEX_R2 << 4) | 933263509Sdim VEX_5M, CurByte, OS); 934263509Sdim EmitByte((VEX_W << 7) | 935263509Sdim (VEX_4V << 3) | 936263509Sdim (EVEX_U << 2) | 937263509Sdim VEX_PP, CurByte, OS); 938263509Sdim EmitByte((EVEX_z << 7) | 939263509Sdim (EVEX_L2 << 6) | 940263509Sdim (VEX_L << 5) | 941263509Sdim (EVEX_b << 4) | 942263509Sdim (EVEX_V2 << 3) | 943263509Sdim EVEX_aaa, CurByte, OS); 944226584Sdim } 945226584Sdim} 946226584Sdim 947226584Sdim/// DetermineREXPrefix - Determine if the MCInst has to be encoded with a X86-64 948226584Sdim/// REX prefix which specifies 1) 64-bit instructions, 2) non-default operand 949226584Sdim/// size, and 3) use of X86-64 extended registers. 950226584Sdimstatic unsigned DetermineREXPrefix(const MCInst &MI, uint64_t TSFlags, 951226584Sdim const MCInstrDesc &Desc) { 952226584Sdim unsigned REX = 0; 953226584Sdim if (TSFlags & X86II::REX_W) 954226584Sdim REX |= 1 << 3; // set REX.W 955226584Sdim 956226584Sdim if (MI.getNumOperands() == 0) return REX; 957226584Sdim 958226584Sdim unsigned NumOps = MI.getNumOperands(); 959226584Sdim // FIXME: MCInst should explicitize the two-addrness. 960226584Sdim bool isTwoAddr = NumOps > 1 && 961226584Sdim Desc.getOperandConstraint(1, MCOI::TIED_TO) != -1; 962226584Sdim 963226584Sdim // If it accesses SPL, BPL, SIL, or DIL, then it requires a 0x40 REX prefix. 964226584Sdim unsigned i = isTwoAddr ? 1 : 0; 965226584Sdim for (; i != NumOps; ++i) { 966226584Sdim const MCOperand &MO = MI.getOperand(i); 967226584Sdim if (!MO.isReg()) continue; 968226584Sdim unsigned Reg = MO.getReg(); 969226584Sdim if (!X86II::isX86_64NonExtLowByteReg(Reg)) continue; 970226584Sdim // FIXME: The caller of DetermineREXPrefix slaps this prefix onto anything 971226584Sdim // that returns non-zero. 972226584Sdim REX |= 0x40; // REX fixed encoding prefix 973226584Sdim break; 974226584Sdim } 975226584Sdim 976226584Sdim switch (TSFlags & X86II::FormMask) { 977235633Sdim case X86II::MRMInitReg: llvm_unreachable("FIXME: Remove this!"); 978226584Sdim case X86II::MRMSrcReg: 979226584Sdim if (MI.getOperand(0).isReg() && 980226584Sdim X86II::isX86_64ExtendedReg(MI.getOperand(0).getReg())) 981226584Sdim REX |= 1 << 2; // set REX.R 982226584Sdim i = isTwoAddr ? 2 : 1; 983226584Sdim for (; i != NumOps; ++i) { 984226584Sdim const MCOperand &MO = MI.getOperand(i); 985226584Sdim if (MO.isReg() && X86II::isX86_64ExtendedReg(MO.getReg())) 986226584Sdim REX |= 1 << 0; // set REX.B 987226584Sdim } 988226584Sdim break; 989226584Sdim case X86II::MRMSrcMem: { 990226584Sdim if (MI.getOperand(0).isReg() && 991226584Sdim X86II::isX86_64ExtendedReg(MI.getOperand(0).getReg())) 992226584Sdim REX |= 1 << 2; // set REX.R 993226584Sdim unsigned Bit = 0; 994226584Sdim i = isTwoAddr ? 2 : 1; 995226584Sdim for (; i != NumOps; ++i) { 996226584Sdim const MCOperand &MO = MI.getOperand(i); 997226584Sdim if (MO.isReg()) { 998226584Sdim if (X86II::isX86_64ExtendedReg(MO.getReg())) 999226584Sdim REX |= 1 << Bit; // set REX.B (Bit=0) and REX.X (Bit=1) 1000226584Sdim Bit++; 1001226584Sdim } 1002226584Sdim } 1003226584Sdim break; 1004226584Sdim } 1005226584Sdim case X86II::MRM0m: case X86II::MRM1m: 1006226584Sdim case X86II::MRM2m: case X86II::MRM3m: 1007226584Sdim case X86II::MRM4m: case X86II::MRM5m: 1008226584Sdim case X86II::MRM6m: case X86II::MRM7m: 1009226584Sdim case X86II::MRMDestMem: { 1010226584Sdim unsigned e = (isTwoAddr ? X86::AddrNumOperands+1 : X86::AddrNumOperands); 1011226584Sdim i = isTwoAddr ? 1 : 0; 1012226584Sdim if (NumOps > e && MI.getOperand(e).isReg() && 1013226584Sdim X86II::isX86_64ExtendedReg(MI.getOperand(e).getReg())) 1014226584Sdim REX |= 1 << 2; // set REX.R 1015226584Sdim unsigned Bit = 0; 1016226584Sdim for (; i != e; ++i) { 1017226584Sdim const MCOperand &MO = MI.getOperand(i); 1018226584Sdim if (MO.isReg()) { 1019226584Sdim if (X86II::isX86_64ExtendedReg(MO.getReg())) 1020226584Sdim REX |= 1 << Bit; // REX.B (Bit=0) and REX.X (Bit=1) 1021226584Sdim Bit++; 1022226584Sdim } 1023226584Sdim } 1024226584Sdim break; 1025226584Sdim } 1026226584Sdim default: 1027226584Sdim if (MI.getOperand(0).isReg() && 1028226584Sdim X86II::isX86_64ExtendedReg(MI.getOperand(0).getReg())) 1029226584Sdim REX |= 1 << 0; // set REX.B 1030226584Sdim i = isTwoAddr ? 2 : 1; 1031226584Sdim for (unsigned e = NumOps; i != e; ++i) { 1032226584Sdim const MCOperand &MO = MI.getOperand(i); 1033226584Sdim if (MO.isReg() && X86II::isX86_64ExtendedReg(MO.getReg())) 1034226584Sdim REX |= 1 << 2; // set REX.R 1035226584Sdim } 1036226584Sdim break; 1037226584Sdim } 1038226584Sdim return REX; 1039226584Sdim} 1040226584Sdim 1041226584Sdim/// EmitSegmentOverridePrefix - Emit segment override opcode prefix as needed 1042226584Sdimvoid X86MCCodeEmitter::EmitSegmentOverridePrefix(uint64_t TSFlags, 1043226584Sdim unsigned &CurByte, int MemOperand, 1044226584Sdim const MCInst &MI, 1045226584Sdim raw_ostream &OS) const { 1046226584Sdim switch (TSFlags & X86II::SegOvrMask) { 1047235633Sdim default: llvm_unreachable("Invalid segment!"); 1048226584Sdim case 0: 1049226584Sdim // No segment override, check for explicit one on memory operand. 1050226584Sdim if (MemOperand != -1) { // If the instruction has a memory operand. 1051226584Sdim switch (MI.getOperand(MemOperand+X86::AddrSegmentReg).getReg()) { 1052235633Sdim default: llvm_unreachable("Unknown segment register!"); 1053226584Sdim case 0: break; 1054226584Sdim case X86::CS: EmitByte(0x2E, CurByte, OS); break; 1055226584Sdim case X86::SS: EmitByte(0x36, CurByte, OS); break; 1056226584Sdim case X86::DS: EmitByte(0x3E, CurByte, OS); break; 1057226584Sdim case X86::ES: EmitByte(0x26, CurByte, OS); break; 1058226584Sdim case X86::FS: EmitByte(0x64, CurByte, OS); break; 1059226584Sdim case X86::GS: EmitByte(0x65, CurByte, OS); break; 1060226584Sdim } 1061226584Sdim } 1062226584Sdim break; 1063226584Sdim case X86II::FS: 1064226584Sdim EmitByte(0x64, CurByte, OS); 1065226584Sdim break; 1066226584Sdim case X86II::GS: 1067226584Sdim EmitByte(0x65, CurByte, OS); 1068226584Sdim break; 1069226584Sdim } 1070226584Sdim} 1071226584Sdim 1072226584Sdim/// EmitOpcodePrefix - Emit all instruction prefixes prior to the opcode. 1073226584Sdim/// 1074226584Sdim/// MemOperand is the operand # of the start of a memory operand if present. If 1075226584Sdim/// Not present, it is -1. 1076226584Sdimvoid X86MCCodeEmitter::EmitOpcodePrefix(uint64_t TSFlags, unsigned &CurByte, 1077226584Sdim int MemOperand, const MCInst &MI, 1078226584Sdim const MCInstrDesc &Desc, 1079226584Sdim raw_ostream &OS) const { 1080226584Sdim 1081226584Sdim // Emit the lock opcode prefix as needed. 1082226584Sdim if (TSFlags & X86II::LOCK) 1083226584Sdim EmitByte(0xF0, CurByte, OS); 1084226584Sdim 1085226584Sdim // Emit segment override opcode prefix as needed. 1086226584Sdim EmitSegmentOverridePrefix(TSFlags, CurByte, MemOperand, MI, OS); 1087226584Sdim 1088226584Sdim // Emit the repeat opcode prefix as needed. 1089226584Sdim if ((TSFlags & X86II::Op0Mask) == X86II::REP) 1090226584Sdim EmitByte(0xF3, CurByte, OS); 1091226584Sdim 1092226584Sdim // Emit the address size opcode prefix as needed. 1093235633Sdim bool need_address_override; 1094235633Sdim if (TSFlags & X86II::AdSize) { 1095235633Sdim need_address_override = true; 1096235633Sdim } else if (MemOperand == -1) { 1097235633Sdim need_address_override = false; 1098235633Sdim } else if (is64BitMode()) { 1099235633Sdim assert(!Is16BitMemOperand(MI, MemOperand)); 1100235633Sdim need_address_override = Is32BitMemOperand(MI, MemOperand); 1101235633Sdim } else if (is32BitMode()) { 1102235633Sdim assert(!Is64BitMemOperand(MI, MemOperand)); 1103235633Sdim need_address_override = Is16BitMemOperand(MI, MemOperand); 1104235633Sdim } else { 1105235633Sdim need_address_override = false; 1106235633Sdim } 1107235633Sdim 1108235633Sdim if (need_address_override) 1109226584Sdim EmitByte(0x67, CurByte, OS); 1110226584Sdim 1111226584Sdim // Emit the operand size opcode prefix as needed. 1112226584Sdim if (TSFlags & X86II::OpSize) 1113226584Sdim EmitByte(0x66, CurByte, OS); 1114226584Sdim 1115226584Sdim bool Need0FPrefix = false; 1116226584Sdim switch (TSFlags & X86II::Op0Mask) { 1117235633Sdim default: llvm_unreachable("Invalid prefix!"); 1118226584Sdim case 0: break; // No prefix! 1119226584Sdim case X86II::REP: break; // already handled. 1120226584Sdim case X86II::TB: // Two-byte opcode prefix 1121226584Sdim case X86II::T8: // 0F 38 1122226584Sdim case X86II::TA: // 0F 3A 1123226584Sdim case X86II::A6: // 0F A6 1124226584Sdim case X86II::A7: // 0F A7 1125226584Sdim Need0FPrefix = true; 1126226584Sdim break; 1127235633Sdim case X86II::T8XS: // F3 0F 38 1128235633Sdim EmitByte(0xF3, CurByte, OS); 1129235633Sdim Need0FPrefix = true; 1130235633Sdim break; 1131235633Sdim case X86II::T8XD: // F2 0F 38 1132226584Sdim EmitByte(0xF2, CurByte, OS); 1133226584Sdim Need0FPrefix = true; 1134226584Sdim break; 1135235633Sdim case X86II::TAXD: // F2 0F 3A 1136235633Sdim EmitByte(0xF2, CurByte, OS); 1137235633Sdim Need0FPrefix = true; 1138235633Sdim break; 1139226584Sdim case X86II::XS: // F3 0F 1140226584Sdim EmitByte(0xF3, CurByte, OS); 1141226584Sdim Need0FPrefix = true; 1142226584Sdim break; 1143226584Sdim case X86II::XD: // F2 0F 1144226584Sdim EmitByte(0xF2, CurByte, OS); 1145226584Sdim Need0FPrefix = true; 1146226584Sdim break; 1147226584Sdim case X86II::D8: EmitByte(0xD8, CurByte, OS); break; 1148226584Sdim case X86II::D9: EmitByte(0xD9, CurByte, OS); break; 1149226584Sdim case X86II::DA: EmitByte(0xDA, CurByte, OS); break; 1150226584Sdim case X86II::DB: EmitByte(0xDB, CurByte, OS); break; 1151226584Sdim case X86II::DC: EmitByte(0xDC, CurByte, OS); break; 1152226584Sdim case X86II::DD: EmitByte(0xDD, CurByte, OS); break; 1153226584Sdim case X86II::DE: EmitByte(0xDE, CurByte, OS); break; 1154226584Sdim case X86II::DF: EmitByte(0xDF, CurByte, OS); break; 1155226584Sdim } 1156226584Sdim 1157226584Sdim // Handle REX prefix. 1158226584Sdim // FIXME: Can this come before F2 etc to simplify emission? 1159226584Sdim if (is64BitMode()) { 1160226584Sdim if (unsigned REX = DetermineREXPrefix(MI, TSFlags, Desc)) 1161226584Sdim EmitByte(0x40 | REX, CurByte, OS); 1162226584Sdim } 1163226584Sdim 1164226584Sdim // 0x0F escape code must be emitted just before the opcode. 1165226584Sdim if (Need0FPrefix) 1166226584Sdim EmitByte(0x0F, CurByte, OS); 1167226584Sdim 1168226584Sdim // FIXME: Pull this up into previous switch if REX can be moved earlier. 1169226584Sdim switch (TSFlags & X86II::Op0Mask) { 1170235633Sdim case X86II::T8XS: // F3 0F 38 1171235633Sdim case X86II::T8XD: // F2 0F 38 1172226584Sdim case X86II::T8: // 0F 38 1173226584Sdim EmitByte(0x38, CurByte, OS); 1174226584Sdim break; 1175235633Sdim case X86II::TAXD: // F2 0F 3A 1176226584Sdim case X86II::TA: // 0F 3A 1177226584Sdim EmitByte(0x3A, CurByte, OS); 1178226584Sdim break; 1179226584Sdim case X86II::A6: // 0F A6 1180226584Sdim EmitByte(0xA6, CurByte, OS); 1181226584Sdim break; 1182226584Sdim case X86II::A7: // 0F A7 1183226584Sdim EmitByte(0xA7, CurByte, OS); 1184226584Sdim break; 1185226584Sdim } 1186226584Sdim} 1187226584Sdim 1188226584Sdimvoid X86MCCodeEmitter:: 1189226584SdimEncodeInstruction(const MCInst &MI, raw_ostream &OS, 1190226584Sdim SmallVectorImpl<MCFixup> &Fixups) const { 1191226584Sdim unsigned Opcode = MI.getOpcode(); 1192226584Sdim const MCInstrDesc &Desc = MCII.get(Opcode); 1193226584Sdim uint64_t TSFlags = Desc.TSFlags; 1194226584Sdim 1195226584Sdim // Pseudo instructions don't get encoded. 1196226584Sdim if ((TSFlags & X86II::FormMask) == X86II::Pseudo) 1197226584Sdim return; 1198226584Sdim 1199226584Sdim unsigned NumOps = Desc.getNumOperands(); 1200252723Sdim unsigned CurOp = X86II::getOperandBias(Desc); 1201226584Sdim 1202226584Sdim // Keep track of the current byte being emitted. 1203226584Sdim unsigned CurByte = 0; 1204226584Sdim 1205226584Sdim // Is this instruction encoded using the AVX VEX prefix? 1206235633Sdim bool HasVEXPrefix = (TSFlags >> X86II::VEXShift) & X86II::VEX; 1207226584Sdim 1208226584Sdim // It uses the VEX.VVVV field? 1209235633Sdim bool HasVEX_4V = (TSFlags >> X86II::VEXShift) & X86II::VEX_4V; 1210235633Sdim bool HasVEX_4VOp3 = (TSFlags >> X86II::VEXShift) & X86II::VEX_4VOp3; 1211235633Sdim bool HasMemOp4 = (TSFlags >> X86II::VEXShift) & X86II::MemOp4; 1212235633Sdim const unsigned MemOp4_I8IMMOperand = 2; 1213226584Sdim 1214263509Sdim // It uses the EVEX.aaa field? 1215263509Sdim bool HasEVEX = (TSFlags >> X86II::VEXShift) & X86II::EVEX; 1216263509Sdim bool HasEVEX_K = HasEVEX && ((TSFlags >> X86II::VEXShift) & X86II::EVEX_K); 1217263509Sdim 1218226584Sdim // Determine where the memory operand starts, if present. 1219235633Sdim int MemoryOperand = X86II::getMemoryOperandNo(TSFlags, Opcode); 1220226584Sdim if (MemoryOperand != -1) MemoryOperand += CurOp; 1221226584Sdim 1222226584Sdim if (!HasVEXPrefix) 1223226584Sdim EmitOpcodePrefix(TSFlags, CurByte, MemoryOperand, MI, Desc, OS); 1224226584Sdim else 1225226584Sdim EmitVEXOpcodePrefix(TSFlags, CurByte, MemoryOperand, MI, Desc, OS); 1226226584Sdim 1227226584Sdim unsigned char BaseOpcode = X86II::getBaseOpcodeFor(TSFlags); 1228226584Sdim 1229226584Sdim if ((TSFlags >> X86II::VEXShift) & X86II::Has3DNow0F0FOpcode) 1230226584Sdim BaseOpcode = 0x0F; // Weird 3DNow! encoding. 1231226584Sdim 1232226584Sdim unsigned SrcRegNum = 0; 1233226584Sdim switch (TSFlags & X86II::FormMask) { 1234226584Sdim case X86II::MRMInitReg: 1235235633Sdim llvm_unreachable("FIXME: Remove this form when the JIT moves to MCCodeEmitter!"); 1236226584Sdim default: errs() << "FORM: " << (TSFlags & X86II::FormMask) << "\n"; 1237235633Sdim llvm_unreachable("Unknown FormMask value in X86MCCodeEmitter!"); 1238226584Sdim case X86II::Pseudo: 1239235633Sdim llvm_unreachable("Pseudo instruction shouldn't be emitted"); 1240226584Sdim case X86II::RawFrm: 1241226584Sdim EmitByte(BaseOpcode, CurByte, OS); 1242226584Sdim break; 1243226584Sdim case X86II::RawFrmImm8: 1244226584Sdim EmitByte(BaseOpcode, CurByte, OS); 1245235633Sdim EmitImmediate(MI.getOperand(CurOp++), MI.getLoc(), 1246226584Sdim X86II::getSizeOfImm(TSFlags), getImmFixupKind(TSFlags), 1247226584Sdim CurByte, OS, Fixups); 1248235633Sdim EmitImmediate(MI.getOperand(CurOp++), MI.getLoc(), 1, FK_Data_1, CurByte, 1249235633Sdim OS, Fixups); 1250226584Sdim break; 1251226584Sdim case X86II::RawFrmImm16: 1252226584Sdim EmitByte(BaseOpcode, CurByte, OS); 1253235633Sdim EmitImmediate(MI.getOperand(CurOp++), MI.getLoc(), 1254226584Sdim X86II::getSizeOfImm(TSFlags), getImmFixupKind(TSFlags), 1255226584Sdim CurByte, OS, Fixups); 1256235633Sdim EmitImmediate(MI.getOperand(CurOp++), MI.getLoc(), 2, FK_Data_2, CurByte, 1257235633Sdim OS, Fixups); 1258226584Sdim break; 1259226584Sdim 1260226584Sdim case X86II::AddRegFrm: 1261226584Sdim EmitByte(BaseOpcode + GetX86RegNum(MI.getOperand(CurOp++)), CurByte, OS); 1262226584Sdim break; 1263226584Sdim 1264226584Sdim case X86II::MRMDestReg: 1265226584Sdim EmitByte(BaseOpcode, CurByte, OS); 1266252723Sdim SrcRegNum = CurOp + 1; 1267252723Sdim 1268263509Sdim if (HasEVEX_K) // Skip writemask 1269263509Sdim SrcRegNum++; 1270263509Sdim 1271252723Sdim if (HasVEX_4V) // Skip 1st src (which is encoded in VEX_VVVV) 1272252723Sdim ++SrcRegNum; 1273252723Sdim 1274226584Sdim EmitRegModRMByte(MI.getOperand(CurOp), 1275252723Sdim GetX86RegNum(MI.getOperand(SrcRegNum)), CurByte, OS); 1276252723Sdim CurOp = SrcRegNum + 1; 1277226584Sdim break; 1278226584Sdim 1279226584Sdim case X86II::MRMDestMem: 1280226584Sdim EmitByte(BaseOpcode, CurByte, OS); 1281226584Sdim SrcRegNum = CurOp + X86::AddrNumOperands; 1282226584Sdim 1283263509Sdim if (HasEVEX_K) // Skip writemask 1284263509Sdim SrcRegNum++; 1285263509Sdim 1286226584Sdim if (HasVEX_4V) // Skip 1st src (which is encoded in VEX_VVVV) 1287245431Sdim ++SrcRegNum; 1288226584Sdim 1289226584Sdim EmitMemModRMByte(MI, CurOp, 1290226584Sdim GetX86RegNum(MI.getOperand(SrcRegNum)), 1291226584Sdim TSFlags, CurByte, OS, Fixups); 1292226584Sdim CurOp = SrcRegNum + 1; 1293226584Sdim break; 1294226584Sdim 1295226584Sdim case X86II::MRMSrcReg: 1296226584Sdim EmitByte(BaseOpcode, CurByte, OS); 1297226584Sdim SrcRegNum = CurOp + 1; 1298226584Sdim 1299263509Sdim if (HasEVEX_K) // Skip writemask 1300263509Sdim SrcRegNum++; 1301263509Sdim 1302226584Sdim if (HasVEX_4V) // Skip 1st src (which is encoded in VEX_VVVV) 1303245431Sdim ++SrcRegNum; 1304226584Sdim 1305245431Sdim if (HasMemOp4) // Skip 2nd src (which is encoded in I8IMM) 1306245431Sdim ++SrcRegNum; 1307235633Sdim 1308226584Sdim EmitRegModRMByte(MI.getOperand(SrcRegNum), 1309226584Sdim GetX86RegNum(MI.getOperand(CurOp)), CurByte, OS); 1310235633Sdim 1311245431Sdim // 2 operands skipped with HasMemOp4, compensate accordingly 1312235633Sdim CurOp = HasMemOp4 ? SrcRegNum : SrcRegNum + 1; 1313235633Sdim if (HasVEX_4VOp3) 1314235633Sdim ++CurOp; 1315226584Sdim break; 1316226584Sdim 1317226584Sdim case X86II::MRMSrcMem: { 1318226584Sdim int AddrOperands = X86::AddrNumOperands; 1319226584Sdim unsigned FirstMemOp = CurOp+1; 1320263509Sdim 1321263509Sdim if (HasEVEX_K) { // Skip writemask 1322263509Sdim ++AddrOperands; 1323263509Sdim ++FirstMemOp; 1324263509Sdim } 1325263509Sdim 1326226584Sdim if (HasVEX_4V) { 1327226584Sdim ++AddrOperands; 1328226584Sdim ++FirstMemOp; // Skip the register source (which is encoded in VEX_VVVV). 1329226584Sdim } 1330245431Sdim if (HasMemOp4) // Skip second register source (encoded in I8IMM) 1331235633Sdim ++FirstMemOp; 1332226584Sdim 1333226584Sdim EmitByte(BaseOpcode, CurByte, OS); 1334226584Sdim 1335226584Sdim EmitMemModRMByte(MI, FirstMemOp, GetX86RegNum(MI.getOperand(CurOp)), 1336226584Sdim TSFlags, CurByte, OS, Fixups); 1337226584Sdim CurOp += AddrOperands + 1; 1338235633Sdim if (HasVEX_4VOp3) 1339235633Sdim ++CurOp; 1340226584Sdim break; 1341226584Sdim } 1342226584Sdim 1343226584Sdim case X86II::MRM0r: case X86II::MRM1r: 1344226584Sdim case X86II::MRM2r: case X86II::MRM3r: 1345226584Sdim case X86II::MRM4r: case X86II::MRM5r: 1346226584Sdim case X86II::MRM6r: case X86II::MRM7r: 1347226584Sdim if (HasVEX_4V) // Skip the register dst (which is encoded in VEX_VVVV). 1348245431Sdim ++CurOp; 1349226584Sdim EmitByte(BaseOpcode, CurByte, OS); 1350226584Sdim EmitRegModRMByte(MI.getOperand(CurOp++), 1351226584Sdim (TSFlags & X86II::FormMask)-X86II::MRM0r, 1352226584Sdim CurByte, OS); 1353226584Sdim break; 1354226584Sdim case X86II::MRM0m: case X86II::MRM1m: 1355226584Sdim case X86II::MRM2m: case X86II::MRM3m: 1356226584Sdim case X86II::MRM4m: case X86II::MRM5m: 1357226584Sdim case X86II::MRM6m: case X86II::MRM7m: 1358235633Sdim if (HasVEX_4V) // Skip the register dst (which is encoded in VEX_VVVV). 1359245431Sdim ++CurOp; 1360226584Sdim EmitByte(BaseOpcode, CurByte, OS); 1361226584Sdim EmitMemModRMByte(MI, CurOp, (TSFlags & X86II::FormMask)-X86II::MRM0m, 1362226584Sdim TSFlags, CurByte, OS, Fixups); 1363226584Sdim CurOp += X86::AddrNumOperands; 1364226584Sdim break; 1365252723Sdim case X86II::MRM_C1: case X86II::MRM_C2: case X86II::MRM_C3: 1366252723Sdim case X86II::MRM_C4: case X86II::MRM_C8: case X86II::MRM_C9: 1367252723Sdim case X86II::MRM_CA: case X86II::MRM_CB: case X86II::MRM_D0: 1368252723Sdim case X86II::MRM_D1: case X86II::MRM_D4: case X86II::MRM_D5: 1369252723Sdim case X86II::MRM_D6: case X86II::MRM_D8: case X86II::MRM_D9: 1370252723Sdim case X86II::MRM_DA: case X86II::MRM_DB: case X86II::MRM_DC: 1371252723Sdim case X86II::MRM_DD: case X86II::MRM_DE: case X86II::MRM_DF: 1372252723Sdim case X86II::MRM_E8: case X86II::MRM_F0: case X86II::MRM_F8: 1373252723Sdim case X86II::MRM_F9: 1374226584Sdim EmitByte(BaseOpcode, CurByte, OS); 1375235633Sdim 1376235633Sdim unsigned char MRM; 1377235633Sdim switch (TSFlags & X86II::FormMask) { 1378235633Sdim default: llvm_unreachable("Invalid Form"); 1379235633Sdim case X86II::MRM_C1: MRM = 0xC1; break; 1380235633Sdim case X86II::MRM_C2: MRM = 0xC2; break; 1381235633Sdim case X86II::MRM_C3: MRM = 0xC3; break; 1382235633Sdim case X86II::MRM_C4: MRM = 0xC4; break; 1383235633Sdim case X86II::MRM_C8: MRM = 0xC8; break; 1384235633Sdim case X86II::MRM_C9: MRM = 0xC9; break; 1385252723Sdim case X86II::MRM_CA: MRM = 0xCA; break; 1386252723Sdim case X86II::MRM_CB: MRM = 0xCB; break; 1387235633Sdim case X86II::MRM_D0: MRM = 0xD0; break; 1388235633Sdim case X86II::MRM_D1: MRM = 0xD1; break; 1389235633Sdim case X86II::MRM_D4: MRM = 0xD4; break; 1390245431Sdim case X86II::MRM_D5: MRM = 0xD5; break; 1391252723Sdim case X86II::MRM_D6: MRM = 0xD6; break; 1392235633Sdim case X86II::MRM_D8: MRM = 0xD8; break; 1393235633Sdim case X86II::MRM_D9: MRM = 0xD9; break; 1394235633Sdim case X86II::MRM_DA: MRM = 0xDA; break; 1395235633Sdim case X86II::MRM_DB: MRM = 0xDB; break; 1396235633Sdim case X86II::MRM_DC: MRM = 0xDC; break; 1397235633Sdim case X86II::MRM_DD: MRM = 0xDD; break; 1398235633Sdim case X86II::MRM_DE: MRM = 0xDE; break; 1399235633Sdim case X86II::MRM_DF: MRM = 0xDF; break; 1400235633Sdim case X86II::MRM_E8: MRM = 0xE8; break; 1401235633Sdim case X86II::MRM_F0: MRM = 0xF0; break; 1402235633Sdim case X86II::MRM_F8: MRM = 0xF8; break; 1403235633Sdim case X86II::MRM_F9: MRM = 0xF9; break; 1404235633Sdim } 1405235633Sdim EmitByte(MRM, CurByte, OS); 1406226584Sdim break; 1407226584Sdim } 1408226584Sdim 1409226584Sdim // If there is a remaining operand, it must be a trailing immediate. Emit it 1410245431Sdim // according to the right size for the instruction. Some instructions 1411245431Sdim // (SSE4a extrq and insertq) have two trailing immediates. 1412245431Sdim while (CurOp != NumOps && NumOps - CurOp <= 2) { 1413226584Sdim // The last source register of a 4 operand instruction in AVX is encoded 1414235633Sdim // in bits[7:4] of a immediate byte. 1415226584Sdim if ((TSFlags >> X86II::VEXShift) & X86II::VEX_I8IMM) { 1416235633Sdim const MCOperand &MO = MI.getOperand(HasMemOp4 ? MemOp4_I8IMMOperand 1417245431Sdim : CurOp); 1418245431Sdim ++CurOp; 1419245431Sdim unsigned RegNum = GetX86RegNum(MO) << 4; 1420245431Sdim if (X86II::isX86_64ExtendedReg(MO.getReg())) 1421245431Sdim RegNum |= 1 << 7; 1422235633Sdim // If there is an additional 5th operand it must be an immediate, which 1423235633Sdim // is encoded in bits[3:0] 1424245431Sdim if (CurOp != NumOps) { 1425235633Sdim const MCOperand &MIMM = MI.getOperand(CurOp++); 1426245431Sdim if (MIMM.isImm()) { 1427235633Sdim unsigned Val = MIMM.getImm(); 1428235633Sdim assert(Val < 16 && "Immediate operand value out of range"); 1429235633Sdim RegNum |= Val; 1430235633Sdim } 1431235633Sdim } 1432235633Sdim EmitImmediate(MCOperand::CreateImm(RegNum), MI.getLoc(), 1, FK_Data_1, 1433235633Sdim CurByte, OS, Fixups); 1434226584Sdim } else { 1435226584Sdim unsigned FixupKind; 1436226584Sdim // FIXME: Is there a better way to know that we need a signed relocation? 1437226584Sdim if (MI.getOpcode() == X86::ADD64ri32 || 1438226584Sdim MI.getOpcode() == X86::MOV64ri32 || 1439226584Sdim MI.getOpcode() == X86::MOV64mi32 || 1440226584Sdim MI.getOpcode() == X86::PUSH64i32) 1441226584Sdim FixupKind = X86::reloc_signed_4byte; 1442226584Sdim else 1443226584Sdim FixupKind = getImmFixupKind(TSFlags); 1444235633Sdim EmitImmediate(MI.getOperand(CurOp++), MI.getLoc(), 1445226584Sdim X86II::getSizeOfImm(TSFlags), MCFixupKind(FixupKind), 1446226584Sdim CurByte, OS, Fixups); 1447226584Sdim } 1448226584Sdim } 1449226584Sdim 1450226584Sdim if ((TSFlags >> X86II::VEXShift) & X86II::Has3DNow0F0FOpcode) 1451226584Sdim EmitByte(X86II::getBaseOpcodeFor(TSFlags), CurByte, OS); 1452226584Sdim 1453226584Sdim#ifndef NDEBUG 1454226584Sdim // FIXME: Verify. 1455226584Sdim if (/*!Desc.isVariadic() &&*/ CurOp != NumOps) { 1456226584Sdim errs() << "Cannot encode all operands of: "; 1457226584Sdim MI.dump(); 1458226584Sdim errs() << '\n'; 1459226584Sdim abort(); 1460226584Sdim } 1461226584Sdim#endif 1462226584Sdim} 1463