X86RecognizableInstr.cpp revision 261991
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, 82261991Sdim A6 = 15, A7 = 16, T8XD = 17, T8XS = 18, TAXD = 19, 83261991Sdim XOP8 = 20, XOP9 = 21, XOPA = 22 84201360Srdivacky }; 85201360Srdivacky} 86203954Srdivacky 87203954Srdivacky// If rows are added to the opcode extension tables, then corresponding entries 88239462Sdim// must be added here. 89203954Srdivacky// 90203954Srdivacky// If the row corresponds to a single byte (i.e., 8f), then add an entry for 91203954Srdivacky// that byte to ONE_BYTE_EXTENSION_TABLES. 92203954Srdivacky// 93239462Sdim// If the row corresponds to two bytes where the first is 0f, add an entry for 94203954Srdivacky// the second byte to TWO_BYTE_EXTENSION_TABLES. 95203954Srdivacky// 96203954Srdivacky// If the row corresponds to some other set of bytes, you will need to modify 97203954Srdivacky// the code in RecognizableInstr::emitDecodePath() as well, and add new prefixes 98239462Sdim// to the X86 TD files, except in two cases: if the first two bytes of such a 99203954Srdivacky// new combination are 0f 38 or 0f 3a, you just have to add maps called 100203954Srdivacky// THREE_BYTE_38_EXTENSION_TABLES and THREE_BYTE_3A_EXTENSION_TABLES and add a 101203954Srdivacky// switch(Opcode) just below the case X86Local::T8: or case X86Local::TA: line 102203954Srdivacky// in RecognizableInstr::emitDecodePath(). 103203954Srdivacky 104201360Srdivacky#define ONE_BYTE_EXTENSION_TABLES \ 105201360Srdivacky EXTENSION_TABLE(80) \ 106201360Srdivacky EXTENSION_TABLE(81) \ 107201360Srdivacky EXTENSION_TABLE(82) \ 108201360Srdivacky EXTENSION_TABLE(83) \ 109201360Srdivacky EXTENSION_TABLE(8f) \ 110201360Srdivacky EXTENSION_TABLE(c0) \ 111201360Srdivacky EXTENSION_TABLE(c1) \ 112201360Srdivacky EXTENSION_TABLE(c6) \ 113201360Srdivacky EXTENSION_TABLE(c7) \ 114201360Srdivacky EXTENSION_TABLE(d0) \ 115201360Srdivacky EXTENSION_TABLE(d1) \ 116201360Srdivacky EXTENSION_TABLE(d2) \ 117201360Srdivacky EXTENSION_TABLE(d3) \ 118201360Srdivacky EXTENSION_TABLE(f6) \ 119201360Srdivacky EXTENSION_TABLE(f7) \ 120201360Srdivacky EXTENSION_TABLE(fe) \ 121201360Srdivacky EXTENSION_TABLE(ff) 122239462Sdim 123201360Srdivacky#define TWO_BYTE_EXTENSION_TABLES \ 124201360Srdivacky EXTENSION_TABLE(00) \ 125201360Srdivacky EXTENSION_TABLE(01) \ 126249423Sdim EXTENSION_TABLE(0d) \ 127201360Srdivacky EXTENSION_TABLE(18) \ 128201360Srdivacky EXTENSION_TABLE(71) \ 129201360Srdivacky EXTENSION_TABLE(72) \ 130201360Srdivacky EXTENSION_TABLE(73) \ 131201360Srdivacky EXTENSION_TABLE(ae) \ 132201360Srdivacky EXTENSION_TABLE(ba) \ 133201360Srdivacky EXTENSION_TABLE(c7) 134201360Srdivacky 135234353Sdim#define THREE_BYTE_38_EXTENSION_TABLES \ 136234353Sdim EXTENSION_TABLE(F3) 137234353Sdim 138261991Sdim#define XOP9_MAP_EXTENSION_TABLES \ 139261991Sdim EXTENSION_TABLE(01) \ 140261991Sdim EXTENSION_TABLE(02) 141261991Sdim 142201360Srdivackyusing namespace X86Disassembler; 143201360Srdivacky 144201360Srdivacky/// needsModRMForDecode - Indicates whether a particular instruction requires a 145239462Sdim/// ModR/M byte for the instruction to be properly decoded. For example, a 146201360Srdivacky/// MRMDestReg instruction needs the Mod field in the ModR/M byte to be set to 147201360Srdivacky/// 0b11. 148201360Srdivacky/// 149201360Srdivacky/// @param form - The form of the instruction. 150201360Srdivacky/// @return - true if the form implies that a ModR/M byte is required, false 151201360Srdivacky/// otherwise. 152201360Srdivackystatic bool needsModRMForDecode(uint8_t form) { 153201360Srdivacky if (form == X86Local::MRMDestReg || 154201360Srdivacky form == X86Local::MRMDestMem || 155201360Srdivacky form == X86Local::MRMSrcReg || 156201360Srdivacky form == X86Local::MRMSrcMem || 157201360Srdivacky (form >= X86Local::MRM0r && form <= X86Local::MRM7r) || 158201360Srdivacky (form >= X86Local::MRM0m && form <= X86Local::MRM7m)) 159201360Srdivacky return true; 160201360Srdivacky else 161201360Srdivacky return false; 162201360Srdivacky} 163201360Srdivacky 164201360Srdivacky/// isRegFormat - Indicates whether a particular form requires the Mod field of 165201360Srdivacky/// the ModR/M byte to be 0b11. 166201360Srdivacky/// 167201360Srdivacky/// @param form - The form of the instruction. 168201360Srdivacky/// @return - true if the form implies that Mod must be 0b11, false 169201360Srdivacky/// otherwise. 170201360Srdivackystatic bool isRegFormat(uint8_t form) { 171201360Srdivacky if (form == X86Local::MRMDestReg || 172201360Srdivacky form == X86Local::MRMSrcReg || 173201360Srdivacky (form >= X86Local::MRM0r && form <= X86Local::MRM7r)) 174201360Srdivacky return true; 175201360Srdivacky else 176201360Srdivacky return false; 177201360Srdivacky} 178201360Srdivacky 179201360Srdivacky/// byteFromBitsInit - Extracts a value at most 8 bits in width from a BitsInit. 180201360Srdivacky/// Useful for switch statements and the like. 181201360Srdivacky/// 182201360Srdivacky/// @param init - A reference to the BitsInit to be decoded. 183201360Srdivacky/// @return - The field, with the first bit in the BitsInit as the lowest 184201360Srdivacky/// order bit. 185201360Srdivackystatic uint8_t byteFromBitsInit(BitsInit &init) { 186201360Srdivacky int width = init.getNumBits(); 187201360Srdivacky 188201360Srdivacky assert(width <= 8 && "Field is too large for uint8_t!"); 189201360Srdivacky 190201360Srdivacky int index; 191201360Srdivacky uint8_t mask = 0x01; 192201360Srdivacky 193201360Srdivacky uint8_t ret = 0; 194201360Srdivacky 195201360Srdivacky for (index = 0; index < width; index++) { 196201360Srdivacky if (static_cast<BitInit*>(init.getBit(index))->getValue()) 197201360Srdivacky ret |= mask; 198201360Srdivacky 199201360Srdivacky mask <<= 1; 200201360Srdivacky } 201201360Srdivacky 202201360Srdivacky return ret; 203201360Srdivacky} 204201360Srdivacky 205201360Srdivacky/// byteFromRec - Extract a value at most 8 bits in with from a Record given the 206201360Srdivacky/// name of the field. 207201360Srdivacky/// 208201360Srdivacky/// @param rec - The record from which to extract the value. 209201360Srdivacky/// @param name - The name of the field in the record. 210201360Srdivacky/// @return - The field, as translated by byteFromBitsInit(). 211201360Srdivackystatic uint8_t byteFromRec(const Record* rec, const std::string &name) { 212201360Srdivacky BitsInit* bits = rec->getValueAsBitsInit(name); 213201360Srdivacky return byteFromBitsInit(*bits); 214201360Srdivacky} 215201360Srdivacky 216201360SrdivackyRecognizableInstr::RecognizableInstr(DisassemblerTables &tables, 217201360Srdivacky const CodeGenInstruction &insn, 218201360Srdivacky InstrUID uid) { 219201360Srdivacky UID = uid; 220201360Srdivacky 221201360Srdivacky Rec = insn.TheDef; 222201360Srdivacky Name = Rec->getName(); 223201360Srdivacky Spec = &tables.specForUID(UID); 224239462Sdim 225201360Srdivacky if (!Rec->isSubClassOf("X86Inst")) { 226201360Srdivacky ShouldBeEmitted = false; 227201360Srdivacky return; 228201360Srdivacky } 229239462Sdim 230201360Srdivacky Prefix = byteFromRec(Rec, "Prefix"); 231201360Srdivacky Opcode = byteFromRec(Rec, "Opcode"); 232201360Srdivacky Form = byteFromRec(Rec, "FormBits"); 233201360Srdivacky SegOvr = byteFromRec(Rec, "SegOvrBits"); 234239462Sdim 235201360Srdivacky HasOpSizePrefix = Rec->getValueAsBit("hasOpSizePrefix"); 236234353Sdim HasAdSizePrefix = Rec->getValueAsBit("hasAdSizePrefix"); 237201360Srdivacky HasREX_WPrefix = Rec->getValueAsBit("hasREX_WPrefix"); 238221345Sdim HasVEXPrefix = Rec->getValueAsBit("hasVEXPrefix"); 239210299Sed HasVEX_4VPrefix = Rec->getValueAsBit("hasVEX_4VPrefix"); 240234353Sdim HasVEX_4VOp3Prefix = Rec->getValueAsBit("hasVEX_4VOp3Prefix"); 241221345Sdim HasVEX_WPrefix = Rec->getValueAsBit("hasVEX_WPrefix"); 242234353Sdim HasMemOp4Prefix = Rec->getValueAsBit("hasMemOp4Prefix"); 243226633Sdim IgnoresVEX_L = Rec->getValueAsBit("ignoresVEX_L"); 244261991Sdim HasEVEXPrefix = Rec->getValueAsBit("hasEVEXPrefix"); 245261991Sdim HasEVEX_L2Prefix = Rec->getValueAsBit("hasEVEX_L2"); 246261991Sdim HasEVEX_K = Rec->getValueAsBit("hasEVEX_K"); 247261991Sdim HasEVEX_KZ = Rec->getValueAsBit("hasEVEX_Z"); 248261991Sdim HasEVEX_B = Rec->getValueAsBit("hasEVEX_B"); 249201360Srdivacky HasLockPrefix = Rec->getValueAsBit("hasLockPrefix"); 250201360Srdivacky IsCodeGenOnly = Rec->getValueAsBit("isCodeGenOnly"); 251239462Sdim 252201360Srdivacky Name = Rec->getName(); 253201360Srdivacky AsmString = Rec->getValueAsString("AsmString"); 254239462Sdim 255218893Sdim Operands = &insn.Operands.OperandList; 256239462Sdim 257226633Sdim IsSSE = (HasOpSizePrefix && (Name.find("16") == Name.npos)) || 258226633Sdim (Name.find("CRC32") != Name.npos); 259221345Sdim HasFROperands = hasFROperands(); 260243830Sdim HasVEX_LPrefix = Rec->getValueAsBit("hasVEX_L"); 261234353Sdim 262224145Sdim // Check for 64-bit inst which does not require REX 263226633Sdim Is32Bit = false; 264224145Sdim Is64Bit = false; 265224145Sdim // FIXME: Is there some better way to check for In64BitMode? 266224145Sdim std::vector<Record*> Predicates = Rec->getValueAsListOfDefs("Predicates"); 267224145Sdim for (unsigned i = 0, e = Predicates.size(); i != e; ++i) { 268226633Sdim if (Predicates[i]->getName().find("32Bit") != Name.npos) { 269226633Sdim Is32Bit = true; 270226633Sdim break; 271226633Sdim } 272224145Sdim if (Predicates[i]->getName().find("64Bit") != Name.npos) { 273224145Sdim Is64Bit = true; 274224145Sdim break; 275224145Sdim } 276224145Sdim } 277224145Sdim // FIXME: These instructions aren't marked as 64-bit in any way 278239462Sdim Is64Bit |= Rec->getName() == "JMP64pcrel32" || 279239462Sdim Rec->getName() == "MASKMOVDQU64" || 280239462Sdim Rec->getName() == "POPFS64" || 281239462Sdim Rec->getName() == "POPGS64" || 282239462Sdim Rec->getName() == "PUSHFS64" || 283224145Sdim Rec->getName() == "PUSHGS64" || 284224145Sdim Rec->getName() == "REX64_PREFIX" || 285239462Sdim Rec->getName().find("MOV64") != Name.npos || 286224145Sdim Rec->getName().find("PUSH64") != Name.npos || 287224145Sdim Rec->getName().find("POP64") != Name.npos; 288224145Sdim 289201360Srdivacky ShouldBeEmitted = true; 290201360Srdivacky} 291239462Sdim 292201360Srdivackyvoid RecognizableInstr::processInstr(DisassemblerTables &tables, 293239462Sdim const CodeGenInstruction &insn, 294239462Sdim InstrUID uid) 295201360Srdivacky{ 296208599Srdivacky // Ignore "asm parser only" instructions. 297208599Srdivacky if (insn.TheDef->getValueAsBit("isAsmParserOnly")) 298208599Srdivacky return; 299239462Sdim 300201360Srdivacky RecognizableInstr recogInstr(tables, insn, uid); 301239462Sdim 302201360Srdivacky recogInstr.emitInstructionSpecifier(tables); 303239462Sdim 304201360Srdivacky if (recogInstr.shouldBeEmitted()) 305201360Srdivacky recogInstr.emitDecodePath(tables); 306201360Srdivacky} 307201360Srdivacky 308261991Sdim#define EVEX_KB(n) (HasEVEX_KZ && HasEVEX_B ? n##_KZ_B : \ 309261991Sdim (HasEVEX_K && HasEVEX_B ? n##_K_B : \ 310261991Sdim (HasEVEX_KZ ? n##_KZ : \ 311261991Sdim (HasEVEX_K? n##_K : (HasEVEX_B ? n##_B : n))))) 312261991Sdim 313201360SrdivackyInstructionContext RecognizableInstr::insnContext() const { 314201360Srdivacky InstructionContext insnContext; 315201360Srdivacky 316261991Sdim if (HasEVEXPrefix) { 317261991Sdim if (HasVEX_LPrefix && HasEVEX_L2Prefix) { 318261991Sdim errs() << "Don't support VEX.L if EVEX_L2 is enabled: " << Name << "\n"; 319261991Sdim llvm_unreachable("Don't support VEX.L if EVEX_L2 is enabled"); 320261991Sdim } 321261991Sdim // VEX_L & VEX_W 322234353Sdim if (HasVEX_LPrefix && HasVEX_WPrefix) { 323234353Sdim if (HasOpSizePrefix) 324261991Sdim insnContext = EVEX_KB(IC_EVEX_L_W_OPSIZE); 325261991Sdim else if (Prefix == X86Local::XS || Prefix == X86Local::T8XS) 326261991Sdim insnContext = EVEX_KB(IC_EVEX_L_W_XS); 327261991Sdim else if (Prefix == X86Local::XD || Prefix == X86Local::T8XD || 328261991Sdim Prefix == X86Local::TAXD) 329261991Sdim insnContext = EVEX_KB(IC_EVEX_L_W_XD); 330261991Sdim else 331261991Sdim insnContext = EVEX_KB(IC_EVEX_L_W); 332261991Sdim } else if (HasVEX_LPrefix) { 333261991Sdim // VEX_L 334261991Sdim if (HasOpSizePrefix) 335261991Sdim insnContext = EVEX_KB(IC_EVEX_L_OPSIZE); 336261991Sdim else if (Prefix == X86Local::XS || Prefix == X86Local::T8XS) 337261991Sdim insnContext = EVEX_KB(IC_EVEX_L_XS); 338261991Sdim else if (Prefix == X86Local::XD || Prefix == X86Local::T8XD || 339261991Sdim Prefix == X86Local::TAXD) 340261991Sdim insnContext = EVEX_KB(IC_EVEX_L_XD); 341261991Sdim else 342261991Sdim insnContext = EVEX_KB(IC_EVEX_L); 343261991Sdim } 344261991Sdim else if (HasEVEX_L2Prefix && HasVEX_WPrefix) { 345261991Sdim // EVEX_L2 & VEX_W 346261991Sdim if (HasOpSizePrefix) 347261991Sdim insnContext = EVEX_KB(IC_EVEX_L2_W_OPSIZE); 348261991Sdim else if (Prefix == X86Local::XS || Prefix == X86Local::T8XS) 349261991Sdim insnContext = EVEX_KB(IC_EVEX_L2_W_XS); 350261991Sdim else if (Prefix == X86Local::XD || Prefix == X86Local::T8XD || 351261991Sdim Prefix == X86Local::TAXD) 352261991Sdim insnContext = EVEX_KB(IC_EVEX_L2_W_XD); 353261991Sdim else 354261991Sdim insnContext = EVEX_KB(IC_EVEX_L2_W); 355261991Sdim } else if (HasEVEX_L2Prefix) { 356261991Sdim // EVEX_L2 357261991Sdim if (HasOpSizePrefix) 358261991Sdim insnContext = EVEX_KB(IC_EVEX_L2_OPSIZE); 359261991Sdim else if (Prefix == X86Local::XD || Prefix == X86Local::T8XD || 360261991Sdim Prefix == X86Local::TAXD) 361261991Sdim insnContext = EVEX_KB(IC_EVEX_L2_XD); 362261991Sdim else if (Prefix == X86Local::XS || Prefix == X86Local::T8XS) 363261991Sdim insnContext = EVEX_KB(IC_EVEX_L2_XS); 364261991Sdim else 365261991Sdim insnContext = EVEX_KB(IC_EVEX_L2); 366261991Sdim } 367261991Sdim else if (HasVEX_WPrefix) { 368261991Sdim // VEX_W 369261991Sdim if (HasOpSizePrefix) 370261991Sdim insnContext = EVEX_KB(IC_EVEX_W_OPSIZE); 371261991Sdim else if (Prefix == X86Local::XS || Prefix == X86Local::T8XS) 372261991Sdim insnContext = EVEX_KB(IC_EVEX_W_XS); 373261991Sdim else if (Prefix == X86Local::XD || Prefix == X86Local::T8XD || 374261991Sdim Prefix == X86Local::TAXD) 375261991Sdim insnContext = EVEX_KB(IC_EVEX_W_XD); 376261991Sdim else 377261991Sdim insnContext = EVEX_KB(IC_EVEX_W); 378261991Sdim } 379261991Sdim // No L, no W 380261991Sdim else if (HasOpSizePrefix) 381261991Sdim insnContext = EVEX_KB(IC_EVEX_OPSIZE); 382261991Sdim else if (Prefix == X86Local::XD || Prefix == X86Local::T8XD || 383261991Sdim Prefix == X86Local::TAXD) 384261991Sdim insnContext = EVEX_KB(IC_EVEX_XD); 385261991Sdim else if (Prefix == X86Local::XS || Prefix == X86Local::T8XS) 386261991Sdim insnContext = EVEX_KB(IC_EVEX_XS); 387261991Sdim else 388261991Sdim insnContext = EVEX_KB(IC_EVEX); 389261991Sdim /// eof EVEX 390261991Sdim } else if (HasVEX_4VPrefix || HasVEX_4VOp3Prefix|| HasVEXPrefix) { 391261991Sdim if (HasVEX_LPrefix && HasVEX_WPrefix) { 392261991Sdim if (HasOpSizePrefix) 393234353Sdim insnContext = IC_VEX_L_W_OPSIZE; 394261991Sdim else if (Prefix == X86Local::XS || Prefix == X86Local::T8XS) 395261991Sdim insnContext = IC_VEX_L_W_XS; 396261991Sdim else if (Prefix == X86Local::XD || Prefix == X86Local::T8XD || 397261991Sdim Prefix == X86Local::TAXD) 398261991Sdim insnContext = IC_VEX_L_W_XD; 399234353Sdim else 400261991Sdim insnContext = IC_VEX_L_W; 401234353Sdim } else if (HasOpSizePrefix && HasVEX_LPrefix) 402221345Sdim insnContext = IC_VEX_L_OPSIZE; 403221345Sdim else if (HasOpSizePrefix && HasVEX_WPrefix) 404221345Sdim insnContext = IC_VEX_W_OPSIZE; 405221345Sdim else if (HasOpSizePrefix) 406221345Sdim insnContext = IC_VEX_OPSIZE; 407234353Sdim else if (HasVEX_LPrefix && 408234353Sdim (Prefix == X86Local::XS || Prefix == X86Local::T8XS)) 409221345Sdim insnContext = IC_VEX_L_XS; 410234353Sdim else if (HasVEX_LPrefix && (Prefix == X86Local::XD || 411234353Sdim Prefix == X86Local::T8XD || 412234353Sdim Prefix == X86Local::TAXD)) 413221345Sdim insnContext = IC_VEX_L_XD; 414234353Sdim else if (HasVEX_WPrefix && 415234353Sdim (Prefix == X86Local::XS || Prefix == X86Local::T8XS)) 416221345Sdim insnContext = IC_VEX_W_XS; 417234353Sdim else if (HasVEX_WPrefix && (Prefix == X86Local::XD || 418234353Sdim Prefix == X86Local::T8XD || 419234353Sdim Prefix == X86Local::TAXD)) 420221345Sdim insnContext = IC_VEX_W_XD; 421221345Sdim else if (HasVEX_WPrefix) 422221345Sdim insnContext = IC_VEX_W; 423221345Sdim else if (HasVEX_LPrefix) 424221345Sdim insnContext = IC_VEX_L; 425234353Sdim else if (Prefix == X86Local::XD || Prefix == X86Local::T8XD || 426234353Sdim Prefix == X86Local::TAXD) 427221345Sdim insnContext = IC_VEX_XD; 428234353Sdim else if (Prefix == X86Local::XS || Prefix == X86Local::T8XS) 429221345Sdim insnContext = IC_VEX_XS; 430221345Sdim else 431221345Sdim insnContext = IC_VEX; 432224145Sdim } else if (Is64Bit || HasREX_WPrefix) { 433201360Srdivacky if (HasREX_WPrefix && HasOpSizePrefix) 434201360Srdivacky insnContext = IC_64BIT_REXW_OPSIZE; 435234353Sdim else if (HasOpSizePrefix && (Prefix == X86Local::XD || 436234353Sdim Prefix == X86Local::T8XD || 437234353Sdim Prefix == X86Local::TAXD)) 438234353Sdim insnContext = IC_64BIT_XD_OPSIZE; 439226633Sdim else if (HasOpSizePrefix && 440234353Sdim (Prefix == X86Local::XS || Prefix == X86Local::T8XS)) 441226633Sdim insnContext = IC_64BIT_XS_OPSIZE; 442201360Srdivacky else if (HasOpSizePrefix) 443201360Srdivacky insnContext = IC_64BIT_OPSIZE; 444234353Sdim else if (HasAdSizePrefix) 445234353Sdim insnContext = IC_64BIT_ADSIZE; 446234353Sdim else if (HasREX_WPrefix && 447234353Sdim (Prefix == X86Local::XS || Prefix == X86Local::T8XS)) 448201360Srdivacky insnContext = IC_64BIT_REXW_XS; 449234353Sdim else if (HasREX_WPrefix && (Prefix == X86Local::XD || 450234353Sdim Prefix == X86Local::T8XD || 451234353Sdim Prefix == X86Local::TAXD)) 452201360Srdivacky insnContext = IC_64BIT_REXW_XD; 453234353Sdim else if (Prefix == X86Local::XD || Prefix == X86Local::T8XD || 454234353Sdim Prefix == X86Local::TAXD) 455201360Srdivacky insnContext = IC_64BIT_XD; 456234353Sdim else if (Prefix == X86Local::XS || Prefix == X86Local::T8XS) 457201360Srdivacky insnContext = IC_64BIT_XS; 458201360Srdivacky else if (HasREX_WPrefix) 459201360Srdivacky insnContext = IC_64BIT_REXW; 460201360Srdivacky else 461201360Srdivacky insnContext = IC_64BIT; 462201360Srdivacky } else { 463234353Sdim if (HasOpSizePrefix && (Prefix == X86Local::XD || 464234353Sdim Prefix == X86Local::T8XD || 465234353Sdim Prefix == X86Local::TAXD)) 466226633Sdim insnContext = IC_XD_OPSIZE; 467234353Sdim else if (HasOpSizePrefix && 468234353Sdim (Prefix == X86Local::XS || Prefix == X86Local::T8XS)) 469226633Sdim insnContext = IC_XS_OPSIZE; 470226633Sdim else if (HasOpSizePrefix) 471201360Srdivacky insnContext = IC_OPSIZE; 472234353Sdim else if (HasAdSizePrefix) 473234353Sdim insnContext = IC_ADSIZE; 474234353Sdim else if (Prefix == X86Local::XD || Prefix == X86Local::T8XD || 475234353Sdim Prefix == X86Local::TAXD) 476201360Srdivacky insnContext = IC_XD; 477234353Sdim else if (Prefix == X86Local::XS || Prefix == X86Local::T8XS || 478234353Sdim Prefix == X86Local::REP) 479201360Srdivacky insnContext = IC_XS; 480201360Srdivacky else 481201360Srdivacky insnContext = IC; 482201360Srdivacky } 483201360Srdivacky 484201360Srdivacky return insnContext; 485201360Srdivacky} 486239462Sdim 487201360SrdivackyRecognizableInstr::filter_ret RecognizableInstr::filter() const { 488221345Sdim /////////////////// 489221345Sdim // FILTER_STRONG 490221345Sdim // 491239462Sdim 492201360Srdivacky // Filter out intrinsics 493239462Sdim 494239462Sdim assert(Rec->isSubClassOf("X86Inst") && "Can only filter X86 instructions"); 495239462Sdim 496201360Srdivacky if (Form == X86Local::Pseudo || 497261991Sdim (IsCodeGenOnly && Name.find("_REV") == Name.npos && 498261991Sdim Name.find("INC32") == Name.npos && Name.find("DEC32") == Name.npos)) 499201360Srdivacky return FILTER_STRONG; 500239462Sdim 501239462Sdim 502234353Sdim // Filter out artificial instructions but leave in the LOCK_PREFIX so it is 503234353Sdim // printed as a separate "instruction". 504239462Sdim 505234353Sdim if (Name.find("_Int") != Name.npos || 506239462Sdim Name.find("Int_") != Name.npos) 507221345Sdim return FILTER_STRONG; 508221345Sdim 509221345Sdim // Filter out instructions with segment override prefixes. 510221345Sdim // They're too messy to handle now and we'll special case them if needed. 511239462Sdim 512221345Sdim if (SegOvr) 513221345Sdim return FILTER_STRONG; 514221345Sdim 515239462Sdim 516221345Sdim ///////////////// 517221345Sdim // FILTER_WEAK 518221345Sdim // 519221345Sdim 520239462Sdim 521201360Srdivacky // Filter out instructions with a LOCK prefix; 522201360Srdivacky // prefer forms that do not have the prefix 523201360Srdivacky if (HasLockPrefix) 524201360Srdivacky return FILTER_WEAK; 525201360Srdivacky 526221345Sdim // Filter out alternate forms of AVX instructions 527221345Sdim if (Name.find("_alt") != Name.npos || 528261991Sdim (Name.find("r64r") != Name.npos && Name.find("r64r64") == Name.npos && Name.find("r64r8") == Name.npos) || 529221345Sdim Name.find("_64mr") != Name.npos || 530221345Sdim Name.find("rr64") != Name.npos) 531221345Sdim return FILTER_WEAK; 532201360Srdivacky 533201360Srdivacky // Special cases. 534218893Sdim 535234353Sdim if (Name == "PUSH64i16" || 536201360Srdivacky Name == "MOVPQI2QImr" || 537221345Sdim Name == "VMOVPQI2QImr" || 538261991Sdim Name == "VMASKMOVDQU64") 539201360Srdivacky return FILTER_WEAK; 540201360Srdivacky 541261991Sdim // XACQUIRE and XRELEASE reuse REPNE and REP respectively. 542261991Sdim // For now, just prefer the REP versions. 543261991Sdim if (Name == "XACQUIRE_PREFIX" || 544261991Sdim Name == "XRELEASE_PREFIX") 545261991Sdim return FILTER_WEAK; 546201360Srdivacky 547201360Srdivacky return FILTER_NORMAL; 548201360Srdivacky} 549221345Sdim 550221345Sdimbool RecognizableInstr::hasFROperands() const { 551221345Sdim const std::vector<CGIOperandList::OperandInfo> &OperandList = *Operands; 552221345Sdim unsigned numOperands = OperandList.size(); 553221345Sdim 554221345Sdim for (unsigned operandIndex = 0; operandIndex < numOperands; ++operandIndex) { 555221345Sdim const std::string &recName = OperandList[operandIndex].Rec->getName(); 556239462Sdim 557221345Sdim if (recName.find("FR") != recName.npos) 558221345Sdim return true; 559221345Sdim } 560221345Sdim return false; 561221345Sdim} 562221345Sdim 563239462Sdimvoid RecognizableInstr::handleOperand(bool optional, unsigned &operandIndex, 564239462Sdim unsigned &physicalOperandIndex, 565239462Sdim unsigned &numPhysicalOperands, 566239462Sdim const unsigned *operandMapping, 567239462Sdim OperandEncoding (*encodingFromString) 568239462Sdim (const std::string&, 569239462Sdim bool hasOpSizePrefix)) { 570201360Srdivacky if (optional) { 571201360Srdivacky if (physicalOperandIndex >= numPhysicalOperands) 572201360Srdivacky return; 573201360Srdivacky } else { 574201360Srdivacky assert(physicalOperandIndex < numPhysicalOperands); 575201360Srdivacky } 576239462Sdim 577201360Srdivacky while (operandMapping[operandIndex] != operandIndex) { 578201360Srdivacky Spec->operands[operandIndex].encoding = ENCODING_DUP; 579201360Srdivacky Spec->operands[operandIndex].type = 580201360Srdivacky (OperandType)(TYPE_DUP0 + operandMapping[operandIndex]); 581201360Srdivacky ++operandIndex; 582201360Srdivacky } 583239462Sdim 584201360Srdivacky const std::string &typeName = (*Operands)[operandIndex].Rec->getName(); 585221345Sdim 586201360Srdivacky Spec->operands[operandIndex].encoding = encodingFromString(typeName, 587201360Srdivacky HasOpSizePrefix); 588239462Sdim Spec->operands[operandIndex].type = typeFromString(typeName, 589221345Sdim IsSSE, 590221345Sdim HasREX_WPrefix, 591221345Sdim HasOpSizePrefix); 592239462Sdim 593201360Srdivacky ++operandIndex; 594201360Srdivacky ++physicalOperandIndex; 595201360Srdivacky} 596201360Srdivacky 597201360Srdivackyvoid RecognizableInstr::emitInstructionSpecifier(DisassemblerTables &tables) { 598201360Srdivacky Spec->name = Name; 599239462Sdim 600239462Sdim if (!ShouldBeEmitted) 601201360Srdivacky return; 602239462Sdim 603201360Srdivacky switch (filter()) { 604201360Srdivacky case FILTER_WEAK: 605201360Srdivacky Spec->filtered = true; 606201360Srdivacky break; 607201360Srdivacky case FILTER_STRONG: 608201360Srdivacky ShouldBeEmitted = false; 609201360Srdivacky return; 610201360Srdivacky case FILTER_NORMAL: 611201360Srdivacky break; 612201360Srdivacky } 613239462Sdim 614201360Srdivacky Spec->insnContext = insnContext(); 615239462Sdim 616218893Sdim const std::vector<CGIOperandList::OperandInfo> &OperandList = *Operands; 617239462Sdim 618201360Srdivacky unsigned numOperands = OperandList.size(); 619201360Srdivacky unsigned numPhysicalOperands = 0; 620239462Sdim 621201360Srdivacky // operandMapping maps from operands in OperandList to their originals. 622201360Srdivacky // If operandMapping[i] != i, then the entry is a duplicate. 623201360Srdivacky unsigned operandMapping[X86_MAX_OPERANDS]; 624234353Sdim assert(numOperands <= X86_MAX_OPERANDS && "X86_MAX_OPERANDS is not large enough"); 625239462Sdim 626239462Sdim for (unsigned operandIndex = 0; operandIndex < numOperands; ++operandIndex) { 627201360Srdivacky if (OperandList[operandIndex].Constraints.size()) { 628218893Sdim const CGIOperandList::ConstraintInfo &Constraint = 629203954Srdivacky OperandList[operandIndex].Constraints[0]; 630203954Srdivacky if (Constraint.isTied()) { 631239462Sdim operandMapping[operandIndex] = operandIndex; 632239462Sdim operandMapping[Constraint.getTiedOperand()] = operandIndex; 633201360Srdivacky } else { 634201360Srdivacky ++numPhysicalOperands; 635201360Srdivacky operandMapping[operandIndex] = operandIndex; 636201360Srdivacky } 637201360Srdivacky } else { 638201360Srdivacky ++numPhysicalOperands; 639201360Srdivacky operandMapping[operandIndex] = operandIndex; 640201360Srdivacky } 641201360Srdivacky } 642201360Srdivacky 643201360Srdivacky#define HANDLE_OPERAND(class) \ 644201360Srdivacky handleOperand(false, \ 645201360Srdivacky operandIndex, \ 646201360Srdivacky physicalOperandIndex, \ 647201360Srdivacky numPhysicalOperands, \ 648201360Srdivacky operandMapping, \ 649201360Srdivacky class##EncodingFromString); 650239462Sdim 651201360Srdivacky#define HANDLE_OPTIONAL(class) \ 652201360Srdivacky handleOperand(true, \ 653201360Srdivacky operandIndex, \ 654201360Srdivacky physicalOperandIndex, \ 655201360Srdivacky numPhysicalOperands, \ 656201360Srdivacky operandMapping, \ 657201360Srdivacky class##EncodingFromString); 658239462Sdim 659201360Srdivacky // operandIndex should always be < numOperands 660239462Sdim unsigned operandIndex = 0; 661201360Srdivacky // physicalOperandIndex should always be < numPhysicalOperands 662201360Srdivacky unsigned physicalOperandIndex = 0; 663239462Sdim 664201360Srdivacky switch (Form) { 665201360Srdivacky case X86Local::RawFrm: 666201360Srdivacky // Operand 1 (optional) is an address or immediate. 667201360Srdivacky // Operand 2 (optional) is an immediate. 668239462Sdim assert(numPhysicalOperands <= 2 && 669201360Srdivacky "Unexpected number of operands for RawFrm"); 670201360Srdivacky HANDLE_OPTIONAL(relocation) 671201360Srdivacky HANDLE_OPTIONAL(immediate) 672201360Srdivacky break; 673201360Srdivacky case X86Local::AddRegFrm: 674201360Srdivacky // Operand 1 is added to the opcode. 675201360Srdivacky // Operand 2 (optional) is an address. 676201360Srdivacky assert(numPhysicalOperands >= 1 && numPhysicalOperands <= 2 && 677201360Srdivacky "Unexpected number of operands for AddRegFrm"); 678201360Srdivacky HANDLE_OPERAND(opcodeModifier) 679201360Srdivacky HANDLE_OPTIONAL(relocation) 680201360Srdivacky break; 681201360Srdivacky case X86Local::MRMDestReg: 682201360Srdivacky // Operand 1 is a register operand in the R/M field. 683201360Srdivacky // Operand 2 is a register operand in the Reg/Opcode field. 684226633Sdim // - In AVX, there is a register operand in the VEX.vvvv field here - 685201360Srdivacky // Operand 3 (optional) is an immediate. 686226633Sdim if (HasVEX_4VPrefix) 687226633Sdim assert(numPhysicalOperands >= 3 && numPhysicalOperands <= 4 && 688226633Sdim "Unexpected number of operands for MRMDestRegFrm with VEX_4V"); 689226633Sdim else 690226633Sdim assert(numPhysicalOperands >= 2 && numPhysicalOperands <= 3 && 691226633Sdim "Unexpected number of operands for MRMDestRegFrm"); 692239462Sdim 693201360Srdivacky HANDLE_OPERAND(rmRegister) 694226633Sdim 695226633Sdim if (HasVEX_4VPrefix) 696226633Sdim // FIXME: In AVX, the register below becomes the one encoded 697226633Sdim // in ModRMVEX and the one above the one in the VEX.VVVV field 698226633Sdim HANDLE_OPERAND(vvvvRegister) 699239462Sdim 700201360Srdivacky HANDLE_OPERAND(roRegister) 701201360Srdivacky HANDLE_OPTIONAL(immediate) 702201360Srdivacky break; 703201360Srdivacky case X86Local::MRMDestMem: 704201360Srdivacky // Operand 1 is a memory operand (possibly SIB-extended) 705201360Srdivacky // Operand 2 is a register operand in the Reg/Opcode field. 706226633Sdim // - In AVX, there is a register operand in the VEX.vvvv field here - 707201360Srdivacky // Operand 3 (optional) is an immediate. 708226633Sdim if (HasVEX_4VPrefix) 709226633Sdim assert(numPhysicalOperands >= 3 && numPhysicalOperands <= 4 && 710226633Sdim "Unexpected number of operands for MRMDestMemFrm with VEX_4V"); 711226633Sdim else 712226633Sdim assert(numPhysicalOperands >= 2 && numPhysicalOperands <= 3 && 713226633Sdim "Unexpected number of operands for MRMDestMemFrm"); 714201360Srdivacky HANDLE_OPERAND(memory) 715226633Sdim 716261991Sdim if (HasEVEX_K) 717261991Sdim HANDLE_OPERAND(writemaskRegister) 718261991Sdim 719226633Sdim if (HasVEX_4VPrefix) 720226633Sdim // FIXME: In AVX, the register below becomes the one encoded 721226633Sdim // in ModRMVEX and the one above the one in the VEX.VVVV field 722226633Sdim HANDLE_OPERAND(vvvvRegister) 723239462Sdim 724201360Srdivacky HANDLE_OPERAND(roRegister) 725201360Srdivacky HANDLE_OPTIONAL(immediate) 726201360Srdivacky break; 727201360Srdivacky case X86Local::MRMSrcReg: 728201360Srdivacky // Operand 1 is a register operand in the Reg/Opcode field. 729201360Srdivacky // Operand 2 is a register operand in the R/M field. 730221345Sdim // - In AVX, there is a register operand in the VEX.vvvv field here - 731201360Srdivacky // Operand 3 (optional) is an immediate. 732239462Sdim // Operand 4 (optional) is an immediate. 733210299Sed 734234353Sdim if (HasVEX_4VPrefix || HasVEX_4VOp3Prefix) 735234353Sdim assert(numPhysicalOperands >= 3 && numPhysicalOperands <= 5 && 736239462Sdim "Unexpected number of operands for MRMSrcRegFrm with VEX_4V"); 737221345Sdim else 738239462Sdim assert(numPhysicalOperands >= 2 && numPhysicalOperands <= 4 && 739221345Sdim "Unexpected number of operands for MRMSrcRegFrm"); 740239462Sdim 741221345Sdim HANDLE_OPERAND(roRegister) 742234353Sdim 743261991Sdim if (HasEVEX_K) 744261991Sdim HANDLE_OPERAND(writemaskRegister) 745261991Sdim 746221345Sdim if (HasVEX_4VPrefix) 747210299Sed // FIXME: In AVX, the register below becomes the one encoded 748210299Sed // in ModRMVEX and the one above the one in the VEX.VVVV field 749221345Sdim HANDLE_OPERAND(vvvvRegister) 750234353Sdim 751234353Sdim if (HasMemOp4Prefix) 752234353Sdim HANDLE_OPERAND(immediate) 753234353Sdim 754221345Sdim HANDLE_OPERAND(rmRegister) 755234353Sdim 756234353Sdim if (HasVEX_4VOp3Prefix) 757234353Sdim HANDLE_OPERAND(vvvvRegister) 758234353Sdim 759234353Sdim if (!HasMemOp4Prefix) 760234353Sdim HANDLE_OPTIONAL(immediate) 761234353Sdim HANDLE_OPTIONAL(immediate) // above might be a register in 7:4 762239462Sdim HANDLE_OPTIONAL(immediate) 763201360Srdivacky break; 764201360Srdivacky case X86Local::MRMSrcMem: 765201360Srdivacky // Operand 1 is a register operand in the Reg/Opcode field. 766201360Srdivacky // Operand 2 is a memory operand (possibly SIB-extended) 767221345Sdim // - In AVX, there is a register operand in the VEX.vvvv field here - 768201360Srdivacky // Operand 3 (optional) is an immediate. 769234353Sdim 770234353Sdim if (HasVEX_4VPrefix || HasVEX_4VOp3Prefix) 771234353Sdim assert(numPhysicalOperands >= 3 && numPhysicalOperands <= 5 && 772239462Sdim "Unexpected number of operands for MRMSrcMemFrm with VEX_4V"); 773221345Sdim else 774221345Sdim assert(numPhysicalOperands >= 2 && numPhysicalOperands <= 3 && 775221345Sdim "Unexpected number of operands for MRMSrcMemFrm"); 776239462Sdim 777201360Srdivacky HANDLE_OPERAND(roRegister) 778210299Sed 779261991Sdim if (HasEVEX_K) 780261991Sdim HANDLE_OPERAND(writemaskRegister) 781261991Sdim 782210299Sed if (HasVEX_4VPrefix) 783210299Sed // FIXME: In AVX, the register below becomes the one encoded 784210299Sed // in ModRMVEX and the one above the one in the VEX.VVVV field 785221345Sdim HANDLE_OPERAND(vvvvRegister) 786210299Sed 787234353Sdim if (HasMemOp4Prefix) 788234353Sdim HANDLE_OPERAND(immediate) 789234353Sdim 790201360Srdivacky HANDLE_OPERAND(memory) 791234353Sdim 792234353Sdim if (HasVEX_4VOp3Prefix) 793234353Sdim HANDLE_OPERAND(vvvvRegister) 794234353Sdim 795234353Sdim if (!HasMemOp4Prefix) 796234353Sdim HANDLE_OPTIONAL(immediate) 797234353Sdim HANDLE_OPTIONAL(immediate) // above might be a register in 7:4 798201360Srdivacky break; 799201360Srdivacky case X86Local::MRM0r: 800201360Srdivacky case X86Local::MRM1r: 801201360Srdivacky case X86Local::MRM2r: 802201360Srdivacky case X86Local::MRM3r: 803201360Srdivacky case X86Local::MRM4r: 804201360Srdivacky case X86Local::MRM5r: 805201360Srdivacky case X86Local::MRM6r: 806201360Srdivacky case X86Local::MRM7r: 807261991Sdim { 808261991Sdim // Operand 1 is a register operand in the R/M field. 809261991Sdim // Operand 2 (optional) is an immediate or relocation. 810261991Sdim // Operand 3 (optional) is an immediate. 811261991Sdim unsigned kOp = (HasEVEX_K) ? 1:0; 812261991Sdim unsigned Op4v = (HasVEX_4VPrefix) ? 1:0; 813261991Sdim if (numPhysicalOperands > 3 + kOp + Op4v) 814261991Sdim llvm_unreachable("Unexpected number of operands for MRMnr"); 815261991Sdim } 816221345Sdim if (HasVEX_4VPrefix) 817234353Sdim HANDLE_OPERAND(vvvvRegister) 818261991Sdim 819261991Sdim if (HasEVEX_K) 820261991Sdim HANDLE_OPERAND(writemaskRegister) 821201360Srdivacky HANDLE_OPTIONAL(rmRegister) 822201360Srdivacky HANDLE_OPTIONAL(relocation) 823239462Sdim HANDLE_OPTIONAL(immediate) 824201360Srdivacky break; 825201360Srdivacky case X86Local::MRM0m: 826201360Srdivacky case X86Local::MRM1m: 827201360Srdivacky case X86Local::MRM2m: 828201360Srdivacky case X86Local::MRM3m: 829201360Srdivacky case X86Local::MRM4m: 830201360Srdivacky case X86Local::MRM5m: 831201360Srdivacky case X86Local::MRM6m: 832201360Srdivacky case X86Local::MRM7m: 833261991Sdim { 834261991Sdim // Operand 1 is a memory operand (possibly SIB-extended) 835261991Sdim // Operand 2 (optional) is an immediate or relocation. 836261991Sdim unsigned kOp = (HasEVEX_K) ? 1:0; 837261991Sdim unsigned Op4v = (HasVEX_4VPrefix) ? 1:0; 838261991Sdim if (numPhysicalOperands < 1 + kOp + Op4v || 839261991Sdim numPhysicalOperands > 2 + kOp + Op4v) 840261991Sdim llvm_unreachable("Unexpected number of operands for MRMnm"); 841261991Sdim } 842234353Sdim if (HasVEX_4VPrefix) 843234353Sdim HANDLE_OPERAND(vvvvRegister) 844261991Sdim if (HasEVEX_K) 845261991Sdim HANDLE_OPERAND(writemaskRegister) 846201360Srdivacky HANDLE_OPERAND(memory) 847201360Srdivacky HANDLE_OPTIONAL(relocation) 848201360Srdivacky break; 849218893Sdim case X86Local::RawFrmImm8: 850218893Sdim // operand 1 is a 16-bit immediate 851218893Sdim // operand 2 is an 8-bit immediate 852218893Sdim assert(numPhysicalOperands == 2 && 853218893Sdim "Unexpected number of operands for X86Local::RawFrmImm8"); 854218893Sdim HANDLE_OPERAND(immediate) 855218893Sdim HANDLE_OPERAND(immediate) 856218893Sdim break; 857218893Sdim case X86Local::RawFrmImm16: 858218893Sdim // operand 1 is a 16-bit immediate 859218893Sdim // operand 2 is a 16-bit immediate 860218893Sdim HANDLE_OPERAND(immediate) 861218893Sdim HANDLE_OPERAND(immediate) 862218893Sdim break; 863249423Sdim case X86Local::MRM_F8: 864249423Sdim if (Opcode == 0xc6) { 865249423Sdim assert(numPhysicalOperands == 1 && 866249423Sdim "Unexpected number of operands for X86Local::MRM_F8"); 867249423Sdim HANDLE_OPERAND(immediate) 868249423Sdim } else if (Opcode == 0xc7) { 869249423Sdim assert(numPhysicalOperands == 1 && 870249423Sdim "Unexpected number of operands for X86Local::MRM_F8"); 871249423Sdim HANDLE_OPERAND(relocation) 872249423Sdim } 873249423Sdim break; 874201360Srdivacky case X86Local::MRMInitReg: 875201360Srdivacky // Ignored. 876201360Srdivacky break; 877201360Srdivacky } 878239462Sdim 879201360Srdivacky #undef HANDLE_OPERAND 880201360Srdivacky #undef HANDLE_OPTIONAL 881201360Srdivacky} 882201360Srdivacky 883201360Srdivackyvoid RecognizableInstr::emitDecodePath(DisassemblerTables &tables) const { 884201360Srdivacky // Special cases where the LLVM tables are not complete 885201360Srdivacky 886203954Srdivacky#define MAP(from, to) \ 887203954Srdivacky case X86Local::MRM_##from: \ 888203954Srdivacky filter = new ExactFilter(0x##from); \ 889203954Srdivacky break; 890201360Srdivacky 891201360Srdivacky OpcodeType opcodeType = (OpcodeType)-1; 892239462Sdim 893239462Sdim ModRMFilter* filter = NULL; 894201360Srdivacky uint8_t opcodeToSet = 0; 895201360Srdivacky 896201360Srdivacky switch (Prefix) { 897261991Sdim default: llvm_unreachable("Invalid prefix!"); 898201360Srdivacky // Extended two-byte opcodes can start with f2 0f, f3 0f, or 0f 899201360Srdivacky case X86Local::XD: 900201360Srdivacky case X86Local::XS: 901201360Srdivacky case X86Local::TB: 902201360Srdivacky opcodeType = TWOBYTE; 903201360Srdivacky 904201360Srdivacky switch (Opcode) { 905203954Srdivacky default: 906203954Srdivacky if (needsModRMForDecode(Form)) 907203954Srdivacky filter = new ModFilter(isRegFormat(Form)); 908203954Srdivacky else 909203954Srdivacky filter = new DumbFilter(); 910203954Srdivacky break; 911201360Srdivacky#define EXTENSION_TABLE(n) case 0x##n: 912201360Srdivacky TWO_BYTE_EXTENSION_TABLES 913201360Srdivacky#undef EXTENSION_TABLE 914201360Srdivacky switch (Form) { 915201360Srdivacky default: 916201360Srdivacky llvm_unreachable("Unhandled two-byte extended opcode"); 917201360Srdivacky case X86Local::MRM0r: 918201360Srdivacky case X86Local::MRM1r: 919201360Srdivacky case X86Local::MRM2r: 920201360Srdivacky case X86Local::MRM3r: 921201360Srdivacky case X86Local::MRM4r: 922201360Srdivacky case X86Local::MRM5r: 923201360Srdivacky case X86Local::MRM6r: 924201360Srdivacky case X86Local::MRM7r: 925201360Srdivacky filter = new ExtendedFilter(true, Form - X86Local::MRM0r); 926201360Srdivacky break; 927201360Srdivacky case X86Local::MRM0m: 928201360Srdivacky case X86Local::MRM1m: 929201360Srdivacky case X86Local::MRM2m: 930201360Srdivacky case X86Local::MRM3m: 931201360Srdivacky case X86Local::MRM4m: 932201360Srdivacky case X86Local::MRM5m: 933201360Srdivacky case X86Local::MRM6m: 934201360Srdivacky case X86Local::MRM7m: 935201360Srdivacky filter = new ExtendedFilter(false, Form - X86Local::MRM0m); 936201360Srdivacky break; 937203954Srdivacky MRM_MAPPING 938201360Srdivacky } // switch (Form) 939201360Srdivacky break; 940203954Srdivacky } // switch (Opcode) 941201360Srdivacky opcodeToSet = Opcode; 942201360Srdivacky break; 943201360Srdivacky case X86Local::T8: 944234353Sdim case X86Local::T8XD: 945234353Sdim case X86Local::T8XS: 946201360Srdivacky opcodeType = THREEBYTE_38; 947234353Sdim switch (Opcode) { 948234353Sdim default: 949234353Sdim if (needsModRMForDecode(Form)) 950234353Sdim filter = new ModFilter(isRegFormat(Form)); 951234353Sdim else 952234353Sdim filter = new DumbFilter(); 953234353Sdim break; 954234353Sdim#define EXTENSION_TABLE(n) case 0x##n: 955234353Sdim THREE_BYTE_38_EXTENSION_TABLES 956234353Sdim#undef EXTENSION_TABLE 957234353Sdim switch (Form) { 958234353Sdim default: 959234353Sdim llvm_unreachable("Unhandled two-byte extended opcode"); 960234353Sdim case X86Local::MRM0r: 961234353Sdim case X86Local::MRM1r: 962234353Sdim case X86Local::MRM2r: 963234353Sdim case X86Local::MRM3r: 964234353Sdim case X86Local::MRM4r: 965234353Sdim case X86Local::MRM5r: 966234353Sdim case X86Local::MRM6r: 967234353Sdim case X86Local::MRM7r: 968234353Sdim filter = new ExtendedFilter(true, Form - X86Local::MRM0r); 969234353Sdim break; 970234353Sdim case X86Local::MRM0m: 971234353Sdim case X86Local::MRM1m: 972234353Sdim case X86Local::MRM2m: 973234353Sdim case X86Local::MRM3m: 974234353Sdim case X86Local::MRM4m: 975234353Sdim case X86Local::MRM5m: 976234353Sdim case X86Local::MRM6m: 977234353Sdim case X86Local::MRM7m: 978234353Sdim filter = new ExtendedFilter(false, Form - X86Local::MRM0m); 979234353Sdim break; 980234353Sdim MRM_MAPPING 981234353Sdim } // switch (Form) 982234353Sdim break; 983234353Sdim } // switch (Opcode) 984201360Srdivacky opcodeToSet = Opcode; 985201360Srdivacky break; 986203954Srdivacky case X86Local::P_TA: 987234353Sdim case X86Local::TAXD: 988201360Srdivacky opcodeType = THREEBYTE_3A; 989201360Srdivacky if (needsModRMForDecode(Form)) 990201360Srdivacky filter = new ModFilter(isRegFormat(Form)); 991201360Srdivacky else 992201360Srdivacky filter = new DumbFilter(); 993201360Srdivacky opcodeToSet = Opcode; 994201360Srdivacky break; 995221345Sdim case X86Local::A6: 996221345Sdim opcodeType = THREEBYTE_A6; 997221345Sdim if (needsModRMForDecode(Form)) 998221345Sdim filter = new ModFilter(isRegFormat(Form)); 999221345Sdim else 1000221345Sdim filter = new DumbFilter(); 1001221345Sdim opcodeToSet = Opcode; 1002221345Sdim break; 1003221345Sdim case X86Local::A7: 1004221345Sdim opcodeType = THREEBYTE_A7; 1005221345Sdim if (needsModRMForDecode(Form)) 1006221345Sdim filter = new ModFilter(isRegFormat(Form)); 1007221345Sdim else 1008221345Sdim filter = new DumbFilter(); 1009221345Sdim opcodeToSet = Opcode; 1010221345Sdim break; 1011261991Sdim case X86Local::XOP8: 1012261991Sdim opcodeType = XOP8_MAP; 1013261991Sdim if (needsModRMForDecode(Form)) 1014261991Sdim filter = new ModFilter(isRegFormat(Form)); 1015261991Sdim else 1016261991Sdim filter = new DumbFilter(); 1017261991Sdim opcodeToSet = Opcode; 1018261991Sdim break; 1019261991Sdim case X86Local::XOP9: 1020261991Sdim opcodeType = XOP9_MAP; 1021261991Sdim switch (Opcode) { 1022261991Sdim default: 1023261991Sdim if (needsModRMForDecode(Form)) 1024261991Sdim filter = new ModFilter(isRegFormat(Form)); 1025261991Sdim else 1026261991Sdim filter = new DumbFilter(); 1027261991Sdim break; 1028261991Sdim#define EXTENSION_TABLE(n) case 0x##n: 1029261991Sdim XOP9_MAP_EXTENSION_TABLES 1030261991Sdim#undef EXTENSION_TABLE 1031261991Sdim switch (Form) { 1032261991Sdim default: 1033261991Sdim llvm_unreachable("Unhandled XOP9 extended opcode"); 1034261991Sdim case X86Local::MRM0r: 1035261991Sdim case X86Local::MRM1r: 1036261991Sdim case X86Local::MRM2r: 1037261991Sdim case X86Local::MRM3r: 1038261991Sdim case X86Local::MRM4r: 1039261991Sdim case X86Local::MRM5r: 1040261991Sdim case X86Local::MRM6r: 1041261991Sdim case X86Local::MRM7r: 1042261991Sdim filter = new ExtendedFilter(true, Form - X86Local::MRM0r); 1043261991Sdim break; 1044261991Sdim case X86Local::MRM0m: 1045261991Sdim case X86Local::MRM1m: 1046261991Sdim case X86Local::MRM2m: 1047261991Sdim case X86Local::MRM3m: 1048261991Sdim case X86Local::MRM4m: 1049261991Sdim case X86Local::MRM5m: 1050261991Sdim case X86Local::MRM6m: 1051261991Sdim case X86Local::MRM7m: 1052261991Sdim filter = new ExtendedFilter(false, Form - X86Local::MRM0m); 1053261991Sdim break; 1054261991Sdim MRM_MAPPING 1055261991Sdim } // switch (Form) 1056261991Sdim break; 1057261991Sdim } // switch (Opcode) 1058261991Sdim opcodeToSet = Opcode; 1059261991Sdim break; 1060261991Sdim case X86Local::XOPA: 1061261991Sdim opcodeType = XOPA_MAP; 1062261991Sdim if (needsModRMForDecode(Form)) 1063261991Sdim filter = new ModFilter(isRegFormat(Form)); 1064261991Sdim else 1065261991Sdim filter = new DumbFilter(); 1066261991Sdim opcodeToSet = Opcode; 1067261991Sdim break; 1068201360Srdivacky case X86Local::D8: 1069201360Srdivacky case X86Local::D9: 1070201360Srdivacky case X86Local::DA: 1071201360Srdivacky case X86Local::DB: 1072201360Srdivacky case X86Local::DC: 1073201360Srdivacky case X86Local::DD: 1074201360Srdivacky case X86Local::DE: 1075201360Srdivacky case X86Local::DF: 1076201360Srdivacky assert(Opcode >= 0xc0 && "Unexpected opcode for an escape opcode"); 1077201360Srdivacky opcodeType = ONEBYTE; 1078201360Srdivacky if (Form == X86Local::AddRegFrm) { 1079201360Srdivacky Spec->modifierType = MODIFIER_MODRM; 1080201360Srdivacky Spec->modifierBase = Opcode; 1081201360Srdivacky filter = new AddRegEscapeFilter(Opcode); 1082201360Srdivacky } else { 1083201360Srdivacky filter = new EscapeFilter(true, Opcode); 1084201360Srdivacky } 1085201360Srdivacky opcodeToSet = 0xd8 + (Prefix - X86Local::D8); 1086201360Srdivacky break; 1087226633Sdim case X86Local::REP: 1088261991Sdim case 0: 1089201360Srdivacky opcodeType = ONEBYTE; 1090201360Srdivacky switch (Opcode) { 1091201360Srdivacky#define EXTENSION_TABLE(n) case 0x##n: 1092201360Srdivacky ONE_BYTE_EXTENSION_TABLES 1093201360Srdivacky#undef EXTENSION_TABLE 1094201360Srdivacky switch (Form) { 1095201360Srdivacky default: 1096201360Srdivacky llvm_unreachable("Fell through the cracks of a single-byte " 1097201360Srdivacky "extended opcode"); 1098201360Srdivacky case X86Local::MRM0r: 1099201360Srdivacky case X86Local::MRM1r: 1100201360Srdivacky case X86Local::MRM2r: 1101201360Srdivacky case X86Local::MRM3r: 1102201360Srdivacky case X86Local::MRM4r: 1103201360Srdivacky case X86Local::MRM5r: 1104201360Srdivacky case X86Local::MRM6r: 1105201360Srdivacky case X86Local::MRM7r: 1106201360Srdivacky filter = new ExtendedFilter(true, Form - X86Local::MRM0r); 1107201360Srdivacky break; 1108201360Srdivacky case X86Local::MRM0m: 1109201360Srdivacky case X86Local::MRM1m: 1110201360Srdivacky case X86Local::MRM2m: 1111201360Srdivacky case X86Local::MRM3m: 1112201360Srdivacky case X86Local::MRM4m: 1113201360Srdivacky case X86Local::MRM5m: 1114201360Srdivacky case X86Local::MRM6m: 1115201360Srdivacky case X86Local::MRM7m: 1116201360Srdivacky filter = new ExtendedFilter(false, Form - X86Local::MRM0m); 1117201360Srdivacky break; 1118203954Srdivacky MRM_MAPPING 1119201360Srdivacky } // switch (Form) 1120201360Srdivacky break; 1121201360Srdivacky case 0xd8: 1122201360Srdivacky case 0xd9: 1123201360Srdivacky case 0xda: 1124201360Srdivacky case 0xdb: 1125201360Srdivacky case 0xdc: 1126201360Srdivacky case 0xdd: 1127201360Srdivacky case 0xde: 1128201360Srdivacky case 0xdf: 1129201360Srdivacky filter = new EscapeFilter(false, Form - X86Local::MRM0m); 1130201360Srdivacky break; 1131201360Srdivacky default: 1132201360Srdivacky if (needsModRMForDecode(Form)) 1133201360Srdivacky filter = new ModFilter(isRegFormat(Form)); 1134201360Srdivacky else 1135201360Srdivacky filter = new DumbFilter(); 1136201360Srdivacky break; 1137201360Srdivacky } // switch (Opcode) 1138201360Srdivacky opcodeToSet = Opcode; 1139201360Srdivacky } // switch (Prefix) 1140201360Srdivacky 1141201360Srdivacky assert(opcodeType != (OpcodeType)-1 && 1142201360Srdivacky "Opcode type not set"); 1143201360Srdivacky assert(filter && "Filter not set"); 1144201360Srdivacky 1145201360Srdivacky if (Form == X86Local::AddRegFrm) { 1146201360Srdivacky if(Spec->modifierType != MODIFIER_MODRM) { 1147201360Srdivacky assert(opcodeToSet < 0xf9 && 1148201360Srdivacky "Not enough room for all ADDREG_FRM operands"); 1149239462Sdim 1150201360Srdivacky uint8_t currentOpcode; 1151201360Srdivacky 1152201360Srdivacky for (currentOpcode = opcodeToSet; 1153201360Srdivacky currentOpcode < opcodeToSet + 8; 1154201360Srdivacky ++currentOpcode) 1155239462Sdim tables.setTableFields(opcodeType, 1156239462Sdim insnContext(), 1157239462Sdim currentOpcode, 1158239462Sdim *filter, 1159226633Sdim UID, Is32Bit, IgnoresVEX_L); 1160239462Sdim 1161201360Srdivacky Spec->modifierType = MODIFIER_OPCODE; 1162201360Srdivacky Spec->modifierBase = opcodeToSet; 1163201360Srdivacky } else { 1164201360Srdivacky // modifierBase was set where MODIFIER_MODRM was set 1165239462Sdim tables.setTableFields(opcodeType, 1166239462Sdim insnContext(), 1167239462Sdim opcodeToSet, 1168239462Sdim *filter, 1169226633Sdim UID, Is32Bit, IgnoresVEX_L); 1170201360Srdivacky } 1171201360Srdivacky } else { 1172201360Srdivacky tables.setTableFields(opcodeType, 1173201360Srdivacky insnContext(), 1174201360Srdivacky opcodeToSet, 1175201360Srdivacky *filter, 1176226633Sdim UID, Is32Bit, IgnoresVEX_L); 1177239462Sdim 1178201360Srdivacky Spec->modifierType = MODIFIER_NONE; 1179201360Srdivacky Spec->modifierBase = opcodeToSet; 1180201360Srdivacky } 1181239462Sdim 1182201360Srdivacky delete filter; 1183239462Sdim 1184203954Srdivacky#undef MAP 1185201360Srdivacky} 1186201360Srdivacky 1187201360Srdivacky#define TYPE(str, type) if (s == str) return type; 1188201360SrdivackyOperandType RecognizableInstr::typeFromString(const std::string &s, 1189201360Srdivacky bool isSSE, 1190201360Srdivacky bool hasREX_WPrefix, 1191201360Srdivacky bool hasOpSizePrefix) { 1192201360Srdivacky if (isSSE) { 1193239462Sdim // For SSE instructions, we ignore the OpSize prefix and force operand 1194201360Srdivacky // sizes. 1195201360Srdivacky TYPE("GR16", TYPE_R16) 1196201360Srdivacky TYPE("GR32", TYPE_R32) 1197201360Srdivacky TYPE("GR64", TYPE_R64) 1198201360Srdivacky } 1199201360Srdivacky if(hasREX_WPrefix) { 1200201360Srdivacky // For instructions with a REX_W prefix, a declared 32-bit register encoding 1201201360Srdivacky // is special. 1202201360Srdivacky TYPE("GR32", TYPE_R32) 1203201360Srdivacky } 1204201360Srdivacky if(!hasOpSizePrefix) { 1205201360Srdivacky // For instructions without an OpSize prefix, a declared 16-bit register or 1206201360Srdivacky // immediate encoding is special. 1207201360Srdivacky TYPE("GR16", TYPE_R16) 1208201360Srdivacky TYPE("i16imm", TYPE_IMM16) 1209201360Srdivacky } 1210201360Srdivacky TYPE("i16mem", TYPE_Mv) 1211201360Srdivacky TYPE("i16imm", TYPE_IMMv) 1212201360Srdivacky TYPE("i16i8imm", TYPE_IMMv) 1213201360Srdivacky TYPE("GR16", TYPE_Rv) 1214201360Srdivacky TYPE("i32mem", TYPE_Mv) 1215201360Srdivacky TYPE("i32imm", TYPE_IMMv) 1216201360Srdivacky TYPE("i32i8imm", TYPE_IMM32) 1217226633Sdim TYPE("u32u8imm", TYPE_IMM32) 1218201360Srdivacky TYPE("GR32", TYPE_Rv) 1219261991Sdim TYPE("GR32orGR64", TYPE_R32) 1220201360Srdivacky TYPE("i64mem", TYPE_Mv) 1221201360Srdivacky TYPE("i64i32imm", TYPE_IMM64) 1222201360Srdivacky TYPE("i64i8imm", TYPE_IMM64) 1223201360Srdivacky TYPE("GR64", TYPE_R64) 1224201360Srdivacky TYPE("i8mem", TYPE_M8) 1225201360Srdivacky TYPE("i8imm", TYPE_IMM8) 1226201360Srdivacky TYPE("GR8", TYPE_R8) 1227201360Srdivacky TYPE("VR128", TYPE_XMM128) 1228261991Sdim TYPE("VR128X", TYPE_XMM128) 1229201360Srdivacky TYPE("f128mem", TYPE_M128) 1230218893Sdim TYPE("f256mem", TYPE_M256) 1231261991Sdim TYPE("f512mem", TYPE_M512) 1232201360Srdivacky TYPE("FR64", TYPE_XMM64) 1233261991Sdim TYPE("FR64X", TYPE_XMM64) 1234201360Srdivacky TYPE("f64mem", TYPE_M64FP) 1235218893Sdim TYPE("sdmem", TYPE_M64FP) 1236201360Srdivacky TYPE("FR32", TYPE_XMM32) 1237261991Sdim TYPE("FR32X", TYPE_XMM32) 1238201360Srdivacky TYPE("f32mem", TYPE_M32FP) 1239218893Sdim TYPE("ssmem", TYPE_M32FP) 1240201360Srdivacky TYPE("RST", TYPE_ST) 1241201360Srdivacky TYPE("i128mem", TYPE_M128) 1242221345Sdim TYPE("i256mem", TYPE_M256) 1243261991Sdim TYPE("i512mem", TYPE_M512) 1244201360Srdivacky TYPE("i64i32imm_pcrel", TYPE_REL64) 1245210299Sed TYPE("i16imm_pcrel", TYPE_REL16) 1246201360Srdivacky TYPE("i32imm_pcrel", TYPE_REL32) 1247207618Srdivacky TYPE("SSECC", TYPE_IMM3) 1248234353Sdim TYPE("AVXCC", TYPE_IMM5) 1249201360Srdivacky TYPE("brtarget", TYPE_RELv) 1250218893Sdim TYPE("uncondbrtarget", TYPE_RELv) 1251201360Srdivacky TYPE("brtarget8", TYPE_REL8) 1252201360Srdivacky TYPE("f80mem", TYPE_M80FP) 1253201360Srdivacky TYPE("lea32mem", TYPE_LEA) 1254201360Srdivacky TYPE("lea64_32mem", TYPE_LEA) 1255201360Srdivacky TYPE("lea64mem", TYPE_LEA) 1256201360Srdivacky TYPE("VR64", TYPE_MM64) 1257201360Srdivacky TYPE("i64imm", TYPE_IMMv) 1258201360Srdivacky TYPE("opaque32mem", TYPE_M1616) 1259201360Srdivacky TYPE("opaque48mem", TYPE_M1632) 1260201360Srdivacky TYPE("opaque80mem", TYPE_M1664) 1261201360Srdivacky TYPE("opaque512mem", TYPE_M512) 1262201360Srdivacky TYPE("SEGMENT_REG", TYPE_SEGMENTREG) 1263201360Srdivacky TYPE("DEBUG_REG", TYPE_DEBUGREG) 1264208599Srdivacky TYPE("CONTROL_REG", TYPE_CONTROLREG) 1265201360Srdivacky TYPE("offset8", TYPE_MOFFS8) 1266201360Srdivacky TYPE("offset16", TYPE_MOFFS16) 1267201360Srdivacky TYPE("offset32", TYPE_MOFFS32) 1268201360Srdivacky TYPE("offset64", TYPE_MOFFS64) 1269221345Sdim TYPE("VR256", TYPE_XMM256) 1270261991Sdim TYPE("VR256X", TYPE_XMM256) 1271261991Sdim TYPE("VR512", TYPE_XMM512) 1272261991Sdim TYPE("VK8", TYPE_VK8) 1273261991Sdim TYPE("VK8WM", TYPE_VK8) 1274261991Sdim TYPE("VK16", TYPE_VK16) 1275261991Sdim TYPE("VK16WM", TYPE_VK16) 1276226633Sdim TYPE("GR16_NOAX", TYPE_Rv) 1277226633Sdim TYPE("GR32_NOAX", TYPE_Rv) 1278226633Sdim TYPE("GR64_NOAX", TYPE_R64) 1279239462Sdim TYPE("vx32mem", TYPE_M32) 1280239462Sdim TYPE("vy32mem", TYPE_M32) 1281261991Sdim TYPE("vz32mem", TYPE_M32) 1282239462Sdim TYPE("vx64mem", TYPE_M64) 1283239462Sdim TYPE("vy64mem", TYPE_M64) 1284261991Sdim TYPE("vy64xmem", TYPE_M64) 1285261991Sdim TYPE("vz64mem", TYPE_M64) 1286201360Srdivacky errs() << "Unhandled type string " << s << "\n"; 1287201360Srdivacky llvm_unreachable("Unhandled type string"); 1288201360Srdivacky} 1289201360Srdivacky#undef TYPE 1290201360Srdivacky 1291201360Srdivacky#define ENCODING(str, encoding) if (s == str) return encoding; 1292201360SrdivackyOperandEncoding RecognizableInstr::immediateEncodingFromString 1293201360Srdivacky (const std::string &s, 1294201360Srdivacky bool hasOpSizePrefix) { 1295201360Srdivacky if(!hasOpSizePrefix) { 1296201360Srdivacky // For instructions without an OpSize prefix, a declared 16-bit register or 1297201360Srdivacky // immediate encoding is special. 1298201360Srdivacky ENCODING("i16imm", ENCODING_IW) 1299201360Srdivacky } 1300201360Srdivacky ENCODING("i32i8imm", ENCODING_IB) 1301226633Sdim ENCODING("u32u8imm", ENCODING_IB) 1302201360Srdivacky ENCODING("SSECC", ENCODING_IB) 1303234353Sdim ENCODING("AVXCC", ENCODING_IB) 1304201360Srdivacky ENCODING("i16imm", ENCODING_Iv) 1305201360Srdivacky ENCODING("i16i8imm", ENCODING_IB) 1306201360Srdivacky ENCODING("i32imm", ENCODING_Iv) 1307201360Srdivacky ENCODING("i64i32imm", ENCODING_ID) 1308201360Srdivacky ENCODING("i64i8imm", ENCODING_IB) 1309201360Srdivacky ENCODING("i8imm", ENCODING_IB) 1310221345Sdim // This is not a typo. Instructions like BLENDVPD put 1311221345Sdim // register IDs in 8-bit immediates nowadays. 1312243830Sdim ENCODING("FR32", ENCODING_IB) 1313243830Sdim ENCODING("FR64", ENCODING_IB) 1314261991Sdim ENCODING("VR128", ENCODING_IB) 1315261991Sdim ENCODING("VR256", ENCODING_IB) 1316261991Sdim ENCODING("FR32X", ENCODING_IB) 1317261991Sdim ENCODING("FR64X", ENCODING_IB) 1318261991Sdim ENCODING("VR128X", ENCODING_IB) 1319261991Sdim ENCODING("VR256X", ENCODING_IB) 1320261991Sdim ENCODING("VR512", ENCODING_IB) 1321201360Srdivacky errs() << "Unhandled immediate encoding " << s << "\n"; 1322201360Srdivacky llvm_unreachable("Unhandled immediate encoding"); 1323201360Srdivacky} 1324201360Srdivacky 1325201360SrdivackyOperandEncoding RecognizableInstr::rmRegisterEncodingFromString 1326201360Srdivacky (const std::string &s, 1327201360Srdivacky bool hasOpSizePrefix) { 1328201360Srdivacky ENCODING("GR16", ENCODING_RM) 1329201360Srdivacky ENCODING("GR32", ENCODING_RM) 1330261991Sdim ENCODING("GR32orGR64", ENCODING_RM) 1331201360Srdivacky ENCODING("GR64", ENCODING_RM) 1332201360Srdivacky ENCODING("GR8", ENCODING_RM) 1333201360Srdivacky ENCODING("VR128", ENCODING_RM) 1334261991Sdim ENCODING("VR128X", ENCODING_RM) 1335201360Srdivacky ENCODING("FR64", ENCODING_RM) 1336201360Srdivacky ENCODING("FR32", ENCODING_RM) 1337261991Sdim ENCODING("FR64X", ENCODING_RM) 1338261991Sdim ENCODING("FR32X", ENCODING_RM) 1339201360Srdivacky ENCODING("VR64", ENCODING_RM) 1340221345Sdim ENCODING("VR256", ENCODING_RM) 1341261991Sdim ENCODING("VR256X", ENCODING_RM) 1342261991Sdim ENCODING("VR512", ENCODING_RM) 1343261991Sdim ENCODING("VK8", ENCODING_RM) 1344261991Sdim ENCODING("VK16", ENCODING_RM) 1345201360Srdivacky errs() << "Unhandled R/M register encoding " << s << "\n"; 1346201360Srdivacky llvm_unreachable("Unhandled R/M register encoding"); 1347201360Srdivacky} 1348201360Srdivacky 1349201360SrdivackyOperandEncoding RecognizableInstr::roRegisterEncodingFromString 1350201360Srdivacky (const std::string &s, 1351201360Srdivacky bool hasOpSizePrefix) { 1352201360Srdivacky ENCODING("GR16", ENCODING_REG) 1353201360Srdivacky ENCODING("GR32", ENCODING_REG) 1354261991Sdim ENCODING("GR32orGR64", ENCODING_REG) 1355201360Srdivacky ENCODING("GR64", ENCODING_REG) 1356201360Srdivacky ENCODING("GR8", ENCODING_REG) 1357201360Srdivacky ENCODING("VR128", ENCODING_REG) 1358201360Srdivacky ENCODING("FR64", ENCODING_REG) 1359201360Srdivacky ENCODING("FR32", ENCODING_REG) 1360201360Srdivacky ENCODING("VR64", ENCODING_REG) 1361201360Srdivacky ENCODING("SEGMENT_REG", ENCODING_REG) 1362201360Srdivacky ENCODING("DEBUG_REG", ENCODING_REG) 1363208599Srdivacky ENCODING("CONTROL_REG", ENCODING_REG) 1364221345Sdim ENCODING("VR256", ENCODING_REG) 1365261991Sdim ENCODING("VR256X", ENCODING_REG) 1366261991Sdim ENCODING("VR128X", ENCODING_REG) 1367261991Sdim ENCODING("FR64X", ENCODING_REG) 1368261991Sdim ENCODING("FR32X", ENCODING_REG) 1369261991Sdim ENCODING("VR512", ENCODING_REG) 1370261991Sdim ENCODING("VK8", ENCODING_REG) 1371261991Sdim ENCODING("VK16", ENCODING_REG) 1372261991Sdim ENCODING("VK8WM", ENCODING_REG) 1373261991Sdim ENCODING("VK16WM", ENCODING_REG) 1374201360Srdivacky errs() << "Unhandled reg/opcode register encoding " << s << "\n"; 1375201360Srdivacky llvm_unreachable("Unhandled reg/opcode register encoding"); 1376201360Srdivacky} 1377201360Srdivacky 1378221345SdimOperandEncoding RecognizableInstr::vvvvRegisterEncodingFromString 1379221345Sdim (const std::string &s, 1380221345Sdim bool hasOpSizePrefix) { 1381226633Sdim ENCODING("GR32", ENCODING_VVVV) 1382226633Sdim ENCODING("GR64", ENCODING_VVVV) 1383221345Sdim ENCODING("FR32", ENCODING_VVVV) 1384221345Sdim ENCODING("FR64", ENCODING_VVVV) 1385221345Sdim ENCODING("VR128", ENCODING_VVVV) 1386221345Sdim ENCODING("VR256", ENCODING_VVVV) 1387261991Sdim ENCODING("FR32X", ENCODING_VVVV) 1388261991Sdim ENCODING("FR64X", ENCODING_VVVV) 1389261991Sdim ENCODING("VR128X", ENCODING_VVVV) 1390261991Sdim ENCODING("VR256X", ENCODING_VVVV) 1391261991Sdim ENCODING("VR512", ENCODING_VVVV) 1392261991Sdim ENCODING("VK8", ENCODING_VVVV) 1393261991Sdim ENCODING("VK16", ENCODING_VVVV) 1394221345Sdim errs() << "Unhandled VEX.vvvv register encoding " << s << "\n"; 1395221345Sdim llvm_unreachable("Unhandled VEX.vvvv register encoding"); 1396221345Sdim} 1397221345Sdim 1398261991SdimOperandEncoding RecognizableInstr::writemaskRegisterEncodingFromString 1399261991Sdim (const std::string &s, 1400261991Sdim bool hasOpSizePrefix) { 1401261991Sdim ENCODING("VK8WM", ENCODING_WRITEMASK) 1402261991Sdim ENCODING("VK16WM", ENCODING_WRITEMASK) 1403261991Sdim errs() << "Unhandled mask register encoding " << s << "\n"; 1404261991Sdim llvm_unreachable("Unhandled mask register encoding"); 1405261991Sdim} 1406261991Sdim 1407201360SrdivackyOperandEncoding RecognizableInstr::memoryEncodingFromString 1408201360Srdivacky (const std::string &s, 1409201360Srdivacky bool hasOpSizePrefix) { 1410201360Srdivacky ENCODING("i16mem", ENCODING_RM) 1411201360Srdivacky ENCODING("i32mem", ENCODING_RM) 1412201360Srdivacky ENCODING("i64mem", ENCODING_RM) 1413201360Srdivacky ENCODING("i8mem", ENCODING_RM) 1414218893Sdim ENCODING("ssmem", ENCODING_RM) 1415218893Sdim ENCODING("sdmem", ENCODING_RM) 1416201360Srdivacky ENCODING("f128mem", ENCODING_RM) 1417218893Sdim ENCODING("f256mem", ENCODING_RM) 1418261991Sdim ENCODING("f512mem", ENCODING_RM) 1419201360Srdivacky ENCODING("f64mem", ENCODING_RM) 1420201360Srdivacky ENCODING("f32mem", ENCODING_RM) 1421201360Srdivacky ENCODING("i128mem", ENCODING_RM) 1422221345Sdim ENCODING("i256mem", ENCODING_RM) 1423261991Sdim ENCODING("i512mem", ENCODING_RM) 1424201360Srdivacky ENCODING("f80mem", ENCODING_RM) 1425201360Srdivacky ENCODING("lea32mem", ENCODING_RM) 1426201360Srdivacky ENCODING("lea64_32mem", ENCODING_RM) 1427201360Srdivacky ENCODING("lea64mem", ENCODING_RM) 1428201360Srdivacky ENCODING("opaque32mem", ENCODING_RM) 1429201360Srdivacky ENCODING("opaque48mem", ENCODING_RM) 1430201360Srdivacky ENCODING("opaque80mem", ENCODING_RM) 1431201360Srdivacky ENCODING("opaque512mem", ENCODING_RM) 1432239462Sdim ENCODING("vx32mem", ENCODING_RM) 1433239462Sdim ENCODING("vy32mem", ENCODING_RM) 1434261991Sdim ENCODING("vz32mem", ENCODING_RM) 1435239462Sdim ENCODING("vx64mem", ENCODING_RM) 1436239462Sdim ENCODING("vy64mem", ENCODING_RM) 1437261991Sdim ENCODING("vy64xmem", ENCODING_RM) 1438261991Sdim ENCODING("vz64mem", ENCODING_RM) 1439201360Srdivacky errs() << "Unhandled memory encoding " << s << "\n"; 1440201360Srdivacky llvm_unreachable("Unhandled memory encoding"); 1441201360Srdivacky} 1442201360Srdivacky 1443201360SrdivackyOperandEncoding RecognizableInstr::relocationEncodingFromString 1444201360Srdivacky (const std::string &s, 1445201360Srdivacky bool hasOpSizePrefix) { 1446201360Srdivacky if(!hasOpSizePrefix) { 1447201360Srdivacky // For instructions without an OpSize prefix, a declared 16-bit register or 1448201360Srdivacky // immediate encoding is special. 1449201360Srdivacky ENCODING("i16imm", ENCODING_IW) 1450201360Srdivacky } 1451201360Srdivacky ENCODING("i16imm", ENCODING_Iv) 1452201360Srdivacky ENCODING("i16i8imm", ENCODING_IB) 1453201360Srdivacky ENCODING("i32imm", ENCODING_Iv) 1454201360Srdivacky ENCODING("i32i8imm", ENCODING_IB) 1455201360Srdivacky ENCODING("i64i32imm", ENCODING_ID) 1456201360Srdivacky ENCODING("i64i8imm", ENCODING_IB) 1457201360Srdivacky ENCODING("i8imm", ENCODING_IB) 1458201360Srdivacky ENCODING("i64i32imm_pcrel", ENCODING_ID) 1459210299Sed ENCODING("i16imm_pcrel", ENCODING_IW) 1460201360Srdivacky ENCODING("i32imm_pcrel", ENCODING_ID) 1461201360Srdivacky ENCODING("brtarget", ENCODING_Iv) 1462201360Srdivacky ENCODING("brtarget8", ENCODING_IB) 1463201360Srdivacky ENCODING("i64imm", ENCODING_IO) 1464201360Srdivacky ENCODING("offset8", ENCODING_Ia) 1465201360Srdivacky ENCODING("offset16", ENCODING_Ia) 1466201360Srdivacky ENCODING("offset32", ENCODING_Ia) 1467201360Srdivacky ENCODING("offset64", ENCODING_Ia) 1468201360Srdivacky errs() << "Unhandled relocation encoding " << s << "\n"; 1469201360Srdivacky llvm_unreachable("Unhandled relocation encoding"); 1470201360Srdivacky} 1471201360Srdivacky 1472201360SrdivackyOperandEncoding RecognizableInstr::opcodeModifierEncodingFromString 1473201360Srdivacky (const std::string &s, 1474201360Srdivacky bool hasOpSizePrefix) { 1475201360Srdivacky ENCODING("RST", ENCODING_I) 1476201360Srdivacky ENCODING("GR32", ENCODING_Rv) 1477201360Srdivacky ENCODING("GR64", ENCODING_RO) 1478201360Srdivacky ENCODING("GR16", ENCODING_Rv) 1479201360Srdivacky ENCODING("GR8", ENCODING_RB) 1480226633Sdim ENCODING("GR16_NOAX", ENCODING_Rv) 1481226633Sdim ENCODING("GR32_NOAX", ENCODING_Rv) 1482226633Sdim ENCODING("GR64_NOAX", ENCODING_RO) 1483201360Srdivacky errs() << "Unhandled opcode modifier encoding " << s << "\n"; 1484201360Srdivacky llvm_unreachable("Unhandled opcode modifier encoding"); 1485201360Srdivacky} 1486201360Srdivacky#undef ENCODING 1487