Path: blob/main/contrib/llvm-project/llvm/utils/TableGen/X86RecognizableInstr.cpp
213766 views
//===- X86RecognizableInstr.cpp - Disassembler instruction spec -*- C++ -*-===//1//2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.3// See https://llvm.org/LICENSE.txt for license information.4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5//6//===----------------------------------------------------------------------===//7//8// This file is part of the X86 Disassembler Emitter.9// It contains the implementation of a single recognizable instruction.10// Documentation for the disassembler emitter in general can be found in11// X86DisassemblerEmitter.h.12//13//===----------------------------------------------------------------------===//1415#include "X86RecognizableInstr.h"16#include "X86DisassemblerShared.h"17#include "X86DisassemblerTables.h"18#include "X86ModRMFilters.h"19#include "llvm/ADT/StringSwitch.h"20#include "llvm/Support/ErrorHandling.h"21#include "llvm/TableGen/Record.h"22#include <string>2324using namespace llvm;25using namespace X86Disassembler;2627std::string X86Disassembler::getMnemonic(const CodeGenInstruction *I,28unsigned Variant) {29// Extract a mnemonic assuming it's separated by \t30std::string Mnemonic =31StringRef(I->FlattenAsmStringVariants(I->AsmString, Variant))32.take_until([](char C) { return C == '\t'; })33.str();3435// Special case: CMOVCC, JCC, SETCC, CMPCCXADD have "${cond}" in mnemonic.36// Replace it with "CC" in-place.37auto CondPos = Mnemonic.find("${cond}");38if (CondPos != std::string::npos)39Mnemonic = Mnemonic.replace(CondPos, 7, "CC");40return StringRef(Mnemonic).upper();41}4243bool X86Disassembler::isRegisterOperand(const Record *Rec) {44return Rec->isSubClassOf("RegisterClass") ||45Rec->isSubClassOf("RegisterOperand");46}4748bool X86Disassembler::isMemoryOperand(const Record *Rec) {49return Rec->isSubClassOf("Operand") &&50Rec->getValueAsString("OperandType") == "OPERAND_MEMORY";51}5253bool X86Disassembler::isImmediateOperand(const Record *Rec) {54return Rec->isSubClassOf("Operand") &&55Rec->getValueAsString("OperandType") == "OPERAND_IMMEDIATE";56}5758unsigned X86Disassembler::getRegOperandSize(const Record *RegRec) {59if (RegRec->isSubClassOf("RegisterClass"))60return RegRec->getValueAsInt("Alignment");61if (RegRec->isSubClassOf("RegisterOperand"))62return RegRec->getValueAsDef("RegClass")->getValueAsInt("Alignment");6364llvm_unreachable("Register operand's size not known!");65}6667unsigned X86Disassembler::getMemOperandSize(const Record *MemRec) {68if (MemRec->isSubClassOf("X86MemOperand"))69return MemRec->getValueAsInt("Size");7071llvm_unreachable("Memory operand's size not known!");72}7374/// byteFromBitsInit - Extracts a value at most 8 bits in width from a BitsInit.75/// Useful for switch statements and the like.76///77/// @param init - A reference to the BitsInit to be decoded.78/// @return - The field, with the first bit in the BitsInit as the lowest79/// order bit.80static uint8_t byteFromBitsInit(const BitsInit &init) {81int width = init.getNumBits();8283assert(width <= 8 && "Field is too large for uint8_t!");8485uint8_t mask = 0x01;86uint8_t ret = 0;8788for (int index = 0; index < width; index++) {89if (cast<BitInit>(init.getBit(index))->getValue())90ret |= mask;9192mask <<= 1;93}9495return ret;96}9798/// byteFromRec - Extract a value at most 8 bits in with from a Record given the99/// name of the field.100///101/// @param rec - The record from which to extract the value.102/// @param name - The name of the field in the record.103/// @return - The field, as translated by byteFromBitsInit().104static uint8_t byteFromRec(const Record *rec, StringRef name) {105const BitsInit *bits = rec->getValueAsBitsInit(name);106return byteFromBitsInit(*bits);107}108109RecognizableInstrBase::RecognizableInstrBase(const CodeGenInstruction &insn) {110const Record *Rec = insn.TheDef;111assert(Rec->isSubClassOf("X86Inst") && "Not a X86 Instruction");112OpPrefix = byteFromRec(Rec, "OpPrefixBits");113OpMap = byteFromRec(Rec, "OpMapBits");114Opcode = byteFromRec(Rec, "Opcode");115Form = byteFromRec(Rec, "FormBits");116Encoding = byteFromRec(Rec, "OpEncBits");117OpSize = byteFromRec(Rec, "OpSizeBits");118AdSize = byteFromRec(Rec, "AdSizeBits");119HasREX_W = Rec->getValueAsBit("hasREX_W");120HasVEX_4V = Rec->getValueAsBit("hasVEX_4V");121IgnoresW = Rec->getValueAsBit("IgnoresW");122IgnoresVEX_L = Rec->getValueAsBit("ignoresVEX_L");123HasEVEX_L2 = Rec->getValueAsBit("hasEVEX_L2");124HasEVEX_K = Rec->getValueAsBit("hasEVEX_K");125HasEVEX_KZ = Rec->getValueAsBit("hasEVEX_Z");126HasEVEX_B = Rec->getValueAsBit("hasEVEX_B");127HasEVEX_U = Rec->getValueAsBit("hasEVEX_U");128HasEVEX_NF = Rec->getValueAsBit("hasEVEX_NF");129HasTwoConditionalOps = Rec->getValueAsBit("hasTwoConditionalOps");130IsCodeGenOnly = Rec->getValueAsBit("isCodeGenOnly");131IsAsmParserOnly = Rec->getValueAsBit("isAsmParserOnly");132ForceDisassemble = Rec->getValueAsBit("ForceDisassemble");133CD8_Scale = byteFromRec(Rec, "CD8_Scale");134HasVEX_L = Rec->getValueAsBit("hasVEX_L");135ExplicitREX2Prefix =136byteFromRec(Rec, "explicitOpPrefixBits") == X86Local::ExplicitREX2;137138EncodeRC = HasEVEX_B &&139(Form == X86Local::MRMDestReg || Form == X86Local::MRMSrcReg);140}141142bool RecognizableInstrBase::shouldBeEmitted() const {143return Form != X86Local::Pseudo && (!IsCodeGenOnly || ForceDisassemble) &&144!IsAsmParserOnly;145}146147RecognizableInstr::RecognizableInstr(DisassemblerTables &tables,148const CodeGenInstruction &insn,149InstrUID uid)150: RecognizableInstrBase(insn), Rec(insn.TheDef), Name(Rec->getName().str()),151Is32Bit(false), Is64Bit(false), Operands(&insn.Operands.OperandList),152UID(uid), Spec(&tables.specForUID(uid)) {153// Check for 64-bit inst which does not require REX154// FIXME: Is there some better way to check for In64BitMode?155for (const Record *Predicate : Rec->getValueAsListOfDefs("Predicates")) {156if (Predicate->getName().contains("Not64Bit") ||157Predicate->getName().contains("In32Bit")) {158Is32Bit = true;159break;160}161if (Predicate->getName().contains("In64Bit")) {162Is64Bit = true;163break;164}165}166}167168void RecognizableInstr::processInstr(DisassemblerTables &tables,169const CodeGenInstruction &insn,170InstrUID uid) {171if (!insn.TheDef->isSubClassOf("X86Inst"))172return;173RecognizableInstr recogInstr(tables, insn, uid);174175if (!recogInstr.shouldBeEmitted())176return;177recogInstr.emitInstructionSpecifier();178recogInstr.emitDecodePath(tables);179}180181#define EVEX_KB(n) \182(HasEVEX_KZ && HasEVEX_B \183? n##_KZ_B \184: (HasEVEX_K && HasEVEX_B \185? n##_K_B \186: (HasEVEX_KZ ? n##_KZ \187: (HasEVEX_K ? n##_K : (HasEVEX_B ? n##_B : n)))))188189#define EVEX_NF(n) (HasEVEX_NF ? n##_NF : n)190#define EVEX_B_NF(n) (HasEVEX_B ? EVEX_NF(n##_B) : EVEX_NF(n))191#define EVEX_KB_ADSIZE(n) AdSize == X86Local::AdSize32 ? n##_ADSIZE : EVEX_KB(n)192#define EVEX_KB_U(n) \193(HasEVEX_KZ ? n##_KZ_B_U : (HasEVEX_K ? n##_K_B_U : n##_B_U))194195InstructionContext RecognizableInstr::insnContext() const {196InstructionContext insnContext;197198if (Encoding == X86Local::EVEX) {199if (HasVEX_L && HasEVEX_L2) {200errs() << "Don't support VEX.L if EVEX_L2 is enabled: " << Name << "\n";201llvm_unreachable("Don't support VEX.L if EVEX_L2 is enabled");202}203if (EncodeRC && HasEVEX_U) {204// EVEX_U205if (HasREX_W) {206if (OpPrefix == X86Local::PD)207insnContext = EVEX_KB_U(IC_EVEX_W_OPSIZE);208else if (OpPrefix == X86Local::XS)209insnContext = EVEX_KB_U(IC_EVEX_W_XS);210else if (OpPrefix == X86Local::XD)211insnContext = EVEX_KB_U(IC_EVEX_W_XD);212else if (OpPrefix == X86Local::PS)213insnContext = EVEX_KB_U(IC_EVEX_W);214else {215errs() << "Instruction does not use a prefix: " << Name << "\n";216llvm_unreachable("Invalid prefix");217}218} else {219if (OpPrefix == X86Local::PD)220insnContext = EVEX_KB_U(IC_EVEX_OPSIZE);221else if (OpPrefix == X86Local::XS)222insnContext = EVEX_KB_U(IC_EVEX_XS);223else if (OpPrefix == X86Local::XD)224insnContext = EVEX_KB_U(IC_EVEX_XD);225else if (OpPrefix == X86Local::PS)226insnContext = EVEX_KB_U(IC_EVEX);227else {228errs() << "Instruction does not use a prefix: " << Name << "\n";229llvm_unreachable("Invalid prefix");230}231}232} else if (HasEVEX_NF) {233if (OpPrefix == X86Local::PD)234insnContext = EVEX_B_NF(IC_EVEX_OPSIZE);235else if (HasREX_W)236insnContext = EVEX_B_NF(IC_EVEX_W);237else238insnContext = EVEX_B_NF(IC_EVEX);239} else if (!EncodeRC && HasVEX_L && HasREX_W) {240// VEX_L & VEX_W241if (OpPrefix == X86Local::PD)242insnContext = EVEX_KB(IC_EVEX_L_W_OPSIZE);243else if (OpPrefix == X86Local::XS)244insnContext = EVEX_KB(IC_EVEX_L_W_XS);245else if (OpPrefix == X86Local::XD)246insnContext = EVEX_KB(IC_EVEX_L_W_XD);247else if (OpPrefix == X86Local::PS)248insnContext = EVEX_KB(IC_EVEX_L_W);249else {250errs() << "Instruction does not use a prefix: " << Name << "\n";251llvm_unreachable("Invalid prefix");252}253} else if (!EncodeRC && HasVEX_L) {254// VEX_L255if (OpPrefix == X86Local::PD)256insnContext = EVEX_KB(IC_EVEX_L_OPSIZE);257else if (OpPrefix == X86Local::XS)258insnContext = EVEX_KB(IC_EVEX_L_XS);259else if (OpPrefix == X86Local::XD)260insnContext = EVEX_KB(IC_EVEX_L_XD);261else if (OpPrefix == X86Local::PS)262insnContext = EVEX_KB(IC_EVEX_L);263else {264errs() << "Instruction does not use a prefix: " << Name << "\n";265llvm_unreachable("Invalid prefix");266}267} else if (!EncodeRC && HasEVEX_L2 && HasREX_W) {268// EVEX_L2 & VEX_W269if (OpPrefix == X86Local::PD)270insnContext = EVEX_KB(IC_EVEX_L2_W_OPSIZE);271else if (OpPrefix == X86Local::XS)272insnContext = EVEX_KB(IC_EVEX_L2_W_XS);273else if (OpPrefix == X86Local::XD)274insnContext = EVEX_KB(IC_EVEX_L2_W_XD);275else if (OpPrefix == X86Local::PS)276insnContext = EVEX_KB(IC_EVEX_L2_W);277else {278errs() << "Instruction does not use a prefix: " << Name << "\n";279llvm_unreachable("Invalid prefix");280}281} else if (!EncodeRC && HasEVEX_L2) {282// EVEX_L2283if (OpPrefix == X86Local::PD)284insnContext = EVEX_KB(IC_EVEX_L2_OPSIZE);285else if (OpPrefix == X86Local::XD)286insnContext = EVEX_KB(IC_EVEX_L2_XD);287else if (OpPrefix == X86Local::XS)288insnContext = EVEX_KB(IC_EVEX_L2_XS);289else if (OpPrefix == X86Local::PS)290insnContext = EVEX_KB(IC_EVEX_L2);291else {292errs() << "Instruction does not use a prefix: " << Name << "\n";293llvm_unreachable("Invalid prefix");294}295} else if (HasREX_W) {296// VEX_W297if (OpPrefix == X86Local::PD)298insnContext = EVEX_KB(IC_EVEX_W_OPSIZE);299else if (OpPrefix == X86Local::XS)300insnContext = EVEX_KB(IC_EVEX_W_XS);301else if (OpPrefix == X86Local::XD)302insnContext = EVEX_KB(IC_EVEX_W_XD);303else if (OpPrefix == X86Local::PS)304insnContext = EVEX_KB(IC_EVEX_W);305else {306errs() << "Instruction does not use a prefix: " << Name << "\n";307llvm_unreachable("Invalid prefix");308}309}310// No L, no W311else if (OpPrefix == X86Local::PD) {312insnContext = EVEX_KB_ADSIZE(IC_EVEX_OPSIZE);313} else if (OpPrefix == X86Local::XD)314insnContext = EVEX_KB_ADSIZE(IC_EVEX_XD);315else if (OpPrefix == X86Local::XS)316insnContext = EVEX_KB_ADSIZE(IC_EVEX_XS);317else if (OpPrefix == X86Local::PS)318insnContext = EVEX_KB(IC_EVEX);319else {320errs() << "Instruction does not use a prefix: " << Name << "\n";321llvm_unreachable("Invalid prefix");322}323/// eof EVEX324} else if (Encoding == X86Local::VEX || Encoding == X86Local::XOP) {325if (HasVEX_L && HasREX_W) {326if (OpPrefix == X86Local::PD)327insnContext = IC_VEX_L_W_OPSIZE;328else if (OpPrefix == X86Local::XS)329insnContext = IC_VEX_L_W_XS;330else if (OpPrefix == X86Local::XD)331insnContext = IC_VEX_L_W_XD;332else if (OpPrefix == X86Local::PS)333insnContext = IC_VEX_L_W;334else {335errs() << "Instruction does not use a prefix: " << Name << "\n";336llvm_unreachable("Invalid prefix");337}338} else if (OpPrefix == X86Local::PD && HasVEX_L)339insnContext = IC_VEX_L_OPSIZE;340else if (OpPrefix == X86Local::PD && HasREX_W)341insnContext = IC_VEX_W_OPSIZE;342else if (OpPrefix == X86Local::PD)343insnContext = IC_VEX_OPSIZE;344else if (HasVEX_L && OpPrefix == X86Local::XS)345insnContext = IC_VEX_L_XS;346else if (HasVEX_L && OpPrefix == X86Local::XD)347insnContext = IC_VEX_L_XD;348else if (HasREX_W && OpPrefix == X86Local::XS)349insnContext = IC_VEX_W_XS;350else if (HasREX_W && OpPrefix == X86Local::XD)351insnContext = IC_VEX_W_XD;352else if (HasREX_W && OpPrefix == X86Local::PS)353insnContext = IC_VEX_W;354else if (HasVEX_L && OpPrefix == X86Local::PS)355insnContext = IC_VEX_L;356else if (OpPrefix == X86Local::XD)357insnContext = IC_VEX_XD;358else if (OpPrefix == X86Local::XS)359insnContext = IC_VEX_XS;360else if (OpPrefix == X86Local::PS)361insnContext = IC_VEX;362else {363errs() << "Instruction does not use a prefix: " << Name << "\n";364llvm_unreachable("Invalid prefix");365}366} else if (Is64Bit || HasREX_W || AdSize == X86Local::AdSize64) {367if (HasREX_W && (OpSize == X86Local::OpSize16 || OpPrefix == X86Local::PD))368insnContext = IC_64BIT_REXW_OPSIZE;369else if (HasREX_W && AdSize == X86Local::AdSize32)370insnContext = IC_64BIT_REXW_ADSIZE;371else if (OpSize == X86Local::OpSize16 && OpPrefix == X86Local::XD)372insnContext = IC_64BIT_XD_OPSIZE;373else if (OpSize == X86Local::OpSize16 && OpPrefix == X86Local::XS)374insnContext = IC_64BIT_XS_OPSIZE;375else if (AdSize == X86Local::AdSize32 && OpPrefix == X86Local::PD)376insnContext = IC_64BIT_OPSIZE_ADSIZE;377else if (OpSize == X86Local::OpSize16 && AdSize == X86Local::AdSize32)378insnContext = IC_64BIT_OPSIZE_ADSIZE;379else if (OpSize == X86Local::OpSize16 || OpPrefix == X86Local::PD)380insnContext = IC_64BIT_OPSIZE;381else if (AdSize == X86Local::AdSize32)382insnContext = IC_64BIT_ADSIZE;383else if (HasREX_W && OpPrefix == X86Local::XS)384insnContext = IC_64BIT_REXW_XS;385else if (HasREX_W && OpPrefix == X86Local::XD)386insnContext = IC_64BIT_REXW_XD;387else if (OpPrefix == X86Local::XD)388insnContext = IC_64BIT_XD;389else if (OpPrefix == X86Local::XS)390insnContext = IC_64BIT_XS;391else if (ExplicitREX2Prefix)392insnContext = IC_64BIT_REX2;393else if (HasREX_W)394insnContext = IC_64BIT_REXW;395else396insnContext = IC_64BIT;397} else {398if (OpSize == X86Local::OpSize16 && OpPrefix == X86Local::XD)399insnContext = IC_XD_OPSIZE;400else if (OpSize == X86Local::OpSize16 && OpPrefix == X86Local::XS)401insnContext = IC_XS_OPSIZE;402else if (AdSize == X86Local::AdSize16 && OpPrefix == X86Local::XD)403insnContext = IC_XD_ADSIZE;404else if (AdSize == X86Local::AdSize16 && OpPrefix == X86Local::XS)405insnContext = IC_XS_ADSIZE;406else if (AdSize == X86Local::AdSize16 && OpPrefix == X86Local::PD)407insnContext = IC_OPSIZE_ADSIZE;408else if (OpSize == X86Local::OpSize16 && AdSize == X86Local::AdSize16)409insnContext = IC_OPSIZE_ADSIZE;410else if (OpSize == X86Local::OpSize16 || OpPrefix == X86Local::PD)411insnContext = IC_OPSIZE;412else if (AdSize == X86Local::AdSize16)413insnContext = IC_ADSIZE;414else if (OpPrefix == X86Local::XD)415insnContext = IC_XD;416else if (OpPrefix == X86Local::XS)417insnContext = IC_XS;418else419insnContext = IC;420}421422return insnContext;423}424425void RecognizableInstr::adjustOperandEncoding(OperandEncoding &encoding) {426// The scaling factor for AVX512 compressed displacement encoding is an427// instruction attribute. Adjust the ModRM encoding type to include the428// scale for compressed displacement.429if ((encoding != ENCODING_RM && encoding != ENCODING_VSIB &&430encoding != ENCODING_SIB) ||431CD8_Scale == 0)432return;433encoding = (OperandEncoding)(encoding + Log2_32(CD8_Scale));434assert(((encoding >= ENCODING_RM && encoding <= ENCODING_RM_CD64) ||435(encoding == ENCODING_SIB) ||436(encoding >= ENCODING_VSIB && encoding <= ENCODING_VSIB_CD64)) &&437"Invalid CDisp scaling");438}439440void RecognizableInstr::handleOperand(bool optional, unsigned &operandIndex,441unsigned &physicalOperandIndex,442unsigned numPhysicalOperands,443const unsigned *operandMapping,444EncodingFn encodingFromString) {445if (optional) {446if (physicalOperandIndex >= numPhysicalOperands)447return;448} else {449assert(physicalOperandIndex < numPhysicalOperands);450}451452while (operandMapping[operandIndex] != operandIndex) {453Spec->operands[operandIndex].encoding = ENCODING_DUP;454Spec->operands[operandIndex].type =455(OperandType)(TYPE_DUP0 + operandMapping[operandIndex]);456++operandIndex;457}458459StringRef typeName = (*Operands)[operandIndex].Rec->getName();460461OperandEncoding encoding = encodingFromString(typeName, OpSize);462// Adjust the encoding type for an operand based on the instruction.463adjustOperandEncoding(encoding);464Spec->operands[operandIndex].encoding = encoding;465Spec->operands[operandIndex].type =466typeFromString(typeName, HasREX_W, OpSize);467468++operandIndex;469++physicalOperandIndex;470}471472void RecognizableInstr::emitInstructionSpecifier() {473Spec->name = Name;474475Spec->insnContext = insnContext();476477const std::vector<CGIOperandList::OperandInfo> &OperandList = *Operands;478479unsigned numOperands = OperandList.size();480unsigned numPhysicalOperands = 0;481482// operandMapping maps from operands in OperandList to their originals.483// If operandMapping[i] != i, then the entry is a duplicate.484unsigned operandMapping[X86_MAX_OPERANDS];485assert(numOperands <= X86_MAX_OPERANDS &&486"X86_MAX_OPERANDS is not large enough");487488for (unsigned operandIndex = 0; operandIndex < numOperands; ++operandIndex) {489if (!OperandList[operandIndex].Constraints.empty()) {490const CGIOperandList::ConstraintInfo &Constraint =491OperandList[operandIndex].Constraints[0];492if (Constraint.isTied()) {493operandMapping[operandIndex] = operandIndex;494operandMapping[Constraint.getTiedOperand()] = operandIndex;495} else {496++numPhysicalOperands;497operandMapping[operandIndex] = operandIndex;498}499} else {500++numPhysicalOperands;501operandMapping[operandIndex] = operandIndex;502}503}504505#define HANDLE_OPERAND(class) \506handleOperand(false, operandIndex, physicalOperandIndex, \507numPhysicalOperands, operandMapping, \508class##EncodingFromString);509510#define HANDLE_OPTIONAL(class) \511handleOperand(true, operandIndex, physicalOperandIndex, numPhysicalOperands, \512operandMapping, class##EncodingFromString);513514// operandIndex should always be < numOperands515unsigned operandIndex = 0;516// physicalOperandIndex should always be < numPhysicalOperands517unsigned physicalOperandIndex = 0;518519#ifndef NDEBUG520// Given the set of prefix bits, how many additional operands does the521// instruction have?522unsigned additionalOperands = 0;523if (HasVEX_4V)524++additionalOperands;525if (HasEVEX_K)526++additionalOperands;527if (HasTwoConditionalOps)528additionalOperands += 2;529#endif530531bool IsND = OpMap == X86Local::T_MAP4 && HasEVEX_B && HasVEX_4V;532switch (Form) {533default:534llvm_unreachable("Unhandled form");535case X86Local::PrefixByte:536return;537case X86Local::RawFrmSrc:538HANDLE_OPERAND(relocation);539return;540case X86Local::RawFrmDst:541HANDLE_OPERAND(relocation);542return;543case X86Local::RawFrmDstSrc:544HANDLE_OPERAND(relocation);545HANDLE_OPERAND(relocation);546return;547case X86Local::RawFrm:548// Operand 1 (optional) is an address or immediate.549assert(numPhysicalOperands <= 1 &&550"Unexpected number of operands for RawFrm");551HANDLE_OPTIONAL(relocation)552break;553case X86Local::RawFrmMemOffs:554// Operand 1 is an address.555HANDLE_OPERAND(relocation);556break;557case X86Local::AddRegFrm:558// Operand 1 is added to the opcode.559// Operand 2 (optional) is an address.560assert(numPhysicalOperands >= 1 && numPhysicalOperands <= 2 &&561"Unexpected number of operands for AddRegFrm");562HANDLE_OPERAND(opcodeModifier)563HANDLE_OPTIONAL(relocation)564break;565case X86Local::AddCCFrm:566// Operand 1 (optional) is an address or immediate.567assert(numPhysicalOperands == 2 &&568"Unexpected number of operands for AddCCFrm");569HANDLE_OPERAND(relocation)570HANDLE_OPERAND(opcodeModifier)571break;572case X86Local::MRMDestRegCC:573assert(numPhysicalOperands == 3 &&574"Unexpected number of operands for MRMDestRegCC");575HANDLE_OPERAND(rmRegister)576HANDLE_OPERAND(roRegister)577HANDLE_OPERAND(opcodeModifier)578break;579case X86Local::MRMDestReg:580// Operand 1 is a register operand in the R/M field.581// - In AVX512 there may be a mask operand here -582// Operand 2 is a register operand in the Reg/Opcode field.583// - In AVX, there is a register operand in the VEX.vvvv field here -584// Operand 3 (optional) is an immediate.585assert(numPhysicalOperands >= 2 + additionalOperands &&586numPhysicalOperands <= 3 + additionalOperands &&587"Unexpected number of operands for MRMDestReg");588589if (IsND)590HANDLE_OPERAND(vvvvRegister)591592HANDLE_OPERAND(rmRegister)593if (HasEVEX_K)594HANDLE_OPERAND(writemaskRegister)595596if (!IsND && HasVEX_4V)597// FIXME: In AVX, the register below becomes the one encoded598// in ModRMVEX and the one above the one in the VEX.VVVV field599HANDLE_OPERAND(vvvvRegister)600601HANDLE_OPERAND(roRegister)602HANDLE_OPTIONAL(immediate)603HANDLE_OPTIONAL(immediate)604break;605case X86Local::MRMDestMemCC:606assert(numPhysicalOperands == 3 &&607"Unexpected number of operands for MRMDestMemCC");608HANDLE_OPERAND(memory)609HANDLE_OPERAND(roRegister)610HANDLE_OPERAND(opcodeModifier)611break;612case X86Local::MRMDestMem4VOp3CC:613// Operand 1 is a register operand in the Reg/Opcode field.614// Operand 2 is a register operand in the R/M field.615// Operand 3 is VEX.vvvv616// Operand 4 is condition code.617assert(numPhysicalOperands == 4 &&618"Unexpected number of operands for MRMDestMem4VOp3CC");619HANDLE_OPERAND(roRegister)620HANDLE_OPERAND(memory)621HANDLE_OPERAND(vvvvRegister)622HANDLE_OPERAND(opcodeModifier)623break;624case X86Local::MRMDestMem:625case X86Local::MRMDestMemFSIB:626// Operand 1 is a memory operand (possibly SIB-extended)627// Operand 2 is a register operand in the Reg/Opcode field.628// - In AVX, there is a register operand in the VEX.vvvv field here -629// Operand 3 (optional) is an immediate.630assert(numPhysicalOperands >= 2 + additionalOperands &&631numPhysicalOperands <= 3 + additionalOperands &&632"Unexpected number of operands for MRMDestMemFrm with VEX_4V");633634if (IsND)635HANDLE_OPERAND(vvvvRegister)636637HANDLE_OPERAND(memory)638639if (HasEVEX_K)640HANDLE_OPERAND(writemaskRegister)641642if (!IsND && HasVEX_4V)643// FIXME: In AVX, the register below becomes the one encoded644// in ModRMVEX and the one above the one in the VEX.VVVV field645HANDLE_OPERAND(vvvvRegister)646647HANDLE_OPERAND(roRegister)648HANDLE_OPTIONAL(immediate)649HANDLE_OPTIONAL(immediate)650break;651case X86Local::MRMSrcReg:652// Operand 1 is a register operand in the Reg/Opcode field.653// Operand 2 is a register operand in the R/M field.654// - In AVX, there is a register operand in the VEX.vvvv field here -655// Operand 3 (optional) is an immediate.656// Operand 4 (optional) is an immediate.657658assert(numPhysicalOperands >= 2 + additionalOperands &&659numPhysicalOperands <= 4 + additionalOperands &&660"Unexpected number of operands for MRMSrcRegFrm");661662if (IsND)663HANDLE_OPERAND(vvvvRegister)664665HANDLE_OPERAND(roRegister)666667if (HasEVEX_K)668HANDLE_OPERAND(writemaskRegister)669670if (!IsND && HasVEX_4V)671// FIXME: In AVX, the register below becomes the one encoded672// in ModRMVEX and the one above the one in the VEX.VVVV field673HANDLE_OPERAND(vvvvRegister)674675HANDLE_OPERAND(rmRegister)676HANDLE_OPTIONAL(immediate)677HANDLE_OPTIONAL(immediate) // above might be a register in 7:4678break;679case X86Local::MRMSrcReg4VOp3:680assert(numPhysicalOperands == 3 &&681"Unexpected number of operands for MRMSrcReg4VOp3Frm");682HANDLE_OPERAND(roRegister)683HANDLE_OPERAND(rmRegister)684HANDLE_OPERAND(vvvvRegister)685break;686case X86Local::MRMSrcRegOp4:687assert(numPhysicalOperands >= 4 && numPhysicalOperands <= 5 &&688"Unexpected number of operands for MRMSrcRegOp4Frm");689HANDLE_OPERAND(roRegister)690HANDLE_OPERAND(vvvvRegister)691HANDLE_OPERAND(immediate) // Register in imm[7:4]692HANDLE_OPERAND(rmRegister)693HANDLE_OPTIONAL(immediate)694break;695case X86Local::MRMSrcRegCC:696assert(numPhysicalOperands >= 3 && numPhysicalOperands <= 4 &&697"Unexpected number of operands for MRMSrcRegCC");698if (IsND)699HANDLE_OPERAND(vvvvRegister)700HANDLE_OPERAND(roRegister)701HANDLE_OPERAND(rmRegister)702HANDLE_OPERAND(opcodeModifier)703break;704case X86Local::MRMSrcMem:705case X86Local::MRMSrcMemFSIB:706// Operand 1 is a register operand in the Reg/Opcode field.707// Operand 2 is a memory operand (possibly SIB-extended)708// - In AVX, there is a register operand in the VEX.vvvv field here -709// Operand 3 (optional) is an immediate.710711assert(numPhysicalOperands >= 2 + additionalOperands &&712numPhysicalOperands <= 4 + additionalOperands &&713"Unexpected number of operands for MRMSrcMemFrm");714if (IsND)715HANDLE_OPERAND(vvvvRegister)716717HANDLE_OPERAND(roRegister)718719if (HasEVEX_K)720HANDLE_OPERAND(writemaskRegister)721722if (!IsND && HasVEX_4V)723// FIXME: In AVX, the register below becomes the one encoded724// in ModRMVEX and the one above the one in the VEX.VVVV field725HANDLE_OPERAND(vvvvRegister)726727HANDLE_OPERAND(memory)728HANDLE_OPTIONAL(immediate)729HANDLE_OPTIONAL(immediate) // above might be a register in 7:4730break;731case X86Local::MRMSrcMem4VOp3:732assert(numPhysicalOperands == 3 &&733"Unexpected number of operands for MRMSrcMem4VOp3Frm");734HANDLE_OPERAND(roRegister)735HANDLE_OPERAND(memory)736HANDLE_OPERAND(vvvvRegister)737break;738case X86Local::MRMSrcMemOp4:739assert(numPhysicalOperands >= 4 && numPhysicalOperands <= 5 &&740"Unexpected number of operands for MRMSrcMemOp4Frm");741HANDLE_OPERAND(roRegister)742HANDLE_OPERAND(vvvvRegister)743HANDLE_OPERAND(immediate) // Register in imm[7:4]744HANDLE_OPERAND(memory)745HANDLE_OPTIONAL(immediate)746break;747case X86Local::MRMSrcMemCC:748assert(numPhysicalOperands >= 3 && numPhysicalOperands <= 4 &&749"Unexpected number of operands for MRMSrcMemCC");750if (IsND)751HANDLE_OPERAND(vvvvRegister)752HANDLE_OPERAND(roRegister)753HANDLE_OPERAND(memory)754HANDLE_OPERAND(opcodeModifier)755break;756case X86Local::MRMXrCC:757assert(numPhysicalOperands == 2 &&758"Unexpected number of operands for MRMXrCC");759HANDLE_OPERAND(rmRegister)760HANDLE_OPERAND(opcodeModifier)761break;762case X86Local::MRMr0:763// Operand 1 is a register operand in the R/M field.764HANDLE_OPERAND(roRegister)765break;766case X86Local::MRMXr:767case X86Local::MRM0r:768case X86Local::MRM1r:769case X86Local::MRM2r:770case X86Local::MRM3r:771case X86Local::MRM4r:772case X86Local::MRM5r:773case X86Local::MRM6r:774case X86Local::MRM7r:775// Operand 1 is a register operand in the R/M field.776// Operand 2 (optional) is an immediate or relocation.777// Operand 3 (optional) is an immediate.778assert(numPhysicalOperands >= 0 + additionalOperands &&779numPhysicalOperands <= 3 + additionalOperands &&780"Unexpected number of operands for MRMnr");781782if (HasVEX_4V)783HANDLE_OPERAND(vvvvRegister)784785if (HasEVEX_K)786HANDLE_OPERAND(writemaskRegister)787HANDLE_OPTIONAL(rmRegister)788HANDLE_OPTIONAL(relocation)789HANDLE_OPTIONAL(immediate)790HANDLE_OPTIONAL(immediate)791break;792case X86Local::MRMXmCC:793assert(numPhysicalOperands == 2 &&794"Unexpected number of operands for MRMXm");795HANDLE_OPERAND(memory)796HANDLE_OPERAND(opcodeModifier)797break;798case X86Local::MRMXm:799case X86Local::MRM0m:800case X86Local::MRM1m:801case X86Local::MRM2m:802case X86Local::MRM3m:803case X86Local::MRM4m:804case X86Local::MRM5m:805case X86Local::MRM6m:806case X86Local::MRM7m:807// Operand 1 is a memory operand (possibly SIB-extended)808// Operand 2 (optional) is an immediate or relocation.809assert(numPhysicalOperands >= 1 + additionalOperands &&810numPhysicalOperands <= 2 + additionalOperands &&811"Unexpected number of operands for MRMnm");812813if (HasVEX_4V)814HANDLE_OPERAND(vvvvRegister)815if (HasEVEX_K)816HANDLE_OPERAND(writemaskRegister)817HANDLE_OPERAND(memory)818HANDLE_OPTIONAL(relocation)819HANDLE_OPTIONAL(immediate)820HANDLE_OPTIONAL(immediate)821break;822case X86Local::RawFrmImm8:823// operand 1 is a 16-bit immediate824// operand 2 is an 8-bit immediate825assert(numPhysicalOperands == 2 &&826"Unexpected number of operands for X86Local::RawFrmImm8");827HANDLE_OPERAND(immediate)828HANDLE_OPERAND(immediate)829break;830case X86Local::RawFrmImm16:831// operand 1 is a 16-bit immediate832// operand 2 is a 16-bit immediate833HANDLE_OPERAND(immediate)834HANDLE_OPERAND(immediate)835break;836case X86Local::MRM0X:837case X86Local::MRM1X:838case X86Local::MRM2X:839case X86Local::MRM3X:840case X86Local::MRM4X:841case X86Local::MRM5X:842case X86Local::MRM6X:843case X86Local::MRM7X:844#define MAP(from, to) case X86Local::MRM_##from:845X86_INSTR_MRM_MAPPING846#undef MAP847HANDLE_OPTIONAL(relocation)848break;849}850851#undef HANDLE_OPERAND852#undef HANDLE_OPTIONAL853}854855void RecognizableInstr::emitDecodePath(DisassemblerTables &tables) const {856// Special cases where the LLVM tables are not complete857858#define MAP(from, to) case X86Local::MRM_##from:859860std::optional<OpcodeType> opcodeType;861switch (OpMap) {862default:863llvm_unreachable("Invalid map!");864case X86Local::OB:865opcodeType = ONEBYTE;866break;867case X86Local::TB:868opcodeType = TWOBYTE;869break;870case X86Local::T8:871opcodeType = THREEBYTE_38;872break;873case X86Local::TA:874opcodeType = THREEBYTE_3A;875break;876case X86Local::XOP8:877opcodeType = XOP8_MAP;878break;879case X86Local::XOP9:880opcodeType = XOP9_MAP;881break;882case X86Local::XOPA:883opcodeType = XOPA_MAP;884break;885case X86Local::ThreeDNow:886opcodeType = THREEDNOW_MAP;887break;888case X86Local::T_MAP4:889opcodeType = MAP4;890break;891case X86Local::T_MAP5:892opcodeType = MAP5;893break;894case X86Local::T_MAP6:895opcodeType = MAP6;896break;897case X86Local::T_MAP7:898opcodeType = MAP7;899break;900}901902std::unique_ptr<ModRMFilter> filter;903switch (Form) {904default:905llvm_unreachable("Invalid form!");906case X86Local::Pseudo:907llvm_unreachable("Pseudo should not be emitted!");908case X86Local::RawFrm:909case X86Local::AddRegFrm:910case X86Local::RawFrmMemOffs:911case X86Local::RawFrmSrc:912case X86Local::RawFrmDst:913case X86Local::RawFrmDstSrc:914case X86Local::RawFrmImm8:915case X86Local::RawFrmImm16:916case X86Local::AddCCFrm:917case X86Local::PrefixByte:918filter = std::make_unique<DumbFilter>();919break;920case X86Local::MRMDestReg:921case X86Local::MRMDestRegCC:922case X86Local::MRMSrcReg:923case X86Local::MRMSrcReg4VOp3:924case X86Local::MRMSrcRegOp4:925case X86Local::MRMSrcRegCC:926case X86Local::MRMXrCC:927case X86Local::MRMXr:928filter = std::make_unique<ModFilter>(true);929break;930case X86Local::MRMDestMem:931case X86Local::MRMDestMemCC:932case X86Local::MRMDestMem4VOp3CC:933case X86Local::MRMDestMemFSIB:934case X86Local::MRMSrcMem:935case X86Local::MRMSrcMemFSIB:936case X86Local::MRMSrcMem4VOp3:937case X86Local::MRMSrcMemOp4:938case X86Local::MRMSrcMemCC:939case X86Local::MRMXmCC:940case X86Local::MRMXm:941filter = std::make_unique<ModFilter>(false);942break;943case X86Local::MRM0r:944case X86Local::MRM1r:945case X86Local::MRM2r:946case X86Local::MRM3r:947case X86Local::MRM4r:948case X86Local::MRM5r:949case X86Local::MRM6r:950case X86Local::MRM7r:951filter = std::make_unique<ExtendedFilter>(true, Form - X86Local::MRM0r);952break;953case X86Local::MRM0X:954case X86Local::MRM1X:955case X86Local::MRM2X:956case X86Local::MRM3X:957case X86Local::MRM4X:958case X86Local::MRM5X:959case X86Local::MRM6X:960case X86Local::MRM7X:961filter = std::make_unique<ExtendedFilter>(true, Form - X86Local::MRM0X);962break;963case X86Local::MRMr0:964filter = std::make_unique<ExtendedRMFilter>(true, Form - X86Local::MRMr0);965break;966case X86Local::MRM0m:967case X86Local::MRM1m:968case X86Local::MRM2m:969case X86Local::MRM3m:970case X86Local::MRM4m:971case X86Local::MRM5m:972case X86Local::MRM6m:973case X86Local::MRM7m:974filter = std::make_unique<ExtendedFilter>(false, Form - X86Local::MRM0m);975break;976X86_INSTR_MRM_MAPPING977filter = std::make_unique<ExactFilter>(0xC0 + Form - X86Local::MRM_C0);978break;979} // switch (Form)980981uint8_t opcodeToSet = Opcode;982983unsigned AddressSize = 0;984switch (AdSize) {985case X86Local::AdSize16:986AddressSize = 16;987break;988case X86Local::AdSize32:989AddressSize = 32;990break;991case X86Local::AdSize64:992AddressSize = 64;993break;994}995996assert(opcodeType && "Opcode type not set");997assert(filter && "Filter not set");998999if (Form == X86Local::AddRegFrm || Form == X86Local::MRMSrcRegCC ||1000Form == X86Local::MRMSrcMemCC || Form == X86Local::MRMXrCC ||1001Form == X86Local::MRMXmCC || Form == X86Local::AddCCFrm ||1002Form == X86Local::MRMDestRegCC || Form == X86Local::MRMDestMemCC ||1003Form == X86Local::MRMDestMem4VOp3CC) {1004uint8_t Count = Form == X86Local::AddRegFrm ? 8 : 16;1005assert(((opcodeToSet % Count) == 0) && "ADDREG_FRM opcode not aligned");10061007uint8_t currentOpcode;10081009for (currentOpcode = opcodeToSet;1010currentOpcode < (uint8_t)(opcodeToSet + Count); ++currentOpcode)1011tables.setTableFields(*opcodeType, insnContext(), currentOpcode, *filter,1012UID, Is32Bit, OpPrefix == 0,1013IgnoresVEX_L || EncodeRC, IgnoresW, AddressSize);1014} else {1015tables.setTableFields(*opcodeType, insnContext(), opcodeToSet, *filter, UID,1016Is32Bit, OpPrefix == 0, IgnoresVEX_L || EncodeRC,1017IgnoresW, AddressSize);1018}10191020#undef MAP1021}10221023OperandType RecognizableInstr::typeFromString(StringRef Str, bool hasREX_W,1024uint8_t OpSize) {1025StringSwitch<OperandType> Switch(Str);1026if (hasREX_W) {1027// For instructions with a REX_W prefix, a declared 32-bit register encoding1028// is special.1029Switch.Case("GR32", TYPE_R32);1030}1031if (OpSize == X86Local::OpSize16) {1032// For OpSize16 instructions, a declared 16-bit register or1033// immediate encoding is special.1034Switch.Case("GR16", TYPE_Rv);1035} else if (OpSize == X86Local::OpSize32) {1036// For OpSize32 instructions, a declared 32-bit register or1037// immediate encoding is special.1038Switch.Case("GR32", TYPE_Rv);1039}1040// clang-format off1041OperandType Type =1042Switch.Case("i16mem", TYPE_M)1043.Case("i16imm", TYPE_IMM)1044.Case("i16i8imm", TYPE_IMM)1045.Case("GR16", TYPE_R16)1046.Case("GR16orGR32orGR64", TYPE_R16)1047.Case("i32mem", TYPE_M)1048.Case("i32imm", TYPE_IMM)1049.Case("i32i8imm", TYPE_IMM)1050.Case("GR32", TYPE_R32)1051.Case("GR32orGR64", TYPE_R32)1052.Case("i64mem", TYPE_M)1053.Case("i64i32imm", TYPE_IMM)1054.Case("i64i8imm", TYPE_IMM)1055.Case("GR64", TYPE_R64)1056.Case("i8mem", TYPE_M)1057.Case("i8imm", TYPE_IMM)1058.Case("u4imm", TYPE_UIMM8)1059.Case("u8imm", TYPE_UIMM8)1060.Case("i16u8imm", TYPE_UIMM8)1061.Case("i32u8imm", TYPE_UIMM8)1062.Case("i64u8imm", TYPE_UIMM8)1063.Case("GR8", TYPE_R8)1064.Case("VR128", TYPE_XMM)1065.Case("VR128X", TYPE_XMM)1066.Case("f128mem", TYPE_M)1067.Case("f256mem", TYPE_M)1068.Case("f512mem", TYPE_M)1069.Case("FR128", TYPE_XMM)1070.Case("FR64", TYPE_XMM)1071.Case("FR64X", TYPE_XMM)1072.Case("f64mem", TYPE_M)1073.Case("sdmem", TYPE_M)1074.Case("FR16X", TYPE_XMM)1075.Case("FR32", TYPE_XMM)1076.Case("FR32X", TYPE_XMM)1077.Case("f32mem", TYPE_M)1078.Case("f16mem", TYPE_M)1079.Case("ssmem", TYPE_M)1080.Case("shmem", TYPE_M)1081.Case("RST", TYPE_ST)1082.Case("RSTi", TYPE_ST)1083.Case("i128mem", TYPE_M)1084.Case("i256mem", TYPE_M)1085.Case("i512mem", TYPE_M)1086.Case("i512mem_GR16", TYPE_M)1087.Case("i512mem_GR32", TYPE_M)1088.Case("i512mem_GR64", TYPE_M)1089.Case("i64i32imm_brtarget", TYPE_REL)1090.Case("i8imm_brtarget", TYPE_REL)1091.Case("i16imm_brtarget", TYPE_REL)1092.Case("i32imm_brtarget", TYPE_REL)1093.Case("ccode", TYPE_IMM)1094.Case("cflags", TYPE_IMM)1095.Case("AVX512RC", TYPE_IMM)1096.Case("brtarget32", TYPE_REL)1097.Case("brtarget16", TYPE_REL)1098.Case("brtarget8", TYPE_REL)1099.Case("f80mem", TYPE_M)1100.Case("lea64_8mem", TYPE_M)1101.Case("lea64_16mem", TYPE_M)1102.Case("lea64_32mem", TYPE_M)1103.Case("lea64mem", TYPE_M)1104.Case("VR64", TYPE_MM64)1105.Case("i64imm", TYPE_IMM)1106.Case("anymem", TYPE_M)1107.Case("opaquemem", TYPE_M)1108.Case("sibmem", TYPE_MSIB)1109.Case("SEGMENT_REG", TYPE_SEGMENTREG)1110.Case("DEBUG_REG", TYPE_DEBUGREG)1111.Case("CONTROL_REG", TYPE_CONTROLREG)1112.Case("srcidx8", TYPE_SRCIDX)1113.Case("srcidx16", TYPE_SRCIDX)1114.Case("srcidx32", TYPE_SRCIDX)1115.Case("srcidx64", TYPE_SRCIDX)1116.Case("dstidx8", TYPE_DSTIDX)1117.Case("dstidx16", TYPE_DSTIDX)1118.Case("dstidx32", TYPE_DSTIDX)1119.Case("dstidx64", TYPE_DSTIDX)1120.Case("offset16_8", TYPE_MOFFS)1121.Case("offset16_16", TYPE_MOFFS)1122.Case("offset16_32", TYPE_MOFFS)1123.Case("offset32_8", TYPE_MOFFS)1124.Case("offset32_16", TYPE_MOFFS)1125.Case("offset32_32", TYPE_MOFFS)1126.Case("offset32_64", TYPE_MOFFS)1127.Case("offset64_8", TYPE_MOFFS)1128.Case("offset64_16", TYPE_MOFFS)1129.Case("offset64_32", TYPE_MOFFS)1130.Case("offset64_64", TYPE_MOFFS)1131.Case("VR256", TYPE_YMM)1132.Case("VR256X", TYPE_YMM)1133.Case("VR512", TYPE_ZMM)1134.Case("VK1", TYPE_VK)1135.Case("VK1WM", TYPE_VK)1136.Case("VK2", TYPE_VK)1137.Case("VK2WM", TYPE_VK)1138.Case("VK4", TYPE_VK)1139.Case("VK4WM", TYPE_VK)1140.Case("VK8", TYPE_VK)1141.Case("VK8WM", TYPE_VK)1142.Case("VK16", TYPE_VK)1143.Case("VK16WM", TYPE_VK)1144.Case("VK32", TYPE_VK)1145.Case("VK32WM", TYPE_VK)1146.Case("VK64", TYPE_VK)1147.Case("VK64WM", TYPE_VK)1148.Case("VK1Pair", TYPE_VK_PAIR)1149.Case("VK2Pair", TYPE_VK_PAIR)1150.Case("VK4Pair", TYPE_VK_PAIR)1151.Case("VK8Pair", TYPE_VK_PAIR)1152.Case("VK16Pair", TYPE_VK_PAIR)1153.Case("vx32mem", TYPE_MVSIBX)1154.Case("vx64mem", TYPE_MVSIBX)1155.Case("vy32mem", TYPE_MVSIBY)1156.Case("vy64mem", TYPE_MVSIBY)1157.Case("vx32xmem", TYPE_MVSIBX)1158.Case("vx64xmem", TYPE_MVSIBX)1159.Case("vy32xmem", TYPE_MVSIBY)1160.Case("vy64xmem", TYPE_MVSIBY)1161.Case("vz32mem", TYPE_MVSIBZ)1162.Case("vz64mem", TYPE_MVSIBZ)1163.Case("BNDR", TYPE_BNDR)1164.Case("TILE", TYPE_TMM)1165.Case("TILEPair", TYPE_TMM_PAIR)1166.Default(TYPE_NONE);1167// clang-format on11681169if (Type != TYPE_NONE)1170return Type;1171errs() << "Unhandled type string " << Str << "\n";1172llvm_unreachable("Unhandled type string");1173}11741175OperandEncoding RecognizableInstr::immediateEncodingFromString(StringRef Str,1176uint8_t OpSize) {1177StringSwitch<OperandEncoding> Switch(Str);1178if (OpSize != X86Local::OpSize16) {1179// For instructions without an OpSize prefix, a declared 16-bit register or1180// immediate encoding is special.1181Switch.Case("i16imm", ENCODING_IW);1182}11831184// clang-format off1185OperandEncoding Encoding =1186Switch.Case("i32i8imm", ENCODING_IB)1187.Case("AVX512RC", ENCODING_IRC)1188.Case("i16imm", ENCODING_Iv)1189.Case("i16i8imm", ENCODING_IB)1190.Case("i32imm", ENCODING_Iv)1191.Case("i64i32imm", ENCODING_ID)1192.Case("i64i8imm", ENCODING_IB)1193.Case("i8imm", ENCODING_IB)1194.Case("ccode", ENCODING_CC)1195.Case("cflags", ENCODING_CF)1196.Case("u4imm", ENCODING_IB)1197.Case("u8imm", ENCODING_IB)1198.Case("i16u8imm", ENCODING_IB)1199.Case("i32u8imm", ENCODING_IB)1200.Case("i64u8imm", ENCODING_IB)1201// This is not a typo. Instructions like BLENDVPD put1202// register IDs in 8-bit immediates nowadays.1203.Case("FR32", ENCODING_IB)1204.Case("FR64", ENCODING_IB)1205.Case("FR128", ENCODING_IB)1206.Case("VR128", ENCODING_IB)1207.Case("VR256", ENCODING_IB)1208.Case("FR16X", ENCODING_IB)1209.Case("FR32X", ENCODING_IB)1210.Case("FR64X", ENCODING_IB)1211.Case("VR128X", ENCODING_IB)1212.Case("VR256X", ENCODING_IB)1213.Case("VR512", ENCODING_IB)1214.Case("TILE", ENCODING_IB)1215.Default(ENCODING_NONE);1216// clang-format on12171218if (Encoding != ENCODING_NONE)1219return Encoding;1220errs() << "Unhandled immediate encoding " << Str << "\n";1221llvm_unreachable("Unhandled immediate encoding");1222}12231224OperandEncoding1225RecognizableInstr::rmRegisterEncodingFromString(StringRef Str, uint8_t OpSize) {1226// clang-format off1227auto Encoding =1228StringSwitch<OperandEncoding>(Str)1229.Case("RST", ENCODING_FP)1230.Case("RSTi", ENCODING_FP)1231.Case("GR16", ENCODING_RM)1232.Case("GR16orGR32orGR64", ENCODING_RM)1233.Case("GR32", ENCODING_RM)1234.Case("GR32orGR64", ENCODING_RM)1235.Case("GR64", ENCODING_RM)1236.Case("GR8", ENCODING_RM)1237.Case("VR128", ENCODING_RM)1238.Case("VR128X", ENCODING_RM)1239.Case("FR128", ENCODING_RM)1240.Case("FR64", ENCODING_RM)1241.Case("FR32", ENCODING_RM)1242.Case("FR64X", ENCODING_RM)1243.Case("FR32X", ENCODING_RM)1244.Case("FR16X", ENCODING_RM)1245.Case("VR64", ENCODING_RM)1246.Case("VR256", ENCODING_RM)1247.Case("VR256X", ENCODING_RM)1248.Case("VR512", ENCODING_RM)1249.Case("VK1", ENCODING_RM)1250.Case("VK2", ENCODING_RM)1251.Case("VK4", ENCODING_RM)1252.Case("VK8", ENCODING_RM)1253.Case("VK16", ENCODING_RM)1254.Case("VK32", ENCODING_RM)1255.Case("VK64", ENCODING_RM)1256.Case("BNDR", ENCODING_RM)1257.Case("TILE", ENCODING_RM)1258.Case("TILEPair", ENCODING_RM)1259.Default(ENCODING_NONE);1260// clang-format on1261if (Encoding != ENCODING_NONE)1262return Encoding;1263errs() << "Unhandled R/M register encoding " << Str << "\n";1264llvm_unreachable("Unhandled R/M register encoding");1265}12661267OperandEncoding1268RecognizableInstr::roRegisterEncodingFromString(StringRef Str, uint8_t OpSize) {1269// clang-format off1270auto Encoding =1271StringSwitch<OperandEncoding>(Str)1272.Case("GR16", ENCODING_REG)1273.Case("GR16orGR32orGR64", ENCODING_REG)1274.Case("GR32", ENCODING_REG)1275.Case("GR32orGR64", ENCODING_REG)1276.Case("GR64", ENCODING_REG)1277.Case("GR8", ENCODING_REG)1278.Case("VR128", ENCODING_REG)1279.Case("FR128", ENCODING_REG)1280.Case("FR64", ENCODING_REG)1281.Case("FR32", ENCODING_REG)1282.Case("VR64", ENCODING_REG)1283.Case("SEGMENT_REG", ENCODING_REG)1284.Case("DEBUG_REG", ENCODING_REG)1285.Case("CONTROL_REG", ENCODING_REG)1286.Case("VR256", ENCODING_REG)1287.Case("VR256X", ENCODING_REG)1288.Case("VR128X", ENCODING_REG)1289.Case("FR64X", ENCODING_REG)1290.Case("FR32X", ENCODING_REG)1291.Case("FR16X", ENCODING_REG)1292.Case("VR512", ENCODING_REG)1293.Case("VK1", ENCODING_REG)1294.Case("VK2", ENCODING_REG)1295.Case("VK4", ENCODING_REG)1296.Case("VK8", ENCODING_REG)1297.Case("VK16", ENCODING_REG)1298.Case("VK32", ENCODING_REG)1299.Case("VK64", ENCODING_REG)1300.Case("VK1Pair", ENCODING_REG)1301.Case("VK2Pair", ENCODING_REG)1302.Case("VK4Pair", ENCODING_REG)1303.Case("VK8Pair", ENCODING_REG)1304.Case("VK16Pair", ENCODING_REG)1305.Case("VK1WM", ENCODING_REG)1306.Case("VK2WM", ENCODING_REG)1307.Case("VK4WM", ENCODING_REG)1308.Case("VK8WM", ENCODING_REG)1309.Case("VK16WM", ENCODING_REG)1310.Case("VK32WM", ENCODING_REG)1311.Case("VK64WM", ENCODING_REG)1312.Case("BNDR", ENCODING_REG)1313.Case("TILE", ENCODING_REG)1314.Case("TILEPair", ENCODING_REG)1315.Default(ENCODING_NONE);1316// clang-format on13171318if (Encoding != ENCODING_NONE)1319return Encoding;13201321errs() << "Unhandled reg/opcode register encoding " << Str << "\n";1322llvm_unreachable("Unhandled reg/opcode register encoding");1323}13241325OperandEncoding1326RecognizableInstr::vvvvRegisterEncodingFromString(StringRef Str,1327uint8_t OpSize) {1328// clang-format off1329auto Encoding =1330StringSwitch<OperandEncoding>(Str)1331.Case("GR8", ENCODING_VVVV)1332.Case("GR16", ENCODING_VVVV)1333.Case("GR32", ENCODING_VVVV)1334.Case("GR64", ENCODING_VVVV)1335.Case("FR32", ENCODING_VVVV)1336.Case("FR128", ENCODING_VVVV)1337.Case("FR64", ENCODING_VVVV)1338.Case("VR128", ENCODING_VVVV)1339.Case("VR256", ENCODING_VVVV)1340.Case("FR16X", ENCODING_VVVV)1341.Case("FR32X", ENCODING_VVVV)1342.Case("FR64X", ENCODING_VVVV)1343.Case("VR128X", ENCODING_VVVV)1344.Case("VR256X", ENCODING_VVVV)1345.Case("VR512", ENCODING_VVVV)1346.Case("VK1", ENCODING_VVVV)1347.Case("VK2", ENCODING_VVVV)1348.Case("VK4", ENCODING_VVVV)1349.Case("VK8", ENCODING_VVVV)1350.Case("VK16", ENCODING_VVVV)1351.Case("VK32", ENCODING_VVVV)1352.Case("VK64", ENCODING_VVVV)1353.Case("TILE", ENCODING_VVVV)1354.Case("TILEPair", ENCODING_VVVV)1355.Default(ENCODING_NONE);1356// clang-format on1357if (Encoding != ENCODING_NONE)1358return Encoding;13591360errs() << "Unhandled VEX.vvvv register encoding " << Str << "\n";1361llvm_unreachable("Unhandled VEX.vvvv register encoding");1362}13631364OperandEncoding1365RecognizableInstr::writemaskRegisterEncodingFromString(StringRef Str,1366uint8_t OpSize) {1367// clang-format off1368auto Encoding =1369StringSwitch<OperandEncoding>(Str)1370.Case("VK1WM", ENCODING_WRITEMASK)1371.Case("VK2WM", ENCODING_WRITEMASK)1372.Case("VK4WM", ENCODING_WRITEMASK)1373.Case("VK8WM", ENCODING_WRITEMASK)1374.Case("VK16WM", ENCODING_WRITEMASK)1375.Case("VK32WM", ENCODING_WRITEMASK)1376.Case("VK64WM", ENCODING_WRITEMASK)1377.Default(ENCODING_NONE);1378// clang-format on13791380if (Encoding != ENCODING_NONE)1381return Encoding;13821383errs() << "Unhandled mask register encoding " << Str << "\n";1384llvm_unreachable("Unhandled mask register encoding");1385}13861387OperandEncoding RecognizableInstr::memoryEncodingFromString(StringRef Str,1388uint8_t OpSize) {1389// clang-format off1390auto Encoding =1391StringSwitch<OperandEncoding>(Str)1392.Case("i16mem", ENCODING_RM)1393.Case("i32mem", ENCODING_RM)1394.Case("i64mem", ENCODING_RM)1395.Case("i8mem", ENCODING_RM)1396.Case("shmem", ENCODING_RM)1397.Case("ssmem", ENCODING_RM)1398.Case("sdmem", ENCODING_RM)1399.Case("f128mem", ENCODING_RM)1400.Case("f256mem", ENCODING_RM)1401.Case("f512mem", ENCODING_RM)1402.Case("f64mem", ENCODING_RM)1403.Case("f32mem", ENCODING_RM)1404.Case("f16mem", ENCODING_RM)1405.Case("i128mem", ENCODING_RM)1406.Case("i256mem", ENCODING_RM)1407.Case("i512mem", ENCODING_RM)1408.Case("i512mem_GR16", ENCODING_RM)1409.Case("i512mem_GR32", ENCODING_RM)1410.Case("i512mem_GR64", ENCODING_RM)1411.Case("f80mem", ENCODING_RM)1412.Case("lea64_8mem", ENCODING_RM)1413.Case("lea64_16mem", ENCODING_RM)1414.Case("lea64_32mem", ENCODING_RM)1415.Case("lea64mem", ENCODING_RM)1416.Case("anymem", ENCODING_RM)1417.Case("opaquemem", ENCODING_RM)1418.Case("sibmem", ENCODING_SIB)1419.Case("vx32mem", ENCODING_VSIB)1420.Case("vx64mem", ENCODING_VSIB)1421.Case("vy32mem", ENCODING_VSIB)1422.Case("vy64mem", ENCODING_VSIB)1423.Case("vx32xmem", ENCODING_VSIB)1424.Case("vx64xmem", ENCODING_VSIB)1425.Case("vy32xmem", ENCODING_VSIB)1426.Case("vy64xmem", ENCODING_VSIB)1427.Case("vz32mem", ENCODING_VSIB)1428.Case("vz64mem", ENCODING_VSIB)1429.Default(ENCODING_NONE);1430// clang-format on14311432if (Encoding != ENCODING_NONE)1433return Encoding;14341435errs() << "Unhandled memory encoding " << Str << "\n";1436llvm_unreachable("Unhandled memory encoding");1437}14381439OperandEncoding1440RecognizableInstr::relocationEncodingFromString(StringRef Str, uint8_t OpSize) {1441StringSwitch<OperandEncoding> Switch(Str);14421443if (OpSize != X86Local::OpSize16) {1444// For instructions without an OpSize prefix, a declared 16-bit register or1445// immediate encoding is special.1446Switch.Case("i16imm", ENCODING_IW);1447}14481449// clang-format off1450OperandEncoding Encoding =1451Switch.Case("i16imm", ENCODING_Iv)1452.Case("i16i8imm", ENCODING_IB)1453.Case("i32imm", ENCODING_Iv)1454.Case("i32i8imm", ENCODING_IB)1455.Case("i64i32imm", ENCODING_ID)1456.Case("i64i8imm", ENCODING_IB)1457.Case("i8imm", ENCODING_IB)1458.Case("u8imm", ENCODING_IB)1459.Case("i16u8imm", ENCODING_IB)1460.Case("i32u8imm", ENCODING_IB)1461.Case("i64u8imm", ENCODING_IB)1462.Case("i64i32imm_brtarget", ENCODING_ID)1463.Case("i16imm_brtarget", ENCODING_IW)1464.Case("i32imm_brtarget", ENCODING_ID)1465.Case("i8imm_brtarget", ENCODING_IB)1466.Case("brtarget32", ENCODING_ID)1467.Case("brtarget16", ENCODING_IW)1468.Case("brtarget8", ENCODING_IB)1469.Case("i64imm", ENCODING_IO)1470.Case("offset16_8", ENCODING_Ia)1471.Case("offset16_16", ENCODING_Ia)1472.Case("offset16_32", ENCODING_Ia)1473.Case("offset32_8", ENCODING_Ia)1474.Case("offset32_16", ENCODING_Ia)1475.Case("offset32_32", ENCODING_Ia)1476.Case("offset32_64", ENCODING_Ia)1477.Case("offset64_8", ENCODING_Ia)1478.Case("offset64_16", ENCODING_Ia)1479.Case("offset64_32", ENCODING_Ia)1480.Case("offset64_64", ENCODING_Ia)1481.Case("srcidx8", ENCODING_SI)1482.Case("srcidx16", ENCODING_SI)1483.Case("srcidx32", ENCODING_SI)1484.Case("srcidx64", ENCODING_SI)1485.Case("dstidx8", ENCODING_DI)1486.Case("dstidx16", ENCODING_DI)1487.Case("dstidx32", ENCODING_DI)1488.Case("dstidx64", ENCODING_DI)1489.Default(ENCODING_NONE);1490// clang-format on14911492if (Encoding != ENCODING_NONE)1493return Encoding;14941495errs() << "Unhandled relocation encoding " << Str << "\n";1496llvm_unreachable("Unhandled relocation encoding");1497}14981499OperandEncoding1500RecognizableInstr::opcodeModifierEncodingFromString(StringRef Str,1501uint8_t OpSize) {1502// clang-format off1503auto Encoding =1504StringSwitch<OperandEncoding>(Str)1505.Case("GR32", ENCODING_Rv)1506.Case("GR64", ENCODING_RO)1507.Case("GR16", ENCODING_Rv)1508.Case("GR8", ENCODING_RB)1509.Case("ccode", ENCODING_CC)1510.Default(ENCODING_NONE);1511// clang-format on1512if (Encoding != ENCODING_NONE)1513return Encoding;15141515errs() << "Unhandled opcode modifier encoding " << Str << "\n";1516llvm_unreachable("Unhandled opcode modifier encoding");1517}151815191520