X86RecognizableInstr.cpp revision 276479
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 \ 26276479Sdim MAP(C0, 32) \ 27203954Srdivacky MAP(C1, 33) \ 28203954Srdivacky MAP(C2, 34) \ 29203954Srdivacky MAP(C3, 35) \ 30203954Srdivacky MAP(C4, 36) \ 31203954Srdivacky MAP(C8, 37) \ 32203954Srdivacky MAP(C9, 38) \ 33251662Sdim MAP(CA, 39) \ 34251662Sdim MAP(CB, 40) \ 35276479Sdim MAP(D0, 41) \ 36276479Sdim MAP(D1, 42) \ 37276479Sdim MAP(D4, 43) \ 38276479Sdim MAP(D5, 44) \ 39276479Sdim MAP(D6, 45) \ 40276479Sdim MAP(D8, 46) \ 41276479Sdim MAP(D9, 47) \ 42276479Sdim MAP(DA, 48) \ 43276479Sdim MAP(DB, 49) \ 44276479Sdim MAP(DC, 50) \ 45276479Sdim MAP(DD, 51) \ 46276479Sdim MAP(DE, 52) \ 47276479Sdim MAP(DF, 53) \ 48276479Sdim MAP(E0, 54) \ 49276479Sdim MAP(E1, 55) \ 50276479Sdim MAP(E2, 56) \ 51276479Sdim MAP(E3, 57) \ 52276479Sdim MAP(E4, 58) \ 53276479Sdim MAP(E5, 59) \ 54276479Sdim MAP(E8, 60) \ 55276479Sdim MAP(E9, 61) \ 56276479Sdim MAP(EA, 62) \ 57276479Sdim MAP(EB, 63) \ 58276479Sdim MAP(EC, 64) \ 59276479Sdim MAP(ED, 65) \ 60276479Sdim MAP(EE, 66) \ 61276479Sdim MAP(F0, 67) \ 62276479Sdim MAP(F1, 68) \ 63276479Sdim MAP(F2, 69) \ 64276479Sdim MAP(F3, 70) \ 65276479Sdim MAP(F4, 71) \ 66276479Sdim MAP(F5, 72) \ 67276479Sdim MAP(F6, 73) \ 68276479Sdim MAP(F7, 74) \ 69276479Sdim MAP(F8, 75) \ 70276479Sdim MAP(F9, 76) \ 71276479Sdim MAP(FA, 77) \ 72276479Sdim MAP(FB, 78) \ 73276479Sdim MAP(FC, 79) \ 74276479Sdim MAP(FD, 80) \ 75276479Sdim MAP(FE, 81) \ 76276479Sdim MAP(FF, 82) 77203954Srdivacky 78201360Srdivacky// A clone of X86 since we can't depend on something that is generated. 79201360Srdivackynamespace X86Local { 80201360Srdivacky enum { 81201360Srdivacky Pseudo = 0, 82201360Srdivacky RawFrm = 1, 83201360Srdivacky AddRegFrm = 2, 84201360Srdivacky MRMDestReg = 3, 85201360Srdivacky MRMDestMem = 4, 86201360Srdivacky MRMSrcReg = 5, 87201360Srdivacky MRMSrcMem = 6, 88276479Sdim RawFrmMemOffs = 7, 89276479Sdim RawFrmSrc = 8, 90276479Sdim RawFrmDst = 9, 91276479Sdim RawFrmDstSrc = 10, 92276479Sdim RawFrmImm8 = 11, 93276479Sdim RawFrmImm16 = 12, 94276479Sdim MRMXr = 14, MRMXm = 15, 95239462Sdim MRM0r = 16, MRM1r = 17, MRM2r = 18, MRM3r = 19, 96201360Srdivacky MRM4r = 20, MRM5r = 21, MRM6r = 22, MRM7r = 23, 97201360Srdivacky MRM0m = 24, MRM1m = 25, MRM2m = 26, MRM3m = 27, 98201360Srdivacky MRM4m = 28, MRM5m = 29, MRM6m = 30, MRM7m = 31, 99203954Srdivacky#define MAP(from, to) MRM_##from = to, 100203954Srdivacky MRM_MAPPING 101203954Srdivacky#undef MAP 102203954Srdivacky lastMRM 103201360Srdivacky }; 104239462Sdim 105201360Srdivacky enum { 106276479Sdim OB = 0, TB = 1, T8 = 2, TA = 3, XOP8 = 4, XOP9 = 5, XOPA = 6 107201360Srdivacky }; 108203954Srdivacky 109276479Sdim enum { 110276479Sdim PS = 1, PD = 2, XS = 3, XD = 4 111276479Sdim }; 112203954Srdivacky 113276479Sdim enum { 114276479Sdim VEX = 1, XOP = 2, EVEX = 3 115276479Sdim }; 116239462Sdim 117276479Sdim enum { 118276479Sdim OpSize16 = 1, OpSize32 = 2 119276479Sdim }; 120276479Sdim} 121201360Srdivacky 122201360Srdivackyusing namespace X86Disassembler; 123201360Srdivacky 124201360Srdivacky/// isRegFormat - Indicates whether a particular form requires the Mod field of 125201360Srdivacky/// the ModR/M byte to be 0b11. 126201360Srdivacky/// 127201360Srdivacky/// @param form - The form of the instruction. 128201360Srdivacky/// @return - true if the form implies that Mod must be 0b11, false 129201360Srdivacky/// otherwise. 130201360Srdivackystatic bool isRegFormat(uint8_t form) { 131276479Sdim return (form == X86Local::MRMDestReg || 132276479Sdim form == X86Local::MRMSrcReg || 133276479Sdim form == X86Local::MRMXr || 134276479Sdim (form >= X86Local::MRM0r && form <= X86Local::MRM7r)); 135201360Srdivacky} 136201360Srdivacky 137201360Srdivacky/// byteFromBitsInit - Extracts a value at most 8 bits in width from a BitsInit. 138201360Srdivacky/// Useful for switch statements and the like. 139201360Srdivacky/// 140201360Srdivacky/// @param init - A reference to the BitsInit to be decoded. 141201360Srdivacky/// @return - The field, with the first bit in the BitsInit as the lowest 142201360Srdivacky/// order bit. 143201360Srdivackystatic uint8_t byteFromBitsInit(BitsInit &init) { 144201360Srdivacky int width = init.getNumBits(); 145201360Srdivacky 146201360Srdivacky assert(width <= 8 && "Field is too large for uint8_t!"); 147201360Srdivacky 148201360Srdivacky int index; 149201360Srdivacky uint8_t mask = 0x01; 150201360Srdivacky 151201360Srdivacky uint8_t ret = 0; 152201360Srdivacky 153201360Srdivacky for (index = 0; index < width; index++) { 154201360Srdivacky if (static_cast<BitInit*>(init.getBit(index))->getValue()) 155201360Srdivacky ret |= mask; 156201360Srdivacky 157201360Srdivacky mask <<= 1; 158201360Srdivacky } 159201360Srdivacky 160201360Srdivacky return ret; 161201360Srdivacky} 162201360Srdivacky 163201360Srdivacky/// byteFromRec - Extract a value at most 8 bits in with from a Record given the 164201360Srdivacky/// name of the field. 165201360Srdivacky/// 166201360Srdivacky/// @param rec - The record from which to extract the value. 167201360Srdivacky/// @param name - The name of the field in the record. 168201360Srdivacky/// @return - The field, as translated by byteFromBitsInit(). 169201360Srdivackystatic uint8_t byteFromRec(const Record* rec, const std::string &name) { 170201360Srdivacky BitsInit* bits = rec->getValueAsBitsInit(name); 171201360Srdivacky return byteFromBitsInit(*bits); 172201360Srdivacky} 173201360Srdivacky 174201360SrdivackyRecognizableInstr::RecognizableInstr(DisassemblerTables &tables, 175201360Srdivacky const CodeGenInstruction &insn, 176201360Srdivacky InstrUID uid) { 177201360Srdivacky UID = uid; 178201360Srdivacky 179201360Srdivacky Rec = insn.TheDef; 180201360Srdivacky Name = Rec->getName(); 181201360Srdivacky Spec = &tables.specForUID(UID); 182239462Sdim 183201360Srdivacky if (!Rec->isSubClassOf("X86Inst")) { 184201360Srdivacky ShouldBeEmitted = false; 185201360Srdivacky return; 186201360Srdivacky } 187239462Sdim 188276479Sdim OpPrefix = byteFromRec(Rec, "OpPrefixBits"); 189276479Sdim OpMap = byteFromRec(Rec, "OpMapBits"); 190201360Srdivacky Opcode = byteFromRec(Rec, "Opcode"); 191201360Srdivacky Form = byteFromRec(Rec, "FormBits"); 192276479Sdim Encoding = byteFromRec(Rec, "OpEncBits"); 193239462Sdim 194276479Sdim OpSize = byteFromRec(Rec, "OpSizeBits"); 195234353Sdim HasAdSizePrefix = Rec->getValueAsBit("hasAdSizePrefix"); 196201360Srdivacky HasREX_WPrefix = Rec->getValueAsBit("hasREX_WPrefix"); 197276479Sdim HasVEX_4V = Rec->getValueAsBit("hasVEX_4V"); 198276479Sdim HasVEX_4VOp3 = Rec->getValueAsBit("hasVEX_4VOp3"); 199221345Sdim HasVEX_WPrefix = Rec->getValueAsBit("hasVEX_WPrefix"); 200234353Sdim HasMemOp4Prefix = Rec->getValueAsBit("hasMemOp4Prefix"); 201226633Sdim IgnoresVEX_L = Rec->getValueAsBit("ignoresVEX_L"); 202261991Sdim HasEVEX_L2Prefix = Rec->getValueAsBit("hasEVEX_L2"); 203261991Sdim HasEVEX_K = Rec->getValueAsBit("hasEVEX_K"); 204261991Sdim HasEVEX_KZ = Rec->getValueAsBit("hasEVEX_Z"); 205261991Sdim HasEVEX_B = Rec->getValueAsBit("hasEVEX_B"); 206201360Srdivacky IsCodeGenOnly = Rec->getValueAsBit("isCodeGenOnly"); 207276479Sdim ForceDisassemble = Rec->getValueAsBit("ForceDisassemble"); 208276479Sdim CD8_Scale = byteFromRec(Rec, "CD8_Scale"); 209239462Sdim 210201360Srdivacky Name = Rec->getName(); 211201360Srdivacky AsmString = Rec->getValueAsString("AsmString"); 212239462Sdim 213218893Sdim Operands = &insn.Operands.OperandList; 214239462Sdim 215243830Sdim HasVEX_LPrefix = Rec->getValueAsBit("hasVEX_L"); 216234353Sdim 217224145Sdim // Check for 64-bit inst which does not require REX 218226633Sdim Is32Bit = false; 219224145Sdim Is64Bit = false; 220224145Sdim // FIXME: Is there some better way to check for In64BitMode? 221224145Sdim std::vector<Record*> Predicates = Rec->getValueAsListOfDefs("Predicates"); 222224145Sdim for (unsigned i = 0, e = Predicates.size(); i != e; ++i) { 223276479Sdim if (Predicates[i]->getName().find("Not64Bit") != Name.npos || 224276479Sdim Predicates[i]->getName().find("In32Bit") != Name.npos) { 225226633Sdim Is32Bit = true; 226226633Sdim break; 227226633Sdim } 228276479Sdim if (Predicates[i]->getName().find("In64Bit") != Name.npos) { 229224145Sdim Is64Bit = true; 230224145Sdim break; 231224145Sdim } 232224145Sdim } 233224145Sdim 234276479Sdim if (Form == X86Local::Pseudo || (IsCodeGenOnly && !ForceDisassemble)) { 235276479Sdim ShouldBeEmitted = false; 236276479Sdim return; 237276479Sdim } 238276479Sdim 239276479Sdim // Special case since there is no attribute class for 64-bit and VEX 240276479Sdim if (Name == "VMASKMOVDQU64") { 241276479Sdim ShouldBeEmitted = false; 242276479Sdim return; 243276479Sdim } 244276479Sdim 245201360Srdivacky ShouldBeEmitted = true; 246201360Srdivacky} 247239462Sdim 248201360Srdivackyvoid RecognizableInstr::processInstr(DisassemblerTables &tables, 249239462Sdim const CodeGenInstruction &insn, 250239462Sdim InstrUID uid) 251201360Srdivacky{ 252208599Srdivacky // Ignore "asm parser only" instructions. 253208599Srdivacky if (insn.TheDef->getValueAsBit("isAsmParserOnly")) 254208599Srdivacky return; 255239462Sdim 256201360Srdivacky RecognizableInstr recogInstr(tables, insn, uid); 257239462Sdim 258276479Sdim if (recogInstr.shouldBeEmitted()) { 259276479Sdim recogInstr.emitInstructionSpecifier(); 260201360Srdivacky recogInstr.emitDecodePath(tables); 261276479Sdim } 262201360Srdivacky} 263201360Srdivacky 264261991Sdim#define EVEX_KB(n) (HasEVEX_KZ && HasEVEX_B ? n##_KZ_B : \ 265261991Sdim (HasEVEX_K && HasEVEX_B ? n##_K_B : \ 266261991Sdim (HasEVEX_KZ ? n##_KZ : \ 267261991Sdim (HasEVEX_K? n##_K : (HasEVEX_B ? n##_B : n))))) 268261991Sdim 269201360SrdivackyInstructionContext RecognizableInstr::insnContext() const { 270201360Srdivacky InstructionContext insnContext; 271201360Srdivacky 272276479Sdim if (Encoding == X86Local::EVEX) { 273261991Sdim if (HasVEX_LPrefix && HasEVEX_L2Prefix) { 274261991Sdim errs() << "Don't support VEX.L if EVEX_L2 is enabled: " << Name << "\n"; 275261991Sdim llvm_unreachable("Don't support VEX.L if EVEX_L2 is enabled"); 276261991Sdim } 277261991Sdim // VEX_L & VEX_W 278234353Sdim if (HasVEX_LPrefix && HasVEX_WPrefix) { 279276479Sdim if (OpPrefix == X86Local::PD) 280261991Sdim insnContext = EVEX_KB(IC_EVEX_L_W_OPSIZE); 281276479Sdim else if (OpPrefix == X86Local::XS) 282261991Sdim insnContext = EVEX_KB(IC_EVEX_L_W_XS); 283276479Sdim else if (OpPrefix == X86Local::XD) 284261991Sdim insnContext = EVEX_KB(IC_EVEX_L_W_XD); 285276479Sdim else if (OpPrefix == X86Local::PS) 286261991Sdim insnContext = EVEX_KB(IC_EVEX_L_W); 287276479Sdim else { 288276479Sdim errs() << "Instruction does not use a prefix: " << Name << "\n"; 289276479Sdim llvm_unreachable("Invalid prefix"); 290276479Sdim } 291261991Sdim } else if (HasVEX_LPrefix) { 292261991Sdim // VEX_L 293276479Sdim if (OpPrefix == X86Local::PD) 294261991Sdim insnContext = EVEX_KB(IC_EVEX_L_OPSIZE); 295276479Sdim else if (OpPrefix == X86Local::XS) 296261991Sdim insnContext = EVEX_KB(IC_EVEX_L_XS); 297276479Sdim else if (OpPrefix == X86Local::XD) 298261991Sdim insnContext = EVEX_KB(IC_EVEX_L_XD); 299276479Sdim else if (OpPrefix == X86Local::PS) 300261991Sdim insnContext = EVEX_KB(IC_EVEX_L); 301276479Sdim else { 302276479Sdim errs() << "Instruction does not use a prefix: " << Name << "\n"; 303276479Sdim llvm_unreachable("Invalid prefix"); 304276479Sdim } 305261991Sdim } 306261991Sdim else if (HasEVEX_L2Prefix && HasVEX_WPrefix) { 307261991Sdim // EVEX_L2 & VEX_W 308276479Sdim if (OpPrefix == X86Local::PD) 309261991Sdim insnContext = EVEX_KB(IC_EVEX_L2_W_OPSIZE); 310276479Sdim else if (OpPrefix == X86Local::XS) 311261991Sdim insnContext = EVEX_KB(IC_EVEX_L2_W_XS); 312276479Sdim else if (OpPrefix == X86Local::XD) 313261991Sdim insnContext = EVEX_KB(IC_EVEX_L2_W_XD); 314276479Sdim else if (OpPrefix == X86Local::PS) 315261991Sdim insnContext = EVEX_KB(IC_EVEX_L2_W); 316276479Sdim else { 317276479Sdim errs() << "Instruction does not use a prefix: " << Name << "\n"; 318276479Sdim llvm_unreachable("Invalid prefix"); 319276479Sdim } 320261991Sdim } else if (HasEVEX_L2Prefix) { 321261991Sdim // EVEX_L2 322276479Sdim if (OpPrefix == X86Local::PD) 323261991Sdim insnContext = EVEX_KB(IC_EVEX_L2_OPSIZE); 324276479Sdim else if (OpPrefix == X86Local::XD) 325261991Sdim insnContext = EVEX_KB(IC_EVEX_L2_XD); 326276479Sdim else if (OpPrefix == X86Local::XS) 327261991Sdim insnContext = EVEX_KB(IC_EVEX_L2_XS); 328276479Sdim else if (OpPrefix == X86Local::PS) 329261991Sdim insnContext = EVEX_KB(IC_EVEX_L2); 330276479Sdim else { 331276479Sdim errs() << "Instruction does not use a prefix: " << Name << "\n"; 332276479Sdim llvm_unreachable("Invalid prefix"); 333276479Sdim } 334261991Sdim } 335261991Sdim else if (HasVEX_WPrefix) { 336261991Sdim // VEX_W 337276479Sdim if (OpPrefix == X86Local::PD) 338261991Sdim insnContext = EVEX_KB(IC_EVEX_W_OPSIZE); 339276479Sdim else if (OpPrefix == X86Local::XS) 340261991Sdim insnContext = EVEX_KB(IC_EVEX_W_XS); 341276479Sdim else if (OpPrefix == X86Local::XD) 342261991Sdim insnContext = EVEX_KB(IC_EVEX_W_XD); 343276479Sdim else if (OpPrefix == X86Local::PS) 344261991Sdim insnContext = EVEX_KB(IC_EVEX_W); 345276479Sdim else { 346276479Sdim errs() << "Instruction does not use a prefix: " << Name << "\n"; 347276479Sdim llvm_unreachable("Invalid prefix"); 348276479Sdim } 349261991Sdim } 350261991Sdim // No L, no W 351276479Sdim else if (OpPrefix == X86Local::PD) 352261991Sdim insnContext = EVEX_KB(IC_EVEX_OPSIZE); 353276479Sdim else if (OpPrefix == X86Local::XD) 354261991Sdim insnContext = EVEX_KB(IC_EVEX_XD); 355276479Sdim else if (OpPrefix == X86Local::XS) 356261991Sdim insnContext = EVEX_KB(IC_EVEX_XS); 357261991Sdim else 358261991Sdim insnContext = EVEX_KB(IC_EVEX); 359261991Sdim /// eof EVEX 360276479Sdim } else if (Encoding == X86Local::VEX || Encoding == X86Local::XOP) { 361261991Sdim if (HasVEX_LPrefix && HasVEX_WPrefix) { 362276479Sdim if (OpPrefix == X86Local::PD) 363234353Sdim insnContext = IC_VEX_L_W_OPSIZE; 364276479Sdim else if (OpPrefix == X86Local::XS) 365261991Sdim insnContext = IC_VEX_L_W_XS; 366276479Sdim else if (OpPrefix == X86Local::XD) 367261991Sdim insnContext = IC_VEX_L_W_XD; 368276479Sdim else if (OpPrefix == X86Local::PS) 369261991Sdim insnContext = IC_VEX_L_W; 370276479Sdim else { 371276479Sdim errs() << "Instruction does not use a prefix: " << Name << "\n"; 372276479Sdim llvm_unreachable("Invalid prefix"); 373276479Sdim } 374276479Sdim } else if (OpPrefix == X86Local::PD && HasVEX_LPrefix) 375221345Sdim insnContext = IC_VEX_L_OPSIZE; 376276479Sdim else if (OpPrefix == X86Local::PD && HasVEX_WPrefix) 377221345Sdim insnContext = IC_VEX_W_OPSIZE; 378276479Sdim else if (OpPrefix == X86Local::PD) 379221345Sdim insnContext = IC_VEX_OPSIZE; 380276479Sdim else if (HasVEX_LPrefix && OpPrefix == X86Local::XS) 381221345Sdim insnContext = IC_VEX_L_XS; 382276479Sdim else if (HasVEX_LPrefix && OpPrefix == X86Local::XD) 383221345Sdim insnContext = IC_VEX_L_XD; 384276479Sdim else if (HasVEX_WPrefix && OpPrefix == X86Local::XS) 385221345Sdim insnContext = IC_VEX_W_XS; 386276479Sdim else if (HasVEX_WPrefix && OpPrefix == X86Local::XD) 387221345Sdim insnContext = IC_VEX_W_XD; 388276479Sdim else if (HasVEX_WPrefix && OpPrefix == X86Local::PS) 389221345Sdim insnContext = IC_VEX_W; 390276479Sdim else if (HasVEX_LPrefix && OpPrefix == X86Local::PS) 391221345Sdim insnContext = IC_VEX_L; 392276479Sdim else if (OpPrefix == X86Local::XD) 393221345Sdim insnContext = IC_VEX_XD; 394276479Sdim else if (OpPrefix == X86Local::XS) 395221345Sdim insnContext = IC_VEX_XS; 396276479Sdim else if (OpPrefix == X86Local::PS) 397221345Sdim insnContext = IC_VEX; 398276479Sdim else { 399276479Sdim errs() << "Instruction does not use a prefix: " << Name << "\n"; 400276479Sdim llvm_unreachable("Invalid prefix"); 401276479Sdim } 402224145Sdim } else if (Is64Bit || HasREX_WPrefix) { 403276479Sdim if (HasREX_WPrefix && (OpSize == X86Local::OpSize16 || OpPrefix == X86Local::PD)) 404201360Srdivacky insnContext = IC_64BIT_REXW_OPSIZE; 405276479Sdim else if (OpSize == X86Local::OpSize16 && OpPrefix == X86Local::XD) 406234353Sdim insnContext = IC_64BIT_XD_OPSIZE; 407276479Sdim else if (OpSize == X86Local::OpSize16 && OpPrefix == X86Local::XS) 408226633Sdim insnContext = IC_64BIT_XS_OPSIZE; 409276479Sdim else if (OpSize == X86Local::OpSize16 || OpPrefix == X86Local::PD) 410201360Srdivacky insnContext = IC_64BIT_OPSIZE; 411234353Sdim else if (HasAdSizePrefix) 412234353Sdim insnContext = IC_64BIT_ADSIZE; 413276479Sdim else if (HasREX_WPrefix && OpPrefix == X86Local::XS) 414201360Srdivacky insnContext = IC_64BIT_REXW_XS; 415276479Sdim else if (HasREX_WPrefix && OpPrefix == X86Local::XD) 416201360Srdivacky insnContext = IC_64BIT_REXW_XD; 417276479Sdim else if (OpPrefix == X86Local::XD) 418201360Srdivacky insnContext = IC_64BIT_XD; 419276479Sdim else if (OpPrefix == X86Local::XS) 420201360Srdivacky insnContext = IC_64BIT_XS; 421201360Srdivacky else if (HasREX_WPrefix) 422201360Srdivacky insnContext = IC_64BIT_REXW; 423201360Srdivacky else 424201360Srdivacky insnContext = IC_64BIT; 425201360Srdivacky } else { 426276479Sdim if (OpSize == X86Local::OpSize16 && OpPrefix == X86Local::XD) 427226633Sdim insnContext = IC_XD_OPSIZE; 428276479Sdim else if (OpSize == X86Local::OpSize16 && OpPrefix == X86Local::XS) 429226633Sdim insnContext = IC_XS_OPSIZE; 430276479Sdim else if (OpSize == X86Local::OpSize16 || OpPrefix == X86Local::PD) 431201360Srdivacky insnContext = IC_OPSIZE; 432234353Sdim else if (HasAdSizePrefix) 433234353Sdim insnContext = IC_ADSIZE; 434276479Sdim else if (OpPrefix == X86Local::XD) 435201360Srdivacky insnContext = IC_XD; 436276479Sdim else if (OpPrefix == X86Local::XS) 437201360Srdivacky insnContext = IC_XS; 438201360Srdivacky else 439201360Srdivacky insnContext = IC; 440201360Srdivacky } 441201360Srdivacky 442201360Srdivacky return insnContext; 443201360Srdivacky} 444239462Sdim 445276479Sdimvoid RecognizableInstr::adjustOperandEncoding(OperandEncoding &encoding) { 446276479Sdim // The scaling factor for AVX512 compressed displacement encoding is an 447276479Sdim // instruction attribute. Adjust the ModRM encoding type to include the 448276479Sdim // scale for compressed displacement. 449276479Sdim if (encoding != ENCODING_RM || CD8_Scale == 0) 450276479Sdim return; 451276479Sdim encoding = (OperandEncoding)(encoding + Log2_32(CD8_Scale)); 452276479Sdim assert(encoding <= ENCODING_RM_CD64 && "Invalid CDisp scaling"); 453201360Srdivacky} 454221345Sdim 455239462Sdimvoid RecognizableInstr::handleOperand(bool optional, unsigned &operandIndex, 456239462Sdim unsigned &physicalOperandIndex, 457239462Sdim unsigned &numPhysicalOperands, 458239462Sdim const unsigned *operandMapping, 459239462Sdim OperandEncoding (*encodingFromString) 460239462Sdim (const std::string&, 461276479Sdim uint8_t OpSize)) { 462201360Srdivacky if (optional) { 463201360Srdivacky if (physicalOperandIndex >= numPhysicalOperands) 464201360Srdivacky return; 465201360Srdivacky } else { 466201360Srdivacky assert(physicalOperandIndex < numPhysicalOperands); 467201360Srdivacky } 468239462Sdim 469201360Srdivacky while (operandMapping[operandIndex] != operandIndex) { 470201360Srdivacky Spec->operands[operandIndex].encoding = ENCODING_DUP; 471201360Srdivacky Spec->operands[operandIndex].type = 472201360Srdivacky (OperandType)(TYPE_DUP0 + operandMapping[operandIndex]); 473201360Srdivacky ++operandIndex; 474201360Srdivacky } 475239462Sdim 476201360Srdivacky const std::string &typeName = (*Operands)[operandIndex].Rec->getName(); 477221345Sdim 478276479Sdim OperandEncoding encoding = encodingFromString(typeName, OpSize); 479276479Sdim // Adjust the encoding type for an operand based on the instruction. 480276479Sdim adjustOperandEncoding(encoding); 481276479Sdim Spec->operands[operandIndex].encoding = encoding; 482239462Sdim Spec->operands[operandIndex].type = typeFromString(typeName, 483276479Sdim HasREX_WPrefix, OpSize); 484239462Sdim 485201360Srdivacky ++operandIndex; 486201360Srdivacky ++physicalOperandIndex; 487201360Srdivacky} 488201360Srdivacky 489276479Sdimvoid RecognizableInstr::emitInstructionSpecifier() { 490201360Srdivacky Spec->name = Name; 491239462Sdim 492201360Srdivacky Spec->insnContext = insnContext(); 493239462Sdim 494218893Sdim const std::vector<CGIOperandList::OperandInfo> &OperandList = *Operands; 495239462Sdim 496201360Srdivacky unsigned numOperands = OperandList.size(); 497201360Srdivacky unsigned numPhysicalOperands = 0; 498239462Sdim 499201360Srdivacky // operandMapping maps from operands in OperandList to their originals. 500201360Srdivacky // If operandMapping[i] != i, then the entry is a duplicate. 501201360Srdivacky unsigned operandMapping[X86_MAX_OPERANDS]; 502234353Sdim assert(numOperands <= X86_MAX_OPERANDS && "X86_MAX_OPERANDS is not large enough"); 503239462Sdim 504239462Sdim for (unsigned operandIndex = 0; operandIndex < numOperands; ++operandIndex) { 505201360Srdivacky if (OperandList[operandIndex].Constraints.size()) { 506218893Sdim const CGIOperandList::ConstraintInfo &Constraint = 507203954Srdivacky OperandList[operandIndex].Constraints[0]; 508203954Srdivacky if (Constraint.isTied()) { 509239462Sdim operandMapping[operandIndex] = operandIndex; 510239462Sdim operandMapping[Constraint.getTiedOperand()] = operandIndex; 511201360Srdivacky } else { 512201360Srdivacky ++numPhysicalOperands; 513201360Srdivacky operandMapping[operandIndex] = operandIndex; 514201360Srdivacky } 515201360Srdivacky } else { 516201360Srdivacky ++numPhysicalOperands; 517201360Srdivacky operandMapping[operandIndex] = operandIndex; 518201360Srdivacky } 519201360Srdivacky } 520201360Srdivacky 521201360Srdivacky#define HANDLE_OPERAND(class) \ 522201360Srdivacky handleOperand(false, \ 523201360Srdivacky operandIndex, \ 524201360Srdivacky physicalOperandIndex, \ 525201360Srdivacky numPhysicalOperands, \ 526201360Srdivacky operandMapping, \ 527201360Srdivacky class##EncodingFromString); 528239462Sdim 529201360Srdivacky#define HANDLE_OPTIONAL(class) \ 530201360Srdivacky handleOperand(true, \ 531201360Srdivacky operandIndex, \ 532201360Srdivacky physicalOperandIndex, \ 533201360Srdivacky numPhysicalOperands, \ 534201360Srdivacky operandMapping, \ 535201360Srdivacky class##EncodingFromString); 536239462Sdim 537201360Srdivacky // operandIndex should always be < numOperands 538239462Sdim unsigned operandIndex = 0; 539201360Srdivacky // physicalOperandIndex should always be < numPhysicalOperands 540201360Srdivacky unsigned physicalOperandIndex = 0; 541239462Sdim 542201360Srdivacky switch (Form) { 543276479Sdim default: llvm_unreachable("Unhandled form"); 544276479Sdim case X86Local::RawFrmSrc: 545276479Sdim HANDLE_OPERAND(relocation); 546276479Sdim return; 547276479Sdim case X86Local::RawFrmDst: 548276479Sdim HANDLE_OPERAND(relocation); 549276479Sdim return; 550276479Sdim case X86Local::RawFrmDstSrc: 551276479Sdim HANDLE_OPERAND(relocation); 552276479Sdim HANDLE_OPERAND(relocation); 553276479Sdim return; 554201360Srdivacky case X86Local::RawFrm: 555201360Srdivacky // Operand 1 (optional) is an address or immediate. 556201360Srdivacky // Operand 2 (optional) is an immediate. 557239462Sdim assert(numPhysicalOperands <= 2 && 558201360Srdivacky "Unexpected number of operands for RawFrm"); 559201360Srdivacky HANDLE_OPTIONAL(relocation) 560201360Srdivacky HANDLE_OPTIONAL(immediate) 561201360Srdivacky break; 562276479Sdim case X86Local::RawFrmMemOffs: 563276479Sdim // Operand 1 is an address. 564276479Sdim HANDLE_OPERAND(relocation); 565276479Sdim break; 566201360Srdivacky case X86Local::AddRegFrm: 567201360Srdivacky // Operand 1 is added to the opcode. 568201360Srdivacky // Operand 2 (optional) is an address. 569201360Srdivacky assert(numPhysicalOperands >= 1 && numPhysicalOperands <= 2 && 570201360Srdivacky "Unexpected number of operands for AddRegFrm"); 571201360Srdivacky HANDLE_OPERAND(opcodeModifier) 572201360Srdivacky HANDLE_OPTIONAL(relocation) 573201360Srdivacky break; 574201360Srdivacky case X86Local::MRMDestReg: 575201360Srdivacky // Operand 1 is a register operand in the R/M field. 576201360Srdivacky // Operand 2 is a register operand in the Reg/Opcode field. 577226633Sdim // - In AVX, there is a register operand in the VEX.vvvv field here - 578201360Srdivacky // Operand 3 (optional) is an immediate. 579276479Sdim if (HasVEX_4V) 580226633Sdim assert(numPhysicalOperands >= 3 && numPhysicalOperands <= 4 && 581226633Sdim "Unexpected number of operands for MRMDestRegFrm with VEX_4V"); 582226633Sdim else 583226633Sdim assert(numPhysicalOperands >= 2 && numPhysicalOperands <= 3 && 584226633Sdim "Unexpected number of operands for MRMDestRegFrm"); 585239462Sdim 586201360Srdivacky HANDLE_OPERAND(rmRegister) 587226633Sdim 588276479Sdim if (HasVEX_4V) 589226633Sdim // FIXME: In AVX, the register below becomes the one encoded 590226633Sdim // in ModRMVEX and the one above the one in the VEX.VVVV field 591226633Sdim HANDLE_OPERAND(vvvvRegister) 592239462Sdim 593201360Srdivacky HANDLE_OPERAND(roRegister) 594201360Srdivacky HANDLE_OPTIONAL(immediate) 595201360Srdivacky break; 596201360Srdivacky case X86Local::MRMDestMem: 597201360Srdivacky // Operand 1 is a memory operand (possibly SIB-extended) 598201360Srdivacky // Operand 2 is a register operand in the Reg/Opcode field. 599226633Sdim // - In AVX, there is a register operand in the VEX.vvvv field here - 600201360Srdivacky // Operand 3 (optional) is an immediate. 601276479Sdim if (HasVEX_4V) 602226633Sdim assert(numPhysicalOperands >= 3 && numPhysicalOperands <= 4 && 603226633Sdim "Unexpected number of operands for MRMDestMemFrm with VEX_4V"); 604226633Sdim else 605226633Sdim assert(numPhysicalOperands >= 2 && numPhysicalOperands <= 3 && 606226633Sdim "Unexpected number of operands for MRMDestMemFrm"); 607201360Srdivacky HANDLE_OPERAND(memory) 608226633Sdim 609261991Sdim if (HasEVEX_K) 610261991Sdim HANDLE_OPERAND(writemaskRegister) 611261991Sdim 612276479Sdim if (HasVEX_4V) 613226633Sdim // FIXME: In AVX, the register below becomes the one encoded 614226633Sdim // in ModRMVEX and the one above the one in the VEX.VVVV field 615226633Sdim HANDLE_OPERAND(vvvvRegister) 616239462Sdim 617201360Srdivacky HANDLE_OPERAND(roRegister) 618201360Srdivacky HANDLE_OPTIONAL(immediate) 619201360Srdivacky break; 620201360Srdivacky case X86Local::MRMSrcReg: 621201360Srdivacky // Operand 1 is a register operand in the Reg/Opcode field. 622201360Srdivacky // Operand 2 is a register operand in the R/M field. 623221345Sdim // - In AVX, there is a register operand in the VEX.vvvv field here - 624201360Srdivacky // Operand 3 (optional) is an immediate. 625239462Sdim // Operand 4 (optional) is an immediate. 626210299Sed 627276479Sdim if (HasVEX_4V || HasVEX_4VOp3) 628234353Sdim assert(numPhysicalOperands >= 3 && numPhysicalOperands <= 5 && 629239462Sdim "Unexpected number of operands for MRMSrcRegFrm with VEX_4V"); 630221345Sdim else 631239462Sdim assert(numPhysicalOperands >= 2 && numPhysicalOperands <= 4 && 632221345Sdim "Unexpected number of operands for MRMSrcRegFrm"); 633239462Sdim 634221345Sdim HANDLE_OPERAND(roRegister) 635234353Sdim 636261991Sdim if (HasEVEX_K) 637261991Sdim HANDLE_OPERAND(writemaskRegister) 638261991Sdim 639276479Sdim if (HasVEX_4V) 640210299Sed // FIXME: In AVX, the register below becomes the one encoded 641210299Sed // in ModRMVEX and the one above the one in the VEX.VVVV field 642221345Sdim HANDLE_OPERAND(vvvvRegister) 643234353Sdim 644234353Sdim if (HasMemOp4Prefix) 645234353Sdim HANDLE_OPERAND(immediate) 646234353Sdim 647221345Sdim HANDLE_OPERAND(rmRegister) 648234353Sdim 649276479Sdim if (HasVEX_4VOp3) 650234353Sdim HANDLE_OPERAND(vvvvRegister) 651234353Sdim 652234353Sdim if (!HasMemOp4Prefix) 653234353Sdim HANDLE_OPTIONAL(immediate) 654234353Sdim HANDLE_OPTIONAL(immediate) // above might be a register in 7:4 655239462Sdim HANDLE_OPTIONAL(immediate) 656201360Srdivacky break; 657201360Srdivacky case X86Local::MRMSrcMem: 658201360Srdivacky // Operand 1 is a register operand in the Reg/Opcode field. 659201360Srdivacky // Operand 2 is a memory operand (possibly SIB-extended) 660221345Sdim // - In AVX, there is a register operand in the VEX.vvvv field here - 661201360Srdivacky // Operand 3 (optional) is an immediate. 662234353Sdim 663276479Sdim if (HasVEX_4V || HasVEX_4VOp3) 664234353Sdim assert(numPhysicalOperands >= 3 && numPhysicalOperands <= 5 && 665239462Sdim "Unexpected number of operands for MRMSrcMemFrm with VEX_4V"); 666221345Sdim else 667221345Sdim assert(numPhysicalOperands >= 2 && numPhysicalOperands <= 3 && 668221345Sdim "Unexpected number of operands for MRMSrcMemFrm"); 669239462Sdim 670201360Srdivacky HANDLE_OPERAND(roRegister) 671210299Sed 672261991Sdim if (HasEVEX_K) 673261991Sdim HANDLE_OPERAND(writemaskRegister) 674261991Sdim 675276479Sdim if (HasVEX_4V) 676210299Sed // FIXME: In AVX, the register below becomes the one encoded 677210299Sed // in ModRMVEX and the one above the one in the VEX.VVVV field 678221345Sdim HANDLE_OPERAND(vvvvRegister) 679210299Sed 680234353Sdim if (HasMemOp4Prefix) 681234353Sdim HANDLE_OPERAND(immediate) 682234353Sdim 683201360Srdivacky HANDLE_OPERAND(memory) 684234353Sdim 685276479Sdim if (HasVEX_4VOp3) 686234353Sdim HANDLE_OPERAND(vvvvRegister) 687234353Sdim 688234353Sdim if (!HasMemOp4Prefix) 689234353Sdim HANDLE_OPTIONAL(immediate) 690234353Sdim HANDLE_OPTIONAL(immediate) // above might be a register in 7:4 691201360Srdivacky break; 692276479Sdim case X86Local::MRMXr: 693201360Srdivacky case X86Local::MRM0r: 694201360Srdivacky case X86Local::MRM1r: 695201360Srdivacky case X86Local::MRM2r: 696201360Srdivacky case X86Local::MRM3r: 697201360Srdivacky case X86Local::MRM4r: 698201360Srdivacky case X86Local::MRM5r: 699201360Srdivacky case X86Local::MRM6r: 700201360Srdivacky case X86Local::MRM7r: 701261991Sdim { 702261991Sdim // Operand 1 is a register operand in the R/M field. 703261991Sdim // Operand 2 (optional) is an immediate or relocation. 704261991Sdim // Operand 3 (optional) is an immediate. 705261991Sdim unsigned kOp = (HasEVEX_K) ? 1:0; 706276479Sdim unsigned Op4v = (HasVEX_4V) ? 1:0; 707261991Sdim if (numPhysicalOperands > 3 + kOp + Op4v) 708261991Sdim llvm_unreachable("Unexpected number of operands for MRMnr"); 709261991Sdim } 710276479Sdim if (HasVEX_4V) 711234353Sdim HANDLE_OPERAND(vvvvRegister) 712261991Sdim 713261991Sdim if (HasEVEX_K) 714261991Sdim HANDLE_OPERAND(writemaskRegister) 715201360Srdivacky HANDLE_OPTIONAL(rmRegister) 716201360Srdivacky HANDLE_OPTIONAL(relocation) 717239462Sdim HANDLE_OPTIONAL(immediate) 718201360Srdivacky break; 719276479Sdim case X86Local::MRMXm: 720201360Srdivacky case X86Local::MRM0m: 721201360Srdivacky case X86Local::MRM1m: 722201360Srdivacky case X86Local::MRM2m: 723201360Srdivacky case X86Local::MRM3m: 724201360Srdivacky case X86Local::MRM4m: 725201360Srdivacky case X86Local::MRM5m: 726201360Srdivacky case X86Local::MRM6m: 727201360Srdivacky case X86Local::MRM7m: 728261991Sdim { 729261991Sdim // Operand 1 is a memory operand (possibly SIB-extended) 730261991Sdim // Operand 2 (optional) is an immediate or relocation. 731261991Sdim unsigned kOp = (HasEVEX_K) ? 1:0; 732276479Sdim unsigned Op4v = (HasVEX_4V) ? 1:0; 733261991Sdim if (numPhysicalOperands < 1 + kOp + Op4v || 734261991Sdim numPhysicalOperands > 2 + kOp + Op4v) 735261991Sdim llvm_unreachable("Unexpected number of operands for MRMnm"); 736261991Sdim } 737276479Sdim if (HasVEX_4V) 738234353Sdim HANDLE_OPERAND(vvvvRegister) 739261991Sdim if (HasEVEX_K) 740261991Sdim HANDLE_OPERAND(writemaskRegister) 741201360Srdivacky HANDLE_OPERAND(memory) 742201360Srdivacky HANDLE_OPTIONAL(relocation) 743201360Srdivacky break; 744218893Sdim case X86Local::RawFrmImm8: 745218893Sdim // operand 1 is a 16-bit immediate 746218893Sdim // operand 2 is an 8-bit immediate 747218893Sdim assert(numPhysicalOperands == 2 && 748218893Sdim "Unexpected number of operands for X86Local::RawFrmImm8"); 749218893Sdim HANDLE_OPERAND(immediate) 750218893Sdim HANDLE_OPERAND(immediate) 751218893Sdim break; 752218893Sdim case X86Local::RawFrmImm16: 753218893Sdim // operand 1 is a 16-bit immediate 754218893Sdim // operand 2 is a 16-bit immediate 755218893Sdim HANDLE_OPERAND(immediate) 756218893Sdim HANDLE_OPERAND(immediate) 757218893Sdim break; 758249423Sdim case X86Local::MRM_F8: 759249423Sdim if (Opcode == 0xc6) { 760249423Sdim assert(numPhysicalOperands == 1 && 761249423Sdim "Unexpected number of operands for X86Local::MRM_F8"); 762249423Sdim HANDLE_OPERAND(immediate) 763249423Sdim } else if (Opcode == 0xc7) { 764249423Sdim assert(numPhysicalOperands == 1 && 765249423Sdim "Unexpected number of operands for X86Local::MRM_F8"); 766249423Sdim HANDLE_OPERAND(relocation) 767249423Sdim } 768249423Sdim break; 769276479Sdim case X86Local::MRM_C0: case X86Local::MRM_C1: case X86Local::MRM_C2: 770276479Sdim case X86Local::MRM_C3: case X86Local::MRM_C4: case X86Local::MRM_C8: 771276479Sdim case X86Local::MRM_C9: case X86Local::MRM_CA: case X86Local::MRM_CB: 772276479Sdim case X86Local::MRM_D0: case X86Local::MRM_D1: case X86Local::MRM_D4: 773276479Sdim case X86Local::MRM_D5: case X86Local::MRM_D6: case X86Local::MRM_D8: 774276479Sdim case X86Local::MRM_D9: case X86Local::MRM_DA: case X86Local::MRM_DB: 775276479Sdim case X86Local::MRM_DC: case X86Local::MRM_DD: case X86Local::MRM_DE: 776276479Sdim case X86Local::MRM_DF: case X86Local::MRM_E0: case X86Local::MRM_E1: 777276479Sdim case X86Local::MRM_E2: case X86Local::MRM_E3: case X86Local::MRM_E4: 778276479Sdim case X86Local::MRM_E5: case X86Local::MRM_E8: case X86Local::MRM_E9: 779276479Sdim case X86Local::MRM_EA: case X86Local::MRM_EB: case X86Local::MRM_EC: 780276479Sdim case X86Local::MRM_ED: case X86Local::MRM_EE: case X86Local::MRM_F0: 781276479Sdim case X86Local::MRM_F1: case X86Local::MRM_F2: case X86Local::MRM_F3: 782276479Sdim case X86Local::MRM_F4: case X86Local::MRM_F5: case X86Local::MRM_F6: 783276479Sdim case X86Local::MRM_F7: case X86Local::MRM_F9: case X86Local::MRM_FA: 784276479Sdim case X86Local::MRM_FB: case X86Local::MRM_FC: case X86Local::MRM_FD: 785276479Sdim case X86Local::MRM_FE: case X86Local::MRM_FF: 786201360Srdivacky // Ignored. 787201360Srdivacky break; 788201360Srdivacky } 789239462Sdim 790201360Srdivacky #undef HANDLE_OPERAND 791201360Srdivacky #undef HANDLE_OPTIONAL 792201360Srdivacky} 793201360Srdivacky 794201360Srdivackyvoid RecognizableInstr::emitDecodePath(DisassemblerTables &tables) const { 795201360Srdivacky // Special cases where the LLVM tables are not complete 796201360Srdivacky 797203954Srdivacky#define MAP(from, to) \ 798203954Srdivacky case X86Local::MRM_##from: \ 799203954Srdivacky filter = new ExactFilter(0x##from); \ 800203954Srdivacky break; 801201360Srdivacky 802201360Srdivacky OpcodeType opcodeType = (OpcodeType)-1; 803239462Sdim 804276479Sdim ModRMFilter* filter = nullptr; 805201360Srdivacky uint8_t opcodeToSet = 0; 806201360Srdivacky 807276479Sdim switch (OpMap) { 808276479Sdim default: llvm_unreachable("Invalid map!"); 809276479Sdim case X86Local::OB: 810201360Srdivacky case X86Local::TB: 811201360Srdivacky case X86Local::T8: 812276479Sdim case X86Local::TA: 813261991Sdim case X86Local::XOP8: 814261991Sdim case X86Local::XOP9: 815276479Sdim case X86Local::XOPA: 816276479Sdim switch (OpMap) { 817276479Sdim default: llvm_unreachable("Unexpected map!"); 818276479Sdim case X86Local::OB: opcodeType = ONEBYTE; break; 819276479Sdim case X86Local::TB: opcodeType = TWOBYTE; break; 820276479Sdim case X86Local::T8: opcodeType = THREEBYTE_38; break; 821276479Sdim case X86Local::TA: opcodeType = THREEBYTE_3A; break; 822276479Sdim case X86Local::XOP8: opcodeType = XOP8_MAP; break; 823276479Sdim case X86Local::XOP9: opcodeType = XOP9_MAP; break; 824276479Sdim case X86Local::XOPA: opcodeType = XOPA_MAP; break; 825276479Sdim } 826276479Sdim 827276479Sdim switch (Form) { 828261991Sdim default: 829276479Sdim filter = new DumbFilter(); 830261991Sdim break; 831276479Sdim case X86Local::MRMDestReg: case X86Local::MRMDestMem: 832276479Sdim case X86Local::MRMSrcReg: case X86Local::MRMSrcMem: 833276479Sdim case X86Local::MRMXr: case X86Local::MRMXm: 834261991Sdim filter = new ModFilter(isRegFormat(Form)); 835201360Srdivacky break; 836276479Sdim case X86Local::MRM0r: case X86Local::MRM1r: 837276479Sdim case X86Local::MRM2r: case X86Local::MRM3r: 838276479Sdim case X86Local::MRM4r: case X86Local::MRM5r: 839276479Sdim case X86Local::MRM6r: case X86Local::MRM7r: 840276479Sdim filter = new ExtendedFilter(true, Form - X86Local::MRM0r); 841201360Srdivacky break; 842276479Sdim case X86Local::MRM0m: case X86Local::MRM1m: 843276479Sdim case X86Local::MRM2m: case X86Local::MRM3m: 844276479Sdim case X86Local::MRM4m: case X86Local::MRM5m: 845276479Sdim case X86Local::MRM6m: case X86Local::MRM7m: 846276479Sdim filter = new ExtendedFilter(false, Form - X86Local::MRM0m); 847201360Srdivacky break; 848276479Sdim MRM_MAPPING 849276479Sdim } // switch (Form) 850276479Sdim 851201360Srdivacky opcodeToSet = Opcode; 852276479Sdim break; 853276479Sdim } // switch (OpMap) 854201360Srdivacky 855201360Srdivacky assert(opcodeType != (OpcodeType)-1 && 856201360Srdivacky "Opcode type not set"); 857201360Srdivacky assert(filter && "Filter not set"); 858201360Srdivacky 859201360Srdivacky if (Form == X86Local::AddRegFrm) { 860276479Sdim assert(((opcodeToSet & 7) == 0) && 861276479Sdim "ADDREG_FRM opcode not aligned"); 862239462Sdim 863276479Sdim uint8_t currentOpcode; 864201360Srdivacky 865276479Sdim for (currentOpcode = opcodeToSet; 866276479Sdim currentOpcode < opcodeToSet + 8; 867276479Sdim ++currentOpcode) 868239462Sdim tables.setTableFields(opcodeType, 869239462Sdim insnContext(), 870276479Sdim currentOpcode, 871239462Sdim *filter, 872226633Sdim UID, Is32Bit, IgnoresVEX_L); 873201360Srdivacky } else { 874201360Srdivacky tables.setTableFields(opcodeType, 875201360Srdivacky insnContext(), 876201360Srdivacky opcodeToSet, 877201360Srdivacky *filter, 878226633Sdim UID, Is32Bit, IgnoresVEX_L); 879201360Srdivacky } 880239462Sdim 881201360Srdivacky delete filter; 882239462Sdim 883203954Srdivacky#undef MAP 884201360Srdivacky} 885201360Srdivacky 886201360Srdivacky#define TYPE(str, type) if (s == str) return type; 887201360SrdivackyOperandType RecognizableInstr::typeFromString(const std::string &s, 888201360Srdivacky bool hasREX_WPrefix, 889276479Sdim uint8_t OpSize) { 890201360Srdivacky if(hasREX_WPrefix) { 891201360Srdivacky // For instructions with a REX_W prefix, a declared 32-bit register encoding 892201360Srdivacky // is special. 893201360Srdivacky TYPE("GR32", TYPE_R32) 894201360Srdivacky } 895276479Sdim if(OpSize == X86Local::OpSize16) { 896276479Sdim // For OpSize16 instructions, a declared 16-bit register or 897201360Srdivacky // immediate encoding is special. 898276479Sdim TYPE("GR16", TYPE_Rv) 899276479Sdim TYPE("i16imm", TYPE_IMMv) 900276479Sdim } else if(OpSize == X86Local::OpSize32) { 901276479Sdim // For OpSize32 instructions, a declared 32-bit register or 902276479Sdim // immediate encoding is special. 903276479Sdim TYPE("GR32", TYPE_Rv) 904201360Srdivacky } 905201360Srdivacky TYPE("i16mem", TYPE_Mv) 906276479Sdim TYPE("i16imm", TYPE_IMM16) 907201360Srdivacky TYPE("i16i8imm", TYPE_IMMv) 908276479Sdim TYPE("GR16", TYPE_R16) 909201360Srdivacky TYPE("i32mem", TYPE_Mv) 910201360Srdivacky TYPE("i32imm", TYPE_IMMv) 911201360Srdivacky TYPE("i32i8imm", TYPE_IMM32) 912226633Sdim TYPE("u32u8imm", TYPE_IMM32) 913276479Sdim TYPE("GR32", TYPE_R32) 914261991Sdim TYPE("GR32orGR64", TYPE_R32) 915201360Srdivacky TYPE("i64mem", TYPE_Mv) 916201360Srdivacky TYPE("i64i32imm", TYPE_IMM64) 917201360Srdivacky TYPE("i64i8imm", TYPE_IMM64) 918201360Srdivacky TYPE("GR64", TYPE_R64) 919201360Srdivacky TYPE("i8mem", TYPE_M8) 920201360Srdivacky TYPE("i8imm", TYPE_IMM8) 921201360Srdivacky TYPE("GR8", TYPE_R8) 922201360Srdivacky TYPE("VR128", TYPE_XMM128) 923261991Sdim TYPE("VR128X", TYPE_XMM128) 924201360Srdivacky TYPE("f128mem", TYPE_M128) 925218893Sdim TYPE("f256mem", TYPE_M256) 926261991Sdim TYPE("f512mem", TYPE_M512) 927201360Srdivacky TYPE("FR64", TYPE_XMM64) 928261991Sdim TYPE("FR64X", TYPE_XMM64) 929201360Srdivacky TYPE("f64mem", TYPE_M64FP) 930218893Sdim TYPE("sdmem", TYPE_M64FP) 931201360Srdivacky TYPE("FR32", TYPE_XMM32) 932261991Sdim TYPE("FR32X", TYPE_XMM32) 933201360Srdivacky TYPE("f32mem", TYPE_M32FP) 934218893Sdim TYPE("ssmem", TYPE_M32FP) 935201360Srdivacky TYPE("RST", TYPE_ST) 936201360Srdivacky TYPE("i128mem", TYPE_M128) 937221345Sdim TYPE("i256mem", TYPE_M256) 938261991Sdim TYPE("i512mem", TYPE_M512) 939201360Srdivacky TYPE("i64i32imm_pcrel", TYPE_REL64) 940210299Sed TYPE("i16imm_pcrel", TYPE_REL16) 941201360Srdivacky TYPE("i32imm_pcrel", TYPE_REL32) 942207618Srdivacky TYPE("SSECC", TYPE_IMM3) 943234353Sdim TYPE("AVXCC", TYPE_IMM5) 944276479Sdim TYPE("AVX512RC", TYPE_IMM32) 945201360Srdivacky TYPE("brtarget", TYPE_RELv) 946218893Sdim TYPE("uncondbrtarget", TYPE_RELv) 947201360Srdivacky TYPE("brtarget8", TYPE_REL8) 948201360Srdivacky TYPE("f80mem", TYPE_M80FP) 949201360Srdivacky TYPE("lea32mem", TYPE_LEA) 950201360Srdivacky TYPE("lea64_32mem", TYPE_LEA) 951201360Srdivacky TYPE("lea64mem", TYPE_LEA) 952201360Srdivacky TYPE("VR64", TYPE_MM64) 953201360Srdivacky TYPE("i64imm", TYPE_IMMv) 954201360Srdivacky TYPE("opaque32mem", TYPE_M1616) 955201360Srdivacky TYPE("opaque48mem", TYPE_M1632) 956201360Srdivacky TYPE("opaque80mem", TYPE_M1664) 957201360Srdivacky TYPE("opaque512mem", TYPE_M512) 958201360Srdivacky TYPE("SEGMENT_REG", TYPE_SEGMENTREG) 959201360Srdivacky TYPE("DEBUG_REG", TYPE_DEBUGREG) 960208599Srdivacky TYPE("CONTROL_REG", TYPE_CONTROLREG) 961276479Sdim TYPE("srcidx8", TYPE_SRCIDX8) 962276479Sdim TYPE("srcidx16", TYPE_SRCIDX16) 963276479Sdim TYPE("srcidx32", TYPE_SRCIDX32) 964276479Sdim TYPE("srcidx64", TYPE_SRCIDX64) 965276479Sdim TYPE("dstidx8", TYPE_DSTIDX8) 966276479Sdim TYPE("dstidx16", TYPE_DSTIDX16) 967276479Sdim TYPE("dstidx32", TYPE_DSTIDX32) 968276479Sdim TYPE("dstidx64", TYPE_DSTIDX64) 969201360Srdivacky TYPE("offset8", TYPE_MOFFS8) 970201360Srdivacky TYPE("offset16", TYPE_MOFFS16) 971201360Srdivacky TYPE("offset32", TYPE_MOFFS32) 972201360Srdivacky TYPE("offset64", TYPE_MOFFS64) 973221345Sdim TYPE("VR256", TYPE_XMM256) 974261991Sdim TYPE("VR256X", TYPE_XMM256) 975261991Sdim TYPE("VR512", TYPE_XMM512) 976276479Sdim TYPE("VK1", TYPE_VK1) 977276479Sdim TYPE("VK1WM", TYPE_VK1) 978276479Sdim TYPE("VK2", TYPE_VK2) 979276479Sdim TYPE("VK2WM", TYPE_VK2) 980276479Sdim TYPE("VK4", TYPE_VK4) 981276479Sdim TYPE("VK4WM", TYPE_VK4) 982261991Sdim TYPE("VK8", TYPE_VK8) 983261991Sdim TYPE("VK8WM", TYPE_VK8) 984261991Sdim TYPE("VK16", TYPE_VK16) 985261991Sdim TYPE("VK16WM", TYPE_VK16) 986276479Sdim TYPE("VK32", TYPE_VK32) 987276479Sdim TYPE("VK32WM", TYPE_VK32) 988276479Sdim TYPE("VK64", TYPE_VK64) 989276479Sdim TYPE("VK64WM", TYPE_VK64) 990226633Sdim TYPE("GR16_NOAX", TYPE_Rv) 991226633Sdim TYPE("GR32_NOAX", TYPE_Rv) 992226633Sdim TYPE("GR64_NOAX", TYPE_R64) 993239462Sdim TYPE("vx32mem", TYPE_M32) 994239462Sdim TYPE("vy32mem", TYPE_M32) 995261991Sdim TYPE("vz32mem", TYPE_M32) 996239462Sdim TYPE("vx64mem", TYPE_M64) 997239462Sdim TYPE("vy64mem", TYPE_M64) 998261991Sdim TYPE("vy64xmem", TYPE_M64) 999261991Sdim TYPE("vz64mem", TYPE_M64) 1000201360Srdivacky errs() << "Unhandled type string " << s << "\n"; 1001201360Srdivacky llvm_unreachable("Unhandled type string"); 1002201360Srdivacky} 1003201360Srdivacky#undef TYPE 1004201360Srdivacky 1005201360Srdivacky#define ENCODING(str, encoding) if (s == str) return encoding; 1006276479SdimOperandEncoding 1007276479SdimRecognizableInstr::immediateEncodingFromString(const std::string &s, 1008276479Sdim uint8_t OpSize) { 1009276479Sdim if(OpSize != X86Local::OpSize16) { 1010201360Srdivacky // For instructions without an OpSize prefix, a declared 16-bit register or 1011201360Srdivacky // immediate encoding is special. 1012201360Srdivacky ENCODING("i16imm", ENCODING_IW) 1013201360Srdivacky } 1014201360Srdivacky ENCODING("i32i8imm", ENCODING_IB) 1015226633Sdim ENCODING("u32u8imm", ENCODING_IB) 1016201360Srdivacky ENCODING("SSECC", ENCODING_IB) 1017234353Sdim ENCODING("AVXCC", ENCODING_IB) 1018276479Sdim ENCODING("AVX512RC", ENCODING_IB) 1019201360Srdivacky ENCODING("i16imm", ENCODING_Iv) 1020201360Srdivacky ENCODING("i16i8imm", ENCODING_IB) 1021201360Srdivacky ENCODING("i32imm", ENCODING_Iv) 1022201360Srdivacky ENCODING("i64i32imm", ENCODING_ID) 1023201360Srdivacky ENCODING("i64i8imm", ENCODING_IB) 1024201360Srdivacky ENCODING("i8imm", ENCODING_IB) 1025221345Sdim // This is not a typo. Instructions like BLENDVPD put 1026221345Sdim // register IDs in 8-bit immediates nowadays. 1027243830Sdim ENCODING("FR32", ENCODING_IB) 1028243830Sdim ENCODING("FR64", ENCODING_IB) 1029261991Sdim ENCODING("VR128", ENCODING_IB) 1030261991Sdim ENCODING("VR256", ENCODING_IB) 1031261991Sdim ENCODING("FR32X", ENCODING_IB) 1032261991Sdim ENCODING("FR64X", ENCODING_IB) 1033261991Sdim ENCODING("VR128X", ENCODING_IB) 1034261991Sdim ENCODING("VR256X", ENCODING_IB) 1035261991Sdim ENCODING("VR512", ENCODING_IB) 1036201360Srdivacky errs() << "Unhandled immediate encoding " << s << "\n"; 1037201360Srdivacky llvm_unreachable("Unhandled immediate encoding"); 1038201360Srdivacky} 1039201360Srdivacky 1040276479SdimOperandEncoding 1041276479SdimRecognizableInstr::rmRegisterEncodingFromString(const std::string &s, 1042276479Sdim uint8_t OpSize) { 1043276479Sdim ENCODING("RST", ENCODING_FP) 1044201360Srdivacky ENCODING("GR16", ENCODING_RM) 1045201360Srdivacky ENCODING("GR32", ENCODING_RM) 1046261991Sdim ENCODING("GR32orGR64", ENCODING_RM) 1047201360Srdivacky ENCODING("GR64", ENCODING_RM) 1048201360Srdivacky ENCODING("GR8", ENCODING_RM) 1049201360Srdivacky ENCODING("VR128", ENCODING_RM) 1050261991Sdim ENCODING("VR128X", ENCODING_RM) 1051201360Srdivacky ENCODING("FR64", ENCODING_RM) 1052201360Srdivacky ENCODING("FR32", ENCODING_RM) 1053261991Sdim ENCODING("FR64X", ENCODING_RM) 1054261991Sdim ENCODING("FR32X", ENCODING_RM) 1055201360Srdivacky ENCODING("VR64", ENCODING_RM) 1056221345Sdim ENCODING("VR256", ENCODING_RM) 1057261991Sdim ENCODING("VR256X", ENCODING_RM) 1058261991Sdim ENCODING("VR512", ENCODING_RM) 1059276479Sdim ENCODING("VK1", ENCODING_RM) 1060261991Sdim ENCODING("VK8", ENCODING_RM) 1061261991Sdim ENCODING("VK16", ENCODING_RM) 1062201360Srdivacky errs() << "Unhandled R/M register encoding " << s << "\n"; 1063201360Srdivacky llvm_unreachable("Unhandled R/M register encoding"); 1064201360Srdivacky} 1065201360Srdivacky 1066276479SdimOperandEncoding 1067276479SdimRecognizableInstr::roRegisterEncodingFromString(const std::string &s, 1068276479Sdim uint8_t OpSize) { 1069201360Srdivacky ENCODING("GR16", ENCODING_REG) 1070201360Srdivacky ENCODING("GR32", ENCODING_REG) 1071261991Sdim ENCODING("GR32orGR64", ENCODING_REG) 1072201360Srdivacky ENCODING("GR64", ENCODING_REG) 1073201360Srdivacky ENCODING("GR8", ENCODING_REG) 1074201360Srdivacky ENCODING("VR128", ENCODING_REG) 1075201360Srdivacky ENCODING("FR64", ENCODING_REG) 1076201360Srdivacky ENCODING("FR32", ENCODING_REG) 1077201360Srdivacky ENCODING("VR64", ENCODING_REG) 1078201360Srdivacky ENCODING("SEGMENT_REG", ENCODING_REG) 1079201360Srdivacky ENCODING("DEBUG_REG", ENCODING_REG) 1080208599Srdivacky ENCODING("CONTROL_REG", ENCODING_REG) 1081221345Sdim ENCODING("VR256", ENCODING_REG) 1082261991Sdim ENCODING("VR256X", ENCODING_REG) 1083261991Sdim ENCODING("VR128X", ENCODING_REG) 1084261991Sdim ENCODING("FR64X", ENCODING_REG) 1085261991Sdim ENCODING("FR32X", ENCODING_REG) 1086261991Sdim ENCODING("VR512", ENCODING_REG) 1087276479Sdim ENCODING("VK1", ENCODING_REG) 1088261991Sdim ENCODING("VK8", ENCODING_REG) 1089261991Sdim ENCODING("VK16", ENCODING_REG) 1090276479Sdim ENCODING("VK1WM", ENCODING_REG) 1091261991Sdim ENCODING("VK8WM", ENCODING_REG) 1092261991Sdim ENCODING("VK16WM", ENCODING_REG) 1093201360Srdivacky errs() << "Unhandled reg/opcode register encoding " << s << "\n"; 1094201360Srdivacky llvm_unreachable("Unhandled reg/opcode register encoding"); 1095201360Srdivacky} 1096201360Srdivacky 1097276479SdimOperandEncoding 1098276479SdimRecognizableInstr::vvvvRegisterEncodingFromString(const std::string &s, 1099276479Sdim uint8_t OpSize) { 1100226633Sdim ENCODING("GR32", ENCODING_VVVV) 1101226633Sdim ENCODING("GR64", ENCODING_VVVV) 1102221345Sdim ENCODING("FR32", ENCODING_VVVV) 1103221345Sdim ENCODING("FR64", ENCODING_VVVV) 1104221345Sdim ENCODING("VR128", ENCODING_VVVV) 1105221345Sdim ENCODING("VR256", ENCODING_VVVV) 1106261991Sdim ENCODING("FR32X", ENCODING_VVVV) 1107261991Sdim ENCODING("FR64X", ENCODING_VVVV) 1108261991Sdim ENCODING("VR128X", ENCODING_VVVV) 1109261991Sdim ENCODING("VR256X", ENCODING_VVVV) 1110261991Sdim ENCODING("VR512", ENCODING_VVVV) 1111276479Sdim ENCODING("VK1", ENCODING_VVVV) 1112276479Sdim ENCODING("VK2", ENCODING_VVVV) 1113276479Sdim ENCODING("VK4", ENCODING_VVVV) 1114261991Sdim ENCODING("VK8", ENCODING_VVVV) 1115261991Sdim ENCODING("VK16", ENCODING_VVVV) 1116221345Sdim errs() << "Unhandled VEX.vvvv register encoding " << s << "\n"; 1117221345Sdim llvm_unreachable("Unhandled VEX.vvvv register encoding"); 1118221345Sdim} 1119221345Sdim 1120276479SdimOperandEncoding 1121276479SdimRecognizableInstr::writemaskRegisterEncodingFromString(const std::string &s, 1122276479Sdim uint8_t OpSize) { 1123276479Sdim ENCODING("VK1WM", ENCODING_WRITEMASK) 1124276479Sdim ENCODING("VK2WM", ENCODING_WRITEMASK) 1125276479Sdim ENCODING("VK4WM", ENCODING_WRITEMASK) 1126261991Sdim ENCODING("VK8WM", ENCODING_WRITEMASK) 1127261991Sdim ENCODING("VK16WM", ENCODING_WRITEMASK) 1128276479Sdim ENCODING("VK32WM", ENCODING_WRITEMASK) 1129276479Sdim ENCODING("VK64WM", ENCODING_WRITEMASK) 1130261991Sdim errs() << "Unhandled mask register encoding " << s << "\n"; 1131261991Sdim llvm_unreachable("Unhandled mask register encoding"); 1132261991Sdim} 1133261991Sdim 1134276479SdimOperandEncoding 1135276479SdimRecognizableInstr::memoryEncodingFromString(const std::string &s, 1136276479Sdim uint8_t OpSize) { 1137201360Srdivacky ENCODING("i16mem", ENCODING_RM) 1138201360Srdivacky ENCODING("i32mem", ENCODING_RM) 1139201360Srdivacky ENCODING("i64mem", ENCODING_RM) 1140201360Srdivacky ENCODING("i8mem", ENCODING_RM) 1141218893Sdim ENCODING("ssmem", ENCODING_RM) 1142218893Sdim ENCODING("sdmem", ENCODING_RM) 1143201360Srdivacky ENCODING("f128mem", ENCODING_RM) 1144218893Sdim ENCODING("f256mem", ENCODING_RM) 1145261991Sdim ENCODING("f512mem", ENCODING_RM) 1146201360Srdivacky ENCODING("f64mem", ENCODING_RM) 1147201360Srdivacky ENCODING("f32mem", ENCODING_RM) 1148201360Srdivacky ENCODING("i128mem", ENCODING_RM) 1149221345Sdim ENCODING("i256mem", ENCODING_RM) 1150261991Sdim ENCODING("i512mem", ENCODING_RM) 1151201360Srdivacky ENCODING("f80mem", ENCODING_RM) 1152201360Srdivacky ENCODING("lea32mem", ENCODING_RM) 1153201360Srdivacky ENCODING("lea64_32mem", ENCODING_RM) 1154201360Srdivacky ENCODING("lea64mem", ENCODING_RM) 1155201360Srdivacky ENCODING("opaque32mem", ENCODING_RM) 1156201360Srdivacky ENCODING("opaque48mem", ENCODING_RM) 1157201360Srdivacky ENCODING("opaque80mem", ENCODING_RM) 1158201360Srdivacky ENCODING("opaque512mem", ENCODING_RM) 1159239462Sdim ENCODING("vx32mem", ENCODING_RM) 1160239462Sdim ENCODING("vy32mem", ENCODING_RM) 1161261991Sdim ENCODING("vz32mem", ENCODING_RM) 1162239462Sdim ENCODING("vx64mem", ENCODING_RM) 1163239462Sdim ENCODING("vy64mem", ENCODING_RM) 1164261991Sdim ENCODING("vy64xmem", ENCODING_RM) 1165261991Sdim ENCODING("vz64mem", ENCODING_RM) 1166201360Srdivacky errs() << "Unhandled memory encoding " << s << "\n"; 1167201360Srdivacky llvm_unreachable("Unhandled memory encoding"); 1168201360Srdivacky} 1169201360Srdivacky 1170276479SdimOperandEncoding 1171276479SdimRecognizableInstr::relocationEncodingFromString(const std::string &s, 1172276479Sdim uint8_t OpSize) { 1173276479Sdim if(OpSize != X86Local::OpSize16) { 1174201360Srdivacky // For instructions without an OpSize prefix, a declared 16-bit register or 1175201360Srdivacky // immediate encoding is special. 1176201360Srdivacky ENCODING("i16imm", ENCODING_IW) 1177201360Srdivacky } 1178201360Srdivacky ENCODING("i16imm", ENCODING_Iv) 1179201360Srdivacky ENCODING("i16i8imm", ENCODING_IB) 1180201360Srdivacky ENCODING("i32imm", ENCODING_Iv) 1181201360Srdivacky ENCODING("i32i8imm", ENCODING_IB) 1182201360Srdivacky ENCODING("i64i32imm", ENCODING_ID) 1183201360Srdivacky ENCODING("i64i8imm", ENCODING_IB) 1184201360Srdivacky ENCODING("i8imm", ENCODING_IB) 1185201360Srdivacky ENCODING("i64i32imm_pcrel", ENCODING_ID) 1186210299Sed ENCODING("i16imm_pcrel", ENCODING_IW) 1187201360Srdivacky ENCODING("i32imm_pcrel", ENCODING_ID) 1188201360Srdivacky ENCODING("brtarget", ENCODING_Iv) 1189201360Srdivacky ENCODING("brtarget8", ENCODING_IB) 1190201360Srdivacky ENCODING("i64imm", ENCODING_IO) 1191201360Srdivacky ENCODING("offset8", ENCODING_Ia) 1192201360Srdivacky ENCODING("offset16", ENCODING_Ia) 1193201360Srdivacky ENCODING("offset32", ENCODING_Ia) 1194201360Srdivacky ENCODING("offset64", ENCODING_Ia) 1195276479Sdim ENCODING("srcidx8", ENCODING_SI) 1196276479Sdim ENCODING("srcidx16", ENCODING_SI) 1197276479Sdim ENCODING("srcidx32", ENCODING_SI) 1198276479Sdim ENCODING("srcidx64", ENCODING_SI) 1199276479Sdim ENCODING("dstidx8", ENCODING_DI) 1200276479Sdim ENCODING("dstidx16", ENCODING_DI) 1201276479Sdim ENCODING("dstidx32", ENCODING_DI) 1202276479Sdim ENCODING("dstidx64", ENCODING_DI) 1203201360Srdivacky errs() << "Unhandled relocation encoding " << s << "\n"; 1204201360Srdivacky llvm_unreachable("Unhandled relocation encoding"); 1205201360Srdivacky} 1206201360Srdivacky 1207276479SdimOperandEncoding 1208276479SdimRecognizableInstr::opcodeModifierEncodingFromString(const std::string &s, 1209276479Sdim uint8_t OpSize) { 1210201360Srdivacky ENCODING("GR32", ENCODING_Rv) 1211201360Srdivacky ENCODING("GR64", ENCODING_RO) 1212201360Srdivacky ENCODING("GR16", ENCODING_Rv) 1213201360Srdivacky ENCODING("GR8", ENCODING_RB) 1214226633Sdim ENCODING("GR16_NOAX", ENCODING_Rv) 1215226633Sdim ENCODING("GR32_NOAX", ENCODING_Rv) 1216226633Sdim ENCODING("GR64_NOAX", ENCODING_RO) 1217201360Srdivacky errs() << "Unhandled opcode modifier encoding " << s << "\n"; 1218201360Srdivacky llvm_unreachable("Unhandled opcode modifier encoding"); 1219201360Srdivacky} 1220201360Srdivacky#undef ENCODING 1221