X86RecognizableInstr.cpp revision 341825
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 13321369Sdim// X86DisassemblerEmitter.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; 24201360Srdivackyusing namespace X86Disassembler; 25201360Srdivacky 26201360Srdivacky/// byteFromBitsInit - Extracts a value at most 8 bits in width from a BitsInit. 27201360Srdivacky/// Useful for switch statements and the like. 28201360Srdivacky/// 29201360Srdivacky/// @param init - A reference to the BitsInit to be decoded. 30201360Srdivacky/// @return - The field, with the first bit in the BitsInit as the lowest 31201360Srdivacky/// order bit. 32201360Srdivackystatic uint8_t byteFromBitsInit(BitsInit &init) { 33201360Srdivacky int width = init.getNumBits(); 34201360Srdivacky 35201360Srdivacky assert(width <= 8 && "Field is too large for uint8_t!"); 36201360Srdivacky 37201360Srdivacky int index; 38201360Srdivacky uint8_t mask = 0x01; 39201360Srdivacky 40201360Srdivacky uint8_t ret = 0; 41201360Srdivacky 42201360Srdivacky for (index = 0; index < width; index++) { 43341825Sdim if (cast<BitInit>(init.getBit(index))->getValue()) 44201360Srdivacky ret |= mask; 45201360Srdivacky 46201360Srdivacky mask <<= 1; 47201360Srdivacky } 48201360Srdivacky 49201360Srdivacky return ret; 50201360Srdivacky} 51201360Srdivacky 52201360Srdivacky/// byteFromRec - Extract a value at most 8 bits in with from a Record given the 53201360Srdivacky/// name of the field. 54201360Srdivacky/// 55201360Srdivacky/// @param rec - The record from which to extract the value. 56201360Srdivacky/// @param name - The name of the field in the record. 57201360Srdivacky/// @return - The field, as translated by byteFromBitsInit(). 58201360Srdivackystatic uint8_t byteFromRec(const Record* rec, const std::string &name) { 59201360Srdivacky BitsInit* bits = rec->getValueAsBitsInit(name); 60201360Srdivacky return byteFromBitsInit(*bits); 61201360Srdivacky} 62201360Srdivacky 63201360SrdivackyRecognizableInstr::RecognizableInstr(DisassemblerTables &tables, 64201360Srdivacky const CodeGenInstruction &insn, 65201360Srdivacky InstrUID uid) { 66201360Srdivacky UID = uid; 67201360Srdivacky 68201360Srdivacky Rec = insn.TheDef; 69201360Srdivacky Name = Rec->getName(); 70201360Srdivacky Spec = &tables.specForUID(UID); 71239462Sdim 72201360Srdivacky if (!Rec->isSubClassOf("X86Inst")) { 73201360Srdivacky ShouldBeEmitted = false; 74201360Srdivacky return; 75201360Srdivacky } 76239462Sdim 77276479Sdim OpPrefix = byteFromRec(Rec, "OpPrefixBits"); 78276479Sdim OpMap = byteFromRec(Rec, "OpMapBits"); 79201360Srdivacky Opcode = byteFromRec(Rec, "Opcode"); 80201360Srdivacky Form = byteFromRec(Rec, "FormBits"); 81276479Sdim Encoding = byteFromRec(Rec, "OpEncBits"); 82239462Sdim 83341825Sdim OpSize = byteFromRec(Rec, "OpSizeBits"); 84341825Sdim AdSize = byteFromRec(Rec, "AdSizeBits"); 85341825Sdim HasREX_WPrefix = Rec->getValueAsBit("hasREX_WPrefix"); 86341825Sdim HasVEX_4V = Rec->getValueAsBit("hasVEX_4V"); 87341825Sdim VEX_WPrefix = byteFromRec(Rec,"VEX_WPrefix"); 88341825Sdim IgnoresVEX_L = Rec->getValueAsBit("ignoresVEX_L"); 89341825Sdim HasEVEX_L2Prefix = Rec->getValueAsBit("hasEVEX_L2"); 90341825Sdim HasEVEX_K = Rec->getValueAsBit("hasEVEX_K"); 91341825Sdim HasEVEX_KZ = Rec->getValueAsBit("hasEVEX_Z"); 92341825Sdim HasEVEX_B = Rec->getValueAsBit("hasEVEX_B"); 93341825Sdim IsCodeGenOnly = Rec->getValueAsBit("isCodeGenOnly"); 94341825Sdim ForceDisassemble = Rec->getValueAsBit("ForceDisassemble"); 95341825Sdim CD8_Scale = byteFromRec(Rec, "CD8_Scale"); 96239462Sdim 97201360Srdivacky Name = Rec->getName(); 98239462Sdim 99218893Sdim Operands = &insn.Operands.OperandList; 100239462Sdim 101243830Sdim HasVEX_LPrefix = Rec->getValueAsBit("hasVEX_L"); 102234353Sdim 103327952Sdim EncodeRC = HasEVEX_B && 104327952Sdim (Form == X86Local::MRMDestReg || Form == X86Local::MRMSrcReg); 105327952Sdim 106224145Sdim // Check for 64-bit inst which does not require REX 107226633Sdim Is32Bit = false; 108224145Sdim Is64Bit = false; 109224145Sdim // FIXME: Is there some better way to check for In64BitMode? 110224145Sdim std::vector<Record*> Predicates = Rec->getValueAsListOfDefs("Predicates"); 111224145Sdim for (unsigned i = 0, e = Predicates.size(); i != e; ++i) { 112276479Sdim if (Predicates[i]->getName().find("Not64Bit") != Name.npos || 113276479Sdim Predicates[i]->getName().find("In32Bit") != Name.npos) { 114226633Sdim Is32Bit = true; 115226633Sdim break; 116226633Sdim } 117276479Sdim if (Predicates[i]->getName().find("In64Bit") != Name.npos) { 118224145Sdim Is64Bit = true; 119224145Sdim break; 120224145Sdim } 121224145Sdim } 122224145Sdim 123276479Sdim if (Form == X86Local::Pseudo || (IsCodeGenOnly && !ForceDisassemble)) { 124276479Sdim ShouldBeEmitted = false; 125276479Sdim return; 126276479Sdim } 127276479Sdim 128276479Sdim // Special case since there is no attribute class for 64-bit and VEX 129276479Sdim if (Name == "VMASKMOVDQU64") { 130276479Sdim ShouldBeEmitted = false; 131276479Sdim return; 132276479Sdim } 133276479Sdim 134201360Srdivacky ShouldBeEmitted = true; 135201360Srdivacky} 136239462Sdim 137201360Srdivackyvoid RecognizableInstr::processInstr(DisassemblerTables &tables, 138239462Sdim const CodeGenInstruction &insn, 139239462Sdim InstrUID uid) 140201360Srdivacky{ 141208599Srdivacky // Ignore "asm parser only" instructions. 142208599Srdivacky if (insn.TheDef->getValueAsBit("isAsmParserOnly")) 143208599Srdivacky return; 144239462Sdim 145201360Srdivacky RecognizableInstr recogInstr(tables, insn, uid); 146239462Sdim 147276479Sdim if (recogInstr.shouldBeEmitted()) { 148276479Sdim recogInstr.emitInstructionSpecifier(); 149201360Srdivacky recogInstr.emitDecodePath(tables); 150276479Sdim } 151201360Srdivacky} 152201360Srdivacky 153261991Sdim#define EVEX_KB(n) (HasEVEX_KZ && HasEVEX_B ? n##_KZ_B : \ 154261991Sdim (HasEVEX_K && HasEVEX_B ? n##_K_B : \ 155261991Sdim (HasEVEX_KZ ? n##_KZ : \ 156261991Sdim (HasEVEX_K? n##_K : (HasEVEX_B ? n##_B : n))))) 157261991Sdim 158201360SrdivackyInstructionContext RecognizableInstr::insnContext() const { 159201360Srdivacky InstructionContext insnContext; 160201360Srdivacky 161276479Sdim if (Encoding == X86Local::EVEX) { 162261991Sdim if (HasVEX_LPrefix && HasEVEX_L2Prefix) { 163261991Sdim errs() << "Don't support VEX.L if EVEX_L2 is enabled: " << Name << "\n"; 164261991Sdim llvm_unreachable("Don't support VEX.L if EVEX_L2 is enabled"); 165261991Sdim } 166261991Sdim // VEX_L & VEX_W 167341825Sdim if (!EncodeRC && HasVEX_LPrefix && (VEX_WPrefix == X86Local::VEX_W1 || 168341825Sdim VEX_WPrefix == X86Local::VEX_W1X)) { 169276479Sdim if (OpPrefix == X86Local::PD) 170261991Sdim insnContext = EVEX_KB(IC_EVEX_L_W_OPSIZE); 171276479Sdim else if (OpPrefix == X86Local::XS) 172261991Sdim insnContext = EVEX_KB(IC_EVEX_L_W_XS); 173276479Sdim else if (OpPrefix == X86Local::XD) 174261991Sdim insnContext = EVEX_KB(IC_EVEX_L_W_XD); 175276479Sdim else if (OpPrefix == X86Local::PS) 176261991Sdim insnContext = EVEX_KB(IC_EVEX_L_W); 177276479Sdim else { 178276479Sdim errs() << "Instruction does not use a prefix: " << Name << "\n"; 179276479Sdim llvm_unreachable("Invalid prefix"); 180276479Sdim } 181327952Sdim } else if (!EncodeRC && HasVEX_LPrefix) { 182261991Sdim // VEX_L 183276479Sdim if (OpPrefix == X86Local::PD) 184261991Sdim insnContext = EVEX_KB(IC_EVEX_L_OPSIZE); 185276479Sdim else if (OpPrefix == X86Local::XS) 186261991Sdim insnContext = EVEX_KB(IC_EVEX_L_XS); 187276479Sdim else if (OpPrefix == X86Local::XD) 188261991Sdim insnContext = EVEX_KB(IC_EVEX_L_XD); 189276479Sdim else if (OpPrefix == X86Local::PS) 190261991Sdim insnContext = EVEX_KB(IC_EVEX_L); 191276479Sdim else { 192276479Sdim errs() << "Instruction does not use a prefix: " << Name << "\n"; 193276479Sdim llvm_unreachable("Invalid prefix"); 194276479Sdim } 195327952Sdim } else if (!EncodeRC && HasEVEX_L2Prefix && 196341825Sdim (VEX_WPrefix == X86Local::VEX_W1 || 197341825Sdim VEX_WPrefix == X86Local::VEX_W1X)) { 198261991Sdim // EVEX_L2 & VEX_W 199276479Sdim if (OpPrefix == X86Local::PD) 200261991Sdim insnContext = EVEX_KB(IC_EVEX_L2_W_OPSIZE); 201276479Sdim else if (OpPrefix == X86Local::XS) 202261991Sdim insnContext = EVEX_KB(IC_EVEX_L2_W_XS); 203276479Sdim else if (OpPrefix == X86Local::XD) 204261991Sdim insnContext = EVEX_KB(IC_EVEX_L2_W_XD); 205276479Sdim else if (OpPrefix == X86Local::PS) 206261991Sdim insnContext = EVEX_KB(IC_EVEX_L2_W); 207276479Sdim else { 208276479Sdim errs() << "Instruction does not use a prefix: " << Name << "\n"; 209276479Sdim llvm_unreachable("Invalid prefix"); 210276479Sdim } 211327952Sdim } else if (!EncodeRC && HasEVEX_L2Prefix) { 212261991Sdim // EVEX_L2 213276479Sdim if (OpPrefix == X86Local::PD) 214261991Sdim insnContext = EVEX_KB(IC_EVEX_L2_OPSIZE); 215276479Sdim else if (OpPrefix == X86Local::XD) 216261991Sdim insnContext = EVEX_KB(IC_EVEX_L2_XD); 217276479Sdim else if (OpPrefix == X86Local::XS) 218261991Sdim insnContext = EVEX_KB(IC_EVEX_L2_XS); 219276479Sdim else if (OpPrefix == X86Local::PS) 220261991Sdim insnContext = EVEX_KB(IC_EVEX_L2); 221276479Sdim else { 222276479Sdim errs() << "Instruction does not use a prefix: " << Name << "\n"; 223276479Sdim llvm_unreachable("Invalid prefix"); 224276479Sdim } 225261991Sdim } 226341825Sdim else if (VEX_WPrefix == X86Local::VEX_W1 || 227341825Sdim VEX_WPrefix == X86Local::VEX_W1X) { 228261991Sdim // VEX_W 229276479Sdim if (OpPrefix == X86Local::PD) 230261991Sdim insnContext = EVEX_KB(IC_EVEX_W_OPSIZE); 231276479Sdim else if (OpPrefix == X86Local::XS) 232261991Sdim insnContext = EVEX_KB(IC_EVEX_W_XS); 233276479Sdim else if (OpPrefix == X86Local::XD) 234261991Sdim insnContext = EVEX_KB(IC_EVEX_W_XD); 235276479Sdim else if (OpPrefix == X86Local::PS) 236261991Sdim insnContext = EVEX_KB(IC_EVEX_W); 237276479Sdim else { 238276479Sdim errs() << "Instruction does not use a prefix: " << Name << "\n"; 239276479Sdim llvm_unreachable("Invalid prefix"); 240276479Sdim } 241261991Sdim } 242261991Sdim // No L, no W 243276479Sdim else if (OpPrefix == X86Local::PD) 244261991Sdim insnContext = EVEX_KB(IC_EVEX_OPSIZE); 245276479Sdim else if (OpPrefix == X86Local::XD) 246261991Sdim insnContext = EVEX_KB(IC_EVEX_XD); 247276479Sdim else if (OpPrefix == X86Local::XS) 248261991Sdim insnContext = EVEX_KB(IC_EVEX_XS); 249341825Sdim else if (OpPrefix == X86Local::PS) 250261991Sdim insnContext = EVEX_KB(IC_EVEX); 251341825Sdim else { 252341825Sdim errs() << "Instruction does not use a prefix: " << Name << "\n"; 253341825Sdim llvm_unreachable("Invalid prefix"); 254341825Sdim } 255261991Sdim /// eof EVEX 256276479Sdim } else if (Encoding == X86Local::VEX || Encoding == X86Local::XOP) { 257341825Sdim if (HasVEX_LPrefix && (VEX_WPrefix == X86Local::VEX_W1 || 258341825Sdim VEX_WPrefix == X86Local::VEX_W1X)) { 259276479Sdim if (OpPrefix == X86Local::PD) 260234353Sdim insnContext = IC_VEX_L_W_OPSIZE; 261276479Sdim else if (OpPrefix == X86Local::XS) 262261991Sdim insnContext = IC_VEX_L_W_XS; 263276479Sdim else if (OpPrefix == X86Local::XD) 264261991Sdim insnContext = IC_VEX_L_W_XD; 265276479Sdim else if (OpPrefix == X86Local::PS) 266261991Sdim insnContext = IC_VEX_L_W; 267276479Sdim else { 268276479Sdim errs() << "Instruction does not use a prefix: " << Name << "\n"; 269276479Sdim llvm_unreachable("Invalid prefix"); 270276479Sdim } 271276479Sdim } else if (OpPrefix == X86Local::PD && HasVEX_LPrefix) 272221345Sdim insnContext = IC_VEX_L_OPSIZE; 273341825Sdim else if (OpPrefix == X86Local::PD && (VEX_WPrefix == X86Local::VEX_W1 || 274341825Sdim VEX_WPrefix == X86Local::VEX_W1X)) 275221345Sdim insnContext = IC_VEX_W_OPSIZE; 276276479Sdim else if (OpPrefix == X86Local::PD) 277221345Sdim insnContext = IC_VEX_OPSIZE; 278276479Sdim else if (HasVEX_LPrefix && OpPrefix == X86Local::XS) 279221345Sdim insnContext = IC_VEX_L_XS; 280276479Sdim else if (HasVEX_LPrefix && OpPrefix == X86Local::XD) 281221345Sdim insnContext = IC_VEX_L_XD; 282341825Sdim else if ((VEX_WPrefix == X86Local::VEX_W1 || 283341825Sdim VEX_WPrefix == X86Local::VEX_W1X) && OpPrefix == X86Local::XS) 284221345Sdim insnContext = IC_VEX_W_XS; 285341825Sdim else if ((VEX_WPrefix == X86Local::VEX_W1 || 286341825Sdim VEX_WPrefix == X86Local::VEX_W1X) && OpPrefix == X86Local::XD) 287221345Sdim insnContext = IC_VEX_W_XD; 288341825Sdim else if ((VEX_WPrefix == X86Local::VEX_W1 || 289341825Sdim VEX_WPrefix == X86Local::VEX_W1X) && OpPrefix == X86Local::PS) 290221345Sdim insnContext = IC_VEX_W; 291276479Sdim else if (HasVEX_LPrefix && OpPrefix == X86Local::PS) 292221345Sdim insnContext = IC_VEX_L; 293276479Sdim else if (OpPrefix == X86Local::XD) 294221345Sdim insnContext = IC_VEX_XD; 295276479Sdim else if (OpPrefix == X86Local::XS) 296221345Sdim insnContext = IC_VEX_XS; 297276479Sdim else if (OpPrefix == X86Local::PS) 298221345Sdim insnContext = IC_VEX; 299276479Sdim else { 300276479Sdim errs() << "Instruction does not use a prefix: " << Name << "\n"; 301276479Sdim llvm_unreachable("Invalid prefix"); 302276479Sdim } 303280031Sdim } else if (Is64Bit || HasREX_WPrefix || AdSize == X86Local::AdSize64) { 304276479Sdim if (HasREX_WPrefix && (OpSize == X86Local::OpSize16 || OpPrefix == X86Local::PD)) 305201360Srdivacky insnContext = IC_64BIT_REXW_OPSIZE; 306280031Sdim else if (HasREX_WPrefix && AdSize == X86Local::AdSize32) 307280031Sdim insnContext = IC_64BIT_REXW_ADSIZE; 308276479Sdim else if (OpSize == X86Local::OpSize16 && OpPrefix == X86Local::XD) 309234353Sdim insnContext = IC_64BIT_XD_OPSIZE; 310276479Sdim else if (OpSize == X86Local::OpSize16 && OpPrefix == X86Local::XS) 311226633Sdim insnContext = IC_64BIT_XS_OPSIZE; 312341825Sdim else if (AdSize == X86Local::AdSize32 && OpPrefix == X86Local::PD) 313341825Sdim insnContext = IC_64BIT_OPSIZE_ADSIZE; 314280031Sdim else if (OpSize == X86Local::OpSize16 && AdSize == X86Local::AdSize32) 315280031Sdim insnContext = IC_64BIT_OPSIZE_ADSIZE; 316276479Sdim else if (OpSize == X86Local::OpSize16 || OpPrefix == X86Local::PD) 317201360Srdivacky insnContext = IC_64BIT_OPSIZE; 318280031Sdim else if (AdSize == X86Local::AdSize32) 319234353Sdim insnContext = IC_64BIT_ADSIZE; 320276479Sdim else if (HasREX_WPrefix && OpPrefix == X86Local::XS) 321201360Srdivacky insnContext = IC_64BIT_REXW_XS; 322276479Sdim else if (HasREX_WPrefix && OpPrefix == X86Local::XD) 323201360Srdivacky insnContext = IC_64BIT_REXW_XD; 324276479Sdim else if (OpPrefix == X86Local::XD) 325201360Srdivacky insnContext = IC_64BIT_XD; 326276479Sdim else if (OpPrefix == X86Local::XS) 327201360Srdivacky insnContext = IC_64BIT_XS; 328201360Srdivacky else if (HasREX_WPrefix) 329201360Srdivacky insnContext = IC_64BIT_REXW; 330201360Srdivacky else 331201360Srdivacky insnContext = IC_64BIT; 332201360Srdivacky } else { 333276479Sdim if (OpSize == X86Local::OpSize16 && OpPrefix == X86Local::XD) 334226633Sdim insnContext = IC_XD_OPSIZE; 335276479Sdim else if (OpSize == X86Local::OpSize16 && OpPrefix == X86Local::XS) 336226633Sdim insnContext = IC_XS_OPSIZE; 337341825Sdim else if (AdSize == X86Local::AdSize16 && OpPrefix == X86Local::XD) 338341825Sdim insnContext = IC_XD_ADSIZE; 339341825Sdim else if (AdSize == X86Local::AdSize16 && OpPrefix == X86Local::XS) 340341825Sdim insnContext = IC_XS_ADSIZE; 341341825Sdim else if (AdSize == X86Local::AdSize16 && OpPrefix == X86Local::PD) 342341825Sdim insnContext = IC_OPSIZE_ADSIZE; 343280031Sdim else if (OpSize == X86Local::OpSize16 && AdSize == X86Local::AdSize16) 344280031Sdim insnContext = IC_OPSIZE_ADSIZE; 345276479Sdim else if (OpSize == X86Local::OpSize16 || OpPrefix == X86Local::PD) 346201360Srdivacky insnContext = IC_OPSIZE; 347280031Sdim else if (AdSize == X86Local::AdSize16) 348234353Sdim insnContext = IC_ADSIZE; 349276479Sdim else if (OpPrefix == X86Local::XD) 350201360Srdivacky insnContext = IC_XD; 351276479Sdim else if (OpPrefix == X86Local::XS) 352201360Srdivacky insnContext = IC_XS; 353201360Srdivacky else 354201360Srdivacky insnContext = IC; 355201360Srdivacky } 356201360Srdivacky 357201360Srdivacky return insnContext; 358201360Srdivacky} 359239462Sdim 360276479Sdimvoid RecognizableInstr::adjustOperandEncoding(OperandEncoding &encoding) { 361276479Sdim // The scaling factor for AVX512 compressed displacement encoding is an 362276479Sdim // instruction attribute. Adjust the ModRM encoding type to include the 363276479Sdim // scale for compressed displacement. 364321369Sdim if ((encoding != ENCODING_RM && encoding != ENCODING_VSIB) ||CD8_Scale == 0) 365276479Sdim return; 366276479Sdim encoding = (OperandEncoding)(encoding + Log2_32(CD8_Scale)); 367321369Sdim assert(((encoding >= ENCODING_RM && encoding <= ENCODING_RM_CD64) || 368321369Sdim (encoding >= ENCODING_VSIB && encoding <= ENCODING_VSIB_CD64)) && 369321369Sdim "Invalid CDisp scaling"); 370201360Srdivacky} 371221345Sdim 372239462Sdimvoid RecognizableInstr::handleOperand(bool optional, unsigned &operandIndex, 373239462Sdim unsigned &physicalOperandIndex, 374309124Sdim unsigned numPhysicalOperands, 375239462Sdim const unsigned *operandMapping, 376239462Sdim OperandEncoding (*encodingFromString) 377239462Sdim (const std::string&, 378276479Sdim uint8_t OpSize)) { 379201360Srdivacky if (optional) { 380201360Srdivacky if (physicalOperandIndex >= numPhysicalOperands) 381201360Srdivacky return; 382201360Srdivacky } else { 383201360Srdivacky assert(physicalOperandIndex < numPhysicalOperands); 384201360Srdivacky } 385239462Sdim 386201360Srdivacky while (operandMapping[operandIndex] != operandIndex) { 387201360Srdivacky Spec->operands[operandIndex].encoding = ENCODING_DUP; 388201360Srdivacky Spec->operands[operandIndex].type = 389201360Srdivacky (OperandType)(TYPE_DUP0 + operandMapping[operandIndex]); 390201360Srdivacky ++operandIndex; 391201360Srdivacky } 392239462Sdim 393321369Sdim StringRef typeName = (*Operands)[operandIndex].Rec->getName(); 394221345Sdim 395276479Sdim OperandEncoding encoding = encodingFromString(typeName, OpSize); 396276479Sdim // Adjust the encoding type for an operand based on the instruction. 397276479Sdim adjustOperandEncoding(encoding); 398276479Sdim Spec->operands[operandIndex].encoding = encoding; 399239462Sdim Spec->operands[operandIndex].type = typeFromString(typeName, 400276479Sdim HasREX_WPrefix, OpSize); 401239462Sdim 402201360Srdivacky ++operandIndex; 403201360Srdivacky ++physicalOperandIndex; 404201360Srdivacky} 405201360Srdivacky 406276479Sdimvoid RecognizableInstr::emitInstructionSpecifier() { 407201360Srdivacky Spec->name = Name; 408239462Sdim 409201360Srdivacky Spec->insnContext = insnContext(); 410239462Sdim 411218893Sdim const std::vector<CGIOperandList::OperandInfo> &OperandList = *Operands; 412239462Sdim 413201360Srdivacky unsigned numOperands = OperandList.size(); 414201360Srdivacky unsigned numPhysicalOperands = 0; 415239462Sdim 416201360Srdivacky // operandMapping maps from operands in OperandList to their originals. 417201360Srdivacky // If operandMapping[i] != i, then the entry is a duplicate. 418201360Srdivacky unsigned operandMapping[X86_MAX_OPERANDS]; 419234353Sdim assert(numOperands <= X86_MAX_OPERANDS && "X86_MAX_OPERANDS is not large enough"); 420239462Sdim 421239462Sdim for (unsigned operandIndex = 0; operandIndex < numOperands; ++operandIndex) { 422288943Sdim if (!OperandList[operandIndex].Constraints.empty()) { 423218893Sdim const CGIOperandList::ConstraintInfo &Constraint = 424203954Srdivacky OperandList[operandIndex].Constraints[0]; 425203954Srdivacky if (Constraint.isTied()) { 426239462Sdim operandMapping[operandIndex] = operandIndex; 427239462Sdim operandMapping[Constraint.getTiedOperand()] = operandIndex; 428201360Srdivacky } else { 429201360Srdivacky ++numPhysicalOperands; 430201360Srdivacky operandMapping[operandIndex] = operandIndex; 431201360Srdivacky } 432201360Srdivacky } else { 433201360Srdivacky ++numPhysicalOperands; 434201360Srdivacky operandMapping[operandIndex] = operandIndex; 435201360Srdivacky } 436201360Srdivacky } 437201360Srdivacky 438201360Srdivacky#define HANDLE_OPERAND(class) \ 439201360Srdivacky handleOperand(false, \ 440201360Srdivacky operandIndex, \ 441201360Srdivacky physicalOperandIndex, \ 442201360Srdivacky numPhysicalOperands, \ 443201360Srdivacky operandMapping, \ 444201360Srdivacky class##EncodingFromString); 445239462Sdim 446201360Srdivacky#define HANDLE_OPTIONAL(class) \ 447201360Srdivacky handleOperand(true, \ 448201360Srdivacky operandIndex, \ 449201360Srdivacky physicalOperandIndex, \ 450201360Srdivacky numPhysicalOperands, \ 451201360Srdivacky operandMapping, \ 452201360Srdivacky class##EncodingFromString); 453239462Sdim 454201360Srdivacky // operandIndex should always be < numOperands 455239462Sdim unsigned operandIndex = 0; 456201360Srdivacky // physicalOperandIndex should always be < numPhysicalOperands 457201360Srdivacky unsigned physicalOperandIndex = 0; 458239462Sdim 459309124Sdim#ifndef NDEBUG 460280031Sdim // Given the set of prefix bits, how many additional operands does the 461280031Sdim // instruction have? 462280031Sdim unsigned additionalOperands = 0; 463314564Sdim if (HasVEX_4V) 464280031Sdim ++additionalOperands; 465280031Sdim if (HasEVEX_K) 466280031Sdim ++additionalOperands; 467309124Sdim#endif 468280031Sdim 469201360Srdivacky switch (Form) { 470276479Sdim default: llvm_unreachable("Unhandled form"); 471276479Sdim case X86Local::RawFrmSrc: 472276479Sdim HANDLE_OPERAND(relocation); 473276479Sdim return; 474276479Sdim case X86Local::RawFrmDst: 475276479Sdim HANDLE_OPERAND(relocation); 476276479Sdim return; 477276479Sdim case X86Local::RawFrmDstSrc: 478276479Sdim HANDLE_OPERAND(relocation); 479276479Sdim HANDLE_OPERAND(relocation); 480276479Sdim return; 481201360Srdivacky case X86Local::RawFrm: 482201360Srdivacky // Operand 1 (optional) is an address or immediate. 483309124Sdim assert(numPhysicalOperands <= 1 && 484201360Srdivacky "Unexpected number of operands for RawFrm"); 485201360Srdivacky HANDLE_OPTIONAL(relocation) 486201360Srdivacky break; 487276479Sdim case X86Local::RawFrmMemOffs: 488276479Sdim // Operand 1 is an address. 489276479Sdim HANDLE_OPERAND(relocation); 490276479Sdim break; 491201360Srdivacky case X86Local::AddRegFrm: 492201360Srdivacky // Operand 1 is added to the opcode. 493201360Srdivacky // Operand 2 (optional) is an address. 494201360Srdivacky assert(numPhysicalOperands >= 1 && numPhysicalOperands <= 2 && 495201360Srdivacky "Unexpected number of operands for AddRegFrm"); 496201360Srdivacky HANDLE_OPERAND(opcodeModifier) 497201360Srdivacky HANDLE_OPTIONAL(relocation) 498201360Srdivacky break; 499201360Srdivacky case X86Local::MRMDestReg: 500201360Srdivacky // Operand 1 is a register operand in the R/M field. 501280031Sdim // - In AVX512 there may be a mask operand here - 502201360Srdivacky // Operand 2 is a register operand in the Reg/Opcode field. 503226633Sdim // - In AVX, there is a register operand in the VEX.vvvv field here - 504201360Srdivacky // Operand 3 (optional) is an immediate. 505280031Sdim assert(numPhysicalOperands >= 2 + additionalOperands && 506280031Sdim numPhysicalOperands <= 3 + additionalOperands && 507280031Sdim "Unexpected number of operands for MRMDestRegFrm"); 508239462Sdim 509201360Srdivacky HANDLE_OPERAND(rmRegister) 510280031Sdim if (HasEVEX_K) 511280031Sdim HANDLE_OPERAND(writemaskRegister) 512226633Sdim 513276479Sdim if (HasVEX_4V) 514226633Sdim // FIXME: In AVX, the register below becomes the one encoded 515226633Sdim // in ModRMVEX and the one above the one in the VEX.VVVV field 516226633Sdim HANDLE_OPERAND(vvvvRegister) 517239462Sdim 518201360Srdivacky HANDLE_OPERAND(roRegister) 519201360Srdivacky HANDLE_OPTIONAL(immediate) 520201360Srdivacky break; 521201360Srdivacky case X86Local::MRMDestMem: 522201360Srdivacky // Operand 1 is a memory operand (possibly SIB-extended) 523201360Srdivacky // Operand 2 is a register operand in the Reg/Opcode field. 524226633Sdim // - In AVX, there is a register operand in the VEX.vvvv field here - 525201360Srdivacky // Operand 3 (optional) is an immediate. 526280031Sdim assert(numPhysicalOperands >= 2 + additionalOperands && 527280031Sdim numPhysicalOperands <= 3 + additionalOperands && 528280031Sdim "Unexpected number of operands for MRMDestMemFrm with VEX_4V"); 529280031Sdim 530201360Srdivacky HANDLE_OPERAND(memory) 531226633Sdim 532261991Sdim if (HasEVEX_K) 533261991Sdim HANDLE_OPERAND(writemaskRegister) 534261991Sdim 535276479Sdim if (HasVEX_4V) 536226633Sdim // FIXME: In AVX, the register below becomes the one encoded 537226633Sdim // in ModRMVEX and the one above the one in the VEX.VVVV field 538226633Sdim HANDLE_OPERAND(vvvvRegister) 539239462Sdim 540201360Srdivacky HANDLE_OPERAND(roRegister) 541201360Srdivacky HANDLE_OPTIONAL(immediate) 542201360Srdivacky break; 543201360Srdivacky case X86Local::MRMSrcReg: 544201360Srdivacky // Operand 1 is a register operand in the Reg/Opcode field. 545201360Srdivacky // Operand 2 is a register operand in the R/M field. 546221345Sdim // - In AVX, there is a register operand in the VEX.vvvv field here - 547201360Srdivacky // Operand 3 (optional) is an immediate. 548239462Sdim // Operand 4 (optional) is an immediate. 549210299Sed 550280031Sdim assert(numPhysicalOperands >= 2 + additionalOperands && 551280031Sdim numPhysicalOperands <= 4 + additionalOperands && 552280031Sdim "Unexpected number of operands for MRMSrcRegFrm"); 553239462Sdim 554221345Sdim HANDLE_OPERAND(roRegister) 555234353Sdim 556261991Sdim if (HasEVEX_K) 557261991Sdim HANDLE_OPERAND(writemaskRegister) 558261991Sdim 559276479Sdim if (HasVEX_4V) 560210299Sed // FIXME: In AVX, the register below becomes the one encoded 561210299Sed // in ModRMVEX and the one above the one in the VEX.VVVV field 562221345Sdim HANDLE_OPERAND(vvvvRegister) 563234353Sdim 564221345Sdim HANDLE_OPERAND(rmRegister) 565314564Sdim HANDLE_OPTIONAL(immediate) 566234353Sdim HANDLE_OPTIONAL(immediate) // above might be a register in 7:4 567201360Srdivacky break; 568314564Sdim case X86Local::MRMSrcReg4VOp3: 569314564Sdim assert(numPhysicalOperands == 3 && 570321369Sdim "Unexpected number of operands for MRMSrcReg4VOp3Frm"); 571314564Sdim HANDLE_OPERAND(roRegister) 572314564Sdim HANDLE_OPERAND(rmRegister) 573314564Sdim HANDLE_OPERAND(vvvvRegister) 574314564Sdim break; 575314564Sdim case X86Local::MRMSrcRegOp4: 576314564Sdim assert(numPhysicalOperands >= 4 && numPhysicalOperands <= 5 && 577314564Sdim "Unexpected number of operands for MRMSrcRegOp4Frm"); 578314564Sdim HANDLE_OPERAND(roRegister) 579314564Sdim HANDLE_OPERAND(vvvvRegister) 580314564Sdim HANDLE_OPERAND(immediate) // Register in imm[7:4] 581314564Sdim HANDLE_OPERAND(rmRegister) 582314564Sdim HANDLE_OPTIONAL(immediate) 583314564Sdim break; 584201360Srdivacky case X86Local::MRMSrcMem: 585201360Srdivacky // Operand 1 is a register operand in the Reg/Opcode field. 586201360Srdivacky // Operand 2 is a memory operand (possibly SIB-extended) 587221345Sdim // - In AVX, there is a register operand in the VEX.vvvv field here - 588201360Srdivacky // Operand 3 (optional) is an immediate. 589234353Sdim 590280031Sdim assert(numPhysicalOperands >= 2 + additionalOperands && 591280031Sdim numPhysicalOperands <= 4 + additionalOperands && 592280031Sdim "Unexpected number of operands for MRMSrcMemFrm"); 593239462Sdim 594201360Srdivacky HANDLE_OPERAND(roRegister) 595210299Sed 596261991Sdim if (HasEVEX_K) 597261991Sdim HANDLE_OPERAND(writemaskRegister) 598261991Sdim 599276479Sdim if (HasVEX_4V) 600210299Sed // FIXME: In AVX, the register below becomes the one encoded 601210299Sed // in ModRMVEX and the one above the one in the VEX.VVVV field 602221345Sdim HANDLE_OPERAND(vvvvRegister) 603210299Sed 604201360Srdivacky HANDLE_OPERAND(memory) 605314564Sdim HANDLE_OPTIONAL(immediate) 606234353Sdim HANDLE_OPTIONAL(immediate) // above might be a register in 7:4 607201360Srdivacky break; 608314564Sdim case X86Local::MRMSrcMem4VOp3: 609314564Sdim assert(numPhysicalOperands == 3 && 610321369Sdim "Unexpected number of operands for MRMSrcMem4VOp3Frm"); 611314564Sdim HANDLE_OPERAND(roRegister) 612314564Sdim HANDLE_OPERAND(memory) 613314564Sdim HANDLE_OPERAND(vvvvRegister) 614314564Sdim break; 615314564Sdim case X86Local::MRMSrcMemOp4: 616314564Sdim assert(numPhysicalOperands >= 4 && numPhysicalOperands <= 5 && 617314564Sdim "Unexpected number of operands for MRMSrcMemOp4Frm"); 618314564Sdim HANDLE_OPERAND(roRegister) 619314564Sdim HANDLE_OPERAND(vvvvRegister) 620314564Sdim HANDLE_OPERAND(immediate) // Register in imm[7:4] 621314564Sdim HANDLE_OPERAND(memory) 622314564Sdim HANDLE_OPTIONAL(immediate) 623314564Sdim break; 624276479Sdim case X86Local::MRMXr: 625201360Srdivacky case X86Local::MRM0r: 626201360Srdivacky case X86Local::MRM1r: 627201360Srdivacky case X86Local::MRM2r: 628201360Srdivacky case X86Local::MRM3r: 629201360Srdivacky case X86Local::MRM4r: 630201360Srdivacky case X86Local::MRM5r: 631201360Srdivacky case X86Local::MRM6r: 632201360Srdivacky case X86Local::MRM7r: 633280031Sdim // Operand 1 is a register operand in the R/M field. 634280031Sdim // Operand 2 (optional) is an immediate or relocation. 635280031Sdim // Operand 3 (optional) is an immediate. 636280031Sdim assert(numPhysicalOperands >= 0 + additionalOperands && 637280031Sdim numPhysicalOperands <= 3 + additionalOperands && 638280031Sdim "Unexpected number of operands for MRMnr"); 639280031Sdim 640276479Sdim if (HasVEX_4V) 641234353Sdim HANDLE_OPERAND(vvvvRegister) 642261991Sdim 643261991Sdim if (HasEVEX_K) 644261991Sdim HANDLE_OPERAND(writemaskRegister) 645201360Srdivacky HANDLE_OPTIONAL(rmRegister) 646201360Srdivacky HANDLE_OPTIONAL(relocation) 647239462Sdim HANDLE_OPTIONAL(immediate) 648201360Srdivacky break; 649276479Sdim case X86Local::MRMXm: 650201360Srdivacky case X86Local::MRM0m: 651201360Srdivacky case X86Local::MRM1m: 652201360Srdivacky case X86Local::MRM2m: 653201360Srdivacky case X86Local::MRM3m: 654201360Srdivacky case X86Local::MRM4m: 655201360Srdivacky case X86Local::MRM5m: 656201360Srdivacky case X86Local::MRM6m: 657201360Srdivacky case X86Local::MRM7m: 658280031Sdim // Operand 1 is a memory operand (possibly SIB-extended) 659280031Sdim // Operand 2 (optional) is an immediate or relocation. 660280031Sdim assert(numPhysicalOperands >= 1 + additionalOperands && 661280031Sdim numPhysicalOperands <= 2 + additionalOperands && 662280031Sdim "Unexpected number of operands for MRMnm"); 663280031Sdim 664276479Sdim if (HasVEX_4V) 665234353Sdim HANDLE_OPERAND(vvvvRegister) 666261991Sdim if (HasEVEX_K) 667261991Sdim HANDLE_OPERAND(writemaskRegister) 668201360Srdivacky HANDLE_OPERAND(memory) 669201360Srdivacky HANDLE_OPTIONAL(relocation) 670201360Srdivacky break; 671218893Sdim case X86Local::RawFrmImm8: 672218893Sdim // operand 1 is a 16-bit immediate 673218893Sdim // operand 2 is an 8-bit immediate 674218893Sdim assert(numPhysicalOperands == 2 && 675218893Sdim "Unexpected number of operands for X86Local::RawFrmImm8"); 676218893Sdim HANDLE_OPERAND(immediate) 677218893Sdim HANDLE_OPERAND(immediate) 678218893Sdim break; 679218893Sdim case X86Local::RawFrmImm16: 680218893Sdim // operand 1 is a 16-bit immediate 681218893Sdim // operand 2 is a 16-bit immediate 682218893Sdim HANDLE_OPERAND(immediate) 683218893Sdim HANDLE_OPERAND(immediate) 684218893Sdim break; 685341825Sdim#define MAP(from, to) case X86Local::MRM_##from: 686341825Sdim X86_INSTR_MRM_MAPPING 687341825Sdim#undef MAP 688341825Sdim HANDLE_OPTIONAL(relocation) 689249423Sdim break; 690201360Srdivacky } 691239462Sdim 692341825Sdim#undef HANDLE_OPERAND 693341825Sdim#undef HANDLE_OPTIONAL 694201360Srdivacky} 695201360Srdivacky 696201360Srdivackyvoid RecognizableInstr::emitDecodePath(DisassemblerTables &tables) const { 697201360Srdivacky // Special cases where the LLVM tables are not complete 698201360Srdivacky 699203954Srdivacky#define MAP(from, to) \ 700288943Sdim case X86Local::MRM_##from: 701201360Srdivacky 702327952Sdim llvm::Optional<OpcodeType> opcodeType; 703276479Sdim switch (OpMap) { 704276479Sdim default: llvm_unreachable("Invalid map!"); 705341825Sdim case X86Local::OB: opcodeType = ONEBYTE; break; 706341825Sdim case X86Local::TB: opcodeType = TWOBYTE; break; 707341825Sdim case X86Local::T8: opcodeType = THREEBYTE_38; break; 708341825Sdim case X86Local::TA: opcodeType = THREEBYTE_3A; break; 709341825Sdim case X86Local::XOP8: opcodeType = XOP8_MAP; break; 710341825Sdim case X86Local::XOP9: opcodeType = XOP9_MAP; break; 711341825Sdim case X86Local::XOPA: opcodeType = XOPA_MAP; break; 712341825Sdim case X86Local::ThreeDNow: opcodeType = THREEDNOW_MAP; break; 713341825Sdim } 714276479Sdim 715341825Sdim std::unique_ptr<ModRMFilter> filter; 716341825Sdim switch (Form) { 717341825Sdim default: llvm_unreachable("Invalid form!"); 718341825Sdim case X86Local::Pseudo: llvm_unreachable("Pseudo should not be emitted!"); 719341825Sdim case X86Local::RawFrm: 720341825Sdim case X86Local::AddRegFrm: 721341825Sdim case X86Local::RawFrmMemOffs: 722341825Sdim case X86Local::RawFrmSrc: 723341825Sdim case X86Local::RawFrmDst: 724341825Sdim case X86Local::RawFrmDstSrc: 725341825Sdim case X86Local::RawFrmImm8: 726341825Sdim case X86Local::RawFrmImm16: 727341825Sdim filter = llvm::make_unique<DumbFilter>(); 728276479Sdim break; 729341825Sdim case X86Local::MRMDestReg: 730341825Sdim case X86Local::MRMSrcReg: 731341825Sdim case X86Local::MRMSrcReg4VOp3: 732341825Sdim case X86Local::MRMSrcRegOp4: 733341825Sdim case X86Local::MRMXr: 734341825Sdim filter = llvm::make_unique<ModFilter>(true); 735341825Sdim break; 736341825Sdim case X86Local::MRMDestMem: 737341825Sdim case X86Local::MRMSrcMem: 738341825Sdim case X86Local::MRMSrcMem4VOp3: 739341825Sdim case X86Local::MRMSrcMemOp4: 740341825Sdim case X86Local::MRMXm: 741341825Sdim filter = llvm::make_unique<ModFilter>(false); 742341825Sdim break; 743341825Sdim case X86Local::MRM0r: case X86Local::MRM1r: 744341825Sdim case X86Local::MRM2r: case X86Local::MRM3r: 745341825Sdim case X86Local::MRM4r: case X86Local::MRM5r: 746341825Sdim case X86Local::MRM6r: case X86Local::MRM7r: 747341825Sdim filter = llvm::make_unique<ExtendedFilter>(true, Form - X86Local::MRM0r); 748341825Sdim break; 749341825Sdim case X86Local::MRM0m: case X86Local::MRM1m: 750341825Sdim case X86Local::MRM2m: case X86Local::MRM3m: 751341825Sdim case X86Local::MRM4m: case X86Local::MRM5m: 752341825Sdim case X86Local::MRM6m: case X86Local::MRM7m: 753341825Sdim filter = llvm::make_unique<ExtendedFilter>(false, Form - X86Local::MRM0m); 754341825Sdim break; 755341825Sdim X86_INSTR_MRM_MAPPING 756341825Sdim filter = llvm::make_unique<ExactFilter>(0xC0 + Form - X86Local::MRM_C0); 757341825Sdim break; 758341825Sdim } // switch (Form) 759201360Srdivacky 760341825Sdim uint8_t opcodeToSet = Opcode; 761341825Sdim 762280031Sdim unsigned AddressSize = 0; 763280031Sdim switch (AdSize) { 764280031Sdim case X86Local::AdSize16: AddressSize = 16; break; 765280031Sdim case X86Local::AdSize32: AddressSize = 32; break; 766280031Sdim case X86Local::AdSize64: AddressSize = 64; break; 767280031Sdim } 768280031Sdim 769327952Sdim assert(opcodeType && "Opcode type not set"); 770201360Srdivacky assert(filter && "Filter not set"); 771201360Srdivacky 772201360Srdivacky if (Form == X86Local::AddRegFrm) { 773276479Sdim assert(((opcodeToSet & 7) == 0) && 774276479Sdim "ADDREG_FRM opcode not aligned"); 775239462Sdim 776276479Sdim uint8_t currentOpcode; 777201360Srdivacky 778276479Sdim for (currentOpcode = opcodeToSet; 779276479Sdim currentOpcode < opcodeToSet + 8; 780276479Sdim ++currentOpcode) 781327952Sdim tables.setTableFields(*opcodeType, insnContext(), currentOpcode, *filter, 782327952Sdim UID, Is32Bit, OpPrefix == 0, 783327952Sdim IgnoresVEX_L || EncodeRC, 784327952Sdim VEX_WPrefix == X86Local::VEX_WIG, AddressSize); 785201360Srdivacky } else { 786327952Sdim tables.setTableFields(*opcodeType, insnContext(), opcodeToSet, *filter, UID, 787327952Sdim Is32Bit, OpPrefix == 0, IgnoresVEX_L || EncodeRC, 788327952Sdim VEX_WPrefix == X86Local::VEX_WIG, AddressSize); 789201360Srdivacky } 790239462Sdim 791203954Srdivacky#undef MAP 792201360Srdivacky} 793201360Srdivacky 794201360Srdivacky#define TYPE(str, type) if (s == str) return type; 795201360SrdivackyOperandType RecognizableInstr::typeFromString(const std::string &s, 796201360Srdivacky bool hasREX_WPrefix, 797276479Sdim uint8_t OpSize) { 798201360Srdivacky if(hasREX_WPrefix) { 799201360Srdivacky // For instructions with a REX_W prefix, a declared 32-bit register encoding 800201360Srdivacky // is special. 801201360Srdivacky TYPE("GR32", TYPE_R32) 802201360Srdivacky } 803276479Sdim if(OpSize == X86Local::OpSize16) { 804276479Sdim // For OpSize16 instructions, a declared 16-bit register or 805201360Srdivacky // immediate encoding is special. 806276479Sdim TYPE("GR16", TYPE_Rv) 807276479Sdim } else if(OpSize == X86Local::OpSize32) { 808276479Sdim // For OpSize32 instructions, a declared 32-bit register or 809276479Sdim // immediate encoding is special. 810276479Sdim TYPE("GR32", TYPE_Rv) 811201360Srdivacky } 812321369Sdim TYPE("i16mem", TYPE_M) 813321369Sdim TYPE("i16imm", TYPE_IMM) 814321369Sdim TYPE("i16i8imm", TYPE_IMM) 815276479Sdim TYPE("GR16", TYPE_R16) 816321369Sdim TYPE("i32mem", TYPE_M) 817321369Sdim TYPE("i32imm", TYPE_IMM) 818321369Sdim TYPE("i32i8imm", TYPE_IMM) 819276479Sdim TYPE("GR32", TYPE_R32) 820261991Sdim TYPE("GR32orGR64", TYPE_R32) 821321369Sdim TYPE("i64mem", TYPE_M) 822321369Sdim TYPE("i64i32imm", TYPE_IMM) 823321369Sdim TYPE("i64i8imm", TYPE_IMM) 824201360Srdivacky TYPE("GR64", TYPE_R64) 825321369Sdim TYPE("i8mem", TYPE_M) 826321369Sdim TYPE("i8imm", TYPE_IMM) 827288943Sdim TYPE("u8imm", TYPE_UIMM8) 828288943Sdim TYPE("i32u8imm", TYPE_UIMM8) 829201360Srdivacky TYPE("GR8", TYPE_R8) 830321369Sdim TYPE("VR128", TYPE_XMM) 831321369Sdim TYPE("VR128X", TYPE_XMM) 832321369Sdim TYPE("f128mem", TYPE_M) 833321369Sdim TYPE("f256mem", TYPE_M) 834321369Sdim TYPE("f512mem", TYPE_M) 835321369Sdim TYPE("FR128", TYPE_XMM) 836321369Sdim TYPE("FR64", TYPE_XMM) 837321369Sdim TYPE("FR64X", TYPE_XMM) 838321369Sdim TYPE("f64mem", TYPE_M) 839321369Sdim TYPE("sdmem", TYPE_M) 840321369Sdim TYPE("FR32", TYPE_XMM) 841321369Sdim TYPE("FR32X", TYPE_XMM) 842321369Sdim TYPE("f32mem", TYPE_M) 843321369Sdim TYPE("ssmem", TYPE_M) 844201360Srdivacky TYPE("RST", TYPE_ST) 845321369Sdim TYPE("i128mem", TYPE_M) 846321369Sdim TYPE("i256mem", TYPE_M) 847321369Sdim TYPE("i512mem", TYPE_M) 848321369Sdim TYPE("i64i32imm_pcrel", TYPE_REL) 849321369Sdim TYPE("i16imm_pcrel", TYPE_REL) 850321369Sdim TYPE("i32imm_pcrel", TYPE_REL) 851207618Srdivacky TYPE("SSECC", TYPE_IMM3) 852288943Sdim TYPE("XOPCC", TYPE_IMM3) 853234353Sdim TYPE("AVXCC", TYPE_IMM5) 854288943Sdim TYPE("AVX512ICC", TYPE_AVX512ICC) 855321369Sdim TYPE("AVX512RC", TYPE_IMM) 856321369Sdim TYPE("brtarget32", TYPE_REL) 857321369Sdim TYPE("brtarget16", TYPE_REL) 858321369Sdim TYPE("brtarget8", TYPE_REL) 859321369Sdim TYPE("f80mem", TYPE_M) 860321369Sdim TYPE("lea64_32mem", TYPE_M) 861321369Sdim TYPE("lea64mem", TYPE_M) 862201360Srdivacky TYPE("VR64", TYPE_MM64) 863321369Sdim TYPE("i64imm", TYPE_IMM) 864280031Sdim TYPE("anymem", TYPE_M) 865341825Sdim TYPE("opaquemem", TYPE_M) 866201360Srdivacky TYPE("SEGMENT_REG", TYPE_SEGMENTREG) 867201360Srdivacky TYPE("DEBUG_REG", TYPE_DEBUGREG) 868208599Srdivacky TYPE("CONTROL_REG", TYPE_CONTROLREG) 869321369Sdim TYPE("srcidx8", TYPE_SRCIDX) 870321369Sdim TYPE("srcidx16", TYPE_SRCIDX) 871321369Sdim TYPE("srcidx32", TYPE_SRCIDX) 872321369Sdim TYPE("srcidx64", TYPE_SRCIDX) 873321369Sdim TYPE("dstidx8", TYPE_DSTIDX) 874321369Sdim TYPE("dstidx16", TYPE_DSTIDX) 875321369Sdim TYPE("dstidx32", TYPE_DSTIDX) 876321369Sdim TYPE("dstidx64", TYPE_DSTIDX) 877321369Sdim TYPE("offset16_8", TYPE_MOFFS) 878321369Sdim TYPE("offset16_16", TYPE_MOFFS) 879321369Sdim TYPE("offset16_32", TYPE_MOFFS) 880321369Sdim TYPE("offset32_8", TYPE_MOFFS) 881321369Sdim TYPE("offset32_16", TYPE_MOFFS) 882321369Sdim TYPE("offset32_32", TYPE_MOFFS) 883321369Sdim TYPE("offset32_64", TYPE_MOFFS) 884321369Sdim TYPE("offset64_8", TYPE_MOFFS) 885321369Sdim TYPE("offset64_16", TYPE_MOFFS) 886321369Sdim TYPE("offset64_32", TYPE_MOFFS) 887321369Sdim TYPE("offset64_64", TYPE_MOFFS) 888321369Sdim TYPE("VR256", TYPE_YMM) 889321369Sdim TYPE("VR256X", TYPE_YMM) 890321369Sdim TYPE("VR512", TYPE_ZMM) 891321369Sdim TYPE("VK1", TYPE_VK) 892321369Sdim TYPE("VK1WM", TYPE_VK) 893321369Sdim TYPE("VK2", TYPE_VK) 894321369Sdim TYPE("VK2WM", TYPE_VK) 895321369Sdim TYPE("VK4", TYPE_VK) 896321369Sdim TYPE("VK4WM", TYPE_VK) 897321369Sdim TYPE("VK8", TYPE_VK) 898321369Sdim TYPE("VK8WM", TYPE_VK) 899321369Sdim TYPE("VK16", TYPE_VK) 900321369Sdim TYPE("VK16WM", TYPE_VK) 901321369Sdim TYPE("VK32", TYPE_VK) 902321369Sdim TYPE("VK32WM", TYPE_VK) 903321369Sdim TYPE("VK64", TYPE_VK) 904321369Sdim TYPE("VK64WM", TYPE_VK) 905327952Sdim TYPE("vx64mem", TYPE_MVSIBX) 906327952Sdim TYPE("vx128mem", TYPE_MVSIBX) 907327952Sdim TYPE("vx256mem", TYPE_MVSIBX) 908327952Sdim TYPE("vy128mem", TYPE_MVSIBY) 909327952Sdim TYPE("vy256mem", TYPE_MVSIBY) 910327952Sdim TYPE("vx64xmem", TYPE_MVSIBX) 911327952Sdim TYPE("vx128xmem", TYPE_MVSIBX) 912327952Sdim TYPE("vx256xmem", TYPE_MVSIBX) 913327952Sdim TYPE("vy128xmem", TYPE_MVSIBY) 914327952Sdim TYPE("vy256xmem", TYPE_MVSIBY) 915341825Sdim TYPE("vy512xmem", TYPE_MVSIBY) 916341825Sdim TYPE("vz256mem", TYPE_MVSIBZ) 917327952Sdim TYPE("vz512mem", TYPE_MVSIBZ) 918288943Sdim TYPE("BNDR", TYPE_BNDR) 919201360Srdivacky errs() << "Unhandled type string " << s << "\n"; 920201360Srdivacky llvm_unreachable("Unhandled type string"); 921201360Srdivacky} 922201360Srdivacky#undef TYPE 923201360Srdivacky 924201360Srdivacky#define ENCODING(str, encoding) if (s == str) return encoding; 925276479SdimOperandEncoding 926276479SdimRecognizableInstr::immediateEncodingFromString(const std::string &s, 927276479Sdim uint8_t OpSize) { 928276479Sdim if(OpSize != X86Local::OpSize16) { 929201360Srdivacky // For instructions without an OpSize prefix, a declared 16-bit register or 930201360Srdivacky // immediate encoding is special. 931201360Srdivacky ENCODING("i16imm", ENCODING_IW) 932201360Srdivacky } 933201360Srdivacky ENCODING("i32i8imm", ENCODING_IB) 934201360Srdivacky ENCODING("SSECC", ENCODING_IB) 935288943Sdim ENCODING("XOPCC", ENCODING_IB) 936234353Sdim ENCODING("AVXCC", ENCODING_IB) 937288943Sdim ENCODING("AVX512ICC", ENCODING_IB) 938327952Sdim ENCODING("AVX512RC", ENCODING_IRC) 939201360Srdivacky ENCODING("i16imm", ENCODING_Iv) 940201360Srdivacky ENCODING("i16i8imm", ENCODING_IB) 941201360Srdivacky ENCODING("i32imm", ENCODING_Iv) 942201360Srdivacky ENCODING("i64i32imm", ENCODING_ID) 943201360Srdivacky ENCODING("i64i8imm", ENCODING_IB) 944201360Srdivacky ENCODING("i8imm", ENCODING_IB) 945288943Sdim ENCODING("u8imm", ENCODING_IB) 946288943Sdim ENCODING("i32u8imm", ENCODING_IB) 947221345Sdim // This is not a typo. Instructions like BLENDVPD put 948221345Sdim // register IDs in 8-bit immediates nowadays. 949243830Sdim ENCODING("FR32", ENCODING_IB) 950243830Sdim ENCODING("FR64", ENCODING_IB) 951296417Sdim ENCODING("FR128", ENCODING_IB) 952261991Sdim ENCODING("VR128", ENCODING_IB) 953261991Sdim ENCODING("VR256", ENCODING_IB) 954261991Sdim ENCODING("FR32X", ENCODING_IB) 955261991Sdim ENCODING("FR64X", ENCODING_IB) 956261991Sdim ENCODING("VR128X", ENCODING_IB) 957261991Sdim ENCODING("VR256X", ENCODING_IB) 958261991Sdim ENCODING("VR512", ENCODING_IB) 959201360Srdivacky errs() << "Unhandled immediate encoding " << s << "\n"; 960201360Srdivacky llvm_unreachable("Unhandled immediate encoding"); 961201360Srdivacky} 962201360Srdivacky 963276479SdimOperandEncoding 964276479SdimRecognizableInstr::rmRegisterEncodingFromString(const std::string &s, 965276479Sdim uint8_t OpSize) { 966276479Sdim ENCODING("RST", ENCODING_FP) 967201360Srdivacky ENCODING("GR16", ENCODING_RM) 968201360Srdivacky ENCODING("GR32", ENCODING_RM) 969261991Sdim ENCODING("GR32orGR64", ENCODING_RM) 970201360Srdivacky ENCODING("GR64", ENCODING_RM) 971201360Srdivacky ENCODING("GR8", ENCODING_RM) 972201360Srdivacky ENCODING("VR128", ENCODING_RM) 973261991Sdim ENCODING("VR128X", ENCODING_RM) 974296417Sdim ENCODING("FR128", ENCODING_RM) 975201360Srdivacky ENCODING("FR64", ENCODING_RM) 976201360Srdivacky ENCODING("FR32", ENCODING_RM) 977261991Sdim ENCODING("FR64X", ENCODING_RM) 978261991Sdim ENCODING("FR32X", ENCODING_RM) 979201360Srdivacky ENCODING("VR64", ENCODING_RM) 980221345Sdim ENCODING("VR256", ENCODING_RM) 981261991Sdim ENCODING("VR256X", ENCODING_RM) 982261991Sdim ENCODING("VR512", ENCODING_RM) 983276479Sdim ENCODING("VK1", ENCODING_RM) 984288943Sdim ENCODING("VK2", ENCODING_RM) 985288943Sdim ENCODING("VK4", ENCODING_RM) 986261991Sdim ENCODING("VK8", ENCODING_RM) 987261991Sdim ENCODING("VK16", ENCODING_RM) 988280031Sdim ENCODING("VK32", ENCODING_RM) 989280031Sdim ENCODING("VK64", ENCODING_RM) 990288943Sdim ENCODING("BNDR", ENCODING_RM) 991201360Srdivacky errs() << "Unhandled R/M register encoding " << s << "\n"; 992201360Srdivacky llvm_unreachable("Unhandled R/M register encoding"); 993201360Srdivacky} 994201360Srdivacky 995276479SdimOperandEncoding 996276479SdimRecognizableInstr::roRegisterEncodingFromString(const std::string &s, 997276479Sdim uint8_t OpSize) { 998201360Srdivacky ENCODING("GR16", ENCODING_REG) 999201360Srdivacky ENCODING("GR32", ENCODING_REG) 1000261991Sdim ENCODING("GR32orGR64", ENCODING_REG) 1001201360Srdivacky ENCODING("GR64", ENCODING_REG) 1002201360Srdivacky ENCODING("GR8", ENCODING_REG) 1003201360Srdivacky ENCODING("VR128", ENCODING_REG) 1004296417Sdim ENCODING("FR128", ENCODING_REG) 1005201360Srdivacky ENCODING("FR64", ENCODING_REG) 1006201360Srdivacky ENCODING("FR32", ENCODING_REG) 1007201360Srdivacky ENCODING("VR64", ENCODING_REG) 1008201360Srdivacky ENCODING("SEGMENT_REG", ENCODING_REG) 1009201360Srdivacky ENCODING("DEBUG_REG", ENCODING_REG) 1010208599Srdivacky ENCODING("CONTROL_REG", ENCODING_REG) 1011221345Sdim ENCODING("VR256", ENCODING_REG) 1012261991Sdim ENCODING("VR256X", ENCODING_REG) 1013261991Sdim ENCODING("VR128X", ENCODING_REG) 1014261991Sdim ENCODING("FR64X", ENCODING_REG) 1015261991Sdim ENCODING("FR32X", ENCODING_REG) 1016261991Sdim ENCODING("VR512", ENCODING_REG) 1017276479Sdim ENCODING("VK1", ENCODING_REG) 1018280031Sdim ENCODING("VK2", ENCODING_REG) 1019280031Sdim ENCODING("VK4", ENCODING_REG) 1020261991Sdim ENCODING("VK8", ENCODING_REG) 1021261991Sdim ENCODING("VK16", ENCODING_REG) 1022280031Sdim ENCODING("VK32", ENCODING_REG) 1023280031Sdim ENCODING("VK64", ENCODING_REG) 1024276479Sdim ENCODING("VK1WM", ENCODING_REG) 1025288943Sdim ENCODING("VK2WM", ENCODING_REG) 1026288943Sdim ENCODING("VK4WM", ENCODING_REG) 1027261991Sdim ENCODING("VK8WM", ENCODING_REG) 1028261991Sdim ENCODING("VK16WM", ENCODING_REG) 1029288943Sdim ENCODING("VK32WM", ENCODING_REG) 1030288943Sdim ENCODING("VK64WM", ENCODING_REG) 1031288943Sdim ENCODING("BNDR", ENCODING_REG) 1032201360Srdivacky errs() << "Unhandled reg/opcode register encoding " << s << "\n"; 1033201360Srdivacky llvm_unreachable("Unhandled reg/opcode register encoding"); 1034201360Srdivacky} 1035201360Srdivacky 1036276479SdimOperandEncoding 1037276479SdimRecognizableInstr::vvvvRegisterEncodingFromString(const std::string &s, 1038276479Sdim uint8_t OpSize) { 1039226633Sdim ENCODING("GR32", ENCODING_VVVV) 1040226633Sdim ENCODING("GR64", ENCODING_VVVV) 1041221345Sdim ENCODING("FR32", ENCODING_VVVV) 1042296417Sdim ENCODING("FR128", ENCODING_VVVV) 1043221345Sdim ENCODING("FR64", ENCODING_VVVV) 1044221345Sdim ENCODING("VR128", ENCODING_VVVV) 1045221345Sdim ENCODING("VR256", ENCODING_VVVV) 1046261991Sdim ENCODING("FR32X", ENCODING_VVVV) 1047261991Sdim ENCODING("FR64X", ENCODING_VVVV) 1048261991Sdim ENCODING("VR128X", ENCODING_VVVV) 1049261991Sdim ENCODING("VR256X", ENCODING_VVVV) 1050261991Sdim ENCODING("VR512", ENCODING_VVVV) 1051276479Sdim ENCODING("VK1", ENCODING_VVVV) 1052276479Sdim ENCODING("VK2", ENCODING_VVVV) 1053276479Sdim ENCODING("VK4", ENCODING_VVVV) 1054261991Sdim ENCODING("VK8", ENCODING_VVVV) 1055261991Sdim ENCODING("VK16", ENCODING_VVVV) 1056280031Sdim ENCODING("VK32", ENCODING_VVVV) 1057280031Sdim ENCODING("VK64", ENCODING_VVVV) 1058221345Sdim errs() << "Unhandled VEX.vvvv register encoding " << s << "\n"; 1059221345Sdim llvm_unreachable("Unhandled VEX.vvvv register encoding"); 1060221345Sdim} 1061221345Sdim 1062276479SdimOperandEncoding 1063276479SdimRecognizableInstr::writemaskRegisterEncodingFromString(const std::string &s, 1064276479Sdim uint8_t OpSize) { 1065276479Sdim ENCODING("VK1WM", ENCODING_WRITEMASK) 1066276479Sdim ENCODING("VK2WM", ENCODING_WRITEMASK) 1067276479Sdim ENCODING("VK4WM", ENCODING_WRITEMASK) 1068261991Sdim ENCODING("VK8WM", ENCODING_WRITEMASK) 1069261991Sdim ENCODING("VK16WM", ENCODING_WRITEMASK) 1070276479Sdim ENCODING("VK32WM", ENCODING_WRITEMASK) 1071276479Sdim ENCODING("VK64WM", ENCODING_WRITEMASK) 1072261991Sdim errs() << "Unhandled mask register encoding " << s << "\n"; 1073261991Sdim llvm_unreachable("Unhandled mask register encoding"); 1074261991Sdim} 1075261991Sdim 1076276479SdimOperandEncoding 1077276479SdimRecognizableInstr::memoryEncodingFromString(const std::string &s, 1078276479Sdim uint8_t OpSize) { 1079201360Srdivacky ENCODING("i16mem", ENCODING_RM) 1080201360Srdivacky ENCODING("i32mem", ENCODING_RM) 1081201360Srdivacky ENCODING("i64mem", ENCODING_RM) 1082201360Srdivacky ENCODING("i8mem", ENCODING_RM) 1083218893Sdim ENCODING("ssmem", ENCODING_RM) 1084218893Sdim ENCODING("sdmem", ENCODING_RM) 1085201360Srdivacky ENCODING("f128mem", ENCODING_RM) 1086218893Sdim ENCODING("f256mem", ENCODING_RM) 1087261991Sdim ENCODING("f512mem", ENCODING_RM) 1088201360Srdivacky ENCODING("f64mem", ENCODING_RM) 1089201360Srdivacky ENCODING("f32mem", ENCODING_RM) 1090201360Srdivacky ENCODING("i128mem", ENCODING_RM) 1091221345Sdim ENCODING("i256mem", ENCODING_RM) 1092261991Sdim ENCODING("i512mem", ENCODING_RM) 1093201360Srdivacky ENCODING("f80mem", ENCODING_RM) 1094201360Srdivacky ENCODING("lea64_32mem", ENCODING_RM) 1095201360Srdivacky ENCODING("lea64mem", ENCODING_RM) 1096280031Sdim ENCODING("anymem", ENCODING_RM) 1097341825Sdim ENCODING("opaquemem", ENCODING_RM) 1098321369Sdim ENCODING("vx64mem", ENCODING_VSIB) 1099321369Sdim ENCODING("vx128mem", ENCODING_VSIB) 1100321369Sdim ENCODING("vx256mem", ENCODING_VSIB) 1101321369Sdim ENCODING("vy128mem", ENCODING_VSIB) 1102321369Sdim ENCODING("vy256mem", ENCODING_VSIB) 1103321369Sdim ENCODING("vx64xmem", ENCODING_VSIB) 1104321369Sdim ENCODING("vx128xmem", ENCODING_VSIB) 1105321369Sdim ENCODING("vx256xmem", ENCODING_VSIB) 1106321369Sdim ENCODING("vy128xmem", ENCODING_VSIB) 1107321369Sdim ENCODING("vy256xmem", ENCODING_VSIB) 1108341825Sdim ENCODING("vy512xmem", ENCODING_VSIB) 1109341825Sdim ENCODING("vz256mem", ENCODING_VSIB) 1110321369Sdim ENCODING("vz512mem", ENCODING_VSIB) 1111201360Srdivacky errs() << "Unhandled memory encoding " << s << "\n"; 1112201360Srdivacky llvm_unreachable("Unhandled memory encoding"); 1113201360Srdivacky} 1114201360Srdivacky 1115276479SdimOperandEncoding 1116276479SdimRecognizableInstr::relocationEncodingFromString(const std::string &s, 1117276479Sdim uint8_t OpSize) { 1118276479Sdim if(OpSize != X86Local::OpSize16) { 1119201360Srdivacky // For instructions without an OpSize prefix, a declared 16-bit register or 1120201360Srdivacky // immediate encoding is special. 1121201360Srdivacky ENCODING("i16imm", ENCODING_IW) 1122201360Srdivacky } 1123201360Srdivacky ENCODING("i16imm", ENCODING_Iv) 1124201360Srdivacky ENCODING("i16i8imm", ENCODING_IB) 1125201360Srdivacky ENCODING("i32imm", ENCODING_Iv) 1126201360Srdivacky ENCODING("i32i8imm", ENCODING_IB) 1127201360Srdivacky ENCODING("i64i32imm", ENCODING_ID) 1128201360Srdivacky ENCODING("i64i8imm", ENCODING_IB) 1129201360Srdivacky ENCODING("i8imm", ENCODING_IB) 1130288943Sdim ENCODING("u8imm", ENCODING_IB) 1131288943Sdim ENCODING("i32u8imm", ENCODING_IB) 1132201360Srdivacky ENCODING("i64i32imm_pcrel", ENCODING_ID) 1133210299Sed ENCODING("i16imm_pcrel", ENCODING_IW) 1134201360Srdivacky ENCODING("i32imm_pcrel", ENCODING_ID) 1135280031Sdim ENCODING("brtarget32", ENCODING_Iv) 1136280031Sdim ENCODING("brtarget16", ENCODING_Iv) 1137201360Srdivacky ENCODING("brtarget8", ENCODING_IB) 1138201360Srdivacky ENCODING("i64imm", ENCODING_IO) 1139280031Sdim ENCODING("offset16_8", ENCODING_Ia) 1140280031Sdim ENCODING("offset16_16", ENCODING_Ia) 1141280031Sdim ENCODING("offset16_32", ENCODING_Ia) 1142280031Sdim ENCODING("offset32_8", ENCODING_Ia) 1143280031Sdim ENCODING("offset32_16", ENCODING_Ia) 1144280031Sdim ENCODING("offset32_32", ENCODING_Ia) 1145280031Sdim ENCODING("offset32_64", ENCODING_Ia) 1146280031Sdim ENCODING("offset64_8", ENCODING_Ia) 1147280031Sdim ENCODING("offset64_16", ENCODING_Ia) 1148280031Sdim ENCODING("offset64_32", ENCODING_Ia) 1149280031Sdim ENCODING("offset64_64", ENCODING_Ia) 1150276479Sdim ENCODING("srcidx8", ENCODING_SI) 1151276479Sdim ENCODING("srcidx16", ENCODING_SI) 1152276479Sdim ENCODING("srcidx32", ENCODING_SI) 1153276479Sdim ENCODING("srcidx64", ENCODING_SI) 1154276479Sdim ENCODING("dstidx8", ENCODING_DI) 1155276479Sdim ENCODING("dstidx16", ENCODING_DI) 1156276479Sdim ENCODING("dstidx32", ENCODING_DI) 1157276479Sdim ENCODING("dstidx64", ENCODING_DI) 1158201360Srdivacky errs() << "Unhandled relocation encoding " << s << "\n"; 1159201360Srdivacky llvm_unreachable("Unhandled relocation encoding"); 1160201360Srdivacky} 1161201360Srdivacky 1162276479SdimOperandEncoding 1163276479SdimRecognizableInstr::opcodeModifierEncodingFromString(const std::string &s, 1164276479Sdim uint8_t OpSize) { 1165201360Srdivacky ENCODING("GR32", ENCODING_Rv) 1166201360Srdivacky ENCODING("GR64", ENCODING_RO) 1167201360Srdivacky ENCODING("GR16", ENCODING_Rv) 1168201360Srdivacky ENCODING("GR8", ENCODING_RB) 1169201360Srdivacky errs() << "Unhandled opcode modifier encoding " << s << "\n"; 1170201360Srdivacky llvm_unreachable("Unhandled opcode modifier encoding"); 1171201360Srdivacky} 1172201360Srdivacky#undef ENCODING 1173