1201360Srdivacky//===- X86RecognizableInstr.cpp - Disassembler instruction spec --*- C++ -*-===// 2201360Srdivacky// 3201360Srdivacky// The LLVM Compiler Infrastructure 4201360Srdivacky// 5201360Srdivacky// This file is distributed under the University of Illinois Open Source 6201360Srdivacky// License. See LICENSE.TXT for details. 7201360Srdivacky// 8201360Srdivacky//===----------------------------------------------------------------------===// 9201360Srdivacky// 10201360Srdivacky// This file is part of the X86 Disassembler Emitter. 11201360Srdivacky// It contains the implementation of a single recognizable instruction. 12201360Srdivacky// Documentation for the disassembler emitter in general can be found in 13201360Srdivacky// X86DisasemblerEmitter.h. 14201360Srdivacky// 15201360Srdivacky//===----------------------------------------------------------------------===// 16201360Srdivacky 17249423Sdim#include "X86RecognizableInstr.h" 18201360Srdivacky#include "X86DisassemblerShared.h" 19201360Srdivacky#include "X86ModRMFilters.h" 20201360Srdivacky#include "llvm/Support/ErrorHandling.h" 21201360Srdivacky#include <string> 22201360Srdivacky 23201360Srdivackyusing namespace llvm; 24201360Srdivacky 25203954Srdivacky#define MRM_MAPPING \ 26203954Srdivacky MAP(C1, 33) \ 27203954Srdivacky MAP(C2, 34) \ 28203954Srdivacky MAP(C3, 35) \ 29203954Srdivacky MAP(C4, 36) \ 30203954Srdivacky MAP(C8, 37) \ 31203954Srdivacky MAP(C9, 38) \ 32251662Sdim MAP(CA, 39) \ 33251662Sdim MAP(CB, 40) \ 34251662Sdim MAP(E8, 41) \ 35251662Sdim MAP(F0, 42) \ 36251662Sdim MAP(F8, 45) \ 37251662Sdim MAP(F9, 46) \ 38251662Sdim MAP(D0, 47) \ 39251662Sdim MAP(D1, 48) \ 40251662Sdim MAP(D4, 49) \ 41251662Sdim MAP(D5, 50) \ 42251662Sdim MAP(D6, 51) \ 43251662Sdim MAP(D8, 52) \ 44251662Sdim MAP(D9, 53) \ 45251662Sdim MAP(DA, 54) \ 46251662Sdim MAP(DB, 55) \ 47251662Sdim MAP(DC, 56) \ 48251662Sdim MAP(DD, 57) \ 49251662Sdim MAP(DE, 58) \ 50251662Sdim MAP(DF, 59) 51203954Srdivacky 52201360Srdivacky// A clone of X86 since we can't depend on something that is generated. 53201360Srdivackynamespace X86Local { 54201360Srdivacky enum { 55201360Srdivacky Pseudo = 0, 56201360Srdivacky RawFrm = 1, 57201360Srdivacky AddRegFrm = 2, 58201360Srdivacky MRMDestReg = 3, 59201360Srdivacky MRMDestMem = 4, 60201360Srdivacky MRMSrcReg = 5, 61201360Srdivacky MRMSrcMem = 6, 62239462Sdim MRM0r = 16, MRM1r = 17, MRM2r = 18, MRM3r = 19, 63201360Srdivacky MRM4r = 20, MRM5r = 21, MRM6r = 22, MRM7r = 23, 64201360Srdivacky MRM0m = 24, MRM1m = 25, MRM2m = 26, MRM3m = 27, 65201360Srdivacky MRM4m = 28, MRM5m = 29, MRM6m = 30, MRM7m = 31, 66203954Srdivacky MRMInitReg = 32, 67239462Sdim RawFrmImm8 = 43, 68239462Sdim RawFrmImm16 = 44, 69203954Srdivacky#define MAP(from, to) MRM_##from = to, 70203954Srdivacky MRM_MAPPING 71203954Srdivacky#undef MAP 72203954Srdivacky lastMRM 73201360Srdivacky }; 74239462Sdim 75201360Srdivacky enum { 76201360Srdivacky TB = 1, 77201360Srdivacky REP = 2, 78201360Srdivacky D8 = 3, D9 = 4, DA = 5, DB = 6, 79201360Srdivacky DC = 7, DD = 8, DE = 9, DF = 10, 80201360Srdivacky XD = 11, XS = 12, 81203954Srdivacky T8 = 13, P_TA = 14, 82234353Sdim A6 = 15, A7 = 16, T8XD = 17, T8XS = 18, TAXD = 19 83201360Srdivacky }; 84201360Srdivacky} 85203954Srdivacky 86203954Srdivacky// If rows are added to the opcode extension tables, then corresponding entries 87239462Sdim// must be added here. 88203954Srdivacky// 89203954Srdivacky// If the row corresponds to a single byte (i.e., 8f), then add an entry for 90203954Srdivacky// that byte to ONE_BYTE_EXTENSION_TABLES. 91203954Srdivacky// 92239462Sdim// If the row corresponds to two bytes where the first is 0f, add an entry for 93203954Srdivacky// the second byte to TWO_BYTE_EXTENSION_TABLES. 94203954Srdivacky// 95203954Srdivacky// If the row corresponds to some other set of bytes, you will need to modify 96203954Srdivacky// the code in RecognizableInstr::emitDecodePath() as well, and add new prefixes 97239462Sdim// to the X86 TD files, except in two cases: if the first two bytes of such a 98203954Srdivacky// new combination are 0f 38 or 0f 3a, you just have to add maps called 99203954Srdivacky// THREE_BYTE_38_EXTENSION_TABLES and THREE_BYTE_3A_EXTENSION_TABLES and add a 100203954Srdivacky// switch(Opcode) just below the case X86Local::T8: or case X86Local::TA: line 101203954Srdivacky// in RecognizableInstr::emitDecodePath(). 102203954Srdivacky 103201360Srdivacky#define ONE_BYTE_EXTENSION_TABLES \ 104201360Srdivacky EXTENSION_TABLE(80) \ 105201360Srdivacky EXTENSION_TABLE(81) \ 106201360Srdivacky EXTENSION_TABLE(82) \ 107201360Srdivacky EXTENSION_TABLE(83) \ 108201360Srdivacky EXTENSION_TABLE(8f) \ 109201360Srdivacky EXTENSION_TABLE(c0) \ 110201360Srdivacky EXTENSION_TABLE(c1) \ 111201360Srdivacky EXTENSION_TABLE(c6) \ 112201360Srdivacky EXTENSION_TABLE(c7) \ 113201360Srdivacky EXTENSION_TABLE(d0) \ 114201360Srdivacky EXTENSION_TABLE(d1) \ 115201360Srdivacky EXTENSION_TABLE(d2) \ 116201360Srdivacky EXTENSION_TABLE(d3) \ 117201360Srdivacky EXTENSION_TABLE(f6) \ 118201360Srdivacky EXTENSION_TABLE(f7) \ 119201360Srdivacky EXTENSION_TABLE(fe) \ 120201360Srdivacky EXTENSION_TABLE(ff) 121239462Sdim 122201360Srdivacky#define TWO_BYTE_EXTENSION_TABLES \ 123201360Srdivacky EXTENSION_TABLE(00) \ 124201360Srdivacky EXTENSION_TABLE(01) \ 125249423Sdim EXTENSION_TABLE(0d) \ 126201360Srdivacky EXTENSION_TABLE(18) \ 127201360Srdivacky EXTENSION_TABLE(71) \ 128201360Srdivacky EXTENSION_TABLE(72) \ 129201360Srdivacky EXTENSION_TABLE(73) \ 130201360Srdivacky EXTENSION_TABLE(ae) \ 131201360Srdivacky EXTENSION_TABLE(ba) \ 132201360Srdivacky EXTENSION_TABLE(c7) 133201360Srdivacky 134234353Sdim#define THREE_BYTE_38_EXTENSION_TABLES \ 135234353Sdim EXTENSION_TABLE(F3) 136234353Sdim 137201360Srdivackyusing namespace X86Disassembler; 138201360Srdivacky 139201360Srdivacky/// needsModRMForDecode - Indicates whether a particular instruction requires a 140239462Sdim/// ModR/M byte for the instruction to be properly decoded. For example, a 141201360Srdivacky/// MRMDestReg instruction needs the Mod field in the ModR/M byte to be set to 142201360Srdivacky/// 0b11. 143201360Srdivacky/// 144201360Srdivacky/// @param form - The form of the instruction. 145201360Srdivacky/// @return - true if the form implies that a ModR/M byte is required, false 146201360Srdivacky/// otherwise. 147201360Srdivackystatic bool needsModRMForDecode(uint8_t form) { 148201360Srdivacky if (form == X86Local::MRMDestReg || 149201360Srdivacky form == X86Local::MRMDestMem || 150201360Srdivacky form == X86Local::MRMSrcReg || 151201360Srdivacky form == X86Local::MRMSrcMem || 152201360Srdivacky (form >= X86Local::MRM0r && form <= X86Local::MRM7r) || 153201360Srdivacky (form >= X86Local::MRM0m && form <= X86Local::MRM7m)) 154201360Srdivacky return true; 155201360Srdivacky else 156201360Srdivacky return false; 157201360Srdivacky} 158201360Srdivacky 159201360Srdivacky/// isRegFormat - Indicates whether a particular form requires the Mod field of 160201360Srdivacky/// the ModR/M byte to be 0b11. 161201360Srdivacky/// 162201360Srdivacky/// @param form - The form of the instruction. 163201360Srdivacky/// @return - true if the form implies that Mod must be 0b11, false 164201360Srdivacky/// otherwise. 165201360Srdivackystatic bool isRegFormat(uint8_t form) { 166201360Srdivacky if (form == X86Local::MRMDestReg || 167201360Srdivacky form == X86Local::MRMSrcReg || 168201360Srdivacky (form >= X86Local::MRM0r && form <= X86Local::MRM7r)) 169201360Srdivacky return true; 170201360Srdivacky else 171201360Srdivacky return false; 172201360Srdivacky} 173201360Srdivacky 174201360Srdivacky/// byteFromBitsInit - Extracts a value at most 8 bits in width from a BitsInit. 175201360Srdivacky/// Useful for switch statements and the like. 176201360Srdivacky/// 177201360Srdivacky/// @param init - A reference to the BitsInit to be decoded. 178201360Srdivacky/// @return - The field, with the first bit in the BitsInit as the lowest 179201360Srdivacky/// order bit. 180201360Srdivackystatic uint8_t byteFromBitsInit(BitsInit &init) { 181201360Srdivacky int width = init.getNumBits(); 182201360Srdivacky 183201360Srdivacky assert(width <= 8 && "Field is too large for uint8_t!"); 184201360Srdivacky 185201360Srdivacky int index; 186201360Srdivacky uint8_t mask = 0x01; 187201360Srdivacky 188201360Srdivacky uint8_t ret = 0; 189201360Srdivacky 190201360Srdivacky for (index = 0; index < width; index++) { 191201360Srdivacky if (static_cast<BitInit*>(init.getBit(index))->getValue()) 192201360Srdivacky ret |= mask; 193201360Srdivacky 194201360Srdivacky mask <<= 1; 195201360Srdivacky } 196201360Srdivacky 197201360Srdivacky return ret; 198201360Srdivacky} 199201360Srdivacky 200201360Srdivacky/// byteFromRec - Extract a value at most 8 bits in with from a Record given the 201201360Srdivacky/// name of the field. 202201360Srdivacky/// 203201360Srdivacky/// @param rec - The record from which to extract the value. 204201360Srdivacky/// @param name - The name of the field in the record. 205201360Srdivacky/// @return - The field, as translated by byteFromBitsInit(). 206201360Srdivackystatic uint8_t byteFromRec(const Record* rec, const std::string &name) { 207201360Srdivacky BitsInit* bits = rec->getValueAsBitsInit(name); 208201360Srdivacky return byteFromBitsInit(*bits); 209201360Srdivacky} 210201360Srdivacky 211201360SrdivackyRecognizableInstr::RecognizableInstr(DisassemblerTables &tables, 212201360Srdivacky const CodeGenInstruction &insn, 213201360Srdivacky InstrUID uid) { 214201360Srdivacky UID = uid; 215201360Srdivacky 216201360Srdivacky Rec = insn.TheDef; 217201360Srdivacky Name = Rec->getName(); 218201360Srdivacky Spec = &tables.specForUID(UID); 219239462Sdim 220201360Srdivacky if (!Rec->isSubClassOf("X86Inst")) { 221201360Srdivacky ShouldBeEmitted = false; 222201360Srdivacky return; 223201360Srdivacky } 224239462Sdim 225201360Srdivacky Prefix = byteFromRec(Rec, "Prefix"); 226201360Srdivacky Opcode = byteFromRec(Rec, "Opcode"); 227201360Srdivacky Form = byteFromRec(Rec, "FormBits"); 228201360Srdivacky SegOvr = byteFromRec(Rec, "SegOvrBits"); 229239462Sdim 230201360Srdivacky HasOpSizePrefix = Rec->getValueAsBit("hasOpSizePrefix"); 231234353Sdim HasAdSizePrefix = Rec->getValueAsBit("hasAdSizePrefix"); 232201360Srdivacky HasREX_WPrefix = Rec->getValueAsBit("hasREX_WPrefix"); 233221345Sdim HasVEXPrefix = Rec->getValueAsBit("hasVEXPrefix"); 234210299Sed HasVEX_4VPrefix = Rec->getValueAsBit("hasVEX_4VPrefix"); 235234353Sdim HasVEX_4VOp3Prefix = Rec->getValueAsBit("hasVEX_4VOp3Prefix"); 236221345Sdim HasVEX_WPrefix = Rec->getValueAsBit("hasVEX_WPrefix"); 237234353Sdim HasMemOp4Prefix = Rec->getValueAsBit("hasMemOp4Prefix"); 238226633Sdim IgnoresVEX_L = Rec->getValueAsBit("ignoresVEX_L"); 239201360Srdivacky HasLockPrefix = Rec->getValueAsBit("hasLockPrefix"); 240201360Srdivacky IsCodeGenOnly = Rec->getValueAsBit("isCodeGenOnly"); 241239462Sdim 242201360Srdivacky Name = Rec->getName(); 243201360Srdivacky AsmString = Rec->getValueAsString("AsmString"); 244239462Sdim 245218893Sdim Operands = &insn.Operands.OperandList; 246239462Sdim 247226633Sdim IsSSE = (HasOpSizePrefix && (Name.find("16") == Name.npos)) || 248226633Sdim (Name.find("CRC32") != Name.npos); 249221345Sdim HasFROperands = hasFROperands(); 250243830Sdim HasVEX_LPrefix = Rec->getValueAsBit("hasVEX_L"); 251234353Sdim 252224145Sdim // Check for 64-bit inst which does not require REX 253226633Sdim Is32Bit = false; 254224145Sdim Is64Bit = false; 255224145Sdim // FIXME: Is there some better way to check for In64BitMode? 256224145Sdim std::vector<Record*> Predicates = Rec->getValueAsListOfDefs("Predicates"); 257224145Sdim for (unsigned i = 0, e = Predicates.size(); i != e; ++i) { 258226633Sdim if (Predicates[i]->getName().find("32Bit") != Name.npos) { 259226633Sdim Is32Bit = true; 260226633Sdim break; 261226633Sdim } 262224145Sdim if (Predicates[i]->getName().find("64Bit") != Name.npos) { 263224145Sdim Is64Bit = true; 264224145Sdim break; 265224145Sdim } 266224145Sdim } 267224145Sdim // FIXME: These instructions aren't marked as 64-bit in any way 268239462Sdim Is64Bit |= Rec->getName() == "JMP64pcrel32" || 269239462Sdim Rec->getName() == "MASKMOVDQU64" || 270239462Sdim Rec->getName() == "POPFS64" || 271239462Sdim Rec->getName() == "POPGS64" || 272239462Sdim Rec->getName() == "PUSHFS64" || 273224145Sdim Rec->getName() == "PUSHGS64" || 274224145Sdim Rec->getName() == "REX64_PREFIX" || 275239462Sdim Rec->getName().find("MOV64") != Name.npos || 276224145Sdim Rec->getName().find("PUSH64") != Name.npos || 277224145Sdim Rec->getName().find("POP64") != Name.npos; 278224145Sdim 279201360Srdivacky ShouldBeEmitted = true; 280201360Srdivacky} 281239462Sdim 282201360Srdivackyvoid RecognizableInstr::processInstr(DisassemblerTables &tables, 283239462Sdim const CodeGenInstruction &insn, 284239462Sdim InstrUID uid) 285201360Srdivacky{ 286208599Srdivacky // Ignore "asm parser only" instructions. 287208599Srdivacky if (insn.TheDef->getValueAsBit("isAsmParserOnly")) 288208599Srdivacky return; 289239462Sdim 290201360Srdivacky RecognizableInstr recogInstr(tables, insn, uid); 291239462Sdim 292201360Srdivacky recogInstr.emitInstructionSpecifier(tables); 293239462Sdim 294201360Srdivacky if (recogInstr.shouldBeEmitted()) 295201360Srdivacky recogInstr.emitDecodePath(tables); 296201360Srdivacky} 297201360Srdivacky 298201360SrdivackyInstructionContext RecognizableInstr::insnContext() const { 299201360Srdivacky InstructionContext insnContext; 300201360Srdivacky 301234353Sdim if (HasVEX_4VPrefix || HasVEX_4VOp3Prefix|| HasVEXPrefix) { 302234353Sdim if (HasVEX_LPrefix && HasVEX_WPrefix) { 303234353Sdim if (HasOpSizePrefix) 304234353Sdim insnContext = IC_VEX_L_W_OPSIZE; 305234353Sdim else 306234353Sdim llvm_unreachable("Don't support VEX.L and VEX.W together"); 307234353Sdim } else if (HasOpSizePrefix && HasVEX_LPrefix) 308221345Sdim insnContext = IC_VEX_L_OPSIZE; 309221345Sdim else if (HasOpSizePrefix && HasVEX_WPrefix) 310221345Sdim insnContext = IC_VEX_W_OPSIZE; 311221345Sdim else if (HasOpSizePrefix) 312221345Sdim insnContext = IC_VEX_OPSIZE; 313234353Sdim else if (HasVEX_LPrefix && 314234353Sdim (Prefix == X86Local::XS || Prefix == X86Local::T8XS)) 315221345Sdim insnContext = IC_VEX_L_XS; 316234353Sdim else if (HasVEX_LPrefix && (Prefix == X86Local::XD || 317234353Sdim Prefix == X86Local::T8XD || 318234353Sdim Prefix == X86Local::TAXD)) 319221345Sdim insnContext = IC_VEX_L_XD; 320234353Sdim else if (HasVEX_WPrefix && 321234353Sdim (Prefix == X86Local::XS || Prefix == X86Local::T8XS)) 322221345Sdim insnContext = IC_VEX_W_XS; 323234353Sdim else if (HasVEX_WPrefix && (Prefix == X86Local::XD || 324234353Sdim Prefix == X86Local::T8XD || 325234353Sdim Prefix == X86Local::TAXD)) 326221345Sdim insnContext = IC_VEX_W_XD; 327221345Sdim else if (HasVEX_WPrefix) 328221345Sdim insnContext = IC_VEX_W; 329221345Sdim else if (HasVEX_LPrefix) 330221345Sdim insnContext = IC_VEX_L; 331234353Sdim else if (Prefix == X86Local::XD || Prefix == X86Local::T8XD || 332234353Sdim Prefix == X86Local::TAXD) 333221345Sdim insnContext = IC_VEX_XD; 334234353Sdim else if (Prefix == X86Local::XS || Prefix == X86Local::T8XS) 335221345Sdim insnContext = IC_VEX_XS; 336221345Sdim else 337221345Sdim insnContext = IC_VEX; 338224145Sdim } else if (Is64Bit || HasREX_WPrefix) { 339201360Srdivacky if (HasREX_WPrefix && HasOpSizePrefix) 340201360Srdivacky insnContext = IC_64BIT_REXW_OPSIZE; 341234353Sdim else if (HasOpSizePrefix && (Prefix == X86Local::XD || 342234353Sdim Prefix == X86Local::T8XD || 343234353Sdim Prefix == X86Local::TAXD)) 344234353Sdim insnContext = IC_64BIT_XD_OPSIZE; 345226633Sdim else if (HasOpSizePrefix && 346234353Sdim (Prefix == X86Local::XS || Prefix == X86Local::T8XS)) 347226633Sdim insnContext = IC_64BIT_XS_OPSIZE; 348201360Srdivacky else if (HasOpSizePrefix) 349201360Srdivacky insnContext = IC_64BIT_OPSIZE; 350234353Sdim else if (HasAdSizePrefix) 351234353Sdim insnContext = IC_64BIT_ADSIZE; 352234353Sdim else if (HasREX_WPrefix && 353234353Sdim (Prefix == X86Local::XS || Prefix == X86Local::T8XS)) 354201360Srdivacky insnContext = IC_64BIT_REXW_XS; 355234353Sdim else if (HasREX_WPrefix && (Prefix == X86Local::XD || 356234353Sdim Prefix == X86Local::T8XD || 357234353Sdim Prefix == X86Local::TAXD)) 358201360Srdivacky insnContext = IC_64BIT_REXW_XD; 359234353Sdim else if (Prefix == X86Local::XD || Prefix == X86Local::T8XD || 360234353Sdim Prefix == X86Local::TAXD) 361201360Srdivacky insnContext = IC_64BIT_XD; 362234353Sdim else if (Prefix == X86Local::XS || Prefix == X86Local::T8XS) 363201360Srdivacky insnContext = IC_64BIT_XS; 364201360Srdivacky else if (HasREX_WPrefix) 365201360Srdivacky insnContext = IC_64BIT_REXW; 366201360Srdivacky else 367201360Srdivacky insnContext = IC_64BIT; 368201360Srdivacky } else { 369234353Sdim if (HasOpSizePrefix && (Prefix == X86Local::XD || 370234353Sdim Prefix == X86Local::T8XD || 371234353Sdim Prefix == X86Local::TAXD)) 372226633Sdim insnContext = IC_XD_OPSIZE; 373234353Sdim else if (HasOpSizePrefix && 374234353Sdim (Prefix == X86Local::XS || Prefix == X86Local::T8XS)) 375226633Sdim insnContext = IC_XS_OPSIZE; 376226633Sdim else if (HasOpSizePrefix) 377201360Srdivacky insnContext = IC_OPSIZE; 378234353Sdim else if (HasAdSizePrefix) 379234353Sdim insnContext = IC_ADSIZE; 380234353Sdim else if (Prefix == X86Local::XD || Prefix == X86Local::T8XD || 381234353Sdim Prefix == X86Local::TAXD) 382201360Srdivacky insnContext = IC_XD; 383234353Sdim else if (Prefix == X86Local::XS || Prefix == X86Local::T8XS || 384234353Sdim Prefix == X86Local::REP) 385201360Srdivacky insnContext = IC_XS; 386201360Srdivacky else 387201360Srdivacky insnContext = IC; 388201360Srdivacky } 389201360Srdivacky 390201360Srdivacky return insnContext; 391201360Srdivacky} 392239462Sdim 393201360SrdivackyRecognizableInstr::filter_ret RecognizableInstr::filter() const { 394221345Sdim /////////////////// 395221345Sdim // FILTER_STRONG 396221345Sdim // 397239462Sdim 398201360Srdivacky // Filter out intrinsics 399239462Sdim 400239462Sdim assert(Rec->isSubClassOf("X86Inst") && "Can only filter X86 instructions"); 401239462Sdim 402201360Srdivacky if (Form == X86Local::Pseudo || 403226633Sdim (IsCodeGenOnly && Name.find("_REV") == Name.npos)) 404201360Srdivacky return FILTER_STRONG; 405239462Sdim 406239462Sdim 407234353Sdim // Filter out artificial instructions but leave in the LOCK_PREFIX so it is 408234353Sdim // printed as a separate "instruction". 409239462Sdim 410234353Sdim if (Name.find("_Int") != Name.npos || 411239462Sdim Name.find("Int_") != Name.npos) 412221345Sdim return FILTER_STRONG; 413221345Sdim 414221345Sdim // Filter out instructions with segment override prefixes. 415221345Sdim // They're too messy to handle now and we'll special case them if needed. 416239462Sdim 417221345Sdim if (SegOvr) 418221345Sdim return FILTER_STRONG; 419221345Sdim 420239462Sdim 421221345Sdim ///////////////// 422221345Sdim // FILTER_WEAK 423221345Sdim // 424221345Sdim 425239462Sdim 426201360Srdivacky // Filter out instructions with a LOCK prefix; 427201360Srdivacky // prefer forms that do not have the prefix 428201360Srdivacky if (HasLockPrefix) 429201360Srdivacky return FILTER_WEAK; 430201360Srdivacky 431221345Sdim // Filter out alternate forms of AVX instructions 432221345Sdim if (Name.find("_alt") != Name.npos || 433221345Sdim Name.find("XrYr") != Name.npos || 434226633Sdim (Name.find("r64r") != Name.npos && Name.find("r64r64") == Name.npos) || 435221345Sdim Name.find("_64mr") != Name.npos || 436221345Sdim Name.find("Xrr") != Name.npos || 437221345Sdim Name.find("rr64") != Name.npos) 438221345Sdim return FILTER_WEAK; 439201360Srdivacky 440201360Srdivacky // Special cases. 441218893Sdim 442201360Srdivacky if (Name.find("PCMPISTRI") != Name.npos && Name != "PCMPISTRI") 443201360Srdivacky return FILTER_WEAK; 444201360Srdivacky if (Name.find("PCMPESTRI") != Name.npos && Name != "PCMPESTRI") 445201360Srdivacky return FILTER_WEAK; 446201360Srdivacky 447201360Srdivacky if (Name.find("MOV") != Name.npos && Name.find("r0") != Name.npos) 448201360Srdivacky return FILTER_WEAK; 449201360Srdivacky if (Name.find("MOVZ") != Name.npos && Name.find("MOVZX") == Name.npos) 450201360Srdivacky return FILTER_WEAK; 451201360Srdivacky if (Name.find("Fs") != Name.npos) 452201360Srdivacky return FILTER_WEAK; 453234353Sdim if (Name == "PUSH64i16" || 454201360Srdivacky Name == "MOVPQI2QImr" || 455221345Sdim Name == "VMOVPQI2QImr" || 456201360Srdivacky Name == "MMX_MOVD64rrv164" || 457201360Srdivacky Name == "MOV64ri64i32" || 458234353Sdim Name == "VMASKMOVDQU64" || 459234353Sdim Name == "VEXTRACTPSrr64" || 460234353Sdim Name == "VMOVQd64rr" || 461234353Sdim Name == "VMOVQs64rr") 462201360Srdivacky return FILTER_WEAK; 463201360Srdivacky 464201360Srdivacky if (HasFROperands && Name.find("MOV") != Name.npos && 465239462Sdim ((Name.find("2") != Name.npos && Name.find("32") == Name.npos) || 466201360Srdivacky (Name.find("to") != Name.npos))) 467239462Sdim return FILTER_STRONG; 468201360Srdivacky 469201360Srdivacky return FILTER_NORMAL; 470201360Srdivacky} 471221345Sdim 472221345Sdimbool RecognizableInstr::hasFROperands() const { 473221345Sdim const std::vector<CGIOperandList::OperandInfo> &OperandList = *Operands; 474221345Sdim unsigned numOperands = OperandList.size(); 475221345Sdim 476221345Sdim for (unsigned operandIndex = 0; operandIndex < numOperands; ++operandIndex) { 477221345Sdim const std::string &recName = OperandList[operandIndex].Rec->getName(); 478239462Sdim 479221345Sdim if (recName.find("FR") != recName.npos) 480221345Sdim return true; 481221345Sdim } 482221345Sdim return false; 483221345Sdim} 484221345Sdim 485239462Sdimvoid RecognizableInstr::handleOperand(bool optional, unsigned &operandIndex, 486239462Sdim unsigned &physicalOperandIndex, 487239462Sdim unsigned &numPhysicalOperands, 488239462Sdim const unsigned *operandMapping, 489239462Sdim OperandEncoding (*encodingFromString) 490239462Sdim (const std::string&, 491239462Sdim bool hasOpSizePrefix)) { 492201360Srdivacky if (optional) { 493201360Srdivacky if (physicalOperandIndex >= numPhysicalOperands) 494201360Srdivacky return; 495201360Srdivacky } else { 496201360Srdivacky assert(physicalOperandIndex < numPhysicalOperands); 497201360Srdivacky } 498239462Sdim 499201360Srdivacky while (operandMapping[operandIndex] != operandIndex) { 500201360Srdivacky Spec->operands[operandIndex].encoding = ENCODING_DUP; 501201360Srdivacky Spec->operands[operandIndex].type = 502201360Srdivacky (OperandType)(TYPE_DUP0 + operandMapping[operandIndex]); 503201360Srdivacky ++operandIndex; 504201360Srdivacky } 505239462Sdim 506201360Srdivacky const std::string &typeName = (*Operands)[operandIndex].Rec->getName(); 507221345Sdim 508201360Srdivacky Spec->operands[operandIndex].encoding = encodingFromString(typeName, 509201360Srdivacky HasOpSizePrefix); 510239462Sdim Spec->operands[operandIndex].type = typeFromString(typeName, 511221345Sdim IsSSE, 512221345Sdim HasREX_WPrefix, 513221345Sdim HasOpSizePrefix); 514239462Sdim 515201360Srdivacky ++operandIndex; 516201360Srdivacky ++physicalOperandIndex; 517201360Srdivacky} 518201360Srdivacky 519201360Srdivackyvoid RecognizableInstr::emitInstructionSpecifier(DisassemblerTables &tables) { 520201360Srdivacky Spec->name = Name; 521239462Sdim 522239462Sdim if (!ShouldBeEmitted) 523201360Srdivacky return; 524239462Sdim 525201360Srdivacky switch (filter()) { 526201360Srdivacky case FILTER_WEAK: 527201360Srdivacky Spec->filtered = true; 528201360Srdivacky break; 529201360Srdivacky case FILTER_STRONG: 530201360Srdivacky ShouldBeEmitted = false; 531201360Srdivacky return; 532201360Srdivacky case FILTER_NORMAL: 533201360Srdivacky break; 534201360Srdivacky } 535239462Sdim 536201360Srdivacky Spec->insnContext = insnContext(); 537239462Sdim 538218893Sdim const std::vector<CGIOperandList::OperandInfo> &OperandList = *Operands; 539239462Sdim 540201360Srdivacky unsigned numOperands = OperandList.size(); 541201360Srdivacky unsigned numPhysicalOperands = 0; 542239462Sdim 543201360Srdivacky // operandMapping maps from operands in OperandList to their originals. 544201360Srdivacky // If operandMapping[i] != i, then the entry is a duplicate. 545201360Srdivacky unsigned operandMapping[X86_MAX_OPERANDS]; 546234353Sdim assert(numOperands <= X86_MAX_OPERANDS && "X86_MAX_OPERANDS is not large enough"); 547239462Sdim 548239462Sdim for (unsigned operandIndex = 0; operandIndex < numOperands; ++operandIndex) { 549201360Srdivacky if (OperandList[operandIndex].Constraints.size()) { 550218893Sdim const CGIOperandList::ConstraintInfo &Constraint = 551203954Srdivacky OperandList[operandIndex].Constraints[0]; 552203954Srdivacky if (Constraint.isTied()) { 553239462Sdim operandMapping[operandIndex] = operandIndex; 554239462Sdim operandMapping[Constraint.getTiedOperand()] = operandIndex; 555201360Srdivacky } else { 556201360Srdivacky ++numPhysicalOperands; 557201360Srdivacky operandMapping[operandIndex] = operandIndex; 558201360Srdivacky } 559201360Srdivacky } else { 560201360Srdivacky ++numPhysicalOperands; 561201360Srdivacky operandMapping[operandIndex] = operandIndex; 562201360Srdivacky } 563201360Srdivacky } 564201360Srdivacky 565201360Srdivacky#define HANDLE_OPERAND(class) \ 566201360Srdivacky handleOperand(false, \ 567201360Srdivacky operandIndex, \ 568201360Srdivacky physicalOperandIndex, \ 569201360Srdivacky numPhysicalOperands, \ 570201360Srdivacky operandMapping, \ 571201360Srdivacky class##EncodingFromString); 572239462Sdim 573201360Srdivacky#define HANDLE_OPTIONAL(class) \ 574201360Srdivacky handleOperand(true, \ 575201360Srdivacky operandIndex, \ 576201360Srdivacky physicalOperandIndex, \ 577201360Srdivacky numPhysicalOperands, \ 578201360Srdivacky operandMapping, \ 579201360Srdivacky class##EncodingFromString); 580239462Sdim 581201360Srdivacky // operandIndex should always be < numOperands 582239462Sdim unsigned operandIndex = 0; 583201360Srdivacky // physicalOperandIndex should always be < numPhysicalOperands 584201360Srdivacky unsigned physicalOperandIndex = 0; 585239462Sdim 586201360Srdivacky switch (Form) { 587201360Srdivacky case X86Local::RawFrm: 588201360Srdivacky // Operand 1 (optional) is an address or immediate. 589201360Srdivacky // Operand 2 (optional) is an immediate. 590239462Sdim assert(numPhysicalOperands <= 2 && 591201360Srdivacky "Unexpected number of operands for RawFrm"); 592201360Srdivacky HANDLE_OPTIONAL(relocation) 593201360Srdivacky HANDLE_OPTIONAL(immediate) 594201360Srdivacky break; 595201360Srdivacky case X86Local::AddRegFrm: 596201360Srdivacky // Operand 1 is added to the opcode. 597201360Srdivacky // Operand 2 (optional) is an address. 598201360Srdivacky assert(numPhysicalOperands >= 1 && numPhysicalOperands <= 2 && 599201360Srdivacky "Unexpected number of operands for AddRegFrm"); 600201360Srdivacky HANDLE_OPERAND(opcodeModifier) 601201360Srdivacky HANDLE_OPTIONAL(relocation) 602201360Srdivacky break; 603201360Srdivacky case X86Local::MRMDestReg: 604201360Srdivacky // Operand 1 is a register operand in the R/M field. 605201360Srdivacky // Operand 2 is a register operand in the Reg/Opcode field. 606226633Sdim // - In AVX, there is a register operand in the VEX.vvvv field here - 607201360Srdivacky // Operand 3 (optional) is an immediate. 608226633Sdim if (HasVEX_4VPrefix) 609226633Sdim assert(numPhysicalOperands >= 3 && numPhysicalOperands <= 4 && 610226633Sdim "Unexpected number of operands for MRMDestRegFrm with VEX_4V"); 611226633Sdim else 612226633Sdim assert(numPhysicalOperands >= 2 && numPhysicalOperands <= 3 && 613226633Sdim "Unexpected number of operands for MRMDestRegFrm"); 614239462Sdim 615201360Srdivacky HANDLE_OPERAND(rmRegister) 616226633Sdim 617226633Sdim if (HasVEX_4VPrefix) 618226633Sdim // FIXME: In AVX, the register below becomes the one encoded 619226633Sdim // in ModRMVEX and the one above the one in the VEX.VVVV field 620226633Sdim HANDLE_OPERAND(vvvvRegister) 621239462Sdim 622201360Srdivacky HANDLE_OPERAND(roRegister) 623201360Srdivacky HANDLE_OPTIONAL(immediate) 624201360Srdivacky break; 625201360Srdivacky case X86Local::MRMDestMem: 626201360Srdivacky // Operand 1 is a memory operand (possibly SIB-extended) 627201360Srdivacky // Operand 2 is a register operand in the Reg/Opcode field. 628226633Sdim // - In AVX, there is a register operand in the VEX.vvvv field here - 629201360Srdivacky // Operand 3 (optional) is an immediate. 630226633Sdim if (HasVEX_4VPrefix) 631226633Sdim assert(numPhysicalOperands >= 3 && numPhysicalOperands <= 4 && 632226633Sdim "Unexpected number of operands for MRMDestMemFrm with VEX_4V"); 633226633Sdim else 634226633Sdim assert(numPhysicalOperands >= 2 && numPhysicalOperands <= 3 && 635226633Sdim "Unexpected number of operands for MRMDestMemFrm"); 636201360Srdivacky HANDLE_OPERAND(memory) 637226633Sdim 638226633Sdim if (HasVEX_4VPrefix) 639226633Sdim // FIXME: In AVX, the register below becomes the one encoded 640226633Sdim // in ModRMVEX and the one above the one in the VEX.VVVV field 641226633Sdim HANDLE_OPERAND(vvvvRegister) 642239462Sdim 643201360Srdivacky HANDLE_OPERAND(roRegister) 644201360Srdivacky HANDLE_OPTIONAL(immediate) 645201360Srdivacky break; 646201360Srdivacky case X86Local::MRMSrcReg: 647201360Srdivacky // Operand 1 is a register operand in the Reg/Opcode field. 648201360Srdivacky // Operand 2 is a register operand in the R/M field. 649221345Sdim // - In AVX, there is a register operand in the VEX.vvvv field here - 650201360Srdivacky // Operand 3 (optional) is an immediate. 651239462Sdim // Operand 4 (optional) is an immediate. 652210299Sed 653234353Sdim if (HasVEX_4VPrefix || HasVEX_4VOp3Prefix) 654234353Sdim assert(numPhysicalOperands >= 3 && numPhysicalOperands <= 5 && 655239462Sdim "Unexpected number of operands for MRMSrcRegFrm with VEX_4V"); 656221345Sdim else 657239462Sdim assert(numPhysicalOperands >= 2 && numPhysicalOperands <= 4 && 658221345Sdim "Unexpected number of operands for MRMSrcRegFrm"); 659239462Sdim 660221345Sdim HANDLE_OPERAND(roRegister) 661234353Sdim 662221345Sdim if (HasVEX_4VPrefix) 663210299Sed // FIXME: In AVX, the register below becomes the one encoded 664210299Sed // in ModRMVEX and the one above the one in the VEX.VVVV field 665221345Sdim HANDLE_OPERAND(vvvvRegister) 666234353Sdim 667234353Sdim if (HasMemOp4Prefix) 668234353Sdim HANDLE_OPERAND(immediate) 669234353Sdim 670221345Sdim HANDLE_OPERAND(rmRegister) 671234353Sdim 672234353Sdim if (HasVEX_4VOp3Prefix) 673234353Sdim HANDLE_OPERAND(vvvvRegister) 674234353Sdim 675234353Sdim if (!HasMemOp4Prefix) 676234353Sdim HANDLE_OPTIONAL(immediate) 677234353Sdim HANDLE_OPTIONAL(immediate) // above might be a register in 7:4 678239462Sdim HANDLE_OPTIONAL(immediate) 679201360Srdivacky break; 680201360Srdivacky case X86Local::MRMSrcMem: 681201360Srdivacky // Operand 1 is a register operand in the Reg/Opcode field. 682201360Srdivacky // Operand 2 is a memory operand (possibly SIB-extended) 683221345Sdim // - In AVX, there is a register operand in the VEX.vvvv field here - 684201360Srdivacky // Operand 3 (optional) is an immediate. 685234353Sdim 686234353Sdim if (HasVEX_4VPrefix || HasVEX_4VOp3Prefix) 687234353Sdim assert(numPhysicalOperands >= 3 && numPhysicalOperands <= 5 && 688239462Sdim "Unexpected number of operands for MRMSrcMemFrm with VEX_4V"); 689221345Sdim else 690221345Sdim assert(numPhysicalOperands >= 2 && numPhysicalOperands <= 3 && 691221345Sdim "Unexpected number of operands for MRMSrcMemFrm"); 692239462Sdim 693201360Srdivacky HANDLE_OPERAND(roRegister) 694210299Sed 695210299Sed if (HasVEX_4VPrefix) 696210299Sed // FIXME: In AVX, the register below becomes the one encoded 697210299Sed // in ModRMVEX and the one above the one in the VEX.VVVV field 698221345Sdim HANDLE_OPERAND(vvvvRegister) 699210299Sed 700234353Sdim if (HasMemOp4Prefix) 701234353Sdim HANDLE_OPERAND(immediate) 702234353Sdim 703201360Srdivacky HANDLE_OPERAND(memory) 704234353Sdim 705234353Sdim if (HasVEX_4VOp3Prefix) 706234353Sdim HANDLE_OPERAND(vvvvRegister) 707234353Sdim 708234353Sdim if (!HasMemOp4Prefix) 709234353Sdim HANDLE_OPTIONAL(immediate) 710234353Sdim HANDLE_OPTIONAL(immediate) // above might be a register in 7:4 711201360Srdivacky break; 712201360Srdivacky case X86Local::MRM0r: 713201360Srdivacky case X86Local::MRM1r: 714201360Srdivacky case X86Local::MRM2r: 715201360Srdivacky case X86Local::MRM3r: 716201360Srdivacky case X86Local::MRM4r: 717201360Srdivacky case X86Local::MRM5r: 718201360Srdivacky case X86Local::MRM6r: 719201360Srdivacky case X86Local::MRM7r: 720201360Srdivacky // Operand 1 is a register operand in the R/M field. 721201360Srdivacky // Operand 2 (optional) is an immediate or relocation. 722239462Sdim // Operand 3 (optional) is an immediate. 723221345Sdim if (HasVEX_4VPrefix) 724221345Sdim assert(numPhysicalOperands <= 3 && 725234353Sdim "Unexpected number of operands for MRMnRFrm with VEX_4V"); 726221345Sdim else 727239462Sdim assert(numPhysicalOperands <= 3 && 728221345Sdim "Unexpected number of operands for MRMnRFrm"); 729221345Sdim if (HasVEX_4VPrefix) 730234353Sdim HANDLE_OPERAND(vvvvRegister) 731201360Srdivacky HANDLE_OPTIONAL(rmRegister) 732201360Srdivacky HANDLE_OPTIONAL(relocation) 733239462Sdim HANDLE_OPTIONAL(immediate) 734201360Srdivacky break; 735201360Srdivacky case X86Local::MRM0m: 736201360Srdivacky case X86Local::MRM1m: 737201360Srdivacky case X86Local::MRM2m: 738201360Srdivacky case X86Local::MRM3m: 739201360Srdivacky case X86Local::MRM4m: 740201360Srdivacky case X86Local::MRM5m: 741201360Srdivacky case X86Local::MRM6m: 742201360Srdivacky case X86Local::MRM7m: 743201360Srdivacky // Operand 1 is a memory operand (possibly SIB-extended) 744201360Srdivacky // Operand 2 (optional) is an immediate or relocation. 745234353Sdim if (HasVEX_4VPrefix) 746234353Sdim assert(numPhysicalOperands >= 2 && numPhysicalOperands <= 3 && 747234353Sdim "Unexpected number of operands for MRMnMFrm"); 748234353Sdim else 749234353Sdim assert(numPhysicalOperands >= 1 && numPhysicalOperands <= 2 && 750234353Sdim "Unexpected number of operands for MRMnMFrm"); 751234353Sdim if (HasVEX_4VPrefix) 752234353Sdim HANDLE_OPERAND(vvvvRegister) 753201360Srdivacky HANDLE_OPERAND(memory) 754201360Srdivacky HANDLE_OPTIONAL(relocation) 755201360Srdivacky break; 756218893Sdim case X86Local::RawFrmImm8: 757218893Sdim // operand 1 is a 16-bit immediate 758218893Sdim // operand 2 is an 8-bit immediate 759218893Sdim assert(numPhysicalOperands == 2 && 760218893Sdim "Unexpected number of operands for X86Local::RawFrmImm8"); 761218893Sdim HANDLE_OPERAND(immediate) 762218893Sdim HANDLE_OPERAND(immediate) 763218893Sdim break; 764218893Sdim case X86Local::RawFrmImm16: 765218893Sdim // operand 1 is a 16-bit immediate 766218893Sdim // operand 2 is a 16-bit immediate 767218893Sdim HANDLE_OPERAND(immediate) 768218893Sdim HANDLE_OPERAND(immediate) 769218893Sdim break; 770249423Sdim case X86Local::MRM_F8: 771249423Sdim if (Opcode == 0xc6) { 772249423Sdim assert(numPhysicalOperands == 1 && 773249423Sdim "Unexpected number of operands for X86Local::MRM_F8"); 774249423Sdim HANDLE_OPERAND(immediate) 775249423Sdim } else if (Opcode == 0xc7) { 776249423Sdim assert(numPhysicalOperands == 1 && 777249423Sdim "Unexpected number of operands for X86Local::MRM_F8"); 778249423Sdim HANDLE_OPERAND(relocation) 779249423Sdim } 780249423Sdim break; 781201360Srdivacky case X86Local::MRMInitReg: 782201360Srdivacky // Ignored. 783201360Srdivacky break; 784201360Srdivacky } 785239462Sdim 786201360Srdivacky #undef HANDLE_OPERAND 787201360Srdivacky #undef HANDLE_OPTIONAL 788201360Srdivacky} 789201360Srdivacky 790201360Srdivackyvoid RecognizableInstr::emitDecodePath(DisassemblerTables &tables) const { 791201360Srdivacky // Special cases where the LLVM tables are not complete 792201360Srdivacky 793203954Srdivacky#define MAP(from, to) \ 794203954Srdivacky case X86Local::MRM_##from: \ 795203954Srdivacky filter = new ExactFilter(0x##from); \ 796203954Srdivacky break; 797201360Srdivacky 798201360Srdivacky OpcodeType opcodeType = (OpcodeType)-1; 799239462Sdim 800239462Sdim ModRMFilter* filter = NULL; 801201360Srdivacky uint8_t opcodeToSet = 0; 802201360Srdivacky 803201360Srdivacky switch (Prefix) { 804201360Srdivacky // Extended two-byte opcodes can start with f2 0f, f3 0f, or 0f 805201360Srdivacky case X86Local::XD: 806201360Srdivacky case X86Local::XS: 807201360Srdivacky case X86Local::TB: 808201360Srdivacky opcodeType = TWOBYTE; 809201360Srdivacky 810201360Srdivacky switch (Opcode) { 811203954Srdivacky default: 812203954Srdivacky if (needsModRMForDecode(Form)) 813203954Srdivacky filter = new ModFilter(isRegFormat(Form)); 814203954Srdivacky else 815203954Srdivacky filter = new DumbFilter(); 816203954Srdivacky break; 817201360Srdivacky#define EXTENSION_TABLE(n) case 0x##n: 818201360Srdivacky TWO_BYTE_EXTENSION_TABLES 819201360Srdivacky#undef EXTENSION_TABLE 820201360Srdivacky switch (Form) { 821201360Srdivacky default: 822201360Srdivacky llvm_unreachable("Unhandled two-byte extended opcode"); 823201360Srdivacky case X86Local::MRM0r: 824201360Srdivacky case X86Local::MRM1r: 825201360Srdivacky case X86Local::MRM2r: 826201360Srdivacky case X86Local::MRM3r: 827201360Srdivacky case X86Local::MRM4r: 828201360Srdivacky case X86Local::MRM5r: 829201360Srdivacky case X86Local::MRM6r: 830201360Srdivacky case X86Local::MRM7r: 831201360Srdivacky filter = new ExtendedFilter(true, Form - X86Local::MRM0r); 832201360Srdivacky break; 833201360Srdivacky case X86Local::MRM0m: 834201360Srdivacky case X86Local::MRM1m: 835201360Srdivacky case X86Local::MRM2m: 836201360Srdivacky case X86Local::MRM3m: 837201360Srdivacky case X86Local::MRM4m: 838201360Srdivacky case X86Local::MRM5m: 839201360Srdivacky case X86Local::MRM6m: 840201360Srdivacky case X86Local::MRM7m: 841201360Srdivacky filter = new ExtendedFilter(false, Form - X86Local::MRM0m); 842201360Srdivacky break; 843203954Srdivacky MRM_MAPPING 844201360Srdivacky } // switch (Form) 845201360Srdivacky break; 846203954Srdivacky } // switch (Opcode) 847201360Srdivacky opcodeToSet = Opcode; 848201360Srdivacky break; 849201360Srdivacky case X86Local::T8: 850234353Sdim case X86Local::T8XD: 851234353Sdim case X86Local::T8XS: 852201360Srdivacky opcodeType = THREEBYTE_38; 853234353Sdim switch (Opcode) { 854234353Sdim default: 855234353Sdim if (needsModRMForDecode(Form)) 856234353Sdim filter = new ModFilter(isRegFormat(Form)); 857234353Sdim else 858234353Sdim filter = new DumbFilter(); 859234353Sdim break; 860234353Sdim#define EXTENSION_TABLE(n) case 0x##n: 861234353Sdim THREE_BYTE_38_EXTENSION_TABLES 862234353Sdim#undef EXTENSION_TABLE 863234353Sdim switch (Form) { 864234353Sdim default: 865234353Sdim llvm_unreachable("Unhandled two-byte extended opcode"); 866234353Sdim case X86Local::MRM0r: 867234353Sdim case X86Local::MRM1r: 868234353Sdim case X86Local::MRM2r: 869234353Sdim case X86Local::MRM3r: 870234353Sdim case X86Local::MRM4r: 871234353Sdim case X86Local::MRM5r: 872234353Sdim case X86Local::MRM6r: 873234353Sdim case X86Local::MRM7r: 874234353Sdim filter = new ExtendedFilter(true, Form - X86Local::MRM0r); 875234353Sdim break; 876234353Sdim case X86Local::MRM0m: 877234353Sdim case X86Local::MRM1m: 878234353Sdim case X86Local::MRM2m: 879234353Sdim case X86Local::MRM3m: 880234353Sdim case X86Local::MRM4m: 881234353Sdim case X86Local::MRM5m: 882234353Sdim case X86Local::MRM6m: 883234353Sdim case X86Local::MRM7m: 884234353Sdim filter = new ExtendedFilter(false, Form - X86Local::MRM0m); 885234353Sdim break; 886234353Sdim MRM_MAPPING 887234353Sdim } // switch (Form) 888234353Sdim break; 889234353Sdim } // switch (Opcode) 890201360Srdivacky opcodeToSet = Opcode; 891201360Srdivacky break; 892203954Srdivacky case X86Local::P_TA: 893234353Sdim case X86Local::TAXD: 894201360Srdivacky opcodeType = THREEBYTE_3A; 895201360Srdivacky if (needsModRMForDecode(Form)) 896201360Srdivacky filter = new ModFilter(isRegFormat(Form)); 897201360Srdivacky else 898201360Srdivacky filter = new DumbFilter(); 899201360Srdivacky opcodeToSet = Opcode; 900201360Srdivacky break; 901221345Sdim case X86Local::A6: 902221345Sdim opcodeType = THREEBYTE_A6; 903221345Sdim if (needsModRMForDecode(Form)) 904221345Sdim filter = new ModFilter(isRegFormat(Form)); 905221345Sdim else 906221345Sdim filter = new DumbFilter(); 907221345Sdim opcodeToSet = Opcode; 908221345Sdim break; 909221345Sdim case X86Local::A7: 910221345Sdim opcodeType = THREEBYTE_A7; 911221345Sdim if (needsModRMForDecode(Form)) 912221345Sdim filter = new ModFilter(isRegFormat(Form)); 913221345Sdim else 914221345Sdim filter = new DumbFilter(); 915221345Sdim opcodeToSet = Opcode; 916221345Sdim break; 917201360Srdivacky case X86Local::D8: 918201360Srdivacky case X86Local::D9: 919201360Srdivacky case X86Local::DA: 920201360Srdivacky case X86Local::DB: 921201360Srdivacky case X86Local::DC: 922201360Srdivacky case X86Local::DD: 923201360Srdivacky case X86Local::DE: 924201360Srdivacky case X86Local::DF: 925201360Srdivacky assert(Opcode >= 0xc0 && "Unexpected opcode for an escape opcode"); 926201360Srdivacky opcodeType = ONEBYTE; 927201360Srdivacky if (Form == X86Local::AddRegFrm) { 928201360Srdivacky Spec->modifierType = MODIFIER_MODRM; 929201360Srdivacky Spec->modifierBase = Opcode; 930201360Srdivacky filter = new AddRegEscapeFilter(Opcode); 931201360Srdivacky } else { 932201360Srdivacky filter = new EscapeFilter(true, Opcode); 933201360Srdivacky } 934201360Srdivacky opcodeToSet = 0xd8 + (Prefix - X86Local::D8); 935201360Srdivacky break; 936226633Sdim case X86Local::REP: 937201360Srdivacky default: 938201360Srdivacky opcodeType = ONEBYTE; 939201360Srdivacky switch (Opcode) { 940201360Srdivacky#define EXTENSION_TABLE(n) case 0x##n: 941201360Srdivacky ONE_BYTE_EXTENSION_TABLES 942201360Srdivacky#undef EXTENSION_TABLE 943201360Srdivacky switch (Form) { 944201360Srdivacky default: 945201360Srdivacky llvm_unreachable("Fell through the cracks of a single-byte " 946201360Srdivacky "extended opcode"); 947201360Srdivacky case X86Local::MRM0r: 948201360Srdivacky case X86Local::MRM1r: 949201360Srdivacky case X86Local::MRM2r: 950201360Srdivacky case X86Local::MRM3r: 951201360Srdivacky case X86Local::MRM4r: 952201360Srdivacky case X86Local::MRM5r: 953201360Srdivacky case X86Local::MRM6r: 954201360Srdivacky case X86Local::MRM7r: 955201360Srdivacky filter = new ExtendedFilter(true, Form - X86Local::MRM0r); 956201360Srdivacky break; 957201360Srdivacky case X86Local::MRM0m: 958201360Srdivacky case X86Local::MRM1m: 959201360Srdivacky case X86Local::MRM2m: 960201360Srdivacky case X86Local::MRM3m: 961201360Srdivacky case X86Local::MRM4m: 962201360Srdivacky case X86Local::MRM5m: 963201360Srdivacky case X86Local::MRM6m: 964201360Srdivacky case X86Local::MRM7m: 965201360Srdivacky filter = new ExtendedFilter(false, Form - X86Local::MRM0m); 966201360Srdivacky break; 967203954Srdivacky MRM_MAPPING 968201360Srdivacky } // switch (Form) 969201360Srdivacky break; 970201360Srdivacky case 0xd8: 971201360Srdivacky case 0xd9: 972201360Srdivacky case 0xda: 973201360Srdivacky case 0xdb: 974201360Srdivacky case 0xdc: 975201360Srdivacky case 0xdd: 976201360Srdivacky case 0xde: 977201360Srdivacky case 0xdf: 978201360Srdivacky filter = new EscapeFilter(false, Form - X86Local::MRM0m); 979201360Srdivacky break; 980201360Srdivacky default: 981201360Srdivacky if (needsModRMForDecode(Form)) 982201360Srdivacky filter = new ModFilter(isRegFormat(Form)); 983201360Srdivacky else 984201360Srdivacky filter = new DumbFilter(); 985201360Srdivacky break; 986201360Srdivacky } // switch (Opcode) 987201360Srdivacky opcodeToSet = Opcode; 988201360Srdivacky } // switch (Prefix) 989201360Srdivacky 990201360Srdivacky assert(opcodeType != (OpcodeType)-1 && 991201360Srdivacky "Opcode type not set"); 992201360Srdivacky assert(filter && "Filter not set"); 993201360Srdivacky 994201360Srdivacky if (Form == X86Local::AddRegFrm) { 995201360Srdivacky if(Spec->modifierType != MODIFIER_MODRM) { 996201360Srdivacky assert(opcodeToSet < 0xf9 && 997201360Srdivacky "Not enough room for all ADDREG_FRM operands"); 998239462Sdim 999201360Srdivacky uint8_t currentOpcode; 1000201360Srdivacky 1001201360Srdivacky for (currentOpcode = opcodeToSet; 1002201360Srdivacky currentOpcode < opcodeToSet + 8; 1003201360Srdivacky ++currentOpcode) 1004239462Sdim tables.setTableFields(opcodeType, 1005239462Sdim insnContext(), 1006239462Sdim currentOpcode, 1007239462Sdim *filter, 1008226633Sdim UID, Is32Bit, IgnoresVEX_L); 1009239462Sdim 1010201360Srdivacky Spec->modifierType = MODIFIER_OPCODE; 1011201360Srdivacky Spec->modifierBase = opcodeToSet; 1012201360Srdivacky } else { 1013201360Srdivacky // modifierBase was set where MODIFIER_MODRM was set 1014239462Sdim tables.setTableFields(opcodeType, 1015239462Sdim insnContext(), 1016239462Sdim opcodeToSet, 1017239462Sdim *filter, 1018226633Sdim UID, Is32Bit, IgnoresVEX_L); 1019201360Srdivacky } 1020201360Srdivacky } else { 1021201360Srdivacky tables.setTableFields(opcodeType, 1022201360Srdivacky insnContext(), 1023201360Srdivacky opcodeToSet, 1024201360Srdivacky *filter, 1025226633Sdim UID, Is32Bit, IgnoresVEX_L); 1026239462Sdim 1027201360Srdivacky Spec->modifierType = MODIFIER_NONE; 1028201360Srdivacky Spec->modifierBase = opcodeToSet; 1029201360Srdivacky } 1030239462Sdim 1031201360Srdivacky delete filter; 1032239462Sdim 1033203954Srdivacky#undef MAP 1034201360Srdivacky} 1035201360Srdivacky 1036201360Srdivacky#define TYPE(str, type) if (s == str) return type; 1037201360SrdivackyOperandType RecognizableInstr::typeFromString(const std::string &s, 1038201360Srdivacky bool isSSE, 1039201360Srdivacky bool hasREX_WPrefix, 1040201360Srdivacky bool hasOpSizePrefix) { 1041201360Srdivacky if (isSSE) { 1042239462Sdim // For SSE instructions, we ignore the OpSize prefix and force operand 1043201360Srdivacky // sizes. 1044201360Srdivacky TYPE("GR16", TYPE_R16) 1045201360Srdivacky TYPE("GR32", TYPE_R32) 1046201360Srdivacky TYPE("GR64", TYPE_R64) 1047201360Srdivacky } 1048201360Srdivacky if(hasREX_WPrefix) { 1049201360Srdivacky // For instructions with a REX_W prefix, a declared 32-bit register encoding 1050201360Srdivacky // is special. 1051201360Srdivacky TYPE("GR32", TYPE_R32) 1052201360Srdivacky } 1053201360Srdivacky if(!hasOpSizePrefix) { 1054201360Srdivacky // For instructions without an OpSize prefix, a declared 16-bit register or 1055201360Srdivacky // immediate encoding is special. 1056201360Srdivacky TYPE("GR16", TYPE_R16) 1057201360Srdivacky TYPE("i16imm", TYPE_IMM16) 1058201360Srdivacky } 1059201360Srdivacky TYPE("i16mem", TYPE_Mv) 1060201360Srdivacky TYPE("i16imm", TYPE_IMMv) 1061201360Srdivacky TYPE("i16i8imm", TYPE_IMMv) 1062201360Srdivacky TYPE("GR16", TYPE_Rv) 1063201360Srdivacky TYPE("i32mem", TYPE_Mv) 1064201360Srdivacky TYPE("i32imm", TYPE_IMMv) 1065201360Srdivacky TYPE("i32i8imm", TYPE_IMM32) 1066226633Sdim TYPE("u32u8imm", TYPE_IMM32) 1067201360Srdivacky TYPE("GR32", TYPE_Rv) 1068201360Srdivacky TYPE("i64mem", TYPE_Mv) 1069201360Srdivacky TYPE("i64i32imm", TYPE_IMM64) 1070201360Srdivacky TYPE("i64i8imm", TYPE_IMM64) 1071201360Srdivacky TYPE("GR64", TYPE_R64) 1072201360Srdivacky TYPE("i8mem", TYPE_M8) 1073201360Srdivacky TYPE("i8imm", TYPE_IMM8) 1074201360Srdivacky TYPE("GR8", TYPE_R8) 1075201360Srdivacky TYPE("VR128", TYPE_XMM128) 1076201360Srdivacky TYPE("f128mem", TYPE_M128) 1077218893Sdim TYPE("f256mem", TYPE_M256) 1078201360Srdivacky TYPE("FR64", TYPE_XMM64) 1079201360Srdivacky TYPE("f64mem", TYPE_M64FP) 1080218893Sdim TYPE("sdmem", TYPE_M64FP) 1081201360Srdivacky TYPE("FR32", TYPE_XMM32) 1082201360Srdivacky TYPE("f32mem", TYPE_M32FP) 1083218893Sdim TYPE("ssmem", TYPE_M32FP) 1084201360Srdivacky TYPE("RST", TYPE_ST) 1085201360Srdivacky TYPE("i128mem", TYPE_M128) 1086221345Sdim TYPE("i256mem", TYPE_M256) 1087201360Srdivacky TYPE("i64i32imm_pcrel", TYPE_REL64) 1088210299Sed TYPE("i16imm_pcrel", TYPE_REL16) 1089201360Srdivacky TYPE("i32imm_pcrel", TYPE_REL32) 1090207618Srdivacky TYPE("SSECC", TYPE_IMM3) 1091234353Sdim TYPE("AVXCC", TYPE_IMM5) 1092201360Srdivacky TYPE("brtarget", TYPE_RELv) 1093218893Sdim TYPE("uncondbrtarget", TYPE_RELv) 1094201360Srdivacky TYPE("brtarget8", TYPE_REL8) 1095201360Srdivacky TYPE("f80mem", TYPE_M80FP) 1096201360Srdivacky TYPE("lea32mem", TYPE_LEA) 1097201360Srdivacky TYPE("lea64_32mem", TYPE_LEA) 1098201360Srdivacky TYPE("lea64mem", TYPE_LEA) 1099201360Srdivacky TYPE("VR64", TYPE_MM64) 1100201360Srdivacky TYPE("i64imm", TYPE_IMMv) 1101201360Srdivacky TYPE("opaque32mem", TYPE_M1616) 1102201360Srdivacky TYPE("opaque48mem", TYPE_M1632) 1103201360Srdivacky TYPE("opaque80mem", TYPE_M1664) 1104201360Srdivacky TYPE("opaque512mem", TYPE_M512) 1105201360Srdivacky TYPE("SEGMENT_REG", TYPE_SEGMENTREG) 1106201360Srdivacky TYPE("DEBUG_REG", TYPE_DEBUGREG) 1107208599Srdivacky TYPE("CONTROL_REG", TYPE_CONTROLREG) 1108201360Srdivacky TYPE("offset8", TYPE_MOFFS8) 1109201360Srdivacky TYPE("offset16", TYPE_MOFFS16) 1110201360Srdivacky TYPE("offset32", TYPE_MOFFS32) 1111201360Srdivacky TYPE("offset64", TYPE_MOFFS64) 1112221345Sdim TYPE("VR256", TYPE_XMM256) 1113226633Sdim TYPE("GR16_NOAX", TYPE_Rv) 1114226633Sdim TYPE("GR32_NOAX", TYPE_Rv) 1115226633Sdim TYPE("GR64_NOAX", TYPE_R64) 1116239462Sdim TYPE("vx32mem", TYPE_M32) 1117239462Sdim TYPE("vy32mem", TYPE_M32) 1118239462Sdim TYPE("vx64mem", TYPE_M64) 1119239462Sdim TYPE("vy64mem", TYPE_M64) 1120201360Srdivacky errs() << "Unhandled type string " << s << "\n"; 1121201360Srdivacky llvm_unreachable("Unhandled type string"); 1122201360Srdivacky} 1123201360Srdivacky#undef TYPE 1124201360Srdivacky 1125201360Srdivacky#define ENCODING(str, encoding) if (s == str) return encoding; 1126201360SrdivackyOperandEncoding RecognizableInstr::immediateEncodingFromString 1127201360Srdivacky (const std::string &s, 1128201360Srdivacky bool hasOpSizePrefix) { 1129201360Srdivacky if(!hasOpSizePrefix) { 1130201360Srdivacky // For instructions without an OpSize prefix, a declared 16-bit register or 1131201360Srdivacky // immediate encoding is special. 1132201360Srdivacky ENCODING("i16imm", ENCODING_IW) 1133201360Srdivacky } 1134201360Srdivacky ENCODING("i32i8imm", ENCODING_IB) 1135226633Sdim ENCODING("u32u8imm", ENCODING_IB) 1136201360Srdivacky ENCODING("SSECC", ENCODING_IB) 1137234353Sdim ENCODING("AVXCC", ENCODING_IB) 1138201360Srdivacky ENCODING("i16imm", ENCODING_Iv) 1139201360Srdivacky ENCODING("i16i8imm", ENCODING_IB) 1140201360Srdivacky ENCODING("i32imm", ENCODING_Iv) 1141201360Srdivacky ENCODING("i64i32imm", ENCODING_ID) 1142201360Srdivacky ENCODING("i64i8imm", ENCODING_IB) 1143201360Srdivacky ENCODING("i8imm", ENCODING_IB) 1144221345Sdim // This is not a typo. Instructions like BLENDVPD put 1145221345Sdim // register IDs in 8-bit immediates nowadays. 1146221345Sdim ENCODING("VR256", ENCODING_IB) 1147221345Sdim ENCODING("VR128", ENCODING_IB) 1148243830Sdim ENCODING("FR32", ENCODING_IB) 1149243830Sdim ENCODING("FR64", ENCODING_IB) 1150201360Srdivacky errs() << "Unhandled immediate encoding " << s << "\n"; 1151201360Srdivacky llvm_unreachable("Unhandled immediate encoding"); 1152201360Srdivacky} 1153201360Srdivacky 1154201360SrdivackyOperandEncoding RecognizableInstr::rmRegisterEncodingFromString 1155201360Srdivacky (const std::string &s, 1156201360Srdivacky bool hasOpSizePrefix) { 1157201360Srdivacky ENCODING("GR16", ENCODING_RM) 1158201360Srdivacky ENCODING("GR32", ENCODING_RM) 1159201360Srdivacky ENCODING("GR64", ENCODING_RM) 1160201360Srdivacky ENCODING("GR8", ENCODING_RM) 1161201360Srdivacky ENCODING("VR128", ENCODING_RM) 1162201360Srdivacky ENCODING("FR64", ENCODING_RM) 1163201360Srdivacky ENCODING("FR32", ENCODING_RM) 1164201360Srdivacky ENCODING("VR64", ENCODING_RM) 1165221345Sdim ENCODING("VR256", ENCODING_RM) 1166201360Srdivacky errs() << "Unhandled R/M register encoding " << s << "\n"; 1167201360Srdivacky llvm_unreachable("Unhandled R/M register encoding"); 1168201360Srdivacky} 1169201360Srdivacky 1170201360SrdivackyOperandEncoding RecognizableInstr::roRegisterEncodingFromString 1171201360Srdivacky (const std::string &s, 1172201360Srdivacky bool hasOpSizePrefix) { 1173201360Srdivacky ENCODING("GR16", ENCODING_REG) 1174201360Srdivacky ENCODING("GR32", ENCODING_REG) 1175201360Srdivacky ENCODING("GR64", ENCODING_REG) 1176201360Srdivacky ENCODING("GR8", ENCODING_REG) 1177201360Srdivacky ENCODING("VR128", ENCODING_REG) 1178201360Srdivacky ENCODING("FR64", ENCODING_REG) 1179201360Srdivacky ENCODING("FR32", ENCODING_REG) 1180201360Srdivacky ENCODING("VR64", ENCODING_REG) 1181201360Srdivacky ENCODING("SEGMENT_REG", ENCODING_REG) 1182201360Srdivacky ENCODING("DEBUG_REG", ENCODING_REG) 1183208599Srdivacky ENCODING("CONTROL_REG", ENCODING_REG) 1184221345Sdim ENCODING("VR256", ENCODING_REG) 1185201360Srdivacky errs() << "Unhandled reg/opcode register encoding " << s << "\n"; 1186201360Srdivacky llvm_unreachable("Unhandled reg/opcode register encoding"); 1187201360Srdivacky} 1188201360Srdivacky 1189221345SdimOperandEncoding RecognizableInstr::vvvvRegisterEncodingFromString 1190221345Sdim (const std::string &s, 1191221345Sdim bool hasOpSizePrefix) { 1192226633Sdim ENCODING("GR32", ENCODING_VVVV) 1193226633Sdim ENCODING("GR64", ENCODING_VVVV) 1194221345Sdim ENCODING("FR32", ENCODING_VVVV) 1195221345Sdim ENCODING("FR64", ENCODING_VVVV) 1196221345Sdim ENCODING("VR128", ENCODING_VVVV) 1197221345Sdim ENCODING("VR256", ENCODING_VVVV) 1198221345Sdim errs() << "Unhandled VEX.vvvv register encoding " << s << "\n"; 1199221345Sdim llvm_unreachable("Unhandled VEX.vvvv register encoding"); 1200221345Sdim} 1201221345Sdim 1202201360SrdivackyOperandEncoding RecognizableInstr::memoryEncodingFromString 1203201360Srdivacky (const std::string &s, 1204201360Srdivacky bool hasOpSizePrefix) { 1205201360Srdivacky ENCODING("i16mem", ENCODING_RM) 1206201360Srdivacky ENCODING("i32mem", ENCODING_RM) 1207201360Srdivacky ENCODING("i64mem", ENCODING_RM) 1208201360Srdivacky ENCODING("i8mem", ENCODING_RM) 1209218893Sdim ENCODING("ssmem", ENCODING_RM) 1210218893Sdim ENCODING("sdmem", ENCODING_RM) 1211201360Srdivacky ENCODING("f128mem", ENCODING_RM) 1212218893Sdim ENCODING("f256mem", ENCODING_RM) 1213201360Srdivacky ENCODING("f64mem", ENCODING_RM) 1214201360Srdivacky ENCODING("f32mem", ENCODING_RM) 1215201360Srdivacky ENCODING("i128mem", ENCODING_RM) 1216221345Sdim ENCODING("i256mem", ENCODING_RM) 1217201360Srdivacky ENCODING("f80mem", ENCODING_RM) 1218201360Srdivacky ENCODING("lea32mem", ENCODING_RM) 1219201360Srdivacky ENCODING("lea64_32mem", ENCODING_RM) 1220201360Srdivacky ENCODING("lea64mem", ENCODING_RM) 1221201360Srdivacky ENCODING("opaque32mem", ENCODING_RM) 1222201360Srdivacky ENCODING("opaque48mem", ENCODING_RM) 1223201360Srdivacky ENCODING("opaque80mem", ENCODING_RM) 1224201360Srdivacky ENCODING("opaque512mem", ENCODING_RM) 1225239462Sdim ENCODING("vx32mem", ENCODING_RM) 1226239462Sdim ENCODING("vy32mem", ENCODING_RM) 1227239462Sdim ENCODING("vx64mem", ENCODING_RM) 1228239462Sdim ENCODING("vy64mem", ENCODING_RM) 1229201360Srdivacky errs() << "Unhandled memory encoding " << s << "\n"; 1230201360Srdivacky llvm_unreachable("Unhandled memory encoding"); 1231201360Srdivacky} 1232201360Srdivacky 1233201360SrdivackyOperandEncoding RecognizableInstr::relocationEncodingFromString 1234201360Srdivacky (const std::string &s, 1235201360Srdivacky bool hasOpSizePrefix) { 1236201360Srdivacky if(!hasOpSizePrefix) { 1237201360Srdivacky // For instructions without an OpSize prefix, a declared 16-bit register or 1238201360Srdivacky // immediate encoding is special. 1239201360Srdivacky ENCODING("i16imm", ENCODING_IW) 1240201360Srdivacky } 1241201360Srdivacky ENCODING("i16imm", ENCODING_Iv) 1242201360Srdivacky ENCODING("i16i8imm", ENCODING_IB) 1243201360Srdivacky ENCODING("i32imm", ENCODING_Iv) 1244201360Srdivacky ENCODING("i32i8imm", ENCODING_IB) 1245201360Srdivacky ENCODING("i64i32imm", ENCODING_ID) 1246201360Srdivacky ENCODING("i64i8imm", ENCODING_IB) 1247201360Srdivacky ENCODING("i8imm", ENCODING_IB) 1248201360Srdivacky ENCODING("i64i32imm_pcrel", ENCODING_ID) 1249210299Sed ENCODING("i16imm_pcrel", ENCODING_IW) 1250201360Srdivacky ENCODING("i32imm_pcrel", ENCODING_ID) 1251201360Srdivacky ENCODING("brtarget", ENCODING_Iv) 1252201360Srdivacky ENCODING("brtarget8", ENCODING_IB) 1253201360Srdivacky ENCODING("i64imm", ENCODING_IO) 1254201360Srdivacky ENCODING("offset8", ENCODING_Ia) 1255201360Srdivacky ENCODING("offset16", ENCODING_Ia) 1256201360Srdivacky ENCODING("offset32", ENCODING_Ia) 1257201360Srdivacky ENCODING("offset64", ENCODING_Ia) 1258201360Srdivacky errs() << "Unhandled relocation encoding " << s << "\n"; 1259201360Srdivacky llvm_unreachable("Unhandled relocation encoding"); 1260201360Srdivacky} 1261201360Srdivacky 1262201360SrdivackyOperandEncoding RecognizableInstr::opcodeModifierEncodingFromString 1263201360Srdivacky (const std::string &s, 1264201360Srdivacky bool hasOpSizePrefix) { 1265201360Srdivacky ENCODING("RST", ENCODING_I) 1266201360Srdivacky ENCODING("GR32", ENCODING_Rv) 1267201360Srdivacky ENCODING("GR64", ENCODING_RO) 1268201360Srdivacky ENCODING("GR16", ENCODING_Rv) 1269201360Srdivacky ENCODING("GR8", ENCODING_RB) 1270226633Sdim ENCODING("GR16_NOAX", ENCODING_Rv) 1271226633Sdim ENCODING("GR32_NOAX", ENCODING_Rv) 1272226633Sdim ENCODING("GR64_NOAX", ENCODING_RO) 1273201360Srdivacky errs() << "Unhandled opcode modifier encoding " << s << "\n"; 1274201360Srdivacky llvm_unreachable("Unhandled opcode modifier encoding"); 1275201360Srdivacky} 1276201360Srdivacky#undef ENCODING 1277