X86MCCodeEmitter.cpp revision 296417
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 { 33288943Sdim X86MCCodeEmitter(const X86MCCodeEmitter &) = delete; 34288943Sdim void operator=(const X86MCCodeEmitter &) = delete; 35226584Sdim const MCInstrInfo &MCII; 36226584Sdim MCContext &Ctx; 37226584Sdimpublic: 38276479Sdim X86MCCodeEmitter(const MCInstrInfo &mcii, MCContext &ctx) 39276479Sdim : MCII(mcii), Ctx(ctx) { 40226584Sdim } 41226584Sdim 42288943Sdim ~X86MCCodeEmitter() override {} 43226584Sdim 44276479Sdim bool is64BitMode(const MCSubtargetInfo &STI) const { 45288943Sdim return STI.getFeatureBits()[X86::Mode64Bit]; 46226584Sdim } 47226584Sdim 48276479Sdim bool is32BitMode(const MCSubtargetInfo &STI) const { 49288943Sdim return STI.getFeatureBits()[X86::Mode32Bit]; 50234353Sdim } 51234353Sdim 52276479Sdim bool is16BitMode(const MCSubtargetInfo &STI) const { 53288943Sdim return STI.getFeatureBits()[X86::Mode16Bit]; 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 152288943Sdim 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 171226584SdimMCCodeEmitter *llvm::createX86MCCodeEmitter(const MCInstrInfo &MCII, 172239462Sdim const MCRegisterInfo &MRI, 173226584Sdim MCContext &Ctx) { 174276479Sdim return new X86MCCodeEmitter(MCII, Ctx); 175226584Sdim} 176226584Sdim 177226584Sdim/// isDisp8 - Return true if this signed displacement fits in a 8-bit 178226584Sdim/// sign-extended field. 179226584Sdimstatic bool isDisp8(int Value) { 180226584Sdim return Value == (signed char)Value; 181226584Sdim} 182226584Sdim 183261991Sdim/// isCDisp8 - Return true if this signed displacement fits in a 8-bit 184261991Sdim/// compressed dispacement field. 185261991Sdimstatic bool isCDisp8(uint64_t TSFlags, int Value, int& CValue) { 186280031Sdim assert(((TSFlags & X86II::EncodingMask) == X86II::EVEX) && 187261991Sdim "Compressed 8-bit displacement is only valid for EVEX inst."); 188261991Sdim 189276479Sdim unsigned CD8_Scale = 190280031Sdim (TSFlags & X86II::CD8_Scale_Mask) >> X86II::CD8_Scale_Shift; 191276479Sdim if (CD8_Scale == 0) { 192261991Sdim CValue = Value; 193261991Sdim return isDisp8(Value); 194261991Sdim } 195261991Sdim 196276479Sdim unsigned Mask = CD8_Scale - 1; 197276479Sdim assert((CD8_Scale & Mask) == 0 && "Invalid memory object size."); 198276479Sdim if (Value & Mask) // Unaligned offset 199261991Sdim return false; 200276479Sdim Value /= (int)CD8_Scale; 201261991Sdim bool Ret = (Value == (signed char)Value); 202261991Sdim 203261991Sdim if (Ret) 204261991Sdim CValue = Value; 205261991Sdim return Ret; 206261991Sdim} 207261991Sdim 208226584Sdim/// getImmFixupKind - Return the appropriate fixup kind to use for an immediate 209226584Sdim/// in an instruction with the specified TSFlags. 210226584Sdimstatic MCFixupKind getImmFixupKind(uint64_t TSFlags) { 211226584Sdim unsigned Size = X86II::getSizeOfImm(TSFlags); 212226584Sdim bool isPCRel = X86II::isImmPCRel(TSFlags); 213226584Sdim 214276479Sdim if (X86II::isImmSigned(TSFlags)) { 215276479Sdim switch (Size) { 216276479Sdim default: llvm_unreachable("Unsupported signed fixup size!"); 217276479Sdim case 4: return MCFixupKind(X86::reloc_signed_4byte); 218276479Sdim } 219276479Sdim } 220226584Sdim return MCFixup::getKindForSize(Size, isPCRel); 221226584Sdim} 222226584Sdim 223234353Sdim/// Is32BitMemOperand - Return true if the specified instruction has 224234353Sdim/// a 32-bit memory operand. Op specifies the operand # of the memoperand. 225226584Sdimstatic bool Is32BitMemOperand(const MCInst &MI, unsigned Op) { 226226584Sdim const MCOperand &BaseReg = MI.getOperand(Op+X86::AddrBaseReg); 227226584Sdim const MCOperand &IndexReg = MI.getOperand(Op+X86::AddrIndexReg); 228226584Sdim 229226584Sdim if ((BaseReg.getReg() != 0 && 230226584Sdim X86MCRegisterClasses[X86::GR32RegClassID].contains(BaseReg.getReg())) || 231226584Sdim (IndexReg.getReg() != 0 && 232226584Sdim X86MCRegisterClasses[X86::GR32RegClassID].contains(IndexReg.getReg()))) 233226584Sdim return true; 234226584Sdim return false; 235226584Sdim} 236226584Sdim 237234353Sdim/// Is64BitMemOperand - Return true if the specified instruction has 238234353Sdim/// a 64-bit memory operand. Op specifies the operand # of the memoperand. 239234353Sdim#ifndef NDEBUG 240234353Sdimstatic bool Is64BitMemOperand(const MCInst &MI, unsigned Op) { 241234353Sdim const MCOperand &BaseReg = MI.getOperand(Op+X86::AddrBaseReg); 242234353Sdim const MCOperand &IndexReg = MI.getOperand(Op+X86::AddrIndexReg); 243234353Sdim 244234353Sdim if ((BaseReg.getReg() != 0 && 245234353Sdim X86MCRegisterClasses[X86::GR64RegClassID].contains(BaseReg.getReg())) || 246234353Sdim (IndexReg.getReg() != 0 && 247234353Sdim X86MCRegisterClasses[X86::GR64RegClassID].contains(IndexReg.getReg()))) 248234353Sdim return true; 249234353Sdim return false; 250234353Sdim} 251234353Sdim#endif 252234353Sdim 253234353Sdim/// StartsWithGlobalOffsetTable - Check if this expression starts with 254234353Sdim/// _GLOBAL_OFFSET_TABLE_ and if it is of the form 255234353Sdim/// _GLOBAL_OFFSET_TABLE_-symbol. This is needed to support PIC on ELF 256234353Sdim/// i386 as _GLOBAL_OFFSET_TABLE_ is magical. We check only simple case that 257226584Sdim/// are know to be used: _GLOBAL_OFFSET_TABLE_ by itself or at the start 258226584Sdim/// of a binary expression. 259234353Sdimenum GlobalOffsetTableExprKind { 260234353Sdim GOT_None, 261234353Sdim GOT_Normal, 262234353Sdim GOT_SymDiff 263234353Sdim}; 264234353Sdimstatic GlobalOffsetTableExprKind 265234353SdimStartsWithGlobalOffsetTable(const MCExpr *Expr) { 266276479Sdim const MCExpr *RHS = nullptr; 267226584Sdim if (Expr->getKind() == MCExpr::Binary) { 268226584Sdim const MCBinaryExpr *BE = static_cast<const MCBinaryExpr *>(Expr); 269226584Sdim Expr = BE->getLHS(); 270234353Sdim RHS = BE->getRHS(); 271226584Sdim } 272226584Sdim 273226584Sdim if (Expr->getKind() != MCExpr::SymbolRef) 274234353Sdim return GOT_None; 275226584Sdim 276226584Sdim const MCSymbolRefExpr *Ref = static_cast<const MCSymbolRefExpr*>(Expr); 277226584Sdim const MCSymbol &S = Ref->getSymbol(); 278234353Sdim if (S.getName() != "_GLOBAL_OFFSET_TABLE_") 279234353Sdim return GOT_None; 280234353Sdim if (RHS && RHS->getKind() == MCExpr::SymbolRef) 281234353Sdim return GOT_SymDiff; 282234353Sdim return GOT_Normal; 283226584Sdim} 284226584Sdim 285251662Sdimstatic bool HasSecRelSymbolRef(const MCExpr *Expr) { 286251662Sdim if (Expr->getKind() == MCExpr::SymbolRef) { 287251662Sdim const MCSymbolRefExpr *Ref = static_cast<const MCSymbolRefExpr*>(Expr); 288251662Sdim return Ref->getKind() == MCSymbolRefExpr::VK_SECREL; 289251662Sdim } 290251662Sdim return false; 291251662Sdim} 292251662Sdim 293226584Sdimvoid X86MCCodeEmitter:: 294234353SdimEmitImmediate(const MCOperand &DispOp, SMLoc Loc, unsigned Size, 295234353Sdim MCFixupKind FixupKind, unsigned &CurByte, raw_ostream &OS, 296226584Sdim SmallVectorImpl<MCFixup> &Fixups, int ImmOffset) const { 297276479Sdim const MCExpr *Expr = nullptr; 298226584Sdim if (DispOp.isImm()) { 299226584Sdim // If this is a simple integer displacement that doesn't require a 300226584Sdim // relocation, emit it now. 301226584Sdim if (FixupKind != FK_PCRel_1 && 302226584Sdim FixupKind != FK_PCRel_2 && 303226584Sdim FixupKind != FK_PCRel_4) { 304226584Sdim EmitConstant(DispOp.getImm()+ImmOffset, Size, CurByte, OS); 305226584Sdim return; 306226584Sdim } 307288943Sdim Expr = MCConstantExpr::create(DispOp.getImm(), Ctx); 308226584Sdim } else { 309226584Sdim Expr = DispOp.getExpr(); 310226584Sdim } 311226584Sdim 312226584Sdim // If we have an immoffset, add it to the expression. 313226584Sdim if ((FixupKind == FK_Data_4 || 314234353Sdim FixupKind == FK_Data_8 || 315234353Sdim FixupKind == MCFixupKind(X86::reloc_signed_4byte))) { 316234353Sdim GlobalOffsetTableExprKind Kind = StartsWithGlobalOffsetTable(Expr); 317234353Sdim if (Kind != GOT_None) { 318234353Sdim assert(ImmOffset == 0); 319226584Sdim 320276479Sdim if (Size == 8) { 321276479Sdim FixupKind = MCFixupKind(X86::reloc_global_offset_table8); 322276479Sdim } else { 323276479Sdim assert(Size == 4); 324276479Sdim FixupKind = MCFixupKind(X86::reloc_global_offset_table); 325276479Sdim } 326276479Sdim 327234353Sdim if (Kind == GOT_Normal) 328234353Sdim ImmOffset = CurByte; 329234353Sdim } else if (Expr->getKind() == MCExpr::SymbolRef) { 330251662Sdim if (HasSecRelSymbolRef(Expr)) { 331234353Sdim FixupKind = MCFixupKind(FK_SecRel_4); 332234353Sdim } 333251662Sdim } else if (Expr->getKind() == MCExpr::Binary) { 334251662Sdim const MCBinaryExpr *Bin = static_cast<const MCBinaryExpr*>(Expr); 335251662Sdim if (HasSecRelSymbolRef(Bin->getLHS()) 336251662Sdim || HasSecRelSymbolRef(Bin->getRHS())) { 337251662Sdim FixupKind = MCFixupKind(FK_SecRel_4); 338251662Sdim } 339234353Sdim } 340226584Sdim } 341226584Sdim 342226584Sdim // If the fixup is pc-relative, we need to bias the value to be relative to 343226584Sdim // the start of the field, not the end of the field. 344226584Sdim if (FixupKind == FK_PCRel_4 || 345226584Sdim FixupKind == MCFixupKind(X86::reloc_riprel_4byte) || 346226584Sdim FixupKind == MCFixupKind(X86::reloc_riprel_4byte_movq_load)) 347226584Sdim ImmOffset -= 4; 348226584Sdim if (FixupKind == FK_PCRel_2) 349226584Sdim ImmOffset -= 2; 350226584Sdim if (FixupKind == FK_PCRel_1) 351226584Sdim ImmOffset -= 1; 352226584Sdim 353226584Sdim if (ImmOffset) 354288943Sdim Expr = MCBinaryExpr::createAdd(Expr, MCConstantExpr::create(ImmOffset, Ctx), 355226584Sdim Ctx); 356226584Sdim 357226584Sdim // Emit a symbolic constant as a fixup and 4 zeros. 358288943Sdim Fixups.push_back(MCFixup::create(CurByte, Expr, FixupKind, Loc)); 359226584Sdim EmitConstant(0, Size, CurByte, OS); 360226584Sdim} 361226584Sdim 362226584Sdimvoid X86MCCodeEmitter::EmitMemModRMByte(const MCInst &MI, unsigned Op, 363226584Sdim unsigned RegOpcodeField, 364226584Sdim uint64_t TSFlags, unsigned &CurByte, 365226584Sdim raw_ostream &OS, 366276479Sdim SmallVectorImpl<MCFixup> &Fixups, 367276479Sdim const MCSubtargetInfo &STI) const{ 368226584Sdim const MCOperand &Disp = MI.getOperand(Op+X86::AddrDisp); 369226584Sdim const MCOperand &Base = MI.getOperand(Op+X86::AddrBaseReg); 370226584Sdim const MCOperand &Scale = MI.getOperand(Op+X86::AddrScaleAmt); 371226584Sdim const MCOperand &IndexReg = MI.getOperand(Op+X86::AddrIndexReg); 372226584Sdim unsigned BaseReg = Base.getReg(); 373280031Sdim bool HasEVEX = (TSFlags & X86II::EncodingMask) == X86II::EVEX; 374226584Sdim 375226584Sdim // Handle %rip relative addressing. 376226584Sdim if (BaseReg == X86::RIP) { // [disp32+RIP] in X86-64 mode 377276479Sdim assert(is64BitMode(STI) && "Rip-relative addressing requires 64-bit mode"); 378226584Sdim assert(IndexReg.getReg() == 0 && "Invalid rip-relative address"); 379226584Sdim EmitByte(ModRMByte(0, RegOpcodeField, 5), CurByte, OS); 380226584Sdim 381226584Sdim unsigned FixupKind = X86::reloc_riprel_4byte; 382226584Sdim 383226584Sdim // movq loads are handled with a special relocation form which allows the 384226584Sdim // linker to eliminate some loads for GOT references which end up in the 385226584Sdim // same linkage unit. 386226584Sdim if (MI.getOpcode() == X86::MOV64rm) 387226584Sdim FixupKind = X86::reloc_riprel_4byte_movq_load; 388226584Sdim 389226584Sdim // rip-relative addressing is actually relative to the *next* instruction. 390226584Sdim // Since an immediate can follow the mod/rm byte for an instruction, this 391226584Sdim // means that we need to bias the immediate field of the instruction with 392226584Sdim // the size of the immediate field. If we have this case, add it into the 393226584Sdim // expression to emit. 394226584Sdim int ImmSize = X86II::hasImm(TSFlags) ? X86II::getSizeOfImm(TSFlags) : 0; 395226584Sdim 396234353Sdim EmitImmediate(Disp, MI.getLoc(), 4, MCFixupKind(FixupKind), 397226584Sdim CurByte, OS, Fixups, -ImmSize); 398226584Sdim return; 399226584Sdim } 400226584Sdim 401226584Sdim unsigned BaseRegNo = BaseReg ? GetX86RegNum(Base) : -1U; 402226584Sdim 403276479Sdim // 16-bit addressing forms of the ModR/M byte have a different encoding for 404276479Sdim // the R/M field and are far more limited in which registers can be used. 405276479Sdim if (Is16BitMemOperand(MI, Op, STI)) { 406276479Sdim if (BaseReg) { 407276479Sdim // For 32-bit addressing, the row and column values in Table 2-2 are 408276479Sdim // basically the same. It's AX/CX/DX/BX/SP/BP/SI/DI in that order, with 409276479Sdim // some special cases. And GetX86RegNum reflects that numbering. 410276479Sdim // For 16-bit addressing it's more fun, as shown in the SDM Vol 2A, 411276479Sdim // Table 2-1 "16-Bit Addressing Forms with the ModR/M byte". We can only 412276479Sdim // use SI/DI/BP/BX, which have "row" values 4-7 in no particular order, 413276479Sdim // while values 0-3 indicate the allowed combinations (base+index) of 414276479Sdim // those: 0 for BX+SI, 1 for BX+DI, 2 for BP+SI, 3 for BP+DI. 415276479Sdim // 416276479Sdim // R16Table[] is a lookup from the normal RegNo, to the row values from 417276479Sdim // Table 2-1 for 16-bit addressing modes. Where zero means disallowed. 418276479Sdim static const unsigned R16Table[] = { 0, 0, 0, 7, 0, 6, 4, 5 }; 419276479Sdim unsigned RMfield = R16Table[BaseRegNo]; 420276479Sdim 421276479Sdim assert(RMfield && "invalid 16-bit base register"); 422276479Sdim 423276479Sdim if (IndexReg.getReg()) { 424276479Sdim unsigned IndexReg16 = R16Table[GetX86RegNum(IndexReg)]; 425276479Sdim 426276479Sdim assert(IndexReg16 && "invalid 16-bit index register"); 427276479Sdim // We must have one of SI/DI (4,5), and one of BP/BX (6,7). 428276479Sdim assert(((IndexReg16 ^ RMfield) & 2) && 429276479Sdim "invalid 16-bit base/index register combination"); 430276479Sdim assert(Scale.getImm() == 1 && 431276479Sdim "invalid scale for 16-bit memory reference"); 432276479Sdim 433276479Sdim // Allow base/index to appear in either order (although GAS doesn't). 434276479Sdim if (IndexReg16 & 2) 435276479Sdim RMfield = (RMfield & 1) | ((7 - IndexReg16) << 1); 436276479Sdim else 437276479Sdim RMfield = (IndexReg16 & 1) | ((7 - RMfield) << 1); 438276479Sdim } 439276479Sdim 440276479Sdim if (Disp.isImm() && isDisp8(Disp.getImm())) { 441276479Sdim if (Disp.getImm() == 0 && BaseRegNo != N86::EBP) { 442276479Sdim // There is no displacement; just the register. 443276479Sdim EmitByte(ModRMByte(0, RegOpcodeField, RMfield), CurByte, OS); 444276479Sdim return; 445276479Sdim } 446276479Sdim // Use the [REG]+disp8 form, including for [BP] which cannot be encoded. 447276479Sdim EmitByte(ModRMByte(1, RegOpcodeField, RMfield), CurByte, OS); 448276479Sdim EmitImmediate(Disp, MI.getLoc(), 1, FK_Data_1, CurByte, OS, Fixups); 449276479Sdim return; 450276479Sdim } 451276479Sdim // This is the [REG]+disp16 case. 452276479Sdim EmitByte(ModRMByte(2, RegOpcodeField, RMfield), CurByte, OS); 453276479Sdim } else { 454276479Sdim // There is no BaseReg; this is the plain [disp16] case. 455276479Sdim EmitByte(ModRMByte(0, RegOpcodeField, 6), CurByte, OS); 456276479Sdim } 457276479Sdim 458276479Sdim // Emit 16-bit displacement for plain disp16 or [REG]+disp16 cases. 459276479Sdim EmitImmediate(Disp, MI.getLoc(), 2, FK_Data_2, CurByte, OS, Fixups); 460276479Sdim return; 461276479Sdim } 462276479Sdim 463226584Sdim // Determine whether a SIB byte is needed. 464226584Sdim // If no BaseReg, issue a RIP relative instruction only if the MCE can 465226584Sdim // resolve addresses on-the-fly, otherwise use SIB (Intel Manual 2A, table 466226584Sdim // 2-7) and absolute references. 467226584Sdim 468226584Sdim if (// The SIB byte must be used if there is an index register. 469226584Sdim IndexReg.getReg() == 0 && 470226584Sdim // The SIB byte must be used if the base is ESP/RSP/R12, all of which 471226584Sdim // encode to an R/M value of 4, which indicates that a SIB byte is 472226584Sdim // present. 473226584Sdim BaseRegNo != N86::ESP && 474226584Sdim // If there is no base register and we're in 64-bit mode, we need a SIB 475226584Sdim // byte to emit an addr that is just 'disp32' (the non-RIP relative form). 476276479Sdim (!is64BitMode(STI) || BaseReg != 0)) { 477226584Sdim 478226584Sdim if (BaseReg == 0) { // [disp32] in X86-32 mode 479226584Sdim EmitByte(ModRMByte(0, RegOpcodeField, 5), CurByte, OS); 480234353Sdim EmitImmediate(Disp, MI.getLoc(), 4, FK_Data_4, CurByte, OS, Fixups); 481226584Sdim return; 482226584Sdim } 483226584Sdim 484226584Sdim // If the base is not EBP/ESP and there is no displacement, use simple 485226584Sdim // indirect register encoding, this handles addresses like [EAX]. The 486226584Sdim // encoding for [EBP] with no displacement means [disp32] so we handle it 487226584Sdim // by emitting a displacement of 0 below. 488226584Sdim if (Disp.isImm() && Disp.getImm() == 0 && BaseRegNo != N86::EBP) { 489226584Sdim EmitByte(ModRMByte(0, RegOpcodeField, BaseRegNo), CurByte, OS); 490226584Sdim return; 491226584Sdim } 492226584Sdim 493226584Sdim // Otherwise, if the displacement fits in a byte, encode as [REG+disp8]. 494261991Sdim if (Disp.isImm()) { 495261991Sdim if (!HasEVEX && isDisp8(Disp.getImm())) { 496261991Sdim EmitByte(ModRMByte(1, RegOpcodeField, BaseRegNo), CurByte, OS); 497261991Sdim EmitImmediate(Disp, MI.getLoc(), 1, FK_Data_1, CurByte, OS, Fixups); 498261991Sdim return; 499261991Sdim } 500261991Sdim // Try EVEX compressed 8-bit displacement first; if failed, fall back to 501261991Sdim // 32-bit displacement. 502261991Sdim int CDisp8 = 0; 503261991Sdim if (HasEVEX && isCDisp8(TSFlags, Disp.getImm(), CDisp8)) { 504261991Sdim EmitByte(ModRMByte(1, RegOpcodeField, BaseRegNo), CurByte, OS); 505261991Sdim EmitImmediate(Disp, MI.getLoc(), 1, FK_Data_1, CurByte, OS, Fixups, 506261991Sdim CDisp8 - Disp.getImm()); 507261991Sdim return; 508261991Sdim } 509226584Sdim } 510226584Sdim 511226584Sdim // Otherwise, emit the most general non-SIB encoding: [REG+disp32] 512226584Sdim EmitByte(ModRMByte(2, RegOpcodeField, BaseRegNo), CurByte, OS); 513296417Sdim EmitImmediate(Disp, MI.getLoc(), 4, MCFixupKind(X86::reloc_signed_4byte), 514296417Sdim CurByte, OS, Fixups); 515226584Sdim return; 516226584Sdim } 517226584Sdim 518226584Sdim // We need a SIB byte, so start by outputting the ModR/M byte first 519226584Sdim assert(IndexReg.getReg() != X86::ESP && 520226584Sdim IndexReg.getReg() != X86::RSP && "Cannot use ESP as index reg!"); 521226584Sdim 522226584Sdim bool ForceDisp32 = false; 523226584Sdim bool ForceDisp8 = false; 524261991Sdim int CDisp8 = 0; 525261991Sdim int ImmOffset = 0; 526226584Sdim if (BaseReg == 0) { 527226584Sdim // If there is no base register, we emit the special case SIB byte with 528226584Sdim // MOD=0, BASE=5, to JUST get the index, scale, and displacement. 529226584Sdim EmitByte(ModRMByte(0, RegOpcodeField, 4), CurByte, OS); 530226584Sdim ForceDisp32 = true; 531226584Sdim } else if (!Disp.isImm()) { 532226584Sdim // Emit the normal disp32 encoding. 533226584Sdim EmitByte(ModRMByte(2, RegOpcodeField, 4), CurByte, OS); 534226584Sdim ForceDisp32 = true; 535226584Sdim } else if (Disp.getImm() == 0 && 536226584Sdim // Base reg can't be anything that ends up with '5' as the base 537226584Sdim // reg, it is the magic [*] nomenclature that indicates no base. 538226584Sdim BaseRegNo != N86::EBP) { 539226584Sdim // Emit no displacement ModR/M byte 540226584Sdim EmitByte(ModRMByte(0, RegOpcodeField, 4), CurByte, OS); 541261991Sdim } else if (!HasEVEX && isDisp8(Disp.getImm())) { 542226584Sdim // Emit the disp8 encoding. 543226584Sdim EmitByte(ModRMByte(1, RegOpcodeField, 4), CurByte, OS); 544226584Sdim ForceDisp8 = true; // Make sure to force 8 bit disp if Base=EBP 545261991Sdim } else if (HasEVEX && isCDisp8(TSFlags, Disp.getImm(), CDisp8)) { 546261991Sdim // Emit the disp8 encoding. 547261991Sdim EmitByte(ModRMByte(1, RegOpcodeField, 4), CurByte, OS); 548261991Sdim ForceDisp8 = true; // Make sure to force 8 bit disp if Base=EBP 549261991Sdim ImmOffset = CDisp8 - Disp.getImm(); 550226584Sdim } else { 551226584Sdim // Emit the normal disp32 encoding. 552226584Sdim EmitByte(ModRMByte(2, RegOpcodeField, 4), CurByte, OS); 553226584Sdim } 554226584Sdim 555226584Sdim // Calculate what the SS field value should be... 556226584Sdim static const unsigned SSTable[] = { ~0U, 0, 1, ~0U, 2, ~0U, ~0U, ~0U, 3 }; 557226584Sdim unsigned SS = SSTable[Scale.getImm()]; 558226584Sdim 559226584Sdim if (BaseReg == 0) { 560226584Sdim // Handle the SIB byte for the case where there is no base, see Intel 561226584Sdim // Manual 2A, table 2-7. The displacement has already been output. 562226584Sdim unsigned IndexRegNo; 563226584Sdim if (IndexReg.getReg()) 564226584Sdim IndexRegNo = GetX86RegNum(IndexReg); 565226584Sdim else // Examples: [ESP+1*<noreg>+4] or [scaled idx]+disp32 (MOD=0,BASE=5) 566226584Sdim IndexRegNo = 4; 567226584Sdim EmitSIBByte(SS, IndexRegNo, 5, CurByte, OS); 568226584Sdim } else { 569226584Sdim unsigned IndexRegNo; 570226584Sdim if (IndexReg.getReg()) 571226584Sdim IndexRegNo = GetX86RegNum(IndexReg); 572226584Sdim else 573226584Sdim IndexRegNo = 4; // For example [ESP+1*<noreg>+4] 574226584Sdim EmitSIBByte(SS, IndexRegNo, GetX86RegNum(Base), CurByte, OS); 575226584Sdim } 576226584Sdim 577226584Sdim // Do we need to output a displacement? 578226584Sdim if (ForceDisp8) 579261991Sdim EmitImmediate(Disp, MI.getLoc(), 1, FK_Data_1, CurByte, OS, Fixups, ImmOffset); 580226584Sdim else if (ForceDisp32 || Disp.getImm() != 0) 581234353Sdim EmitImmediate(Disp, MI.getLoc(), 4, MCFixupKind(X86::reloc_signed_4byte), 582234353Sdim CurByte, OS, Fixups); 583226584Sdim} 584226584Sdim 585226584Sdim/// EmitVEXOpcodePrefix - AVX instructions are encoded using a opcode prefix 586226584Sdim/// called VEX. 587226584Sdimvoid X86MCCodeEmitter::EmitVEXOpcodePrefix(uint64_t TSFlags, unsigned &CurByte, 588226584Sdim int MemOperand, const MCInst &MI, 589226584Sdim const MCInstrDesc &Desc, 590226584Sdim raw_ostream &OS) const { 591280031Sdim assert(!(TSFlags & X86II::LOCK) && "Can't have LOCK VEX."); 592226584Sdim 593280031Sdim uint64_t Encoding = TSFlags & X86II::EncodingMask; 594280031Sdim bool HasEVEX_K = TSFlags & X86II::EVEX_K; 595280031Sdim bool HasVEX_4V = TSFlags & X86II::VEX_4V; 596280031Sdim bool HasVEX_4VOp3 = TSFlags & X86II::VEX_4VOp3; 597280031Sdim bool HasMemOp4 = TSFlags & X86II::MemOp4; 598280031Sdim bool HasEVEX_RC = TSFlags & X86II::EVEX_RC; 599280031Sdim 600226584Sdim // VEX_R: opcode externsion equivalent to REX.R in 601226584Sdim // 1's complement (inverted) form 602226584Sdim // 603226584Sdim // 1: Same as REX_R=0 (must be 1 in 32-bit mode) 604226584Sdim // 0: Same as REX_R=1 (64 bit mode only) 605226584Sdim // 606226584Sdim unsigned char VEX_R = 0x1; 607261991Sdim unsigned char EVEX_R2 = 0x1; 608226584Sdim 609226584Sdim // VEX_X: equivalent to REX.X, only used when a 610226584Sdim // register is used for index in SIB Byte. 611226584Sdim // 612226584Sdim // 1: Same as REX.X=0 (must be 1 in 32-bit mode) 613226584Sdim // 0: Same as REX.X=1 (64-bit mode only) 614226584Sdim unsigned char VEX_X = 0x1; 615226584Sdim 616226584Sdim // VEX_B: 617226584Sdim // 618226584Sdim // 1: Same as REX_B=0 (ignored in 32-bit mode) 619226584Sdim // 0: Same as REX_B=1 (64 bit mode only) 620226584Sdim // 621226584Sdim unsigned char VEX_B = 0x1; 622226584Sdim 623226584Sdim // VEX_W: opcode specific (use like REX.W, or used for 624226584Sdim // opcode extension, or ignored, depending on the opcode byte) 625226584Sdim unsigned char VEX_W = 0; 626226584Sdim 627226584Sdim // VEX_5M (VEX m-mmmmm field): 628226584Sdim // 629226584Sdim // 0b00000: Reserved for future use 630226584Sdim // 0b00001: implied 0F leading opcode 631226584Sdim // 0b00010: implied 0F 38 leading opcode bytes 632226584Sdim // 0b00011: implied 0F 3A leading opcode bytes 633226584Sdim // 0b00100-0b11111: Reserved for future use 634234353Sdim // 0b01000: XOP map select - 08h instructions with imm byte 635261991Sdim // 0b01001: XOP map select - 09h instructions with no imm byte 636261991Sdim // 0b01010: XOP map select - 0Ah instructions with imm dword 637276479Sdim unsigned char VEX_5M = 0; 638226584Sdim 639226584Sdim // VEX_4V (VEX vvvv field): a register specifier 640226584Sdim // (in 1's complement form) or 1111 if unused. 641226584Sdim unsigned char VEX_4V = 0xf; 642261991Sdim unsigned char EVEX_V2 = 0x1; 643226584Sdim 644226584Sdim // VEX_L (Vector Length): 645226584Sdim // 646226584Sdim // 0: scalar or 128-bit vector 647226584Sdim // 1: 256-bit vector 648226584Sdim // 649226584Sdim unsigned char VEX_L = 0; 650261991Sdim unsigned char EVEX_L2 = 0; 651226584Sdim 652226584Sdim // VEX_PP: opcode extension providing equivalent 653226584Sdim // functionality of a SIMD prefix 654226584Sdim // 655226584Sdim // 0b00: None 656226584Sdim // 0b01: 66 657226584Sdim // 0b10: F3 658226584Sdim // 0b11: F2 659226584Sdim // 660226584Sdim unsigned char VEX_PP = 0; 661226584Sdim 662261991Sdim // EVEX_U 663261991Sdim unsigned char EVEX_U = 1; // Always '1' so far 664261991Sdim 665261991Sdim // EVEX_z 666261991Sdim unsigned char EVEX_z = 0; 667261991Sdim 668261991Sdim // EVEX_b 669261991Sdim unsigned char EVEX_b = 0; 670261991Sdim 671276479Sdim // EVEX_rc 672276479Sdim unsigned char EVEX_rc = 0; 673276479Sdim 674261991Sdim // EVEX_aaa 675261991Sdim unsigned char EVEX_aaa = 0; 676261991Sdim 677276479Sdim bool EncodeRC = false; 678226584Sdim 679280031Sdim if (TSFlags & X86II::VEX_W) 680226584Sdim VEX_W = 1; 681226584Sdim 682280031Sdim if (TSFlags & X86II::VEX_L) 683226584Sdim VEX_L = 1; 684280031Sdim if (TSFlags & X86II::EVEX_L2) 685261991Sdim EVEX_L2 = 1; 686226584Sdim 687280031Sdim if (HasEVEX_K && (TSFlags & X86II::EVEX_Z)) 688261991Sdim EVEX_z = 1; 689261991Sdim 690280031Sdim if ((TSFlags & X86II::EVEX_B)) 691261991Sdim EVEX_b = 1; 692261991Sdim 693276479Sdim switch (TSFlags & X86II::OpPrefixMask) { 694276479Sdim default: break; // VEX_PP already correct 695276479Sdim case X86II::PD: VEX_PP = 0x1; break; // 66 696276479Sdim case X86II::XS: VEX_PP = 0x2; break; // F3 697276479Sdim case X86II::XD: VEX_PP = 0x3; break; // F2 698276479Sdim } 699276479Sdim 700276479Sdim switch (TSFlags & X86II::OpMapMask) { 701234353Sdim default: llvm_unreachable("Invalid prefix!"); 702276479Sdim case X86II::TB: VEX_5M = 0x1; break; // 0F 703276479Sdim case X86II::T8: VEX_5M = 0x2; break; // 0F 38 704276479Sdim case X86II::TA: VEX_5M = 0x3; break; // 0F 3A 705276479Sdim case X86II::XOP8: VEX_5M = 0x8; break; 706276479Sdim case X86II::XOP9: VEX_5M = 0x9; break; 707276479Sdim case X86II::XOPA: VEX_5M = 0xA; break; 708226584Sdim } 709226584Sdim 710226584Sdim // Classify VEX_B, VEX_4V, VEX_R, VEX_X 711239462Sdim unsigned NumOps = Desc.getNumOperands(); 712276479Sdim unsigned CurOp = X86II::getOperandBias(Desc); 713239462Sdim 714226584Sdim switch (TSFlags & X86II::FormMask) { 715276479Sdim default: llvm_unreachable("Unexpected form in EmitVEXOpcodePrefix!"); 716276479Sdim case X86II::RawFrm: 717276479Sdim break; 718226584Sdim case X86II::MRMDestMem: { 719226584Sdim // MRMDestMem instructions forms: 720226584Sdim // MemAddr, src1(ModR/M) 721226584Sdim // MemAddr, src1(VEX_4V), src2(ModR/M) 722226584Sdim // MemAddr, src1(ModR/M), imm8 723226584Sdim // 724280031Sdim if (X86II::isX86_64ExtendedReg(MI.getOperand(MemOperand + 725261991Sdim X86::AddrBaseReg).getReg())) 726226584Sdim VEX_B = 0x0; 727261991Sdim if (X86II::isX86_64ExtendedReg(MI.getOperand(MemOperand + 728261991Sdim X86::AddrIndexReg).getReg())) 729226584Sdim VEX_X = 0x0; 730276479Sdim if (X86II::is32ExtendedReg(MI.getOperand(MemOperand + 731261991Sdim X86::AddrIndexReg).getReg())) 732261991Sdim EVEX_V2 = 0x0; 733226584Sdim 734261991Sdim CurOp += X86::AddrNumOperands; 735226584Sdim 736261991Sdim if (HasEVEX_K) 737261991Sdim EVEX_aaa = getWriteMaskRegisterEncoding(MI, CurOp++); 738261991Sdim 739261991Sdim if (HasVEX_4V) { 740261991Sdim VEX_4V = getVEXRegisterEncoding(MI, CurOp); 741276479Sdim if (X86II::is32ExtendedReg(MI.getOperand(CurOp).getReg())) 742261991Sdim EVEX_V2 = 0x0; 743261991Sdim CurOp++; 744261991Sdim } 745261991Sdim 746226584Sdim const MCOperand &MO = MI.getOperand(CurOp); 747261991Sdim if (MO.isReg()) { 748261991Sdim if (X86II::isX86_64ExtendedReg(MO.getReg())) 749261991Sdim VEX_R = 0x0; 750276479Sdim if (X86II::is32ExtendedReg(MO.getReg())) 751261991Sdim EVEX_R2 = 0x0; 752261991Sdim } 753226584Sdim break; 754226584Sdim } 755234353Sdim case X86II::MRMSrcMem: 756226584Sdim // MRMSrcMem instructions forms: 757226584Sdim // src1(ModR/M), MemAddr 758226584Sdim // src1(ModR/M), src2(VEX_4V), MemAddr 759226584Sdim // src1(ModR/M), MemAddr, imm8 760226584Sdim // src1(ModR/M), MemAddr, src2(VEX_I8IMM) 761226584Sdim // 762234353Sdim // FMA4: 763234353Sdim // dst(ModR/M.reg), src1(VEX_4V), src2(ModR/M), src3(VEX_I8IMM) 764234353Sdim // dst(ModR/M.reg), src1(VEX_4V), src2(VEX_I8IMM), src3(ModR/M), 765261991Sdim if (X86II::isX86_64ExtendedReg(MI.getOperand(CurOp).getReg())) 766226584Sdim VEX_R = 0x0; 767276479Sdim if (X86II::is32ExtendedReg(MI.getOperand(CurOp).getReg())) 768261991Sdim EVEX_R2 = 0x0; 769261991Sdim CurOp++; 770226584Sdim 771261991Sdim if (HasEVEX_K) 772261991Sdim EVEX_aaa = getWriteMaskRegisterEncoding(MI, CurOp++); 773261991Sdim 774261991Sdim if (HasVEX_4V) { 775239462Sdim VEX_4V = getVEXRegisterEncoding(MI, CurOp); 776276479Sdim if (X86II::is32ExtendedReg(MI.getOperand(CurOp).getReg())) 777261991Sdim EVEX_V2 = 0x0; 778261991Sdim CurOp++; 779261991Sdim } 780226584Sdim 781226584Sdim if (X86II::isX86_64ExtendedReg( 782234353Sdim MI.getOperand(MemOperand+X86::AddrBaseReg).getReg())) 783226584Sdim VEX_B = 0x0; 784226584Sdim if (X86II::isX86_64ExtendedReg( 785234353Sdim MI.getOperand(MemOperand+X86::AddrIndexReg).getReg())) 786226584Sdim VEX_X = 0x0; 787276479Sdim if (X86II::is32ExtendedReg(MI.getOperand(MemOperand + 788276479Sdim X86::AddrIndexReg).getReg())) 789261991Sdim EVEX_V2 = 0x0; 790234353Sdim 791234353Sdim if (HasVEX_4VOp3) 792239462Sdim // Instruction format for 4VOp3: 793239462Sdim // src1(ModR/M), MemAddr, src3(VEX_4V) 794239462Sdim // CurOp points to start of the MemoryOperand, 795239462Sdim // it skips TIED_TO operands if exist, then increments past src1. 796239462Sdim // CurOp + X86::AddrNumOperands will point to src3. 797239462Sdim VEX_4V = getVEXRegisterEncoding(MI, CurOp+X86::AddrNumOperands); 798226584Sdim break; 799226584Sdim case X86II::MRM0m: case X86II::MRM1m: 800226584Sdim case X86II::MRM2m: case X86II::MRM3m: 801226584Sdim case X86II::MRM4m: case X86II::MRM5m: 802234353Sdim case X86II::MRM6m: case X86II::MRM7m: { 803226584Sdim // MRM[0-9]m instructions forms: 804226584Sdim // MemAddr 805234353Sdim // src1(VEX_4V), MemAddr 806261991Sdim if (HasVEX_4V) { 807261991Sdim VEX_4V = getVEXRegisterEncoding(MI, CurOp); 808276479Sdim if (X86II::is32ExtendedReg(MI.getOperand(CurOp).getReg())) 809261991Sdim EVEX_V2 = 0x0; 810261991Sdim CurOp++; 811261991Sdim } 812234353Sdim 813261991Sdim if (HasEVEX_K) 814261991Sdim EVEX_aaa = getWriteMaskRegisterEncoding(MI, CurOp++); 815261991Sdim 816234353Sdim if (X86II::isX86_64ExtendedReg( 817234353Sdim MI.getOperand(MemOperand+X86::AddrBaseReg).getReg())) 818226584Sdim VEX_B = 0x0; 819234353Sdim if (X86II::isX86_64ExtendedReg( 820234353Sdim MI.getOperand(MemOperand+X86::AddrIndexReg).getReg())) 821226584Sdim VEX_X = 0x0; 822226584Sdim break; 823234353Sdim } 824226584Sdim case X86II::MRMSrcReg: 825226584Sdim // MRMSrcReg instructions forms: 826226584Sdim // dst(ModR/M), src1(VEX_4V), src2(ModR/M), src3(VEX_I8IMM) 827226584Sdim // dst(ModR/M), src1(ModR/M) 828226584Sdim // dst(ModR/M), src1(ModR/M), imm8 829226584Sdim // 830249423Sdim // FMA4: 831249423Sdim // dst(ModR/M.reg), src1(VEX_4V), src2(ModR/M), src3(VEX_I8IMM) 832249423Sdim // dst(ModR/M.reg), src1(VEX_4V), src2(VEX_I8IMM), src3(ModR/M), 833226584Sdim if (X86II::isX86_64ExtendedReg(MI.getOperand(CurOp).getReg())) 834226584Sdim VEX_R = 0x0; 835276479Sdim if (X86II::is32ExtendedReg(MI.getOperand(CurOp).getReg())) 836261991Sdim EVEX_R2 = 0x0; 837226584Sdim CurOp++; 838226584Sdim 839261991Sdim if (HasEVEX_K) 840261991Sdim EVEX_aaa = getWriteMaskRegisterEncoding(MI, CurOp++); 841249423Sdim 842261991Sdim if (HasVEX_4V) { 843261991Sdim VEX_4V = getVEXRegisterEncoding(MI, CurOp); 844276479Sdim if (X86II::is32ExtendedReg(MI.getOperand(CurOp).getReg())) 845261991Sdim EVEX_V2 = 0x0; 846261991Sdim CurOp++; 847261991Sdim } 848261991Sdim 849249423Sdim if (HasMemOp4) // Skip second register source (encoded in I8IMM) 850249423Sdim CurOp++; 851249423Sdim 852226584Sdim if (X86II::isX86_64ExtendedReg(MI.getOperand(CurOp).getReg())) 853226584Sdim VEX_B = 0x0; 854276479Sdim if (X86II::is32ExtendedReg(MI.getOperand(CurOp).getReg())) 855261991Sdim VEX_X = 0x0; 856234353Sdim CurOp++; 857234353Sdim if (HasVEX_4VOp3) 858276479Sdim VEX_4V = getVEXRegisterEncoding(MI, CurOp++); 859276479Sdim if (EVEX_b) { 860276479Sdim if (HasEVEX_RC) { 861276479Sdim unsigned RcOperand = NumOps-1; 862276479Sdim assert(RcOperand >= CurOp); 863276479Sdim EVEX_rc = MI.getOperand(RcOperand).getImm() & 0x3; 864276479Sdim } 865276479Sdim EncodeRC = true; 866280031Sdim } 867226584Sdim break; 868226584Sdim case X86II::MRMDestReg: 869226584Sdim // MRMDestReg instructions forms: 870226584Sdim // dst(ModR/M), src(ModR/M) 871226584Sdim // dst(ModR/M), src(ModR/M), imm8 872249423Sdim // dst(ModR/M), src1(VEX_4V), src2(ModR/M) 873249423Sdim if (X86II::isX86_64ExtendedReg(MI.getOperand(CurOp).getReg())) 874226584Sdim VEX_B = 0x0; 875276479Sdim if (X86II::is32ExtendedReg(MI.getOperand(CurOp).getReg())) 876261991Sdim VEX_X = 0x0; 877249423Sdim CurOp++; 878249423Sdim 879261991Sdim if (HasEVEX_K) 880261991Sdim EVEX_aaa = getWriteMaskRegisterEncoding(MI, CurOp++); 881249423Sdim 882261991Sdim if (HasVEX_4V) { 883261991Sdim VEX_4V = getVEXRegisterEncoding(MI, CurOp); 884276479Sdim if (X86II::is32ExtendedReg(MI.getOperand(CurOp).getReg())) 885261991Sdim EVEX_V2 = 0x0; 886261991Sdim CurOp++; 887261991Sdim } 888261991Sdim 889249423Sdim if (X86II::isX86_64ExtendedReg(MI.getOperand(CurOp).getReg())) 890226584Sdim VEX_R = 0x0; 891276479Sdim if (X86II::is32ExtendedReg(MI.getOperand(CurOp).getReg())) 892261991Sdim EVEX_R2 = 0x0; 893276479Sdim if (EVEX_b) 894276479Sdim EncodeRC = true; 895226584Sdim break; 896226584Sdim case X86II::MRM0r: case X86II::MRM1r: 897226584Sdim case X86II::MRM2r: case X86II::MRM3r: 898226584Sdim case X86II::MRM4r: case X86II::MRM5r: 899226584Sdim case X86II::MRM6r: case X86II::MRM7r: 900226584Sdim // MRM0r-MRM7r instructions forms: 901226584Sdim // dst(VEX_4V), src(ModR/M), imm8 902261991Sdim if (HasVEX_4V) { 903261991Sdim VEX_4V = getVEXRegisterEncoding(MI, CurOp); 904276479Sdim if (X86II::is32ExtendedReg(MI.getOperand(CurOp).getReg())) 905261991Sdim EVEX_V2 = 0x0; 906261991Sdim CurOp++; 907276479Sdim } 908261991Sdim if (HasEVEX_K) 909261991Sdim EVEX_aaa = getWriteMaskRegisterEncoding(MI, CurOp++); 910261991Sdim 911261991Sdim if (X86II::isX86_64ExtendedReg(MI.getOperand(CurOp).getReg())) 912226584Sdim VEX_B = 0x0; 913276479Sdim if (X86II::is32ExtendedReg(MI.getOperand(CurOp).getReg())) 914261991Sdim VEX_X = 0x0; 915226584Sdim break; 916226584Sdim } 917226584Sdim 918276479Sdim if (Encoding == X86II::VEX || Encoding == X86II::XOP) { 919261991Sdim // VEX opcode prefix can have 2 or 3 bytes 920261991Sdim // 921261991Sdim // 3 bytes: 922261991Sdim // +-----+ +--------------+ +-------------------+ 923261991Sdim // | C4h | | RXB | m-mmmm | | W | vvvv | L | pp | 924261991Sdim // +-----+ +--------------+ +-------------------+ 925261991Sdim // 2 bytes: 926261991Sdim // +-----+ +-------------------+ 927261991Sdim // | C5h | | R | vvvv | L | pp | 928261991Sdim // +-----+ +-------------------+ 929261991Sdim // 930276479Sdim // XOP uses a similar prefix: 931276479Sdim // +-----+ +--------------+ +-------------------+ 932276479Sdim // | 8Fh | | RXB | m-mmmm | | W | vvvv | L | pp | 933276479Sdim // +-----+ +--------------+ +-------------------+ 934261991Sdim unsigned char LastByte = VEX_PP | (VEX_L << 2) | (VEX_4V << 3); 935226584Sdim 936276479Sdim // Can we use the 2 byte VEX prefix? 937276479Sdim if (Encoding == X86II::VEX && VEX_B && VEX_X && !VEX_W && (VEX_5M == 1)) { 938261991Sdim EmitByte(0xC5, CurByte, OS); 939261991Sdim EmitByte(LastByte | (VEX_R << 7), CurByte, OS); 940261991Sdim return; 941261991Sdim } 942261991Sdim 943261991Sdim // 3 byte VEX prefix 944276479Sdim EmitByte(Encoding == X86II::XOP ? 0x8F : 0xC4, CurByte, OS); 945261991Sdim EmitByte(VEX_R << 7 | VEX_X << 6 | VEX_B << 5 | VEX_5M, CurByte, OS); 946261991Sdim EmitByte(LastByte | (VEX_W << 7), CurByte, OS); 947261991Sdim } else { 948276479Sdim assert(Encoding == X86II::EVEX && "unknown encoding!"); 949261991Sdim // EVEX opcode prefix can have 4 bytes 950261991Sdim // 951261991Sdim // +-----+ +--------------+ +-------------------+ +------------------------+ 952261991Sdim // | 62h | | RXBR' | 00mm | | W | vvvv | U | pp | | z | L'L | b | v' | aaa | 953261991Sdim // +-----+ +--------------+ +-------------------+ +------------------------+ 954261991Sdim assert((VEX_5M & 0x3) == VEX_5M 955261991Sdim && "More than 2 significant bits in VEX.m-mmmm fields for EVEX!"); 956261991Sdim 957261991Sdim VEX_5M &= 0x3; 958261991Sdim 959261991Sdim EmitByte(0x62, CurByte, OS); 960261991Sdim EmitByte((VEX_R << 7) | 961261991Sdim (VEX_X << 6) | 962261991Sdim (VEX_B << 5) | 963261991Sdim (EVEX_R2 << 4) | 964261991Sdim VEX_5M, CurByte, OS); 965261991Sdim EmitByte((VEX_W << 7) | 966261991Sdim (VEX_4V << 3) | 967261991Sdim (EVEX_U << 2) | 968261991Sdim VEX_PP, CurByte, OS); 969276479Sdim if (EncodeRC) 970276479Sdim EmitByte((EVEX_z << 7) | 971276479Sdim (EVEX_rc << 5) | 972276479Sdim (EVEX_b << 4) | 973276479Sdim (EVEX_V2 << 3) | 974276479Sdim EVEX_aaa, CurByte, OS); 975276479Sdim else 976276479Sdim EmitByte((EVEX_z << 7) | 977276479Sdim (EVEX_L2 << 6) | 978276479Sdim (VEX_L << 5) | 979276479Sdim (EVEX_b << 4) | 980276479Sdim (EVEX_V2 << 3) | 981276479Sdim EVEX_aaa, CurByte, OS); 982226584Sdim } 983226584Sdim} 984226584Sdim 985226584Sdim/// DetermineREXPrefix - Determine if the MCInst has to be encoded with a X86-64 986226584Sdim/// REX prefix which specifies 1) 64-bit instructions, 2) non-default operand 987226584Sdim/// size, and 3) use of X86-64 extended registers. 988226584Sdimstatic unsigned DetermineREXPrefix(const MCInst &MI, uint64_t TSFlags, 989226584Sdim const MCInstrDesc &Desc) { 990226584Sdim unsigned REX = 0; 991296417Sdim bool UsesHighByteReg = false; 992296417Sdim 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(); 1009296417Sdim if (Reg == X86::AH || Reg == X86::BH || Reg == X86::CH || Reg == X86::DH) 1010296417Sdim UsesHighByteReg = true; 1011226584Sdim if (!X86II::isX86_64NonExtLowByteReg(Reg)) continue; 1012226584Sdim // FIXME: The caller of DetermineREXPrefix slaps this prefix onto anything 1013226584Sdim // that returns non-zero. 1014226584Sdim REX |= 0x40; // REX fixed encoding prefix 1015226584Sdim break; 1016226584Sdim } 1017226584Sdim 1018226584Sdim switch (TSFlags & X86II::FormMask) { 1019226584Sdim case X86II::MRMSrcReg: 1020226584Sdim if (MI.getOperand(0).isReg() && 1021226584Sdim X86II::isX86_64ExtendedReg(MI.getOperand(0).getReg())) 1022226584Sdim REX |= 1 << 2; // set REX.R 1023226584Sdim i = isTwoAddr ? 2 : 1; 1024226584Sdim for (; i != NumOps; ++i) { 1025226584Sdim const MCOperand &MO = MI.getOperand(i); 1026226584Sdim if (MO.isReg() && X86II::isX86_64ExtendedReg(MO.getReg())) 1027226584Sdim REX |= 1 << 0; // set REX.B 1028226584Sdim } 1029226584Sdim break; 1030226584Sdim case X86II::MRMSrcMem: { 1031226584Sdim if (MI.getOperand(0).isReg() && 1032226584Sdim X86II::isX86_64ExtendedReg(MI.getOperand(0).getReg())) 1033226584Sdim REX |= 1 << 2; // set REX.R 1034226584Sdim unsigned Bit = 0; 1035226584Sdim i = isTwoAddr ? 2 : 1; 1036226584Sdim for (; i != NumOps; ++i) { 1037226584Sdim const MCOperand &MO = MI.getOperand(i); 1038226584Sdim if (MO.isReg()) { 1039226584Sdim if (X86II::isX86_64ExtendedReg(MO.getReg())) 1040226584Sdim REX |= 1 << Bit; // set REX.B (Bit=0) and REX.X (Bit=1) 1041226584Sdim Bit++; 1042226584Sdim } 1043226584Sdim } 1044226584Sdim break; 1045226584Sdim } 1046276479Sdim case X86II::MRMXm: 1047226584Sdim case X86II::MRM0m: case X86II::MRM1m: 1048226584Sdim case X86II::MRM2m: case X86II::MRM3m: 1049226584Sdim case X86II::MRM4m: case X86II::MRM5m: 1050226584Sdim case X86II::MRM6m: case X86II::MRM7m: 1051226584Sdim case X86II::MRMDestMem: { 1052226584Sdim unsigned e = (isTwoAddr ? X86::AddrNumOperands+1 : X86::AddrNumOperands); 1053226584Sdim i = isTwoAddr ? 1 : 0; 1054226584Sdim if (NumOps > e && MI.getOperand(e).isReg() && 1055226584Sdim X86II::isX86_64ExtendedReg(MI.getOperand(e).getReg())) 1056226584Sdim REX |= 1 << 2; // set REX.R 1057226584Sdim unsigned Bit = 0; 1058226584Sdim for (; i != e; ++i) { 1059226584Sdim const MCOperand &MO = MI.getOperand(i); 1060226584Sdim if (MO.isReg()) { 1061226584Sdim if (X86II::isX86_64ExtendedReg(MO.getReg())) 1062226584Sdim REX |= 1 << Bit; // REX.B (Bit=0) and REX.X (Bit=1) 1063226584Sdim Bit++; 1064226584Sdim } 1065226584Sdim } 1066226584Sdim break; 1067226584Sdim } 1068226584Sdim default: 1069226584Sdim if (MI.getOperand(0).isReg() && 1070226584Sdim X86II::isX86_64ExtendedReg(MI.getOperand(0).getReg())) 1071226584Sdim REX |= 1 << 0; // set REX.B 1072226584Sdim i = isTwoAddr ? 2 : 1; 1073226584Sdim for (unsigned e = NumOps; i != e; ++i) { 1074226584Sdim const MCOperand &MO = MI.getOperand(i); 1075226584Sdim if (MO.isReg() && X86II::isX86_64ExtendedReg(MO.getReg())) 1076226584Sdim REX |= 1 << 2; // set REX.R 1077226584Sdim } 1078226584Sdim break; 1079226584Sdim } 1080296417Sdim if (REX && UsesHighByteReg) 1081296417Sdim report_fatal_error("Cannot encode high byte register in REX-prefixed instruction"); 1082296417Sdim 1083226584Sdim return REX; 1084226584Sdim} 1085226584Sdim 1086226584Sdim/// EmitSegmentOverridePrefix - Emit segment override opcode prefix as needed 1087276479Sdimvoid X86MCCodeEmitter::EmitSegmentOverridePrefix(unsigned &CurByte, 1088276479Sdim unsigned SegOperand, 1089276479Sdim const MCInst &MI, 1090276479Sdim raw_ostream &OS) const { 1091276479Sdim // Check for explicit segment override on memory operand. 1092276479Sdim switch (MI.getOperand(SegOperand).getReg()) { 1093276479Sdim default: llvm_unreachable("Unknown segment register!"); 1094276479Sdim case 0: break; 1095276479Sdim case X86::CS: EmitByte(0x2E, CurByte, OS); break; 1096276479Sdim case X86::SS: EmitByte(0x36, CurByte, OS); break; 1097276479Sdim case X86::DS: EmitByte(0x3E, CurByte, OS); break; 1098276479Sdim case X86::ES: EmitByte(0x26, CurByte, OS); break; 1099276479Sdim case X86::FS: EmitByte(0x64, CurByte, OS); break; 1100276479Sdim case X86::GS: EmitByte(0x65, CurByte, OS); break; 1101226584Sdim } 1102226584Sdim} 1103226584Sdim 1104226584Sdim/// EmitOpcodePrefix - Emit all instruction prefixes prior to the opcode. 1105226584Sdim/// 1106226584Sdim/// MemOperand is the operand # of the start of a memory operand if present. If 1107226584Sdim/// Not present, it is -1. 1108226584Sdimvoid X86MCCodeEmitter::EmitOpcodePrefix(uint64_t TSFlags, unsigned &CurByte, 1109226584Sdim int MemOperand, const MCInst &MI, 1110226584Sdim const MCInstrDesc &Desc, 1111276479Sdim const MCSubtargetInfo &STI, 1112226584Sdim raw_ostream &OS) const { 1113226584Sdim 1114226584Sdim // Emit the operand size opcode prefix as needed. 1115280031Sdim if ((TSFlags & X86II::OpSizeMask) == (is16BitMode(STI) ? X86II::OpSize32 1116280031Sdim : X86II::OpSize16)) 1117226584Sdim EmitByte(0x66, CurByte, OS); 1118226584Sdim 1119280031Sdim // Emit the LOCK opcode prefix. 1120280031Sdim if (TSFlags & X86II::LOCK) 1121280031Sdim EmitByte(0xF0, CurByte, OS); 1122280031Sdim 1123276479Sdim switch (TSFlags & X86II::OpPrefixMask) { 1124276479Sdim case X86II::PD: // 66 1125276479Sdim EmitByte(0x66, CurByte, OS); 1126226584Sdim break; 1127276479Sdim case X86II::XS: // F3 1128234353Sdim EmitByte(0xF3, CurByte, OS); 1129234353Sdim break; 1130276479Sdim case X86II::XD: // F2 1131226584Sdim EmitByte(0xF2, CurByte, OS); 1132226584Sdim break; 1133226584Sdim } 1134226584Sdim 1135226584Sdim // Handle REX prefix. 1136226584Sdim // FIXME: Can this come before F2 etc to simplify emission? 1137276479Sdim if (is64BitMode(STI)) { 1138226584Sdim if (unsigned REX = DetermineREXPrefix(MI, TSFlags, Desc)) 1139226584Sdim EmitByte(0x40 | REX, CurByte, OS); 1140226584Sdim } 1141226584Sdim 1142226584Sdim // 0x0F escape code must be emitted just before the opcode. 1143276479Sdim switch (TSFlags & X86II::OpMapMask) { 1144276479Sdim case X86II::TB: // Two-byte opcode map 1145276479Sdim case X86II::T8: // 0F 38 1146276479Sdim case X86II::TA: // 0F 3A 1147226584Sdim EmitByte(0x0F, CurByte, OS); 1148276479Sdim break; 1149276479Sdim } 1150226584Sdim 1151276479Sdim switch (TSFlags & X86II::OpMapMask) { 1152226584Sdim case X86II::T8: // 0F 38 1153226584Sdim EmitByte(0x38, CurByte, OS); 1154226584Sdim break; 1155226584Sdim case X86II::TA: // 0F 3A 1156226584Sdim EmitByte(0x3A, CurByte, OS); 1157226584Sdim break; 1158226584Sdim } 1159226584Sdim} 1160226584Sdim 1161226584Sdimvoid X86MCCodeEmitter:: 1162288943SdimencodeInstruction(const MCInst &MI, raw_ostream &OS, 1163276479Sdim SmallVectorImpl<MCFixup> &Fixups, 1164276479Sdim const MCSubtargetInfo &STI) const { 1165226584Sdim unsigned Opcode = MI.getOpcode(); 1166226584Sdim const MCInstrDesc &Desc = MCII.get(Opcode); 1167226584Sdim uint64_t TSFlags = Desc.TSFlags; 1168226584Sdim 1169226584Sdim // Pseudo instructions don't get encoded. 1170226584Sdim if ((TSFlags & X86II::FormMask) == X86II::Pseudo) 1171226584Sdim return; 1172226584Sdim 1173226584Sdim unsigned NumOps = Desc.getNumOperands(); 1174251662Sdim unsigned CurOp = X86II::getOperandBias(Desc); 1175226584Sdim 1176226584Sdim // Keep track of the current byte being emitted. 1177226584Sdim unsigned CurByte = 0; 1178226584Sdim 1179276479Sdim // Encoding type for this instruction. 1180280031Sdim uint64_t Encoding = TSFlags & X86II::EncodingMask; 1181226584Sdim 1182226584Sdim // It uses the VEX.VVVV field? 1183280031Sdim bool HasVEX_4V = TSFlags & X86II::VEX_4V; 1184280031Sdim bool HasVEX_4VOp3 = TSFlags & X86II::VEX_4VOp3; 1185280031Sdim bool HasMemOp4 = TSFlags & X86II::MemOp4; 1186234353Sdim const unsigned MemOp4_I8IMMOperand = 2; 1187226584Sdim 1188261991Sdim // It uses the EVEX.aaa field? 1189280031Sdim bool HasEVEX_K = TSFlags & X86II::EVEX_K; 1190280031Sdim bool HasEVEX_RC = TSFlags & X86II::EVEX_RC; 1191280031Sdim 1192226584Sdim // Determine where the memory operand starts, if present. 1193234353Sdim int MemoryOperand = X86II::getMemoryOperandNo(TSFlags, Opcode); 1194226584Sdim if (MemoryOperand != -1) MemoryOperand += CurOp; 1195226584Sdim 1196276479Sdim // Emit segment override opcode prefix as needed. 1197276479Sdim if (MemoryOperand >= 0) 1198276479Sdim EmitSegmentOverridePrefix(CurByte, MemoryOperand+X86::AddrSegmentReg, 1199276479Sdim MI, OS); 1200276479Sdim 1201276479Sdim // Emit the repeat opcode prefix as needed. 1202276479Sdim if (TSFlags & X86II::REP) 1203276479Sdim EmitByte(0xF3, CurByte, OS); 1204276479Sdim 1205276479Sdim // Emit the address size opcode prefix as needed. 1206276479Sdim bool need_address_override; 1207280031Sdim uint64_t AdSize = TSFlags & X86II::AdSizeMask; 1208280031Sdim if ((is16BitMode(STI) && AdSize == X86II::AdSize32) || 1209280031Sdim (is32BitMode(STI) && AdSize == X86II::AdSize16) || 1210280031Sdim (is64BitMode(STI) && AdSize == X86II::AdSize32)) { 1211276479Sdim need_address_override = true; 1212276479Sdim } else if (MemoryOperand < 0) { 1213276479Sdim need_address_override = false; 1214276479Sdim } else if (is64BitMode(STI)) { 1215276479Sdim assert(!Is16BitMemOperand(MI, MemoryOperand, STI)); 1216276479Sdim need_address_override = Is32BitMemOperand(MI, MemoryOperand); 1217276479Sdim } else if (is32BitMode(STI)) { 1218276479Sdim assert(!Is64BitMemOperand(MI, MemoryOperand)); 1219276479Sdim need_address_override = Is16BitMemOperand(MI, MemoryOperand, STI); 1220276479Sdim } else { 1221276479Sdim assert(is16BitMode(STI)); 1222276479Sdim assert(!Is64BitMemOperand(MI, MemoryOperand)); 1223276479Sdim need_address_override = !Is16BitMemOperand(MI, MemoryOperand, STI); 1224276479Sdim } 1225276479Sdim 1226276479Sdim if (need_address_override) 1227276479Sdim EmitByte(0x67, CurByte, OS); 1228276479Sdim 1229276479Sdim if (Encoding == 0) 1230276479Sdim EmitOpcodePrefix(TSFlags, CurByte, MemoryOperand, MI, Desc, STI, OS); 1231226584Sdim else 1232226584Sdim EmitVEXOpcodePrefix(TSFlags, CurByte, MemoryOperand, MI, Desc, OS); 1233226584Sdim 1234226584Sdim unsigned char BaseOpcode = X86II::getBaseOpcodeFor(TSFlags); 1235226584Sdim 1236280031Sdim if (TSFlags & X86II::Has3DNow0F0FOpcode) 1237226584Sdim BaseOpcode = 0x0F; // Weird 3DNow! encoding. 1238226584Sdim 1239226584Sdim unsigned SrcRegNum = 0; 1240226584Sdim switch (TSFlags & X86II::FormMask) { 1241226584Sdim default: errs() << "FORM: " << (TSFlags & X86II::FormMask) << "\n"; 1242234353Sdim llvm_unreachable("Unknown FormMask value in X86MCCodeEmitter!"); 1243226584Sdim case X86II::Pseudo: 1244234353Sdim llvm_unreachable("Pseudo instruction shouldn't be emitted"); 1245276479Sdim case X86II::RawFrmDstSrc: { 1246276479Sdim unsigned siReg = MI.getOperand(1).getReg(); 1247276479Sdim assert(((siReg == X86::SI && MI.getOperand(0).getReg() == X86::DI) || 1248276479Sdim (siReg == X86::ESI && MI.getOperand(0).getReg() == X86::EDI) || 1249276479Sdim (siReg == X86::RSI && MI.getOperand(0).getReg() == X86::RDI)) && 1250276479Sdim "SI and DI register sizes do not match"); 1251276479Sdim // Emit segment override opcode prefix as needed (not for %ds). 1252276479Sdim if (MI.getOperand(2).getReg() != X86::DS) 1253276479Sdim EmitSegmentOverridePrefix(CurByte, 2, MI, OS); 1254276479Sdim // Emit AdSize prefix as needed. 1255276479Sdim if ((!is32BitMode(STI) && siReg == X86::ESI) || 1256276479Sdim (is32BitMode(STI) && siReg == X86::SI)) 1257276479Sdim EmitByte(0x67, CurByte, OS); 1258276479Sdim CurOp += 3; // Consume operands. 1259276479Sdim EmitByte(BaseOpcode, CurByte, OS); 1260276479Sdim break; 1261276479Sdim } 1262276479Sdim case X86II::RawFrmSrc: { 1263276479Sdim unsigned siReg = MI.getOperand(0).getReg(); 1264276479Sdim // Emit segment override opcode prefix as needed (not for %ds). 1265276479Sdim if (MI.getOperand(1).getReg() != X86::DS) 1266276479Sdim EmitSegmentOverridePrefix(CurByte, 1, MI, OS); 1267276479Sdim // Emit AdSize prefix as needed. 1268276479Sdim if ((!is32BitMode(STI) && siReg == X86::ESI) || 1269276479Sdim (is32BitMode(STI) && siReg == X86::SI)) 1270276479Sdim EmitByte(0x67, CurByte, OS); 1271276479Sdim CurOp += 2; // Consume operands. 1272276479Sdim EmitByte(BaseOpcode, CurByte, OS); 1273276479Sdim break; 1274276479Sdim } 1275276479Sdim case X86II::RawFrmDst: { 1276276479Sdim unsigned siReg = MI.getOperand(0).getReg(); 1277276479Sdim // Emit AdSize prefix as needed. 1278276479Sdim if ((!is32BitMode(STI) && siReg == X86::EDI) || 1279276479Sdim (is32BitMode(STI) && siReg == X86::DI)) 1280276479Sdim EmitByte(0x67, CurByte, OS); 1281276479Sdim ++CurOp; // Consume operand. 1282276479Sdim EmitByte(BaseOpcode, CurByte, OS); 1283276479Sdim break; 1284276479Sdim } 1285226584Sdim case X86II::RawFrm: 1286226584Sdim EmitByte(BaseOpcode, CurByte, OS); 1287226584Sdim break; 1288276479Sdim case X86II::RawFrmMemOffs: 1289276479Sdim // Emit segment override opcode prefix as needed. 1290276479Sdim EmitSegmentOverridePrefix(CurByte, 1, MI, OS); 1291276479Sdim EmitByte(BaseOpcode, CurByte, OS); 1292276479Sdim EmitImmediate(MI.getOperand(CurOp++), MI.getLoc(), 1293276479Sdim X86II::getSizeOfImm(TSFlags), getImmFixupKind(TSFlags), 1294276479Sdim CurByte, OS, Fixups); 1295276479Sdim ++CurOp; // skip segment operand 1296276479Sdim break; 1297226584Sdim case X86II::RawFrmImm8: 1298226584Sdim EmitByte(BaseOpcode, CurByte, OS); 1299234353Sdim EmitImmediate(MI.getOperand(CurOp++), MI.getLoc(), 1300226584Sdim X86II::getSizeOfImm(TSFlags), getImmFixupKind(TSFlags), 1301226584Sdim CurByte, OS, Fixups); 1302234353Sdim EmitImmediate(MI.getOperand(CurOp++), MI.getLoc(), 1, FK_Data_1, CurByte, 1303234353Sdim OS, Fixups); 1304226584Sdim break; 1305226584Sdim case X86II::RawFrmImm16: 1306226584Sdim EmitByte(BaseOpcode, CurByte, OS); 1307234353Sdim EmitImmediate(MI.getOperand(CurOp++), MI.getLoc(), 1308226584Sdim X86II::getSizeOfImm(TSFlags), getImmFixupKind(TSFlags), 1309226584Sdim CurByte, OS, Fixups); 1310234353Sdim EmitImmediate(MI.getOperand(CurOp++), MI.getLoc(), 2, FK_Data_2, CurByte, 1311234353Sdim OS, Fixups); 1312226584Sdim break; 1313226584Sdim 1314226584Sdim case X86II::AddRegFrm: 1315226584Sdim EmitByte(BaseOpcode + GetX86RegNum(MI.getOperand(CurOp++)), CurByte, OS); 1316226584Sdim break; 1317226584Sdim 1318226584Sdim case X86II::MRMDestReg: 1319226584Sdim EmitByte(BaseOpcode, CurByte, OS); 1320249423Sdim SrcRegNum = CurOp + 1; 1321249423Sdim 1322261991Sdim if (HasEVEX_K) // Skip writemask 1323261991Sdim SrcRegNum++; 1324261991Sdim 1325249423Sdim if (HasVEX_4V) // Skip 1st src (which is encoded in VEX_VVVV) 1326249423Sdim ++SrcRegNum; 1327249423Sdim 1328226584Sdim EmitRegModRMByte(MI.getOperand(CurOp), 1329249423Sdim GetX86RegNum(MI.getOperand(SrcRegNum)), CurByte, OS); 1330249423Sdim CurOp = SrcRegNum + 1; 1331226584Sdim break; 1332226584Sdim 1333226584Sdim case X86II::MRMDestMem: 1334226584Sdim EmitByte(BaseOpcode, CurByte, OS); 1335226584Sdim SrcRegNum = CurOp + X86::AddrNumOperands; 1336226584Sdim 1337261991Sdim if (HasEVEX_K) // Skip writemask 1338261991Sdim SrcRegNum++; 1339261991Sdim 1340226584Sdim if (HasVEX_4V) // Skip 1st src (which is encoded in VEX_VVVV) 1341239462Sdim ++SrcRegNum; 1342226584Sdim 1343226584Sdim EmitMemModRMByte(MI, CurOp, 1344226584Sdim GetX86RegNum(MI.getOperand(SrcRegNum)), 1345276479Sdim TSFlags, CurByte, OS, Fixups, STI); 1346226584Sdim CurOp = SrcRegNum + 1; 1347226584Sdim break; 1348226584Sdim 1349226584Sdim case X86II::MRMSrcReg: 1350226584Sdim EmitByte(BaseOpcode, CurByte, OS); 1351226584Sdim SrcRegNum = CurOp + 1; 1352226584Sdim 1353261991Sdim if (HasEVEX_K) // Skip writemask 1354261991Sdim SrcRegNum++; 1355261991Sdim 1356226584Sdim if (HasVEX_4V) // Skip 1st src (which is encoded in VEX_VVVV) 1357239462Sdim ++SrcRegNum; 1358226584Sdim 1359239462Sdim if (HasMemOp4) // Skip 2nd src (which is encoded in I8IMM) 1360239462Sdim ++SrcRegNum; 1361234353Sdim 1362226584Sdim EmitRegModRMByte(MI.getOperand(SrcRegNum), 1363226584Sdim GetX86RegNum(MI.getOperand(CurOp)), CurByte, OS); 1364234353Sdim 1365239462Sdim // 2 operands skipped with HasMemOp4, compensate accordingly 1366234353Sdim CurOp = HasMemOp4 ? SrcRegNum : SrcRegNum + 1; 1367234353Sdim if (HasVEX_4VOp3) 1368234353Sdim ++CurOp; 1369276479Sdim // do not count the rounding control operand 1370276479Sdim if (HasEVEX_RC) 1371276479Sdim NumOps--; 1372226584Sdim break; 1373226584Sdim 1374226584Sdim case X86II::MRMSrcMem: { 1375226584Sdim int AddrOperands = X86::AddrNumOperands; 1376226584Sdim unsigned FirstMemOp = CurOp+1; 1377261991Sdim 1378261991Sdim if (HasEVEX_K) { // Skip writemask 1379261991Sdim ++AddrOperands; 1380261991Sdim ++FirstMemOp; 1381261991Sdim } 1382261991Sdim 1383226584Sdim if (HasVEX_4V) { 1384226584Sdim ++AddrOperands; 1385226584Sdim ++FirstMemOp; // Skip the register source (which is encoded in VEX_VVVV). 1386226584Sdim } 1387239462Sdim if (HasMemOp4) // Skip second register source (encoded in I8IMM) 1388234353Sdim ++FirstMemOp; 1389226584Sdim 1390226584Sdim EmitByte(BaseOpcode, CurByte, OS); 1391226584Sdim 1392226584Sdim EmitMemModRMByte(MI, FirstMemOp, GetX86RegNum(MI.getOperand(CurOp)), 1393276479Sdim TSFlags, CurByte, OS, Fixups, STI); 1394226584Sdim CurOp += AddrOperands + 1; 1395234353Sdim if (HasVEX_4VOp3) 1396234353Sdim ++CurOp; 1397226584Sdim break; 1398226584Sdim } 1399226584Sdim 1400276479Sdim case X86II::MRMXr: 1401226584Sdim case X86II::MRM0r: case X86II::MRM1r: 1402226584Sdim case X86II::MRM2r: case X86II::MRM3r: 1403226584Sdim case X86II::MRM4r: case X86II::MRM5r: 1404276479Sdim case X86II::MRM6r: case X86II::MRM7r: { 1405226584Sdim if (HasVEX_4V) // Skip the register dst (which is encoded in VEX_VVVV). 1406239462Sdim ++CurOp; 1407276479Sdim if (HasEVEX_K) // Skip writemask 1408276479Sdim ++CurOp; 1409226584Sdim EmitByte(BaseOpcode, CurByte, OS); 1410276479Sdim uint64_t Form = TSFlags & X86II::FormMask; 1411226584Sdim EmitRegModRMByte(MI.getOperand(CurOp++), 1412276479Sdim (Form == X86II::MRMXr) ? 0 : Form-X86II::MRM0r, 1413226584Sdim CurByte, OS); 1414226584Sdim break; 1415276479Sdim } 1416276479Sdim 1417276479Sdim case X86II::MRMXm: 1418226584Sdim case X86II::MRM0m: case X86II::MRM1m: 1419226584Sdim case X86II::MRM2m: case X86II::MRM3m: 1420226584Sdim case X86II::MRM4m: case X86II::MRM5m: 1421276479Sdim case X86II::MRM6m: case X86II::MRM7m: { 1422234353Sdim if (HasVEX_4V) // Skip the register dst (which is encoded in VEX_VVVV). 1423239462Sdim ++CurOp; 1424276479Sdim if (HasEVEX_K) // Skip writemask 1425276479Sdim ++CurOp; 1426226584Sdim EmitByte(BaseOpcode, CurByte, OS); 1427276479Sdim uint64_t Form = TSFlags & X86II::FormMask; 1428276479Sdim EmitMemModRMByte(MI, CurOp, (Form == X86II::MRMXm) ? 0 : Form-X86II::MRM0m, 1429276479Sdim TSFlags, CurByte, OS, Fixups, STI); 1430226584Sdim CurOp += X86::AddrNumOperands; 1431226584Sdim break; 1432276479Sdim } 1433276479Sdim case X86II::MRM_C0: case X86II::MRM_C1: case X86II::MRM_C2: 1434288943Sdim case X86II::MRM_C3: case X86II::MRM_C4: case X86II::MRM_C5: 1435288943Sdim case X86II::MRM_C6: case X86II::MRM_C7: case X86II::MRM_C8: 1436276479Sdim case X86II::MRM_C9: case X86II::MRM_CA: case X86II::MRM_CB: 1437288943Sdim case X86II::MRM_CC: case X86II::MRM_CD: case X86II::MRM_CE: 1438280031Sdim case X86II::MRM_CF: case X86II::MRM_D0: case X86II::MRM_D1: 1439288943Sdim case X86II::MRM_D2: case X86II::MRM_D3: case X86II::MRM_D4: 1440288943Sdim case X86II::MRM_D5: case X86II::MRM_D6: case X86II::MRM_D7: 1441288943Sdim case X86II::MRM_D8: case X86II::MRM_D9: case X86II::MRM_DA: 1442288943Sdim case X86II::MRM_DB: case X86II::MRM_DC: case X86II::MRM_DD: 1443288943Sdim case X86II::MRM_DE: case X86II::MRM_DF: case X86II::MRM_E0: 1444288943Sdim case X86II::MRM_E1: case X86II::MRM_E2: case X86II::MRM_E3: 1445288943Sdim case X86II::MRM_E4: case X86II::MRM_E5: case X86II::MRM_E6: 1446288943Sdim case X86II::MRM_E7: case X86II::MRM_E8: case X86II::MRM_E9: 1447288943Sdim case X86II::MRM_EA: case X86II::MRM_EB: case X86II::MRM_EC: 1448288943Sdim case X86II::MRM_ED: case X86II::MRM_EE: case X86II::MRM_EF: 1449288943Sdim case X86II::MRM_F0: case X86II::MRM_F1: case X86II::MRM_F2: 1450288943Sdim case X86II::MRM_F3: case X86II::MRM_F4: case X86II::MRM_F5: 1451288943Sdim case X86II::MRM_F6: case X86II::MRM_F7: case X86II::MRM_F8: 1452288943Sdim case X86II::MRM_F9: case X86II::MRM_FA: case X86II::MRM_FB: 1453288943Sdim case X86II::MRM_FC: case X86II::MRM_FD: case X86II::MRM_FE: 1454288943Sdim case X86II::MRM_FF: 1455226584Sdim EmitByte(BaseOpcode, CurByte, OS); 1456234353Sdim 1457288943Sdim uint64_t Form = TSFlags & X86II::FormMask; 1458288943Sdim EmitByte(0xC0 + Form - X86II::MRM_C0, CurByte, OS); 1459226584Sdim break; 1460226584Sdim } 1461226584Sdim 1462226584Sdim // If there is a remaining operand, it must be a trailing immediate. Emit it 1463239462Sdim // according to the right size for the instruction. Some instructions 1464239462Sdim // (SSE4a extrq and insertq) have two trailing immediates. 1465239462Sdim while (CurOp != NumOps && NumOps - CurOp <= 2) { 1466226584Sdim // The last source register of a 4 operand instruction in AVX is encoded 1467234353Sdim // in bits[7:4] of a immediate byte. 1468280031Sdim if (TSFlags & X86II::VEX_I8IMM) { 1469234353Sdim const MCOperand &MO = MI.getOperand(HasMemOp4 ? MemOp4_I8IMMOperand 1470239462Sdim : CurOp); 1471239462Sdim ++CurOp; 1472239462Sdim unsigned RegNum = GetX86RegNum(MO) << 4; 1473239462Sdim if (X86II::isX86_64ExtendedReg(MO.getReg())) 1474239462Sdim RegNum |= 1 << 7; 1475234353Sdim // If there is an additional 5th operand it must be an immediate, which 1476234353Sdim // is encoded in bits[3:0] 1477239462Sdim if (CurOp != NumOps) { 1478234353Sdim const MCOperand &MIMM = MI.getOperand(CurOp++); 1479239462Sdim if (MIMM.isImm()) { 1480234353Sdim unsigned Val = MIMM.getImm(); 1481234353Sdim assert(Val < 16 && "Immediate operand value out of range"); 1482234353Sdim RegNum |= Val; 1483234353Sdim } 1484234353Sdim } 1485288943Sdim EmitImmediate(MCOperand::createImm(RegNum), MI.getLoc(), 1, FK_Data_1, 1486234353Sdim CurByte, OS, Fixups); 1487226584Sdim } else { 1488234353Sdim EmitImmediate(MI.getOperand(CurOp++), MI.getLoc(), 1489276479Sdim X86II::getSizeOfImm(TSFlags), getImmFixupKind(TSFlags), 1490226584Sdim CurByte, OS, Fixups); 1491226584Sdim } 1492226584Sdim } 1493226584Sdim 1494280031Sdim if (TSFlags & X86II::Has3DNow0F0FOpcode) 1495226584Sdim EmitByte(X86II::getBaseOpcodeFor(TSFlags), CurByte, OS); 1496226584Sdim 1497226584Sdim#ifndef NDEBUG 1498226584Sdim // FIXME: Verify. 1499226584Sdim if (/*!Desc.isVariadic() &&*/ CurOp != NumOps) { 1500226584Sdim errs() << "Cannot encode all operands of: "; 1501226584Sdim MI.dump(); 1502226584Sdim errs() << '\n'; 1503226584Sdim abort(); 1504226584Sdim } 1505226584Sdim#endif 1506226584Sdim} 1507