X86MCCodeEmitter.cpp revision 280031
1234353Sdim//===-- 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#include "MCTargetDesc/X86MCTargetDesc.h" 15226584Sdim#include "MCTargetDesc/X86BaseInfo.h" 16226584Sdim#include "MCTargetDesc/X86FixupKinds.h" 17226584Sdim#include "llvm/MC/MCCodeEmitter.h" 18243830Sdim#include "llvm/MC/MCContext.h" 19226584Sdim#include "llvm/MC/MCExpr.h" 20226584Sdim#include "llvm/MC/MCInst.h" 21226584Sdim#include "llvm/MC/MCInstrInfo.h" 22226584Sdim#include "llvm/MC/MCRegisterInfo.h" 23226584Sdim#include "llvm/MC/MCSubtargetInfo.h" 24226584Sdim#include "llvm/MC/MCSymbol.h" 25226584Sdim#include "llvm/Support/raw_ostream.h" 26226584Sdim 27226584Sdimusing namespace llvm; 28226584Sdim 29276479Sdim#define DEBUG_TYPE "mccodeemitter" 30276479Sdim 31226584Sdimnamespace { 32226584Sdimclass X86MCCodeEmitter : public MCCodeEmitter { 33243830Sdim X86MCCodeEmitter(const X86MCCodeEmitter &) LLVM_DELETED_FUNCTION; 34243830Sdim void operator=(const X86MCCodeEmitter &) LLVM_DELETED_FUNCTION; 35226584Sdim const MCInstrInfo &MCII; 36226584Sdim MCContext &Ctx; 37226584Sdimpublic: 38276479Sdim X86MCCodeEmitter(const MCInstrInfo &mcii, MCContext &ctx) 39276479Sdim : MCII(mcii), Ctx(ctx) { 40226584Sdim } 41226584Sdim 42226584Sdim ~X86MCCodeEmitter() {} 43226584Sdim 44276479Sdim bool is64BitMode(const MCSubtargetInfo &STI) const { 45226584Sdim return (STI.getFeatureBits() & X86::Mode64Bit) != 0; 46226584Sdim } 47226584Sdim 48276479Sdim bool is32BitMode(const MCSubtargetInfo &STI) const { 49276479Sdim return (STI.getFeatureBits() & X86::Mode32Bit) != 0; 50234353Sdim } 51234353Sdim 52276479Sdim bool is16BitMode(const MCSubtargetInfo &STI) const { 53276479Sdim return (STI.getFeatureBits() & X86::Mode16Bit) != 0; 54276479Sdim } 55276479Sdim 56276479Sdim /// Is16BitMemOperand - Return true if the specified instruction has 57276479Sdim /// a 16-bit memory operand. Op specifies the operand # of the memoperand. 58276479Sdim bool Is16BitMemOperand(const MCInst &MI, unsigned Op, 59276479Sdim const MCSubtargetInfo &STI) const { 60276479Sdim const MCOperand &BaseReg = MI.getOperand(Op+X86::AddrBaseReg); 61276479Sdim const MCOperand &IndexReg = MI.getOperand(Op+X86::AddrIndexReg); 62276479Sdim const MCOperand &Disp = MI.getOperand(Op+X86::AddrDisp); 63276479Sdim 64276479Sdim if (is16BitMode(STI) && BaseReg.getReg() == 0 && 65276479Sdim Disp.isImm() && Disp.getImm() < 0x10000) 66276479Sdim return true; 67276479Sdim if ((BaseReg.getReg() != 0 && 68276479Sdim X86MCRegisterClasses[X86::GR16RegClassID].contains(BaseReg.getReg())) || 69276479Sdim (IndexReg.getReg() != 0 && 70276479Sdim X86MCRegisterClasses[X86::GR16RegClassID].contains(IndexReg.getReg()))) 71276479Sdim return true; 72276479Sdim return false; 73276479Sdim } 74276479Sdim 75243830Sdim unsigned GetX86RegNum(const MCOperand &MO) const { 76261991Sdim return Ctx.getRegisterInfo()->getEncodingValue(MO.getReg()) & 0x7; 77226584Sdim } 78226584Sdim 79226584Sdim // On regular x86, both XMM0-XMM7 and XMM8-XMM15 are encoded in the range 80226584Sdim // 0-7 and the difference between the 2 groups is given by the REX prefix. 81226584Sdim // In the VEX prefix, registers are seen sequencially from 0-15 and encoded 82226584Sdim // in 1's complement form, example: 83226584Sdim // 84226584Sdim // ModRM field => XMM9 => 1 85226584Sdim // VEX.VVVV => XMM9 => ~9 86226584Sdim // 87226584Sdim // See table 4-35 of Intel AVX Programming Reference for details. 88243830Sdim unsigned char getVEXRegisterEncoding(const MCInst &MI, 89243830Sdim unsigned OpNum) const { 90226584Sdim unsigned SrcReg = MI.getOperand(OpNum).getReg(); 91226584Sdim unsigned SrcRegNum = GetX86RegNum(MI.getOperand(OpNum)); 92234353Sdim if (X86II::isX86_64ExtendedReg(SrcReg)) 93234353Sdim SrcRegNum |= 8; 94226584Sdim 95226584Sdim // The registers represented through VEX_VVVV should 96226584Sdim // be encoded in 1's complement form. 97226584Sdim return (~SrcRegNum) & 0xf; 98226584Sdim } 99226584Sdim 100261991Sdim unsigned char getWriteMaskRegisterEncoding(const MCInst &MI, 101261991Sdim unsigned OpNum) const { 102261991Sdim assert(X86::K0 != MI.getOperand(OpNum).getReg() && 103261991Sdim "Invalid mask register as write-mask!"); 104261991Sdim unsigned MaskRegNum = GetX86RegNum(MI.getOperand(OpNum)); 105261991Sdim return MaskRegNum; 106261991Sdim } 107261991Sdim 108226584Sdim void EmitByte(unsigned char C, unsigned &CurByte, raw_ostream &OS) const { 109226584Sdim OS << (char)C; 110226584Sdim ++CurByte; 111226584Sdim } 112226584Sdim 113226584Sdim void EmitConstant(uint64_t Val, unsigned Size, unsigned &CurByte, 114226584Sdim raw_ostream &OS) const { 115226584Sdim // Output the constant in little endian byte order. 116226584Sdim for (unsigned i = 0; i != Size; ++i) { 117226584Sdim EmitByte(Val & 255, CurByte, OS); 118226584Sdim Val >>= 8; 119226584Sdim } 120226584Sdim } 121226584Sdim 122234353Sdim void EmitImmediate(const MCOperand &Disp, SMLoc Loc, 123226584Sdim unsigned ImmSize, MCFixupKind FixupKind, 124226584Sdim unsigned &CurByte, raw_ostream &OS, 125226584Sdim SmallVectorImpl<MCFixup> &Fixups, 126226584Sdim int ImmOffset = 0) const; 127226584Sdim 128226584Sdim inline static unsigned char ModRMByte(unsigned Mod, unsigned RegOpcode, 129226584Sdim unsigned RM) { 130226584Sdim assert(Mod < 4 && RegOpcode < 8 && RM < 8 && "ModRM Fields out of range!"); 131226584Sdim return RM | (RegOpcode << 3) | (Mod << 6); 132226584Sdim } 133226584Sdim 134226584Sdim void EmitRegModRMByte(const MCOperand &ModRMReg, unsigned RegOpcodeFld, 135226584Sdim unsigned &CurByte, raw_ostream &OS) const { 136226584Sdim EmitByte(ModRMByte(3, RegOpcodeFld, GetX86RegNum(ModRMReg)), CurByte, OS); 137226584Sdim } 138226584Sdim 139226584Sdim void EmitSIBByte(unsigned SS, unsigned Index, unsigned Base, 140226584Sdim unsigned &CurByte, raw_ostream &OS) const { 141226584Sdim // SIB byte is in the same format as the ModRMByte. 142226584Sdim EmitByte(ModRMByte(SS, Index, Base), CurByte, OS); 143226584Sdim } 144226584Sdim 145226584Sdim 146226584Sdim void EmitMemModRMByte(const MCInst &MI, unsigned Op, 147226584Sdim unsigned RegOpcodeField, 148226584Sdim uint64_t TSFlags, unsigned &CurByte, raw_ostream &OS, 149276479Sdim SmallVectorImpl<MCFixup> &Fixups, 150276479Sdim const MCSubtargetInfo &STI) const; 151226584Sdim 152226584Sdim void EncodeInstruction(const MCInst &MI, raw_ostream &OS, 153276479Sdim SmallVectorImpl<MCFixup> &Fixups, 154276479Sdim const MCSubtargetInfo &STI) const override; 155226584Sdim 156226584Sdim void EmitVEXOpcodePrefix(uint64_t TSFlags, unsigned &CurByte, int MemOperand, 157226584Sdim const MCInst &MI, const MCInstrDesc &Desc, 158226584Sdim raw_ostream &OS) const; 159226584Sdim 160276479Sdim void EmitSegmentOverridePrefix(unsigned &CurByte, unsigned SegOperand, 161276479Sdim const MCInst &MI, raw_ostream &OS) const; 162226584Sdim 163226584Sdim void EmitOpcodePrefix(uint64_t TSFlags, unsigned &CurByte, int MemOperand, 164226584Sdim const MCInst &MI, const MCInstrDesc &Desc, 165276479Sdim const MCSubtargetInfo &STI, 166226584Sdim raw_ostream &OS) const; 167226584Sdim}; 168226584Sdim 169226584Sdim} // end anonymous namespace 170226584Sdim 171226584Sdim 172226584SdimMCCodeEmitter *llvm::createX86MCCodeEmitter(const MCInstrInfo &MCII, 173239462Sdim const MCRegisterInfo &MRI, 174226584Sdim const MCSubtargetInfo &STI, 175226584Sdim MCContext &Ctx) { 176276479Sdim return new X86MCCodeEmitter(MCII, Ctx); 177226584Sdim} 178226584Sdim 179226584Sdim/// isDisp8 - Return true if this signed displacement fits in a 8-bit 180226584Sdim/// sign-extended field. 181226584Sdimstatic bool isDisp8(int Value) { 182226584Sdim return Value == (signed char)Value; 183226584Sdim} 184226584Sdim 185261991Sdim/// isCDisp8 - Return true if this signed displacement fits in a 8-bit 186261991Sdim/// compressed dispacement field. 187261991Sdimstatic bool isCDisp8(uint64_t TSFlags, int Value, int& CValue) { 188280031Sdim assert(((TSFlags & X86II::EncodingMask) == X86II::EVEX) && 189261991Sdim "Compressed 8-bit displacement is only valid for EVEX inst."); 190261991Sdim 191276479Sdim unsigned CD8_Scale = 192280031Sdim (TSFlags & X86II::CD8_Scale_Mask) >> X86II::CD8_Scale_Shift; 193276479Sdim if (CD8_Scale == 0) { 194261991Sdim CValue = Value; 195261991Sdim return isDisp8(Value); 196261991Sdim } 197261991Sdim 198276479Sdim unsigned Mask = CD8_Scale - 1; 199276479Sdim assert((CD8_Scale & Mask) == 0 && "Invalid memory object size."); 200276479Sdim if (Value & Mask) // Unaligned offset 201261991Sdim return false; 202276479Sdim Value /= (int)CD8_Scale; 203261991Sdim bool Ret = (Value == (signed char)Value); 204261991Sdim 205261991Sdim if (Ret) 206261991Sdim CValue = Value; 207261991Sdim return Ret; 208261991Sdim} 209261991Sdim 210226584Sdim/// getImmFixupKind - Return the appropriate fixup kind to use for an immediate 211226584Sdim/// in an instruction with the specified TSFlags. 212226584Sdimstatic MCFixupKind getImmFixupKind(uint64_t TSFlags) { 213226584Sdim unsigned Size = X86II::getSizeOfImm(TSFlags); 214226584Sdim bool isPCRel = X86II::isImmPCRel(TSFlags); 215226584Sdim 216276479Sdim if (X86II::isImmSigned(TSFlags)) { 217276479Sdim switch (Size) { 218276479Sdim default: llvm_unreachable("Unsupported signed fixup size!"); 219276479Sdim case 4: return MCFixupKind(X86::reloc_signed_4byte); 220276479Sdim } 221276479Sdim } 222226584Sdim return MCFixup::getKindForSize(Size, isPCRel); 223226584Sdim} 224226584Sdim 225234353Sdim/// Is32BitMemOperand - Return true if the specified instruction has 226234353Sdim/// a 32-bit memory operand. Op specifies the operand # of the memoperand. 227226584Sdimstatic bool Is32BitMemOperand(const MCInst &MI, unsigned Op) { 228226584Sdim const MCOperand &BaseReg = MI.getOperand(Op+X86::AddrBaseReg); 229226584Sdim const MCOperand &IndexReg = MI.getOperand(Op+X86::AddrIndexReg); 230226584Sdim 231226584Sdim if ((BaseReg.getReg() != 0 && 232226584Sdim X86MCRegisterClasses[X86::GR32RegClassID].contains(BaseReg.getReg())) || 233226584Sdim (IndexReg.getReg() != 0 && 234226584Sdim X86MCRegisterClasses[X86::GR32RegClassID].contains(IndexReg.getReg()))) 235226584Sdim return true; 236226584Sdim return false; 237226584Sdim} 238226584Sdim 239234353Sdim/// Is64BitMemOperand - Return true if the specified instruction has 240234353Sdim/// a 64-bit memory operand. Op specifies the operand # of the memoperand. 241234353Sdim#ifndef NDEBUG 242234353Sdimstatic bool Is64BitMemOperand(const MCInst &MI, unsigned Op) { 243234353Sdim const MCOperand &BaseReg = MI.getOperand(Op+X86::AddrBaseReg); 244234353Sdim const MCOperand &IndexReg = MI.getOperand(Op+X86::AddrIndexReg); 245234353Sdim 246234353Sdim if ((BaseReg.getReg() != 0 && 247234353Sdim X86MCRegisterClasses[X86::GR64RegClassID].contains(BaseReg.getReg())) || 248234353Sdim (IndexReg.getReg() != 0 && 249234353Sdim X86MCRegisterClasses[X86::GR64RegClassID].contains(IndexReg.getReg()))) 250234353Sdim return true; 251234353Sdim return false; 252234353Sdim} 253234353Sdim#endif 254234353Sdim 255234353Sdim/// StartsWithGlobalOffsetTable - Check if this expression starts with 256234353Sdim/// _GLOBAL_OFFSET_TABLE_ and if it is of the form 257234353Sdim/// _GLOBAL_OFFSET_TABLE_-symbol. This is needed to support PIC on ELF 258234353Sdim/// i386 as _GLOBAL_OFFSET_TABLE_ is magical. We check only simple case that 259226584Sdim/// are know to be used: _GLOBAL_OFFSET_TABLE_ by itself or at the start 260226584Sdim/// of a binary expression. 261234353Sdimenum GlobalOffsetTableExprKind { 262234353Sdim GOT_None, 263234353Sdim GOT_Normal, 264234353Sdim GOT_SymDiff 265234353Sdim}; 266234353Sdimstatic GlobalOffsetTableExprKind 267234353SdimStartsWithGlobalOffsetTable(const MCExpr *Expr) { 268276479Sdim const MCExpr *RHS = nullptr; 269226584Sdim if (Expr->getKind() == MCExpr::Binary) { 270226584Sdim const MCBinaryExpr *BE = static_cast<const MCBinaryExpr *>(Expr); 271226584Sdim Expr = BE->getLHS(); 272234353Sdim RHS = BE->getRHS(); 273226584Sdim } 274226584Sdim 275226584Sdim if (Expr->getKind() != MCExpr::SymbolRef) 276234353Sdim return GOT_None; 277226584Sdim 278226584Sdim const MCSymbolRefExpr *Ref = static_cast<const MCSymbolRefExpr*>(Expr); 279226584Sdim const MCSymbol &S = Ref->getSymbol(); 280234353Sdim if (S.getName() != "_GLOBAL_OFFSET_TABLE_") 281234353Sdim return GOT_None; 282234353Sdim if (RHS && RHS->getKind() == MCExpr::SymbolRef) 283234353Sdim return GOT_SymDiff; 284234353Sdim return GOT_Normal; 285226584Sdim} 286226584Sdim 287251662Sdimstatic bool HasSecRelSymbolRef(const MCExpr *Expr) { 288251662Sdim if (Expr->getKind() == MCExpr::SymbolRef) { 289251662Sdim const MCSymbolRefExpr *Ref = static_cast<const MCSymbolRefExpr*>(Expr); 290251662Sdim return Ref->getKind() == MCSymbolRefExpr::VK_SECREL; 291251662Sdim } 292251662Sdim return false; 293251662Sdim} 294251662Sdim 295226584Sdimvoid X86MCCodeEmitter:: 296234353SdimEmitImmediate(const MCOperand &DispOp, SMLoc Loc, unsigned Size, 297234353Sdim MCFixupKind FixupKind, unsigned &CurByte, raw_ostream &OS, 298226584Sdim SmallVectorImpl<MCFixup> &Fixups, int ImmOffset) const { 299276479Sdim const MCExpr *Expr = nullptr; 300226584Sdim if (DispOp.isImm()) { 301226584Sdim // If this is a simple integer displacement that doesn't require a 302226584Sdim // relocation, emit it now. 303226584Sdim if (FixupKind != FK_PCRel_1 && 304226584Sdim FixupKind != FK_PCRel_2 && 305226584Sdim FixupKind != FK_PCRel_4) { 306226584Sdim EmitConstant(DispOp.getImm()+ImmOffset, Size, CurByte, OS); 307226584Sdim return; 308226584Sdim } 309226584Sdim Expr = MCConstantExpr::Create(DispOp.getImm(), Ctx); 310226584Sdim } else { 311226584Sdim Expr = DispOp.getExpr(); 312226584Sdim } 313226584Sdim 314226584Sdim // If we have an immoffset, add it to the expression. 315226584Sdim if ((FixupKind == FK_Data_4 || 316234353Sdim FixupKind == FK_Data_8 || 317234353Sdim FixupKind == MCFixupKind(X86::reloc_signed_4byte))) { 318234353Sdim GlobalOffsetTableExprKind Kind = StartsWithGlobalOffsetTable(Expr); 319234353Sdim if (Kind != GOT_None) { 320234353Sdim assert(ImmOffset == 0); 321226584Sdim 322276479Sdim if (Size == 8) { 323276479Sdim FixupKind = MCFixupKind(X86::reloc_global_offset_table8); 324276479Sdim } else { 325276479Sdim assert(Size == 4); 326276479Sdim FixupKind = MCFixupKind(X86::reloc_global_offset_table); 327276479Sdim } 328276479Sdim 329234353Sdim if (Kind == GOT_Normal) 330234353Sdim ImmOffset = CurByte; 331234353Sdim } else if (Expr->getKind() == MCExpr::SymbolRef) { 332251662Sdim if (HasSecRelSymbolRef(Expr)) { 333234353Sdim FixupKind = MCFixupKind(FK_SecRel_4); 334234353Sdim } 335251662Sdim } else if (Expr->getKind() == MCExpr::Binary) { 336251662Sdim const MCBinaryExpr *Bin = static_cast<const MCBinaryExpr*>(Expr); 337251662Sdim if (HasSecRelSymbolRef(Bin->getLHS()) 338251662Sdim || HasSecRelSymbolRef(Bin->getRHS())) { 339251662Sdim FixupKind = MCFixupKind(FK_SecRel_4); 340251662Sdim } 341234353Sdim } 342226584Sdim } 343226584Sdim 344226584Sdim // If the fixup is pc-relative, we need to bias the value to be relative to 345226584Sdim // the start of the field, not the end of the field. 346226584Sdim if (FixupKind == FK_PCRel_4 || 347226584Sdim FixupKind == MCFixupKind(X86::reloc_riprel_4byte) || 348226584Sdim FixupKind == MCFixupKind(X86::reloc_riprel_4byte_movq_load)) 349226584Sdim ImmOffset -= 4; 350226584Sdim if (FixupKind == FK_PCRel_2) 351226584Sdim ImmOffset -= 2; 352226584Sdim if (FixupKind == FK_PCRel_1) 353226584Sdim ImmOffset -= 1; 354226584Sdim 355226584Sdim if (ImmOffset) 356226584Sdim Expr = MCBinaryExpr::CreateAdd(Expr, MCConstantExpr::Create(ImmOffset, Ctx), 357226584Sdim Ctx); 358226584Sdim 359226584Sdim // Emit a symbolic constant as a fixup and 4 zeros. 360234353Sdim Fixups.push_back(MCFixup::Create(CurByte, Expr, FixupKind, Loc)); 361226584Sdim EmitConstant(0, Size, CurByte, OS); 362226584Sdim} 363226584Sdim 364226584Sdimvoid X86MCCodeEmitter::EmitMemModRMByte(const MCInst &MI, unsigned Op, 365226584Sdim unsigned RegOpcodeField, 366226584Sdim uint64_t TSFlags, unsigned &CurByte, 367226584Sdim raw_ostream &OS, 368276479Sdim SmallVectorImpl<MCFixup> &Fixups, 369276479Sdim const MCSubtargetInfo &STI) 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(); 375280031Sdim bool HasEVEX = (TSFlags & X86II::EncodingMask) == X86II::EVEX; 376226584Sdim 377226584Sdim // Handle %rip relative addressing. 378226584Sdim if (BaseReg == X86::RIP) { // [disp32+RIP] in X86-64 mode 379276479Sdim assert(is64BitMode(STI) && "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 398234353Sdim EmitImmediate(Disp, MI.getLoc(), 4, MCFixupKind(FixupKind), 399226584Sdim CurByte, OS, Fixups, -ImmSize); 400226584Sdim return; 401226584Sdim } 402226584Sdim 403226584Sdim unsigned BaseRegNo = BaseReg ? GetX86RegNum(Base) : -1U; 404226584Sdim 405276479Sdim // 16-bit addressing forms of the ModR/M byte have a different encoding for 406276479Sdim // the R/M field and are far more limited in which registers can be used. 407276479Sdim if (Is16BitMemOperand(MI, Op, STI)) { 408276479Sdim if (BaseReg) { 409276479Sdim // For 32-bit addressing, the row and column values in Table 2-2 are 410276479Sdim // basically the same. It's AX/CX/DX/BX/SP/BP/SI/DI in that order, with 411276479Sdim // some special cases. And GetX86RegNum reflects that numbering. 412276479Sdim // For 16-bit addressing it's more fun, as shown in the SDM Vol 2A, 413276479Sdim // Table 2-1 "16-Bit Addressing Forms with the ModR/M byte". We can only 414276479Sdim // use SI/DI/BP/BX, which have "row" values 4-7 in no particular order, 415276479Sdim // while values 0-3 indicate the allowed combinations (base+index) of 416276479Sdim // those: 0 for BX+SI, 1 for BX+DI, 2 for BP+SI, 3 for BP+DI. 417276479Sdim // 418276479Sdim // R16Table[] is a lookup from the normal RegNo, to the row values from 419276479Sdim // Table 2-1 for 16-bit addressing modes. Where zero means disallowed. 420276479Sdim static const unsigned R16Table[] = { 0, 0, 0, 7, 0, 6, 4, 5 }; 421276479Sdim unsigned RMfield = R16Table[BaseRegNo]; 422276479Sdim 423276479Sdim assert(RMfield && "invalid 16-bit base register"); 424276479Sdim 425276479Sdim if (IndexReg.getReg()) { 426276479Sdim unsigned IndexReg16 = R16Table[GetX86RegNum(IndexReg)]; 427276479Sdim 428276479Sdim assert(IndexReg16 && "invalid 16-bit index register"); 429276479Sdim // We must have one of SI/DI (4,5), and one of BP/BX (6,7). 430276479Sdim assert(((IndexReg16 ^ RMfield) & 2) && 431276479Sdim "invalid 16-bit base/index register combination"); 432276479Sdim assert(Scale.getImm() == 1 && 433276479Sdim "invalid scale for 16-bit memory reference"); 434276479Sdim 435276479Sdim // Allow base/index to appear in either order (although GAS doesn't). 436276479Sdim if (IndexReg16 & 2) 437276479Sdim RMfield = (RMfield & 1) | ((7 - IndexReg16) << 1); 438276479Sdim else 439276479Sdim RMfield = (IndexReg16 & 1) | ((7 - RMfield) << 1); 440276479Sdim } 441276479Sdim 442276479Sdim if (Disp.isImm() && isDisp8(Disp.getImm())) { 443276479Sdim if (Disp.getImm() == 0 && BaseRegNo != N86::EBP) { 444276479Sdim // There is no displacement; just the register. 445276479Sdim EmitByte(ModRMByte(0, RegOpcodeField, RMfield), CurByte, OS); 446276479Sdim return; 447276479Sdim } 448276479Sdim // Use the [REG]+disp8 form, including for [BP] which cannot be encoded. 449276479Sdim EmitByte(ModRMByte(1, RegOpcodeField, RMfield), CurByte, OS); 450276479Sdim EmitImmediate(Disp, MI.getLoc(), 1, FK_Data_1, CurByte, OS, Fixups); 451276479Sdim return; 452276479Sdim } 453276479Sdim // This is the [REG]+disp16 case. 454276479Sdim EmitByte(ModRMByte(2, RegOpcodeField, RMfield), CurByte, OS); 455276479Sdim } else { 456276479Sdim // There is no BaseReg; this is the plain [disp16] case. 457276479Sdim EmitByte(ModRMByte(0, RegOpcodeField, 6), CurByte, OS); 458276479Sdim } 459276479Sdim 460276479Sdim // Emit 16-bit displacement for plain disp16 or [REG]+disp16 cases. 461276479Sdim EmitImmediate(Disp, MI.getLoc(), 2, FK_Data_2, CurByte, OS, Fixups); 462276479Sdim return; 463276479Sdim } 464276479Sdim 465226584Sdim // Determine whether a SIB byte is needed. 466226584Sdim // If no BaseReg, issue a RIP relative instruction only if the MCE can 467226584Sdim // resolve addresses on-the-fly, otherwise use SIB (Intel Manual 2A, table 468226584Sdim // 2-7) and absolute references. 469226584Sdim 470226584Sdim if (// The SIB byte must be used if there is an index register. 471226584Sdim IndexReg.getReg() == 0 && 472226584Sdim // The SIB byte must be used if the base is ESP/RSP/R12, all of which 473226584Sdim // encode to an R/M value of 4, which indicates that a SIB byte is 474226584Sdim // present. 475226584Sdim BaseRegNo != N86::ESP && 476226584Sdim // If there is no base register and we're in 64-bit mode, we need a SIB 477226584Sdim // byte to emit an addr that is just 'disp32' (the non-RIP relative form). 478276479Sdim (!is64BitMode(STI) || BaseReg != 0)) { 479226584Sdim 480226584Sdim if (BaseReg == 0) { // [disp32] in X86-32 mode 481226584Sdim EmitByte(ModRMByte(0, RegOpcodeField, 5), CurByte, OS); 482234353Sdim EmitImmediate(Disp, MI.getLoc(), 4, FK_Data_4, CurByte, OS, Fixups); 483226584Sdim return; 484226584Sdim } 485226584Sdim 486226584Sdim // If the base is not EBP/ESP and there is no displacement, use simple 487226584Sdim // indirect register encoding, this handles addresses like [EAX]. The 488226584Sdim // encoding for [EBP] with no displacement means [disp32] so we handle it 489226584Sdim // by emitting a displacement of 0 below. 490226584Sdim if (Disp.isImm() && Disp.getImm() == 0 && BaseRegNo != N86::EBP) { 491226584Sdim EmitByte(ModRMByte(0, RegOpcodeField, BaseRegNo), CurByte, OS); 492226584Sdim return; 493226584Sdim } 494226584Sdim 495226584Sdim // Otherwise, if the displacement fits in a byte, encode as [REG+disp8]. 496261991Sdim if (Disp.isImm()) { 497261991Sdim if (!HasEVEX && isDisp8(Disp.getImm())) { 498261991Sdim EmitByte(ModRMByte(1, RegOpcodeField, BaseRegNo), CurByte, OS); 499261991Sdim EmitImmediate(Disp, MI.getLoc(), 1, FK_Data_1, CurByte, OS, Fixups); 500261991Sdim return; 501261991Sdim } 502261991Sdim // Try EVEX compressed 8-bit displacement first; if failed, fall back to 503261991Sdim // 32-bit displacement. 504261991Sdim int CDisp8 = 0; 505261991Sdim if (HasEVEX && isCDisp8(TSFlags, Disp.getImm(), CDisp8)) { 506261991Sdim EmitByte(ModRMByte(1, RegOpcodeField, BaseRegNo), CurByte, OS); 507261991Sdim EmitImmediate(Disp, MI.getLoc(), 1, FK_Data_1, CurByte, OS, Fixups, 508261991Sdim CDisp8 - Disp.getImm()); 509261991Sdim return; 510261991Sdim } 511226584Sdim } 512226584Sdim 513226584Sdim // Otherwise, emit the most general non-SIB encoding: [REG+disp32] 514226584Sdim EmitByte(ModRMByte(2, RegOpcodeField, BaseRegNo), CurByte, OS); 515234353Sdim EmitImmediate(Disp, MI.getLoc(), 4, MCFixupKind(X86::reloc_signed_4byte), CurByte, OS, 516226584Sdim Fixups); 517226584Sdim return; 518226584Sdim } 519226584Sdim 520226584Sdim // We need a SIB byte, so start by outputting the ModR/M byte first 521226584Sdim assert(IndexReg.getReg() != X86::ESP && 522226584Sdim IndexReg.getReg() != X86::RSP && "Cannot use ESP as index reg!"); 523226584Sdim 524226584Sdim bool ForceDisp32 = false; 525226584Sdim bool ForceDisp8 = false; 526261991Sdim int CDisp8 = 0; 527261991Sdim int ImmOffset = 0; 528226584Sdim if (BaseReg == 0) { 529226584Sdim // If there is no base register, we emit the special case SIB byte with 530226584Sdim // MOD=0, BASE=5, to JUST get the index, scale, and displacement. 531226584Sdim EmitByte(ModRMByte(0, RegOpcodeField, 4), CurByte, OS); 532226584Sdim ForceDisp32 = true; 533226584Sdim } else if (!Disp.isImm()) { 534226584Sdim // Emit the normal disp32 encoding. 535226584Sdim EmitByte(ModRMByte(2, RegOpcodeField, 4), CurByte, OS); 536226584Sdim ForceDisp32 = true; 537226584Sdim } else if (Disp.getImm() == 0 && 538226584Sdim // Base reg can't be anything that ends up with '5' as the base 539226584Sdim // reg, it is the magic [*] nomenclature that indicates no base. 540226584Sdim BaseRegNo != N86::EBP) { 541226584Sdim // Emit no displacement ModR/M byte 542226584Sdim EmitByte(ModRMByte(0, RegOpcodeField, 4), CurByte, OS); 543261991Sdim } else if (!HasEVEX && isDisp8(Disp.getImm())) { 544226584Sdim // Emit the disp8 encoding. 545226584Sdim EmitByte(ModRMByte(1, RegOpcodeField, 4), CurByte, OS); 546226584Sdim ForceDisp8 = true; // Make sure to force 8 bit disp if Base=EBP 547261991Sdim } else if (HasEVEX && isCDisp8(TSFlags, Disp.getImm(), CDisp8)) { 548261991Sdim // Emit the disp8 encoding. 549261991Sdim EmitByte(ModRMByte(1, RegOpcodeField, 4), CurByte, OS); 550261991Sdim ForceDisp8 = true; // Make sure to force 8 bit disp if Base=EBP 551261991Sdim ImmOffset = CDisp8 - Disp.getImm(); 552226584Sdim } else { 553226584Sdim // Emit the normal disp32 encoding. 554226584Sdim EmitByte(ModRMByte(2, RegOpcodeField, 4), CurByte, OS); 555226584Sdim } 556226584Sdim 557226584Sdim // Calculate what the SS field value should be... 558226584Sdim static const unsigned SSTable[] = { ~0U, 0, 1, ~0U, 2, ~0U, ~0U, ~0U, 3 }; 559226584Sdim unsigned SS = SSTable[Scale.getImm()]; 560226584Sdim 561226584Sdim if (BaseReg == 0) { 562226584Sdim // Handle the SIB byte for the case where there is no base, see Intel 563226584Sdim // Manual 2A, table 2-7. The displacement has already been output. 564226584Sdim unsigned IndexRegNo; 565226584Sdim if (IndexReg.getReg()) 566226584Sdim IndexRegNo = GetX86RegNum(IndexReg); 567226584Sdim else // Examples: [ESP+1*<noreg>+4] or [scaled idx]+disp32 (MOD=0,BASE=5) 568226584Sdim IndexRegNo = 4; 569226584Sdim EmitSIBByte(SS, IndexRegNo, 5, CurByte, OS); 570226584Sdim } else { 571226584Sdim unsigned IndexRegNo; 572226584Sdim if (IndexReg.getReg()) 573226584Sdim IndexRegNo = GetX86RegNum(IndexReg); 574226584Sdim else 575226584Sdim IndexRegNo = 4; // For example [ESP+1*<noreg>+4] 576226584Sdim EmitSIBByte(SS, IndexRegNo, GetX86RegNum(Base), CurByte, OS); 577226584Sdim } 578226584Sdim 579226584Sdim // Do we need to output a displacement? 580226584Sdim if (ForceDisp8) 581261991Sdim EmitImmediate(Disp, MI.getLoc(), 1, FK_Data_1, CurByte, OS, Fixups, ImmOffset); 582226584Sdim else if (ForceDisp32 || Disp.getImm() != 0) 583234353Sdim EmitImmediate(Disp, MI.getLoc(), 4, MCFixupKind(X86::reloc_signed_4byte), 584234353Sdim CurByte, OS, Fixups); 585226584Sdim} 586226584Sdim 587226584Sdim/// EmitVEXOpcodePrefix - AVX instructions are encoded using a opcode prefix 588226584Sdim/// called VEX. 589226584Sdimvoid X86MCCodeEmitter::EmitVEXOpcodePrefix(uint64_t TSFlags, unsigned &CurByte, 590226584Sdim int MemOperand, const MCInst &MI, 591226584Sdim const MCInstrDesc &Desc, 592226584Sdim raw_ostream &OS) const { 593280031Sdim assert(!(TSFlags & X86II::LOCK) && "Can't have LOCK VEX."); 594226584Sdim 595280031Sdim uint64_t Encoding = TSFlags & X86II::EncodingMask; 596280031Sdim bool HasEVEX_K = TSFlags & X86II::EVEX_K; 597280031Sdim bool HasVEX_4V = TSFlags & X86II::VEX_4V; 598280031Sdim bool HasVEX_4VOp3 = TSFlags & X86II::VEX_4VOp3; 599280031Sdim bool HasMemOp4 = TSFlags & X86II::MemOp4; 600280031Sdim bool HasEVEX_RC = TSFlags & X86II::EVEX_RC; 601280031Sdim 602226584Sdim // VEX_R: opcode externsion equivalent to REX.R in 603226584Sdim // 1's complement (inverted) form 604226584Sdim // 605226584Sdim // 1: Same as REX_R=0 (must be 1 in 32-bit mode) 606226584Sdim // 0: Same as REX_R=1 (64 bit mode only) 607226584Sdim // 608226584Sdim unsigned char VEX_R = 0x1; 609261991Sdim unsigned char EVEX_R2 = 0x1; 610226584Sdim 611226584Sdim // VEX_X: equivalent to REX.X, only used when a 612226584Sdim // register is used for index in SIB Byte. 613226584Sdim // 614226584Sdim // 1: Same as REX.X=0 (must be 1 in 32-bit mode) 615226584Sdim // 0: Same as REX.X=1 (64-bit mode only) 616226584Sdim unsigned char VEX_X = 0x1; 617226584Sdim 618226584Sdim // VEX_B: 619226584Sdim // 620226584Sdim // 1: Same as REX_B=0 (ignored in 32-bit mode) 621226584Sdim // 0: Same as REX_B=1 (64 bit mode only) 622226584Sdim // 623226584Sdim unsigned char VEX_B = 0x1; 624226584Sdim 625226584Sdim // VEX_W: opcode specific (use like REX.W, or used for 626226584Sdim // opcode extension, or ignored, depending on the opcode byte) 627226584Sdim unsigned char VEX_W = 0; 628226584Sdim 629226584Sdim // VEX_5M (VEX m-mmmmm field): 630226584Sdim // 631226584Sdim // 0b00000: Reserved for future use 632226584Sdim // 0b00001: implied 0F leading opcode 633226584Sdim // 0b00010: implied 0F 38 leading opcode bytes 634226584Sdim // 0b00011: implied 0F 3A leading opcode bytes 635226584Sdim // 0b00100-0b11111: Reserved for future use 636234353Sdim // 0b01000: XOP map select - 08h instructions with imm byte 637261991Sdim // 0b01001: XOP map select - 09h instructions with no imm byte 638261991Sdim // 0b01010: XOP map select - 0Ah instructions with imm dword 639276479Sdim unsigned char VEX_5M = 0; 640226584Sdim 641226584Sdim // VEX_4V (VEX vvvv field): a register specifier 642226584Sdim // (in 1's complement form) or 1111 if unused. 643226584Sdim unsigned char VEX_4V = 0xf; 644261991Sdim unsigned char EVEX_V2 = 0x1; 645226584Sdim 646226584Sdim // VEX_L (Vector Length): 647226584Sdim // 648226584Sdim // 0: scalar or 128-bit vector 649226584Sdim // 1: 256-bit vector 650226584Sdim // 651226584Sdim unsigned char VEX_L = 0; 652261991Sdim unsigned char EVEX_L2 = 0; 653226584Sdim 654226584Sdim // VEX_PP: opcode extension providing equivalent 655226584Sdim // functionality of a SIMD prefix 656226584Sdim // 657226584Sdim // 0b00: None 658226584Sdim // 0b01: 66 659226584Sdim // 0b10: F3 660226584Sdim // 0b11: F2 661226584Sdim // 662226584Sdim unsigned char VEX_PP = 0; 663226584Sdim 664261991Sdim // EVEX_U 665261991Sdim unsigned char EVEX_U = 1; // Always '1' so far 666261991Sdim 667261991Sdim // EVEX_z 668261991Sdim unsigned char EVEX_z = 0; 669261991Sdim 670261991Sdim // EVEX_b 671261991Sdim unsigned char EVEX_b = 0; 672261991Sdim 673276479Sdim // EVEX_rc 674276479Sdim unsigned char EVEX_rc = 0; 675276479Sdim 676261991Sdim // EVEX_aaa 677261991Sdim unsigned char EVEX_aaa = 0; 678261991Sdim 679276479Sdim bool EncodeRC = false; 680226584Sdim 681280031Sdim if (TSFlags & X86II::VEX_W) 682226584Sdim VEX_W = 1; 683226584Sdim 684280031Sdim if (TSFlags & X86II::VEX_L) 685226584Sdim VEX_L = 1; 686280031Sdim if (TSFlags & X86II::EVEX_L2) 687261991Sdim EVEX_L2 = 1; 688226584Sdim 689280031Sdim if (HasEVEX_K && (TSFlags & X86II::EVEX_Z)) 690261991Sdim EVEX_z = 1; 691261991Sdim 692280031Sdim if ((TSFlags & X86II::EVEX_B)) 693261991Sdim EVEX_b = 1; 694261991Sdim 695276479Sdim switch (TSFlags & X86II::OpPrefixMask) { 696276479Sdim default: break; // VEX_PP already correct 697276479Sdim case X86II::PD: VEX_PP = 0x1; break; // 66 698276479Sdim case X86II::XS: VEX_PP = 0x2; break; // F3 699276479Sdim case X86II::XD: VEX_PP = 0x3; break; // F2 700276479Sdim } 701276479Sdim 702276479Sdim switch (TSFlags & X86II::OpMapMask) { 703234353Sdim default: llvm_unreachable("Invalid prefix!"); 704276479Sdim case X86II::TB: VEX_5M = 0x1; break; // 0F 705276479Sdim case X86II::T8: VEX_5M = 0x2; break; // 0F 38 706276479Sdim case X86II::TA: VEX_5M = 0x3; break; // 0F 3A 707276479Sdim case X86II::XOP8: VEX_5M = 0x8; break; 708276479Sdim case X86II::XOP9: VEX_5M = 0x9; break; 709276479Sdim case X86II::XOPA: VEX_5M = 0xA; break; 710226584Sdim } 711226584Sdim 712226584Sdim // Classify VEX_B, VEX_4V, VEX_R, VEX_X 713239462Sdim unsigned NumOps = Desc.getNumOperands(); 714276479Sdim unsigned CurOp = X86II::getOperandBias(Desc); 715239462Sdim 716226584Sdim switch (TSFlags & X86II::FormMask) { 717276479Sdim default: llvm_unreachable("Unexpected form in EmitVEXOpcodePrefix!"); 718276479Sdim case X86II::RawFrm: 719276479Sdim break; 720226584Sdim case X86II::MRMDestMem: { 721226584Sdim // MRMDestMem instructions forms: 722226584Sdim // MemAddr, src1(ModR/M) 723226584Sdim // MemAddr, src1(VEX_4V), src2(ModR/M) 724226584Sdim // MemAddr, src1(ModR/M), imm8 725226584Sdim // 726280031Sdim if (X86II::isX86_64ExtendedReg(MI.getOperand(MemOperand + 727261991Sdim X86::AddrBaseReg).getReg())) 728226584Sdim VEX_B = 0x0; 729261991Sdim if (X86II::isX86_64ExtendedReg(MI.getOperand(MemOperand + 730261991Sdim X86::AddrIndexReg).getReg())) 731226584Sdim VEX_X = 0x0; 732276479Sdim if (X86II::is32ExtendedReg(MI.getOperand(MemOperand + 733261991Sdim X86::AddrIndexReg).getReg())) 734261991Sdim EVEX_V2 = 0x0; 735226584Sdim 736261991Sdim CurOp += X86::AddrNumOperands; 737226584Sdim 738261991Sdim if (HasEVEX_K) 739261991Sdim EVEX_aaa = getWriteMaskRegisterEncoding(MI, CurOp++); 740261991Sdim 741261991Sdim if (HasVEX_4V) { 742261991Sdim VEX_4V = getVEXRegisterEncoding(MI, CurOp); 743276479Sdim if (X86II::is32ExtendedReg(MI.getOperand(CurOp).getReg())) 744261991Sdim EVEX_V2 = 0x0; 745261991Sdim CurOp++; 746261991Sdim } 747261991Sdim 748226584Sdim const MCOperand &MO = MI.getOperand(CurOp); 749261991Sdim if (MO.isReg()) { 750261991Sdim if (X86II::isX86_64ExtendedReg(MO.getReg())) 751261991Sdim VEX_R = 0x0; 752276479Sdim if (X86II::is32ExtendedReg(MO.getReg())) 753261991Sdim EVEX_R2 = 0x0; 754261991Sdim } 755226584Sdim break; 756226584Sdim } 757234353Sdim case X86II::MRMSrcMem: 758226584Sdim // MRMSrcMem instructions forms: 759226584Sdim // src1(ModR/M), MemAddr 760226584Sdim // src1(ModR/M), src2(VEX_4V), MemAddr 761226584Sdim // src1(ModR/M), MemAddr, imm8 762226584Sdim // src1(ModR/M), MemAddr, src2(VEX_I8IMM) 763226584Sdim // 764234353Sdim // FMA4: 765234353Sdim // dst(ModR/M.reg), src1(VEX_4V), src2(ModR/M), src3(VEX_I8IMM) 766234353Sdim // dst(ModR/M.reg), src1(VEX_4V), src2(VEX_I8IMM), src3(ModR/M), 767261991Sdim if (X86II::isX86_64ExtendedReg(MI.getOperand(CurOp).getReg())) 768226584Sdim VEX_R = 0x0; 769276479Sdim if (X86II::is32ExtendedReg(MI.getOperand(CurOp).getReg())) 770261991Sdim EVEX_R2 = 0x0; 771261991Sdim CurOp++; 772226584Sdim 773261991Sdim if (HasEVEX_K) 774261991Sdim EVEX_aaa = getWriteMaskRegisterEncoding(MI, CurOp++); 775261991Sdim 776261991Sdim if (HasVEX_4V) { 777239462Sdim VEX_4V = getVEXRegisterEncoding(MI, CurOp); 778276479Sdim if (X86II::is32ExtendedReg(MI.getOperand(CurOp).getReg())) 779261991Sdim EVEX_V2 = 0x0; 780261991Sdim CurOp++; 781261991Sdim } 782226584Sdim 783226584Sdim if (X86II::isX86_64ExtendedReg( 784234353Sdim MI.getOperand(MemOperand+X86::AddrBaseReg).getReg())) 785226584Sdim VEX_B = 0x0; 786226584Sdim if (X86II::isX86_64ExtendedReg( 787234353Sdim MI.getOperand(MemOperand+X86::AddrIndexReg).getReg())) 788226584Sdim VEX_X = 0x0; 789276479Sdim if (X86II::is32ExtendedReg(MI.getOperand(MemOperand + 790276479Sdim X86::AddrIndexReg).getReg())) 791261991Sdim EVEX_V2 = 0x0; 792234353Sdim 793234353Sdim if (HasVEX_4VOp3) 794239462Sdim // Instruction format for 4VOp3: 795239462Sdim // src1(ModR/M), MemAddr, src3(VEX_4V) 796239462Sdim // CurOp points to start of the MemoryOperand, 797239462Sdim // it skips TIED_TO operands if exist, then increments past src1. 798239462Sdim // CurOp + X86::AddrNumOperands will point to src3. 799239462Sdim VEX_4V = getVEXRegisterEncoding(MI, CurOp+X86::AddrNumOperands); 800226584Sdim break; 801226584Sdim case X86II::MRM0m: case X86II::MRM1m: 802226584Sdim case X86II::MRM2m: case X86II::MRM3m: 803226584Sdim case X86II::MRM4m: case X86II::MRM5m: 804234353Sdim case X86II::MRM6m: case X86II::MRM7m: { 805226584Sdim // MRM[0-9]m instructions forms: 806226584Sdim // MemAddr 807234353Sdim // src1(VEX_4V), MemAddr 808261991Sdim if (HasVEX_4V) { 809261991Sdim VEX_4V = getVEXRegisterEncoding(MI, CurOp); 810276479Sdim if (X86II::is32ExtendedReg(MI.getOperand(CurOp).getReg())) 811261991Sdim EVEX_V2 = 0x0; 812261991Sdim CurOp++; 813261991Sdim } 814234353Sdim 815261991Sdim if (HasEVEX_K) 816261991Sdim EVEX_aaa = getWriteMaskRegisterEncoding(MI, CurOp++); 817261991Sdim 818234353Sdim if (X86II::isX86_64ExtendedReg( 819234353Sdim MI.getOperand(MemOperand+X86::AddrBaseReg).getReg())) 820226584Sdim VEX_B = 0x0; 821234353Sdim if (X86II::isX86_64ExtendedReg( 822234353Sdim MI.getOperand(MemOperand+X86::AddrIndexReg).getReg())) 823226584Sdim VEX_X = 0x0; 824226584Sdim break; 825234353Sdim } 826226584Sdim case X86II::MRMSrcReg: 827226584Sdim // MRMSrcReg instructions forms: 828226584Sdim // dst(ModR/M), src1(VEX_4V), src2(ModR/M), src3(VEX_I8IMM) 829226584Sdim // dst(ModR/M), src1(ModR/M) 830226584Sdim // dst(ModR/M), src1(ModR/M), imm8 831226584Sdim // 832249423Sdim // FMA4: 833249423Sdim // dst(ModR/M.reg), src1(VEX_4V), src2(ModR/M), src3(VEX_I8IMM) 834249423Sdim // dst(ModR/M.reg), src1(VEX_4V), src2(VEX_I8IMM), src3(ModR/M), 835226584Sdim if (X86II::isX86_64ExtendedReg(MI.getOperand(CurOp).getReg())) 836226584Sdim VEX_R = 0x0; 837276479Sdim if (X86II::is32ExtendedReg(MI.getOperand(CurOp).getReg())) 838261991Sdim EVEX_R2 = 0x0; 839226584Sdim CurOp++; 840226584Sdim 841261991Sdim if (HasEVEX_K) 842261991Sdim EVEX_aaa = getWriteMaskRegisterEncoding(MI, CurOp++); 843249423Sdim 844261991Sdim if (HasVEX_4V) { 845261991Sdim VEX_4V = getVEXRegisterEncoding(MI, CurOp); 846276479Sdim if (X86II::is32ExtendedReg(MI.getOperand(CurOp).getReg())) 847261991Sdim EVEX_V2 = 0x0; 848261991Sdim CurOp++; 849261991Sdim } 850261991Sdim 851249423Sdim if (HasMemOp4) // Skip second register source (encoded in I8IMM) 852249423Sdim CurOp++; 853249423Sdim 854226584Sdim if (X86II::isX86_64ExtendedReg(MI.getOperand(CurOp).getReg())) 855226584Sdim VEX_B = 0x0; 856276479Sdim if (X86II::is32ExtendedReg(MI.getOperand(CurOp).getReg())) 857261991Sdim VEX_X = 0x0; 858234353Sdim CurOp++; 859234353Sdim if (HasVEX_4VOp3) 860276479Sdim VEX_4V = getVEXRegisterEncoding(MI, CurOp++); 861276479Sdim if (EVEX_b) { 862276479Sdim if (HasEVEX_RC) { 863276479Sdim unsigned RcOperand = NumOps-1; 864276479Sdim assert(RcOperand >= CurOp); 865276479Sdim EVEX_rc = MI.getOperand(RcOperand).getImm() & 0x3; 866276479Sdim } 867276479Sdim EncodeRC = true; 868280031Sdim } 869226584Sdim break; 870226584Sdim case X86II::MRMDestReg: 871226584Sdim // MRMDestReg instructions forms: 872226584Sdim // dst(ModR/M), src(ModR/M) 873226584Sdim // dst(ModR/M), src(ModR/M), imm8 874249423Sdim // dst(ModR/M), src1(VEX_4V), src2(ModR/M) 875249423Sdim if (X86II::isX86_64ExtendedReg(MI.getOperand(CurOp).getReg())) 876226584Sdim VEX_B = 0x0; 877276479Sdim if (X86II::is32ExtendedReg(MI.getOperand(CurOp).getReg())) 878261991Sdim VEX_X = 0x0; 879249423Sdim CurOp++; 880249423Sdim 881261991Sdim if (HasEVEX_K) 882261991Sdim EVEX_aaa = getWriteMaskRegisterEncoding(MI, CurOp++); 883249423Sdim 884261991Sdim if (HasVEX_4V) { 885261991Sdim VEX_4V = getVEXRegisterEncoding(MI, CurOp); 886276479Sdim if (X86II::is32ExtendedReg(MI.getOperand(CurOp).getReg())) 887261991Sdim EVEX_V2 = 0x0; 888261991Sdim CurOp++; 889261991Sdim } 890261991Sdim 891249423Sdim if (X86II::isX86_64ExtendedReg(MI.getOperand(CurOp).getReg())) 892226584Sdim VEX_R = 0x0; 893276479Sdim if (X86II::is32ExtendedReg(MI.getOperand(CurOp).getReg())) 894261991Sdim EVEX_R2 = 0x0; 895276479Sdim if (EVEX_b) 896276479Sdim EncodeRC = true; 897226584Sdim break; 898226584Sdim case X86II::MRM0r: case X86II::MRM1r: 899226584Sdim case X86II::MRM2r: case X86II::MRM3r: 900226584Sdim case X86II::MRM4r: case X86II::MRM5r: 901226584Sdim case X86II::MRM6r: case X86II::MRM7r: 902226584Sdim // MRM0r-MRM7r instructions forms: 903226584Sdim // dst(VEX_4V), src(ModR/M), imm8 904261991Sdim if (HasVEX_4V) { 905261991Sdim VEX_4V = getVEXRegisterEncoding(MI, CurOp); 906276479Sdim if (X86II::is32ExtendedReg(MI.getOperand(CurOp).getReg())) 907261991Sdim EVEX_V2 = 0x0; 908261991Sdim CurOp++; 909276479Sdim } 910261991Sdim if (HasEVEX_K) 911261991Sdim EVEX_aaa = getWriteMaskRegisterEncoding(MI, CurOp++); 912261991Sdim 913261991Sdim if (X86II::isX86_64ExtendedReg(MI.getOperand(CurOp).getReg())) 914226584Sdim VEX_B = 0x0; 915276479Sdim if (X86II::is32ExtendedReg(MI.getOperand(CurOp).getReg())) 916261991Sdim VEX_X = 0x0; 917226584Sdim break; 918226584Sdim } 919226584Sdim 920276479Sdim if (Encoding == X86II::VEX || Encoding == X86II::XOP) { 921261991Sdim // VEX opcode prefix can have 2 or 3 bytes 922261991Sdim // 923261991Sdim // 3 bytes: 924261991Sdim // +-----+ +--------------+ +-------------------+ 925261991Sdim // | C4h | | RXB | m-mmmm | | W | vvvv | L | pp | 926261991Sdim // +-----+ +--------------+ +-------------------+ 927261991Sdim // 2 bytes: 928261991Sdim // +-----+ +-------------------+ 929261991Sdim // | C5h | | R | vvvv | L | pp | 930261991Sdim // +-----+ +-------------------+ 931261991Sdim // 932276479Sdim // XOP uses a similar prefix: 933276479Sdim // +-----+ +--------------+ +-------------------+ 934276479Sdim // | 8Fh | | RXB | m-mmmm | | W | vvvv | L | pp | 935276479Sdim // +-----+ +--------------+ +-------------------+ 936261991Sdim unsigned char LastByte = VEX_PP | (VEX_L << 2) | (VEX_4V << 3); 937226584Sdim 938276479Sdim // Can we use the 2 byte VEX prefix? 939276479Sdim if (Encoding == X86II::VEX && VEX_B && VEX_X && !VEX_W && (VEX_5M == 1)) { 940261991Sdim EmitByte(0xC5, CurByte, OS); 941261991Sdim EmitByte(LastByte | (VEX_R << 7), CurByte, OS); 942261991Sdim return; 943261991Sdim } 944261991Sdim 945261991Sdim // 3 byte VEX prefix 946276479Sdim EmitByte(Encoding == X86II::XOP ? 0x8F : 0xC4, CurByte, OS); 947261991Sdim EmitByte(VEX_R << 7 | VEX_X << 6 | VEX_B << 5 | VEX_5M, CurByte, OS); 948261991Sdim EmitByte(LastByte | (VEX_W << 7), CurByte, OS); 949261991Sdim } else { 950276479Sdim assert(Encoding == X86II::EVEX && "unknown encoding!"); 951261991Sdim // EVEX opcode prefix can have 4 bytes 952261991Sdim // 953261991Sdim // +-----+ +--------------+ +-------------------+ +------------------------+ 954261991Sdim // | 62h | | RXBR' | 00mm | | W | vvvv | U | pp | | z | L'L | b | v' | aaa | 955261991Sdim // +-----+ +--------------+ +-------------------+ +------------------------+ 956261991Sdim assert((VEX_5M & 0x3) == VEX_5M 957261991Sdim && "More than 2 significant bits in VEX.m-mmmm fields for EVEX!"); 958261991Sdim 959261991Sdim VEX_5M &= 0x3; 960261991Sdim 961261991Sdim EmitByte(0x62, CurByte, OS); 962261991Sdim EmitByte((VEX_R << 7) | 963261991Sdim (VEX_X << 6) | 964261991Sdim (VEX_B << 5) | 965261991Sdim (EVEX_R2 << 4) | 966261991Sdim VEX_5M, CurByte, OS); 967261991Sdim EmitByte((VEX_W << 7) | 968261991Sdim (VEX_4V << 3) | 969261991Sdim (EVEX_U << 2) | 970261991Sdim VEX_PP, CurByte, OS); 971276479Sdim if (EncodeRC) 972276479Sdim EmitByte((EVEX_z << 7) | 973276479Sdim (EVEX_rc << 5) | 974276479Sdim (EVEX_b << 4) | 975276479Sdim (EVEX_V2 << 3) | 976276479Sdim EVEX_aaa, CurByte, OS); 977276479Sdim else 978276479Sdim EmitByte((EVEX_z << 7) | 979276479Sdim (EVEX_L2 << 6) | 980276479Sdim (VEX_L << 5) | 981276479Sdim (EVEX_b << 4) | 982276479Sdim (EVEX_V2 << 3) | 983276479Sdim EVEX_aaa, CurByte, OS); 984226584Sdim } 985226584Sdim} 986226584Sdim 987226584Sdim/// DetermineREXPrefix - Determine if the MCInst has to be encoded with a X86-64 988226584Sdim/// REX prefix which specifies 1) 64-bit instructions, 2) non-default operand 989226584Sdim/// size, and 3) use of X86-64 extended registers. 990226584Sdimstatic unsigned DetermineREXPrefix(const MCInst &MI, uint64_t TSFlags, 991226584Sdim const MCInstrDesc &Desc) { 992226584Sdim unsigned REX = 0; 993226584Sdim if (TSFlags & X86II::REX_W) 994226584Sdim REX |= 1 << 3; // set REX.W 995226584Sdim 996226584Sdim if (MI.getNumOperands() == 0) return REX; 997226584Sdim 998226584Sdim unsigned NumOps = MI.getNumOperands(); 999226584Sdim // FIXME: MCInst should explicitize the two-addrness. 1000226584Sdim bool isTwoAddr = NumOps > 1 && 1001226584Sdim Desc.getOperandConstraint(1, MCOI::TIED_TO) != -1; 1002226584Sdim 1003226584Sdim // If it accesses SPL, BPL, SIL, or DIL, then it requires a 0x40 REX prefix. 1004226584Sdim unsigned i = isTwoAddr ? 1 : 0; 1005226584Sdim for (; i != NumOps; ++i) { 1006226584Sdim const MCOperand &MO = MI.getOperand(i); 1007226584Sdim if (!MO.isReg()) continue; 1008226584Sdim unsigned Reg = MO.getReg(); 1009226584Sdim if (!X86II::isX86_64NonExtLowByteReg(Reg)) continue; 1010226584Sdim // FIXME: The caller of DetermineREXPrefix slaps this prefix onto anything 1011226584Sdim // that returns non-zero. 1012226584Sdim REX |= 0x40; // REX fixed encoding prefix 1013226584Sdim break; 1014226584Sdim } 1015226584Sdim 1016226584Sdim switch (TSFlags & X86II::FormMask) { 1017226584Sdim case X86II::MRMSrcReg: 1018226584Sdim if (MI.getOperand(0).isReg() && 1019226584Sdim X86II::isX86_64ExtendedReg(MI.getOperand(0).getReg())) 1020226584Sdim REX |= 1 << 2; // set REX.R 1021226584Sdim i = isTwoAddr ? 2 : 1; 1022226584Sdim for (; i != NumOps; ++i) { 1023226584Sdim const MCOperand &MO = MI.getOperand(i); 1024226584Sdim if (MO.isReg() && X86II::isX86_64ExtendedReg(MO.getReg())) 1025226584Sdim REX |= 1 << 0; // set REX.B 1026226584Sdim } 1027226584Sdim break; 1028226584Sdim case X86II::MRMSrcMem: { 1029226584Sdim if (MI.getOperand(0).isReg() && 1030226584Sdim X86II::isX86_64ExtendedReg(MI.getOperand(0).getReg())) 1031226584Sdim REX |= 1 << 2; // set REX.R 1032226584Sdim unsigned Bit = 0; 1033226584Sdim i = isTwoAddr ? 2 : 1; 1034226584Sdim for (; i != NumOps; ++i) { 1035226584Sdim const MCOperand &MO = MI.getOperand(i); 1036226584Sdim if (MO.isReg()) { 1037226584Sdim if (X86II::isX86_64ExtendedReg(MO.getReg())) 1038226584Sdim REX |= 1 << Bit; // set REX.B (Bit=0) and REX.X (Bit=1) 1039226584Sdim Bit++; 1040226584Sdim } 1041226584Sdim } 1042226584Sdim break; 1043226584Sdim } 1044276479Sdim case X86II::MRMXm: 1045226584Sdim case X86II::MRM0m: case X86II::MRM1m: 1046226584Sdim case X86II::MRM2m: case X86II::MRM3m: 1047226584Sdim case X86II::MRM4m: case X86II::MRM5m: 1048226584Sdim case X86II::MRM6m: case X86II::MRM7m: 1049226584Sdim case X86II::MRMDestMem: { 1050226584Sdim unsigned e = (isTwoAddr ? X86::AddrNumOperands+1 : X86::AddrNumOperands); 1051226584Sdim i = isTwoAddr ? 1 : 0; 1052226584Sdim if (NumOps > e && MI.getOperand(e).isReg() && 1053226584Sdim X86II::isX86_64ExtendedReg(MI.getOperand(e).getReg())) 1054226584Sdim REX |= 1 << 2; // set REX.R 1055226584Sdim unsigned Bit = 0; 1056226584Sdim for (; i != e; ++i) { 1057226584Sdim const MCOperand &MO = MI.getOperand(i); 1058226584Sdim if (MO.isReg()) { 1059226584Sdim if (X86II::isX86_64ExtendedReg(MO.getReg())) 1060226584Sdim REX |= 1 << Bit; // REX.B (Bit=0) and REX.X (Bit=1) 1061226584Sdim Bit++; 1062226584Sdim } 1063226584Sdim } 1064226584Sdim break; 1065226584Sdim } 1066226584Sdim default: 1067226584Sdim if (MI.getOperand(0).isReg() && 1068226584Sdim X86II::isX86_64ExtendedReg(MI.getOperand(0).getReg())) 1069226584Sdim REX |= 1 << 0; // set REX.B 1070226584Sdim i = isTwoAddr ? 2 : 1; 1071226584Sdim for (unsigned e = NumOps; i != e; ++i) { 1072226584Sdim const MCOperand &MO = MI.getOperand(i); 1073226584Sdim if (MO.isReg() && X86II::isX86_64ExtendedReg(MO.getReg())) 1074226584Sdim REX |= 1 << 2; // set REX.R 1075226584Sdim } 1076226584Sdim break; 1077226584Sdim } 1078226584Sdim return REX; 1079226584Sdim} 1080226584Sdim 1081226584Sdim/// EmitSegmentOverridePrefix - Emit segment override opcode prefix as needed 1082276479Sdimvoid X86MCCodeEmitter::EmitSegmentOverridePrefix(unsigned &CurByte, 1083276479Sdim unsigned SegOperand, 1084276479Sdim const MCInst &MI, 1085276479Sdim raw_ostream &OS) const { 1086276479Sdim // Check for explicit segment override on memory operand. 1087276479Sdim switch (MI.getOperand(SegOperand).getReg()) { 1088276479Sdim default: llvm_unreachable("Unknown segment register!"); 1089276479Sdim case 0: break; 1090276479Sdim case X86::CS: EmitByte(0x2E, CurByte, OS); break; 1091276479Sdim case X86::SS: EmitByte(0x36, CurByte, OS); break; 1092276479Sdim case X86::DS: EmitByte(0x3E, CurByte, OS); break; 1093276479Sdim case X86::ES: EmitByte(0x26, CurByte, OS); break; 1094276479Sdim case X86::FS: EmitByte(0x64, CurByte, OS); break; 1095276479Sdim case X86::GS: EmitByte(0x65, CurByte, OS); break; 1096226584Sdim } 1097226584Sdim} 1098226584Sdim 1099226584Sdim/// EmitOpcodePrefix - Emit all instruction prefixes prior to the opcode. 1100226584Sdim/// 1101226584Sdim/// MemOperand is the operand # of the start of a memory operand if present. If 1102226584Sdim/// Not present, it is -1. 1103226584Sdimvoid X86MCCodeEmitter::EmitOpcodePrefix(uint64_t TSFlags, unsigned &CurByte, 1104226584Sdim int MemOperand, const MCInst &MI, 1105226584Sdim const MCInstrDesc &Desc, 1106276479Sdim const MCSubtargetInfo &STI, 1107226584Sdim raw_ostream &OS) const { 1108226584Sdim 1109226584Sdim // Emit the operand size opcode prefix as needed. 1110280031Sdim if ((TSFlags & X86II::OpSizeMask) == (is16BitMode(STI) ? X86II::OpSize32 1111280031Sdim : X86II::OpSize16)) 1112226584Sdim EmitByte(0x66, CurByte, OS); 1113226584Sdim 1114280031Sdim // Emit the LOCK opcode prefix. 1115280031Sdim if (TSFlags & X86II::LOCK) 1116280031Sdim EmitByte(0xF0, CurByte, OS); 1117280031Sdim 1118276479Sdim switch (TSFlags & X86II::OpPrefixMask) { 1119276479Sdim case X86II::PD: // 66 1120276479Sdim EmitByte(0x66, CurByte, OS); 1121226584Sdim break; 1122276479Sdim case X86II::XS: // F3 1123234353Sdim EmitByte(0xF3, CurByte, OS); 1124234353Sdim break; 1125276479Sdim case X86II::XD: // F2 1126226584Sdim EmitByte(0xF2, CurByte, OS); 1127226584Sdim break; 1128226584Sdim } 1129226584Sdim 1130226584Sdim // Handle REX prefix. 1131226584Sdim // FIXME: Can this come before F2 etc to simplify emission? 1132276479Sdim if (is64BitMode(STI)) { 1133226584Sdim if (unsigned REX = DetermineREXPrefix(MI, TSFlags, Desc)) 1134226584Sdim EmitByte(0x40 | REX, CurByte, OS); 1135226584Sdim } 1136226584Sdim 1137226584Sdim // 0x0F escape code must be emitted just before the opcode. 1138276479Sdim switch (TSFlags & X86II::OpMapMask) { 1139276479Sdim case X86II::TB: // Two-byte opcode map 1140276479Sdim case X86II::T8: // 0F 38 1141276479Sdim case X86II::TA: // 0F 3A 1142226584Sdim EmitByte(0x0F, CurByte, OS); 1143276479Sdim break; 1144276479Sdim } 1145226584Sdim 1146276479Sdim switch (TSFlags & X86II::OpMapMask) { 1147226584Sdim case X86II::T8: // 0F 38 1148226584Sdim EmitByte(0x38, CurByte, OS); 1149226584Sdim break; 1150226584Sdim case X86II::TA: // 0F 3A 1151226584Sdim EmitByte(0x3A, CurByte, OS); 1152226584Sdim break; 1153226584Sdim } 1154226584Sdim} 1155226584Sdim 1156226584Sdimvoid X86MCCodeEmitter:: 1157226584SdimEncodeInstruction(const MCInst &MI, raw_ostream &OS, 1158276479Sdim SmallVectorImpl<MCFixup> &Fixups, 1159276479Sdim const MCSubtargetInfo &STI) const { 1160226584Sdim unsigned Opcode = MI.getOpcode(); 1161226584Sdim const MCInstrDesc &Desc = MCII.get(Opcode); 1162226584Sdim uint64_t TSFlags = Desc.TSFlags; 1163226584Sdim 1164226584Sdim // Pseudo instructions don't get encoded. 1165226584Sdim if ((TSFlags & X86II::FormMask) == X86II::Pseudo) 1166226584Sdim return; 1167226584Sdim 1168226584Sdim unsigned NumOps = Desc.getNumOperands(); 1169251662Sdim unsigned CurOp = X86II::getOperandBias(Desc); 1170226584Sdim 1171226584Sdim // Keep track of the current byte being emitted. 1172226584Sdim unsigned CurByte = 0; 1173226584Sdim 1174276479Sdim // Encoding type for this instruction. 1175280031Sdim uint64_t Encoding = TSFlags & X86II::EncodingMask; 1176226584Sdim 1177226584Sdim // It uses the VEX.VVVV field? 1178280031Sdim bool HasVEX_4V = TSFlags & X86II::VEX_4V; 1179280031Sdim bool HasVEX_4VOp3 = TSFlags & X86II::VEX_4VOp3; 1180280031Sdim bool HasMemOp4 = TSFlags & X86II::MemOp4; 1181234353Sdim const unsigned MemOp4_I8IMMOperand = 2; 1182226584Sdim 1183261991Sdim // It uses the EVEX.aaa field? 1184280031Sdim bool HasEVEX_K = TSFlags & X86II::EVEX_K; 1185280031Sdim bool HasEVEX_RC = TSFlags & X86II::EVEX_RC; 1186280031Sdim 1187226584Sdim // Determine where the memory operand starts, if present. 1188234353Sdim int MemoryOperand = X86II::getMemoryOperandNo(TSFlags, Opcode); 1189226584Sdim if (MemoryOperand != -1) MemoryOperand += CurOp; 1190226584Sdim 1191276479Sdim // Emit segment override opcode prefix as needed. 1192276479Sdim if (MemoryOperand >= 0) 1193276479Sdim EmitSegmentOverridePrefix(CurByte, MemoryOperand+X86::AddrSegmentReg, 1194276479Sdim MI, OS); 1195276479Sdim 1196276479Sdim // Emit the repeat opcode prefix as needed. 1197276479Sdim if (TSFlags & X86II::REP) 1198276479Sdim EmitByte(0xF3, CurByte, OS); 1199276479Sdim 1200276479Sdim // Emit the address size opcode prefix as needed. 1201276479Sdim bool need_address_override; 1202280031Sdim uint64_t AdSize = TSFlags & X86II::AdSizeMask; 1203280031Sdim if ((is16BitMode(STI) && AdSize == X86II::AdSize32) || 1204280031Sdim (is32BitMode(STI) && AdSize == X86II::AdSize16) || 1205280031Sdim (is64BitMode(STI) && AdSize == X86II::AdSize32)) { 1206276479Sdim need_address_override = true; 1207276479Sdim } else if (MemoryOperand < 0) { 1208276479Sdim need_address_override = false; 1209276479Sdim } else if (is64BitMode(STI)) { 1210276479Sdim assert(!Is16BitMemOperand(MI, MemoryOperand, STI)); 1211276479Sdim need_address_override = Is32BitMemOperand(MI, MemoryOperand); 1212276479Sdim } else if (is32BitMode(STI)) { 1213276479Sdim assert(!Is64BitMemOperand(MI, MemoryOperand)); 1214276479Sdim need_address_override = Is16BitMemOperand(MI, MemoryOperand, STI); 1215276479Sdim } else { 1216276479Sdim assert(is16BitMode(STI)); 1217276479Sdim assert(!Is64BitMemOperand(MI, MemoryOperand)); 1218276479Sdim need_address_override = !Is16BitMemOperand(MI, MemoryOperand, STI); 1219276479Sdim } 1220276479Sdim 1221276479Sdim if (need_address_override) 1222276479Sdim EmitByte(0x67, CurByte, OS); 1223276479Sdim 1224276479Sdim if (Encoding == 0) 1225276479Sdim EmitOpcodePrefix(TSFlags, CurByte, MemoryOperand, MI, Desc, STI, OS); 1226226584Sdim else 1227226584Sdim EmitVEXOpcodePrefix(TSFlags, CurByte, MemoryOperand, MI, Desc, OS); 1228226584Sdim 1229226584Sdim unsigned char BaseOpcode = X86II::getBaseOpcodeFor(TSFlags); 1230226584Sdim 1231280031Sdim if (TSFlags & X86II::Has3DNow0F0FOpcode) 1232226584Sdim BaseOpcode = 0x0F; // Weird 3DNow! encoding. 1233226584Sdim 1234226584Sdim unsigned SrcRegNum = 0; 1235226584Sdim switch (TSFlags & X86II::FormMask) { 1236226584Sdim default: errs() << "FORM: " << (TSFlags & X86II::FormMask) << "\n"; 1237234353Sdim llvm_unreachable("Unknown FormMask value in X86MCCodeEmitter!"); 1238226584Sdim case X86II::Pseudo: 1239234353Sdim llvm_unreachable("Pseudo instruction shouldn't be emitted"); 1240276479Sdim case X86II::RawFrmDstSrc: { 1241276479Sdim unsigned siReg = MI.getOperand(1).getReg(); 1242276479Sdim assert(((siReg == X86::SI && MI.getOperand(0).getReg() == X86::DI) || 1243276479Sdim (siReg == X86::ESI && MI.getOperand(0).getReg() == X86::EDI) || 1244276479Sdim (siReg == X86::RSI && MI.getOperand(0).getReg() == X86::RDI)) && 1245276479Sdim "SI and DI register sizes do not match"); 1246276479Sdim // Emit segment override opcode prefix as needed (not for %ds). 1247276479Sdim if (MI.getOperand(2).getReg() != X86::DS) 1248276479Sdim EmitSegmentOverridePrefix(CurByte, 2, MI, OS); 1249276479Sdim // Emit AdSize prefix as needed. 1250276479Sdim if ((!is32BitMode(STI) && siReg == X86::ESI) || 1251276479Sdim (is32BitMode(STI) && siReg == X86::SI)) 1252276479Sdim EmitByte(0x67, CurByte, OS); 1253276479Sdim CurOp += 3; // Consume operands. 1254276479Sdim EmitByte(BaseOpcode, CurByte, OS); 1255276479Sdim break; 1256276479Sdim } 1257276479Sdim case X86II::RawFrmSrc: { 1258276479Sdim unsigned siReg = MI.getOperand(0).getReg(); 1259276479Sdim // Emit segment override opcode prefix as needed (not for %ds). 1260276479Sdim if (MI.getOperand(1).getReg() != X86::DS) 1261276479Sdim EmitSegmentOverridePrefix(CurByte, 1, MI, OS); 1262276479Sdim // Emit AdSize prefix as needed. 1263276479Sdim if ((!is32BitMode(STI) && siReg == X86::ESI) || 1264276479Sdim (is32BitMode(STI) && siReg == X86::SI)) 1265276479Sdim EmitByte(0x67, CurByte, OS); 1266276479Sdim CurOp += 2; // Consume operands. 1267276479Sdim EmitByte(BaseOpcode, CurByte, OS); 1268276479Sdim break; 1269276479Sdim } 1270276479Sdim case X86II::RawFrmDst: { 1271276479Sdim unsigned siReg = MI.getOperand(0).getReg(); 1272276479Sdim // Emit AdSize prefix as needed. 1273276479Sdim if ((!is32BitMode(STI) && siReg == X86::EDI) || 1274276479Sdim (is32BitMode(STI) && siReg == X86::DI)) 1275276479Sdim EmitByte(0x67, CurByte, OS); 1276276479Sdim ++CurOp; // Consume operand. 1277276479Sdim EmitByte(BaseOpcode, CurByte, OS); 1278276479Sdim break; 1279276479Sdim } 1280226584Sdim case X86II::RawFrm: 1281226584Sdim EmitByte(BaseOpcode, CurByte, OS); 1282226584Sdim break; 1283276479Sdim case X86II::RawFrmMemOffs: 1284276479Sdim // Emit segment override opcode prefix as needed. 1285276479Sdim EmitSegmentOverridePrefix(CurByte, 1, MI, OS); 1286276479Sdim EmitByte(BaseOpcode, CurByte, OS); 1287276479Sdim EmitImmediate(MI.getOperand(CurOp++), MI.getLoc(), 1288276479Sdim X86II::getSizeOfImm(TSFlags), getImmFixupKind(TSFlags), 1289276479Sdim CurByte, OS, Fixups); 1290276479Sdim ++CurOp; // skip segment operand 1291276479Sdim break; 1292226584Sdim case X86II::RawFrmImm8: 1293226584Sdim EmitByte(BaseOpcode, CurByte, OS); 1294234353Sdim EmitImmediate(MI.getOperand(CurOp++), MI.getLoc(), 1295226584Sdim X86II::getSizeOfImm(TSFlags), getImmFixupKind(TSFlags), 1296226584Sdim CurByte, OS, Fixups); 1297234353Sdim EmitImmediate(MI.getOperand(CurOp++), MI.getLoc(), 1, FK_Data_1, CurByte, 1298234353Sdim OS, Fixups); 1299226584Sdim break; 1300226584Sdim case X86II::RawFrmImm16: 1301226584Sdim EmitByte(BaseOpcode, CurByte, OS); 1302234353Sdim EmitImmediate(MI.getOperand(CurOp++), MI.getLoc(), 1303226584Sdim X86II::getSizeOfImm(TSFlags), getImmFixupKind(TSFlags), 1304226584Sdim CurByte, OS, Fixups); 1305234353Sdim EmitImmediate(MI.getOperand(CurOp++), MI.getLoc(), 2, FK_Data_2, CurByte, 1306234353Sdim OS, Fixups); 1307226584Sdim break; 1308226584Sdim 1309226584Sdim case X86II::AddRegFrm: 1310226584Sdim EmitByte(BaseOpcode + GetX86RegNum(MI.getOperand(CurOp++)), CurByte, OS); 1311226584Sdim break; 1312226584Sdim 1313226584Sdim case X86II::MRMDestReg: 1314226584Sdim EmitByte(BaseOpcode, CurByte, OS); 1315249423Sdim SrcRegNum = CurOp + 1; 1316249423Sdim 1317261991Sdim if (HasEVEX_K) // Skip writemask 1318261991Sdim SrcRegNum++; 1319261991Sdim 1320249423Sdim if (HasVEX_4V) // Skip 1st src (which is encoded in VEX_VVVV) 1321249423Sdim ++SrcRegNum; 1322249423Sdim 1323226584Sdim EmitRegModRMByte(MI.getOperand(CurOp), 1324249423Sdim GetX86RegNum(MI.getOperand(SrcRegNum)), CurByte, OS); 1325249423Sdim CurOp = SrcRegNum + 1; 1326226584Sdim break; 1327226584Sdim 1328226584Sdim case X86II::MRMDestMem: 1329226584Sdim EmitByte(BaseOpcode, CurByte, OS); 1330226584Sdim SrcRegNum = CurOp + X86::AddrNumOperands; 1331226584Sdim 1332261991Sdim if (HasEVEX_K) // Skip writemask 1333261991Sdim SrcRegNum++; 1334261991Sdim 1335226584Sdim if (HasVEX_4V) // Skip 1st src (which is encoded in VEX_VVVV) 1336239462Sdim ++SrcRegNum; 1337226584Sdim 1338226584Sdim EmitMemModRMByte(MI, CurOp, 1339226584Sdim GetX86RegNum(MI.getOperand(SrcRegNum)), 1340276479Sdim TSFlags, CurByte, OS, Fixups, STI); 1341226584Sdim CurOp = SrcRegNum + 1; 1342226584Sdim break; 1343226584Sdim 1344226584Sdim case X86II::MRMSrcReg: 1345226584Sdim EmitByte(BaseOpcode, CurByte, OS); 1346226584Sdim SrcRegNum = CurOp + 1; 1347226584Sdim 1348261991Sdim if (HasEVEX_K) // Skip writemask 1349261991Sdim SrcRegNum++; 1350261991Sdim 1351226584Sdim if (HasVEX_4V) // Skip 1st src (which is encoded in VEX_VVVV) 1352239462Sdim ++SrcRegNum; 1353226584Sdim 1354239462Sdim if (HasMemOp4) // Skip 2nd src (which is encoded in I8IMM) 1355239462Sdim ++SrcRegNum; 1356234353Sdim 1357226584Sdim EmitRegModRMByte(MI.getOperand(SrcRegNum), 1358226584Sdim GetX86RegNum(MI.getOperand(CurOp)), CurByte, OS); 1359234353Sdim 1360239462Sdim // 2 operands skipped with HasMemOp4, compensate accordingly 1361234353Sdim CurOp = HasMemOp4 ? SrcRegNum : SrcRegNum + 1; 1362234353Sdim if (HasVEX_4VOp3) 1363234353Sdim ++CurOp; 1364276479Sdim // do not count the rounding control operand 1365276479Sdim if (HasEVEX_RC) 1366276479Sdim NumOps--; 1367226584Sdim break; 1368226584Sdim 1369226584Sdim case X86II::MRMSrcMem: { 1370226584Sdim int AddrOperands = X86::AddrNumOperands; 1371226584Sdim unsigned FirstMemOp = CurOp+1; 1372261991Sdim 1373261991Sdim if (HasEVEX_K) { // Skip writemask 1374261991Sdim ++AddrOperands; 1375261991Sdim ++FirstMemOp; 1376261991Sdim } 1377261991Sdim 1378226584Sdim if (HasVEX_4V) { 1379226584Sdim ++AddrOperands; 1380226584Sdim ++FirstMemOp; // Skip the register source (which is encoded in VEX_VVVV). 1381226584Sdim } 1382239462Sdim if (HasMemOp4) // Skip second register source (encoded in I8IMM) 1383234353Sdim ++FirstMemOp; 1384226584Sdim 1385226584Sdim EmitByte(BaseOpcode, CurByte, OS); 1386226584Sdim 1387226584Sdim EmitMemModRMByte(MI, FirstMemOp, GetX86RegNum(MI.getOperand(CurOp)), 1388276479Sdim TSFlags, CurByte, OS, Fixups, STI); 1389226584Sdim CurOp += AddrOperands + 1; 1390234353Sdim if (HasVEX_4VOp3) 1391234353Sdim ++CurOp; 1392226584Sdim break; 1393226584Sdim } 1394226584Sdim 1395276479Sdim case X86II::MRMXr: 1396226584Sdim case X86II::MRM0r: case X86II::MRM1r: 1397226584Sdim case X86II::MRM2r: case X86II::MRM3r: 1398226584Sdim case X86II::MRM4r: case X86II::MRM5r: 1399276479Sdim case X86II::MRM6r: case X86II::MRM7r: { 1400226584Sdim if (HasVEX_4V) // Skip the register dst (which is encoded in VEX_VVVV). 1401239462Sdim ++CurOp; 1402276479Sdim if (HasEVEX_K) // Skip writemask 1403276479Sdim ++CurOp; 1404226584Sdim EmitByte(BaseOpcode, CurByte, OS); 1405276479Sdim uint64_t Form = TSFlags & X86II::FormMask; 1406226584Sdim EmitRegModRMByte(MI.getOperand(CurOp++), 1407276479Sdim (Form == X86II::MRMXr) ? 0 : Form-X86II::MRM0r, 1408226584Sdim CurByte, OS); 1409226584Sdim break; 1410276479Sdim } 1411276479Sdim 1412276479Sdim case X86II::MRMXm: 1413226584Sdim case X86II::MRM0m: case X86II::MRM1m: 1414226584Sdim case X86II::MRM2m: case X86II::MRM3m: 1415226584Sdim case X86II::MRM4m: case X86II::MRM5m: 1416276479Sdim case X86II::MRM6m: case X86II::MRM7m: { 1417234353Sdim if (HasVEX_4V) // Skip the register dst (which is encoded in VEX_VVVV). 1418239462Sdim ++CurOp; 1419276479Sdim if (HasEVEX_K) // Skip writemask 1420276479Sdim ++CurOp; 1421226584Sdim EmitByte(BaseOpcode, CurByte, OS); 1422276479Sdim uint64_t Form = TSFlags & X86II::FormMask; 1423276479Sdim EmitMemModRMByte(MI, CurOp, (Form == X86II::MRMXm) ? 0 : Form-X86II::MRM0m, 1424276479Sdim TSFlags, CurByte, OS, Fixups, STI); 1425226584Sdim CurOp += X86::AddrNumOperands; 1426226584Sdim break; 1427276479Sdim } 1428276479Sdim case X86II::MRM_C0: case X86II::MRM_C1: case X86II::MRM_C2: 1429276479Sdim case X86II::MRM_C3: case X86II::MRM_C4: case X86II::MRM_C8: 1430276479Sdim case X86II::MRM_C9: case X86II::MRM_CA: case X86II::MRM_CB: 1431280031Sdim case X86II::MRM_CF: case X86II::MRM_D0: case X86II::MRM_D1: 1432280031Sdim case X86II::MRM_D4: case X86II::MRM_D5: case X86II::MRM_D6: 1433280031Sdim case X86II::MRM_D7: case X86II::MRM_D8: case X86II::MRM_D9: 1434280031Sdim case X86II::MRM_DA: case X86II::MRM_DB: case X86II::MRM_DC: 1435280031Sdim case X86II::MRM_DD: case X86II::MRM_DE: case X86II::MRM_DF: 1436280031Sdim case X86II::MRM_E0: case X86II::MRM_E1: case X86II::MRM_E2: 1437280031Sdim case X86II::MRM_E3: case X86II::MRM_E4: case X86II::MRM_E5: 1438280031Sdim case X86II::MRM_E8: case X86II::MRM_E9: case X86II::MRM_EA: 1439280031Sdim case X86II::MRM_EB: case X86II::MRM_EC: case X86II::MRM_ED: 1440280031Sdim case X86II::MRM_EE: case X86II::MRM_F0: case X86II::MRM_F1: 1441280031Sdim case X86II::MRM_F2: case X86II::MRM_F3: case X86II::MRM_F4: 1442280031Sdim case X86II::MRM_F5: case X86II::MRM_F6: case X86II::MRM_F7: 1443280031Sdim case X86II::MRM_F8: case X86II::MRM_F9: case X86II::MRM_FA: 1444280031Sdim case X86II::MRM_FB: case X86II::MRM_FC: case X86II::MRM_FD: 1445280031Sdim case X86II::MRM_FE: case X86II::MRM_FF: 1446226584Sdim EmitByte(BaseOpcode, CurByte, OS); 1447234353Sdim 1448234353Sdim unsigned char MRM; 1449234353Sdim switch (TSFlags & X86II::FormMask) { 1450234353Sdim default: llvm_unreachable("Invalid Form"); 1451276479Sdim case X86II::MRM_C0: MRM = 0xC0; break; 1452234353Sdim case X86II::MRM_C1: MRM = 0xC1; break; 1453234353Sdim case X86II::MRM_C2: MRM = 0xC2; break; 1454234353Sdim case X86II::MRM_C3: MRM = 0xC3; break; 1455234353Sdim case X86II::MRM_C4: MRM = 0xC4; break; 1456234353Sdim case X86II::MRM_C8: MRM = 0xC8; break; 1457234353Sdim case X86II::MRM_C9: MRM = 0xC9; break; 1458251662Sdim case X86II::MRM_CA: MRM = 0xCA; break; 1459251662Sdim case X86II::MRM_CB: MRM = 0xCB; break; 1460280031Sdim case X86II::MRM_CF: MRM = 0xCF; break; 1461234353Sdim case X86II::MRM_D0: MRM = 0xD0; break; 1462234353Sdim case X86II::MRM_D1: MRM = 0xD1; break; 1463234353Sdim case X86II::MRM_D4: MRM = 0xD4; break; 1464243830Sdim case X86II::MRM_D5: MRM = 0xD5; break; 1465249423Sdim case X86II::MRM_D6: MRM = 0xD6; break; 1466280031Sdim case X86II::MRM_D7: MRM = 0xD7; break; 1467234353Sdim case X86II::MRM_D8: MRM = 0xD8; break; 1468234353Sdim case X86II::MRM_D9: MRM = 0xD9; break; 1469234353Sdim case X86II::MRM_DA: MRM = 0xDA; break; 1470234353Sdim case X86II::MRM_DB: MRM = 0xDB; break; 1471234353Sdim case X86II::MRM_DC: MRM = 0xDC; break; 1472234353Sdim case X86II::MRM_DD: MRM = 0xDD; break; 1473234353Sdim case X86II::MRM_DE: MRM = 0xDE; break; 1474234353Sdim case X86II::MRM_DF: MRM = 0xDF; break; 1475276479Sdim case X86II::MRM_E0: MRM = 0xE0; break; 1476276479Sdim case X86II::MRM_E1: MRM = 0xE1; break; 1477276479Sdim case X86II::MRM_E2: MRM = 0xE2; break; 1478276479Sdim case X86II::MRM_E3: MRM = 0xE3; break; 1479276479Sdim case X86II::MRM_E4: MRM = 0xE4; break; 1480276479Sdim case X86II::MRM_E5: MRM = 0xE5; break; 1481234353Sdim case X86II::MRM_E8: MRM = 0xE8; break; 1482276479Sdim case X86II::MRM_E9: MRM = 0xE9; break; 1483276479Sdim case X86II::MRM_EA: MRM = 0xEA; break; 1484276479Sdim case X86II::MRM_EB: MRM = 0xEB; break; 1485276479Sdim case X86II::MRM_EC: MRM = 0xEC; break; 1486276479Sdim case X86II::MRM_ED: MRM = 0xED; break; 1487276479Sdim case X86II::MRM_EE: MRM = 0xEE; break; 1488234353Sdim case X86II::MRM_F0: MRM = 0xF0; break; 1489276479Sdim case X86II::MRM_F1: MRM = 0xF1; break; 1490276479Sdim case X86II::MRM_F2: MRM = 0xF2; break; 1491276479Sdim case X86II::MRM_F3: MRM = 0xF3; break; 1492276479Sdim case X86II::MRM_F4: MRM = 0xF4; break; 1493276479Sdim case X86II::MRM_F5: MRM = 0xF5; break; 1494276479Sdim case X86II::MRM_F6: MRM = 0xF6; break; 1495276479Sdim case X86II::MRM_F7: MRM = 0xF7; break; 1496234353Sdim case X86II::MRM_F8: MRM = 0xF8; break; 1497234353Sdim case X86II::MRM_F9: MRM = 0xF9; break; 1498276479Sdim case X86II::MRM_FA: MRM = 0xFA; break; 1499276479Sdim case X86II::MRM_FB: MRM = 0xFB; break; 1500276479Sdim case X86II::MRM_FC: MRM = 0xFC; break; 1501276479Sdim case X86II::MRM_FD: MRM = 0xFD; break; 1502276479Sdim case X86II::MRM_FE: MRM = 0xFE; break; 1503276479Sdim case X86II::MRM_FF: MRM = 0xFF; break; 1504234353Sdim } 1505234353Sdim EmitByte(MRM, CurByte, OS); 1506226584Sdim break; 1507226584Sdim } 1508226584Sdim 1509226584Sdim // If there is a remaining operand, it must be a trailing immediate. Emit it 1510239462Sdim // according to the right size for the instruction. Some instructions 1511239462Sdim // (SSE4a extrq and insertq) have two trailing immediates. 1512239462Sdim while (CurOp != NumOps && NumOps - CurOp <= 2) { 1513226584Sdim // The last source register of a 4 operand instruction in AVX is encoded 1514234353Sdim // in bits[7:4] of a immediate byte. 1515280031Sdim if (TSFlags & X86II::VEX_I8IMM) { 1516234353Sdim const MCOperand &MO = MI.getOperand(HasMemOp4 ? MemOp4_I8IMMOperand 1517239462Sdim : CurOp); 1518239462Sdim ++CurOp; 1519239462Sdim unsigned RegNum = GetX86RegNum(MO) << 4; 1520239462Sdim if (X86II::isX86_64ExtendedReg(MO.getReg())) 1521239462Sdim RegNum |= 1 << 7; 1522234353Sdim // If there is an additional 5th operand it must be an immediate, which 1523234353Sdim // is encoded in bits[3:0] 1524239462Sdim if (CurOp != NumOps) { 1525234353Sdim const MCOperand &MIMM = MI.getOperand(CurOp++); 1526239462Sdim if (MIMM.isImm()) { 1527234353Sdim unsigned Val = MIMM.getImm(); 1528234353Sdim assert(Val < 16 && "Immediate operand value out of range"); 1529234353Sdim RegNum |= Val; 1530234353Sdim } 1531234353Sdim } 1532234353Sdim EmitImmediate(MCOperand::CreateImm(RegNum), MI.getLoc(), 1, FK_Data_1, 1533234353Sdim CurByte, OS, Fixups); 1534226584Sdim } else { 1535234353Sdim EmitImmediate(MI.getOperand(CurOp++), MI.getLoc(), 1536276479Sdim X86II::getSizeOfImm(TSFlags), getImmFixupKind(TSFlags), 1537226584Sdim CurByte, OS, Fixups); 1538226584Sdim } 1539226584Sdim } 1540226584Sdim 1541280031Sdim if (TSFlags & X86II::Has3DNow0F0FOpcode) 1542226584Sdim EmitByte(X86II::getBaseOpcodeFor(TSFlags), CurByte, OS); 1543226584Sdim 1544226584Sdim#ifndef NDEBUG 1545226584Sdim // FIXME: Verify. 1546226584Sdim if (/*!Desc.isVariadic() &&*/ CurOp != NumOps) { 1547226584Sdim errs() << "Cannot encode all operands of: "; 1548226584Sdim MI.dump(); 1549226584Sdim errs() << '\n'; 1550226584Sdim abort(); 1551226584Sdim } 1552226584Sdim#endif 1553226584Sdim} 1554