1*0fca6ea1SDimitry Andric //===- X86RecognizableInstr.cpp - Disassembler instruction spec -*- C++ -*-===// 20b57cec5SDimitry Andric // 30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 60b57cec5SDimitry Andric // 70b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 80b57cec5SDimitry Andric // 90b57cec5SDimitry Andric // This file is part of the X86 Disassembler Emitter. 100b57cec5SDimitry Andric // It contains the implementation of a single recognizable instruction. 110b57cec5SDimitry Andric // Documentation for the disassembler emitter in general can be found in 120b57cec5SDimitry Andric // X86DisassemblerEmitter.h. 130b57cec5SDimitry Andric // 140b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 150b57cec5SDimitry Andric 160b57cec5SDimitry Andric #include "X86RecognizableInstr.h" 170b57cec5SDimitry Andric #include "X86DisassemblerShared.h" 181fd87a68SDimitry Andric #include "X86DisassemblerTables.h" 190b57cec5SDimitry Andric #include "X86ModRMFilters.h" 200b57cec5SDimitry Andric #include "llvm/Support/ErrorHandling.h" 211fd87a68SDimitry Andric #include "llvm/TableGen/Record.h" 220b57cec5SDimitry Andric #include <string> 230b57cec5SDimitry Andric 240b57cec5SDimitry Andric using namespace llvm; 250b57cec5SDimitry Andric using namespace X86Disassembler; 260b57cec5SDimitry Andric 275f757f3fSDimitry Andric std::string X86Disassembler::getMnemonic(const CodeGenInstruction *I, 285f757f3fSDimitry Andric unsigned Variant) { 2981ad6265SDimitry Andric // Extract a mnemonic assuming it's separated by \t 30*0fca6ea1SDimitry Andric std::string Mnemonic = 31*0fca6ea1SDimitry Andric StringRef(I->FlattenAsmStringVariants(I->AsmString, Variant)) 32*0fca6ea1SDimitry Andric .take_until([](char C) { return C == '\t'; }) 33*0fca6ea1SDimitry Andric .str(); 3481ad6265SDimitry Andric 35*0fca6ea1SDimitry Andric // Special case: CMOVCC, JCC, SETCC, CMPCCXADD have "${cond}" in mnemonic. 3681ad6265SDimitry Andric // Replace it with "CC" in-place. 37*0fca6ea1SDimitry Andric auto CondPos = Mnemonic.find("${cond}"); 38*0fca6ea1SDimitry Andric if (CondPos != std::string::npos) 39*0fca6ea1SDimitry Andric Mnemonic = Mnemonic.replace(CondPos, 7, "CC"); 40*0fca6ea1SDimitry Andric return StringRef(Mnemonic).upper(); 4181ad6265SDimitry Andric } 4281ad6265SDimitry Andric 4381ad6265SDimitry Andric bool X86Disassembler::isRegisterOperand(const Record *Rec) { 4481ad6265SDimitry Andric return Rec->isSubClassOf("RegisterClass") || 4581ad6265SDimitry Andric Rec->isSubClassOf("RegisterOperand"); 4681ad6265SDimitry Andric } 4781ad6265SDimitry Andric 4881ad6265SDimitry Andric bool X86Disassembler::isMemoryOperand(const Record *Rec) { 4981ad6265SDimitry Andric return Rec->isSubClassOf("Operand") && 5081ad6265SDimitry Andric Rec->getValueAsString("OperandType") == "OPERAND_MEMORY"; 5181ad6265SDimitry Andric } 5281ad6265SDimitry Andric 5381ad6265SDimitry Andric bool X86Disassembler::isImmediateOperand(const Record *Rec) { 5481ad6265SDimitry Andric return Rec->isSubClassOf("Operand") && 5581ad6265SDimitry Andric Rec->getValueAsString("OperandType") == "OPERAND_IMMEDIATE"; 5681ad6265SDimitry Andric } 5781ad6265SDimitry Andric 5881ad6265SDimitry Andric unsigned X86Disassembler::getRegOperandSize(const Record *RegRec) { 5981ad6265SDimitry Andric if (RegRec->isSubClassOf("RegisterClass")) 6081ad6265SDimitry Andric return RegRec->getValueAsInt("Alignment"); 6181ad6265SDimitry Andric if (RegRec->isSubClassOf("RegisterOperand")) 6281ad6265SDimitry Andric return RegRec->getValueAsDef("RegClass")->getValueAsInt("Alignment"); 6381ad6265SDimitry Andric 6481ad6265SDimitry Andric llvm_unreachable("Register operand's size not known!"); 6581ad6265SDimitry Andric } 6681ad6265SDimitry Andric 6781ad6265SDimitry Andric unsigned X86Disassembler::getMemOperandSize(const Record *MemRec) { 6881ad6265SDimitry Andric if (MemRec->isSubClassOf("X86MemOperand")) 6981ad6265SDimitry Andric return MemRec->getValueAsInt("Size"); 7081ad6265SDimitry Andric 7181ad6265SDimitry Andric llvm_unreachable("Memory operand's size not known!"); 7281ad6265SDimitry Andric } 7381ad6265SDimitry Andric 740b57cec5SDimitry Andric /// byteFromBitsInit - Extracts a value at most 8 bits in width from a BitsInit. 750b57cec5SDimitry Andric /// Useful for switch statements and the like. 760b57cec5SDimitry Andric /// 770b57cec5SDimitry Andric /// @param init - A reference to the BitsInit to be decoded. 780b57cec5SDimitry Andric /// @return - The field, with the first bit in the BitsInit as the lowest 790b57cec5SDimitry Andric /// order bit. 800b57cec5SDimitry Andric static uint8_t byteFromBitsInit(BitsInit &init) { 810b57cec5SDimitry Andric int width = init.getNumBits(); 820b57cec5SDimitry Andric 830b57cec5SDimitry Andric assert(width <= 8 && "Field is too large for uint8_t!"); 840b57cec5SDimitry Andric 850b57cec5SDimitry Andric int index; 860b57cec5SDimitry Andric uint8_t mask = 0x01; 870b57cec5SDimitry Andric 880b57cec5SDimitry Andric uint8_t ret = 0; 890b57cec5SDimitry Andric 900b57cec5SDimitry Andric for (index = 0; index < width; index++) { 910b57cec5SDimitry Andric if (cast<BitInit>(init.getBit(index))->getValue()) 920b57cec5SDimitry Andric ret |= mask; 930b57cec5SDimitry Andric 940b57cec5SDimitry Andric mask <<= 1; 950b57cec5SDimitry Andric } 960b57cec5SDimitry Andric 970b57cec5SDimitry Andric return ret; 980b57cec5SDimitry Andric } 990b57cec5SDimitry Andric 1000b57cec5SDimitry Andric /// byteFromRec - Extract a value at most 8 bits in with from a Record given the 1010b57cec5SDimitry Andric /// name of the field. 1020b57cec5SDimitry Andric /// 1030b57cec5SDimitry Andric /// @param rec - The record from which to extract the value. 1040b57cec5SDimitry Andric /// @param name - The name of the field in the record. 1050b57cec5SDimitry Andric /// @return - The field, as translated by byteFromBitsInit(). 106e8d8bef9SDimitry Andric static uint8_t byteFromRec(const Record *rec, StringRef name) { 1070b57cec5SDimitry Andric BitsInit *bits = rec->getValueAsBitsInit(name); 1080b57cec5SDimitry Andric return byteFromBitsInit(*bits); 1090b57cec5SDimitry Andric } 1100b57cec5SDimitry Andric 11181ad6265SDimitry Andric RecognizableInstrBase::RecognizableInstrBase(const CodeGenInstruction &insn) { 11281ad6265SDimitry Andric const Record *Rec = insn.TheDef; 11381ad6265SDimitry Andric assert(Rec->isSubClassOf("X86Inst") && "Not a X86 Instruction"); 1140b57cec5SDimitry Andric OpPrefix = byteFromRec(Rec, "OpPrefixBits"); 1150b57cec5SDimitry Andric OpMap = byteFromRec(Rec, "OpMapBits"); 1160b57cec5SDimitry Andric Opcode = byteFromRec(Rec, "Opcode"); 1170b57cec5SDimitry Andric Form = byteFromRec(Rec, "FormBits"); 1180b57cec5SDimitry Andric Encoding = byteFromRec(Rec, "OpEncBits"); 1190b57cec5SDimitry Andric OpSize = byteFromRec(Rec, "OpSizeBits"); 1200b57cec5SDimitry Andric AdSize = byteFromRec(Rec, "AdSizeBits"); 12181ad6265SDimitry Andric HasREX_W = Rec->getValueAsBit("hasREX_W"); 1220b57cec5SDimitry Andric HasVEX_4V = Rec->getValueAsBit("hasVEX_4V"); 12306c3fb27SDimitry Andric IgnoresW = Rec->getValueAsBit("IgnoresW"); 1240b57cec5SDimitry Andric IgnoresVEX_L = Rec->getValueAsBit("ignoresVEX_L"); 12581ad6265SDimitry Andric HasEVEX_L2 = Rec->getValueAsBit("hasEVEX_L2"); 1260b57cec5SDimitry Andric HasEVEX_K = Rec->getValueAsBit("hasEVEX_K"); 1270b57cec5SDimitry Andric HasEVEX_KZ = Rec->getValueAsBit("hasEVEX_Z"); 1280b57cec5SDimitry Andric HasEVEX_B = Rec->getValueAsBit("hasEVEX_B"); 129647cbc5dSDimitry Andric HasEVEX_NF = Rec->getValueAsBit("hasEVEX_NF"); 130*0fca6ea1SDimitry Andric HasTwoConditionalOps = Rec->getValueAsBit("hasTwoConditionalOps"); 1310b57cec5SDimitry Andric IsCodeGenOnly = Rec->getValueAsBit("isCodeGenOnly"); 13281ad6265SDimitry Andric IsAsmParserOnly = Rec->getValueAsBit("isAsmParserOnly"); 1330b57cec5SDimitry Andric ForceDisassemble = Rec->getValueAsBit("ForceDisassemble"); 1340b57cec5SDimitry Andric CD8_Scale = byteFromRec(Rec, "CD8_Scale"); 13581ad6265SDimitry Andric HasVEX_L = Rec->getValueAsBit("hasVEX_L"); 1365f757f3fSDimitry Andric ExplicitREX2Prefix = 1375f757f3fSDimitry Andric byteFromRec(Rec, "explicitOpPrefixBits") == X86Local::ExplicitREX2; 1380b57cec5SDimitry Andric 1390b57cec5SDimitry Andric EncodeRC = HasEVEX_B && 1400b57cec5SDimitry Andric (Form == X86Local::MRMDestReg || Form == X86Local::MRMSrcReg); 14181ad6265SDimitry Andric } 1420b57cec5SDimitry Andric 14381ad6265SDimitry Andric bool RecognizableInstrBase::shouldBeEmitted() const { 14481ad6265SDimitry Andric return Form != X86Local::Pseudo && (!IsCodeGenOnly || ForceDisassemble) && 14581ad6265SDimitry Andric !IsAsmParserOnly; 14681ad6265SDimitry Andric } 14781ad6265SDimitry Andric 14881ad6265SDimitry Andric RecognizableInstr::RecognizableInstr(DisassemblerTables &tables, 14981ad6265SDimitry Andric const CodeGenInstruction &insn, 15081ad6265SDimitry Andric InstrUID uid) 15181ad6265SDimitry Andric : RecognizableInstrBase(insn), Rec(insn.TheDef), Name(Rec->getName().str()), 15281ad6265SDimitry Andric Is32Bit(false), Is64Bit(false), Operands(&insn.Operands.OperandList), 15381ad6265SDimitry Andric UID(uid), Spec(&tables.specForUID(uid)) { 1540b57cec5SDimitry Andric // Check for 64-bit inst which does not require REX 1550b57cec5SDimitry Andric // FIXME: Is there some better way to check for In64BitMode? 1560b57cec5SDimitry Andric std::vector<Record *> Predicates = Rec->getValueAsListOfDefs("Predicates"); 1570b57cec5SDimitry Andric for (unsigned i = 0, e = Predicates.size(); i != e; ++i) { 158349cc55cSDimitry Andric if (Predicates[i]->getName().contains("Not64Bit") || 159349cc55cSDimitry Andric Predicates[i]->getName().contains("In32Bit")) { 1600b57cec5SDimitry Andric Is32Bit = true; 1610b57cec5SDimitry Andric break; 1620b57cec5SDimitry Andric } 163349cc55cSDimitry Andric if (Predicates[i]->getName().contains("In64Bit")) { 1640b57cec5SDimitry Andric Is64Bit = true; 1650b57cec5SDimitry Andric break; 1660b57cec5SDimitry Andric } 1670b57cec5SDimitry Andric } 1680b57cec5SDimitry Andric } 1690b57cec5SDimitry Andric 1700b57cec5SDimitry Andric void RecognizableInstr::processInstr(DisassemblerTables &tables, 1710b57cec5SDimitry Andric const CodeGenInstruction &insn, 17281ad6265SDimitry Andric InstrUID uid) { 17381ad6265SDimitry Andric if (!insn.TheDef->isSubClassOf("X86Inst")) 1740b57cec5SDimitry Andric return; 1750b57cec5SDimitry Andric RecognizableInstr recogInstr(tables, insn, uid); 1760b57cec5SDimitry Andric 17781ad6265SDimitry Andric if (!recogInstr.shouldBeEmitted()) 17881ad6265SDimitry Andric return; 1790b57cec5SDimitry Andric recogInstr.emitInstructionSpecifier(); 1800b57cec5SDimitry Andric recogInstr.emitDecodePath(tables); 1810b57cec5SDimitry Andric } 1820b57cec5SDimitry Andric 1835f757f3fSDimitry Andric #define EVEX_KB(n) \ 1845f757f3fSDimitry Andric (HasEVEX_KZ && HasEVEX_B \ 1855f757f3fSDimitry Andric ? n##_KZ_B \ 1865f757f3fSDimitry Andric : (HasEVEX_K && HasEVEX_B \ 1875f757f3fSDimitry Andric ? n##_K_B \ 1885f757f3fSDimitry Andric : (HasEVEX_KZ ? n##_KZ \ 1895f757f3fSDimitry Andric : (HasEVEX_K ? n##_K : (HasEVEX_B ? n##_B : n))))) 1900b57cec5SDimitry Andric 191647cbc5dSDimitry Andric #define EVEX_NF(n) (HasEVEX_NF ? n##_NF : n) 192647cbc5dSDimitry Andric #define EVEX_B_NF(n) (HasEVEX_B ? EVEX_NF(n##_B) : EVEX_NF(n)) 193*0fca6ea1SDimitry Andric #define EVEX_KB_ADSIZE(n) AdSize == X86Local::AdSize32 ? n##_ADSIZE : EVEX_KB(n) 194647cbc5dSDimitry Andric 1950b57cec5SDimitry Andric InstructionContext RecognizableInstr::insnContext() const { 1960b57cec5SDimitry Andric InstructionContext insnContext; 1970b57cec5SDimitry Andric 1980b57cec5SDimitry Andric if (Encoding == X86Local::EVEX) { 19981ad6265SDimitry Andric if (HasVEX_L && HasEVEX_L2) { 2000b57cec5SDimitry Andric errs() << "Don't support VEX.L if EVEX_L2 is enabled: " << Name << "\n"; 2010b57cec5SDimitry Andric llvm_unreachable("Don't support VEX.L if EVEX_L2 is enabled"); 2020b57cec5SDimitry Andric } 203647cbc5dSDimitry Andric if (HasEVEX_NF) { 204647cbc5dSDimitry Andric if (OpPrefix == X86Local::PD) 205647cbc5dSDimitry Andric insnContext = EVEX_B_NF(IC_EVEX_OPSIZE); 206647cbc5dSDimitry Andric else if (HasREX_W) 207647cbc5dSDimitry Andric insnContext = EVEX_B_NF(IC_EVEX_W); 208647cbc5dSDimitry Andric else 209647cbc5dSDimitry Andric insnContext = EVEX_B_NF(IC_EVEX); 210647cbc5dSDimitry Andric } else if (!EncodeRC && HasVEX_L && HasREX_W) { 2110b57cec5SDimitry Andric // VEX_L & VEX_W 2120b57cec5SDimitry Andric if (OpPrefix == X86Local::PD) 2130b57cec5SDimitry Andric insnContext = EVEX_KB(IC_EVEX_L_W_OPSIZE); 2140b57cec5SDimitry Andric else if (OpPrefix == X86Local::XS) 2150b57cec5SDimitry Andric insnContext = EVEX_KB(IC_EVEX_L_W_XS); 2160b57cec5SDimitry Andric else if (OpPrefix == X86Local::XD) 2170b57cec5SDimitry Andric insnContext = EVEX_KB(IC_EVEX_L_W_XD); 2180b57cec5SDimitry Andric else if (OpPrefix == X86Local::PS) 2190b57cec5SDimitry Andric insnContext = EVEX_KB(IC_EVEX_L_W); 2200b57cec5SDimitry Andric else { 2210b57cec5SDimitry Andric errs() << "Instruction does not use a prefix: " << Name << "\n"; 2220b57cec5SDimitry Andric llvm_unreachable("Invalid prefix"); 2230b57cec5SDimitry Andric } 22481ad6265SDimitry Andric } else if (!EncodeRC && HasVEX_L) { 2250b57cec5SDimitry Andric // VEX_L 2260b57cec5SDimitry Andric if (OpPrefix == X86Local::PD) 2270b57cec5SDimitry Andric insnContext = EVEX_KB(IC_EVEX_L_OPSIZE); 2280b57cec5SDimitry Andric else if (OpPrefix == X86Local::XS) 2290b57cec5SDimitry Andric insnContext = EVEX_KB(IC_EVEX_L_XS); 2300b57cec5SDimitry Andric else if (OpPrefix == X86Local::XD) 2310b57cec5SDimitry Andric insnContext = EVEX_KB(IC_EVEX_L_XD); 2320b57cec5SDimitry Andric else if (OpPrefix == X86Local::PS) 2330b57cec5SDimitry Andric insnContext = EVEX_KB(IC_EVEX_L); 2340b57cec5SDimitry Andric else { 2350b57cec5SDimitry Andric errs() << "Instruction does not use a prefix: " << Name << "\n"; 2360b57cec5SDimitry Andric llvm_unreachable("Invalid prefix"); 2370b57cec5SDimitry Andric } 23806c3fb27SDimitry Andric } else if (!EncodeRC && HasEVEX_L2 && HasREX_W) { 2390b57cec5SDimitry Andric // EVEX_L2 & VEX_W 2400b57cec5SDimitry Andric if (OpPrefix == X86Local::PD) 2410b57cec5SDimitry Andric insnContext = EVEX_KB(IC_EVEX_L2_W_OPSIZE); 2420b57cec5SDimitry Andric else if (OpPrefix == X86Local::XS) 2430b57cec5SDimitry Andric insnContext = EVEX_KB(IC_EVEX_L2_W_XS); 2440b57cec5SDimitry Andric else if (OpPrefix == X86Local::XD) 2450b57cec5SDimitry Andric insnContext = EVEX_KB(IC_EVEX_L2_W_XD); 2460b57cec5SDimitry Andric else if (OpPrefix == X86Local::PS) 2470b57cec5SDimitry Andric insnContext = EVEX_KB(IC_EVEX_L2_W); 2480b57cec5SDimitry Andric else { 2490b57cec5SDimitry Andric errs() << "Instruction does not use a prefix: " << Name << "\n"; 2500b57cec5SDimitry Andric llvm_unreachable("Invalid prefix"); 2510b57cec5SDimitry Andric } 25281ad6265SDimitry Andric } else if (!EncodeRC && HasEVEX_L2) { 2530b57cec5SDimitry Andric // EVEX_L2 2540b57cec5SDimitry Andric if (OpPrefix == X86Local::PD) 2550b57cec5SDimitry Andric insnContext = EVEX_KB(IC_EVEX_L2_OPSIZE); 2560b57cec5SDimitry Andric else if (OpPrefix == X86Local::XD) 2570b57cec5SDimitry Andric insnContext = EVEX_KB(IC_EVEX_L2_XD); 2580b57cec5SDimitry Andric else if (OpPrefix == X86Local::XS) 2590b57cec5SDimitry Andric insnContext = EVEX_KB(IC_EVEX_L2_XS); 2600b57cec5SDimitry Andric else if (OpPrefix == X86Local::PS) 2610b57cec5SDimitry Andric insnContext = EVEX_KB(IC_EVEX_L2); 2620b57cec5SDimitry Andric else { 2630b57cec5SDimitry Andric errs() << "Instruction does not use a prefix: " << Name << "\n"; 2640b57cec5SDimitry Andric llvm_unreachable("Invalid prefix"); 2650b57cec5SDimitry Andric } 2665f757f3fSDimitry Andric } else if (HasREX_W) { 2670b57cec5SDimitry Andric // VEX_W 2680b57cec5SDimitry Andric if (OpPrefix == X86Local::PD) 2690b57cec5SDimitry Andric insnContext = EVEX_KB(IC_EVEX_W_OPSIZE); 2700b57cec5SDimitry Andric else if (OpPrefix == X86Local::XS) 2710b57cec5SDimitry Andric insnContext = EVEX_KB(IC_EVEX_W_XS); 2720b57cec5SDimitry Andric else if (OpPrefix == X86Local::XD) 2730b57cec5SDimitry Andric insnContext = EVEX_KB(IC_EVEX_W_XD); 2740b57cec5SDimitry Andric else if (OpPrefix == X86Local::PS) 2750b57cec5SDimitry Andric insnContext = EVEX_KB(IC_EVEX_W); 2760b57cec5SDimitry Andric else { 2770b57cec5SDimitry Andric errs() << "Instruction does not use a prefix: " << Name << "\n"; 2780b57cec5SDimitry Andric llvm_unreachable("Invalid prefix"); 2790b57cec5SDimitry Andric } 2800b57cec5SDimitry Andric } 2810b57cec5SDimitry Andric // No L, no W 2825f757f3fSDimitry Andric else if (OpPrefix == X86Local::PD) { 283*0fca6ea1SDimitry Andric insnContext = EVEX_KB_ADSIZE(IC_EVEX_OPSIZE); 2845f757f3fSDimitry Andric } else if (OpPrefix == X86Local::XD) 285*0fca6ea1SDimitry Andric insnContext = EVEX_KB_ADSIZE(IC_EVEX_XD); 2860b57cec5SDimitry Andric else if (OpPrefix == X86Local::XS) 287*0fca6ea1SDimitry Andric insnContext = EVEX_KB_ADSIZE(IC_EVEX_XS); 2880b57cec5SDimitry Andric else if (OpPrefix == X86Local::PS) 2890b57cec5SDimitry Andric insnContext = EVEX_KB(IC_EVEX); 2900b57cec5SDimitry Andric else { 2910b57cec5SDimitry Andric errs() << "Instruction does not use a prefix: " << Name << "\n"; 2920b57cec5SDimitry Andric llvm_unreachable("Invalid prefix"); 2930b57cec5SDimitry Andric } 2940b57cec5SDimitry Andric /// eof EVEX 2950b57cec5SDimitry Andric } else if (Encoding == X86Local::VEX || Encoding == X86Local::XOP) { 29606c3fb27SDimitry Andric if (HasVEX_L && HasREX_W) { 2970b57cec5SDimitry Andric if (OpPrefix == X86Local::PD) 2980b57cec5SDimitry Andric insnContext = IC_VEX_L_W_OPSIZE; 2990b57cec5SDimitry Andric else if (OpPrefix == X86Local::XS) 3000b57cec5SDimitry Andric insnContext = IC_VEX_L_W_XS; 3010b57cec5SDimitry Andric else if (OpPrefix == X86Local::XD) 3020b57cec5SDimitry Andric insnContext = IC_VEX_L_W_XD; 3030b57cec5SDimitry Andric else if (OpPrefix == X86Local::PS) 3040b57cec5SDimitry Andric insnContext = IC_VEX_L_W; 3050b57cec5SDimitry Andric else { 3060b57cec5SDimitry Andric errs() << "Instruction does not use a prefix: " << Name << "\n"; 3070b57cec5SDimitry Andric llvm_unreachable("Invalid prefix"); 3080b57cec5SDimitry Andric } 30981ad6265SDimitry Andric } else if (OpPrefix == X86Local::PD && HasVEX_L) 3100b57cec5SDimitry Andric insnContext = IC_VEX_L_OPSIZE; 31106c3fb27SDimitry Andric else if (OpPrefix == X86Local::PD && HasREX_W) 3120b57cec5SDimitry Andric insnContext = IC_VEX_W_OPSIZE; 3130b57cec5SDimitry Andric else if (OpPrefix == X86Local::PD) 3140b57cec5SDimitry Andric insnContext = IC_VEX_OPSIZE; 31581ad6265SDimitry Andric else if (HasVEX_L && OpPrefix == X86Local::XS) 3160b57cec5SDimitry Andric insnContext = IC_VEX_L_XS; 31781ad6265SDimitry Andric else if (HasVEX_L && OpPrefix == X86Local::XD) 3180b57cec5SDimitry Andric insnContext = IC_VEX_L_XD; 31906c3fb27SDimitry Andric else if (HasREX_W && OpPrefix == X86Local::XS) 3200b57cec5SDimitry Andric insnContext = IC_VEX_W_XS; 32106c3fb27SDimitry Andric else if (HasREX_W && OpPrefix == X86Local::XD) 3220b57cec5SDimitry Andric insnContext = IC_VEX_W_XD; 32306c3fb27SDimitry Andric else if (HasREX_W && OpPrefix == X86Local::PS) 3240b57cec5SDimitry Andric insnContext = IC_VEX_W; 32581ad6265SDimitry Andric else if (HasVEX_L && OpPrefix == X86Local::PS) 3260b57cec5SDimitry Andric insnContext = IC_VEX_L; 3270b57cec5SDimitry Andric else if (OpPrefix == X86Local::XD) 3280b57cec5SDimitry Andric insnContext = IC_VEX_XD; 3290b57cec5SDimitry Andric else if (OpPrefix == X86Local::XS) 3300b57cec5SDimitry Andric insnContext = IC_VEX_XS; 3310b57cec5SDimitry Andric else if (OpPrefix == X86Local::PS) 3320b57cec5SDimitry Andric insnContext = IC_VEX; 3330b57cec5SDimitry Andric else { 3340b57cec5SDimitry Andric errs() << "Instruction does not use a prefix: " << Name << "\n"; 3350b57cec5SDimitry Andric llvm_unreachable("Invalid prefix"); 3360b57cec5SDimitry Andric } 33781ad6265SDimitry Andric } else if (Is64Bit || HasREX_W || AdSize == X86Local::AdSize64) { 33881ad6265SDimitry Andric if (HasREX_W && (OpSize == X86Local::OpSize16 || OpPrefix == X86Local::PD)) 3390b57cec5SDimitry Andric insnContext = IC_64BIT_REXW_OPSIZE; 34081ad6265SDimitry Andric else if (HasREX_W && AdSize == X86Local::AdSize32) 3410b57cec5SDimitry Andric insnContext = IC_64BIT_REXW_ADSIZE; 3420b57cec5SDimitry Andric else if (OpSize == X86Local::OpSize16 && OpPrefix == X86Local::XD) 3430b57cec5SDimitry Andric insnContext = IC_64BIT_XD_OPSIZE; 3440b57cec5SDimitry Andric else if (OpSize == X86Local::OpSize16 && OpPrefix == X86Local::XS) 3450b57cec5SDimitry Andric insnContext = IC_64BIT_XS_OPSIZE; 3460b57cec5SDimitry Andric else if (AdSize == X86Local::AdSize32 && OpPrefix == X86Local::PD) 3470b57cec5SDimitry Andric insnContext = IC_64BIT_OPSIZE_ADSIZE; 3480b57cec5SDimitry Andric else if (OpSize == X86Local::OpSize16 && AdSize == X86Local::AdSize32) 3490b57cec5SDimitry Andric insnContext = IC_64BIT_OPSIZE_ADSIZE; 3500b57cec5SDimitry Andric else if (OpSize == X86Local::OpSize16 || OpPrefix == X86Local::PD) 3510b57cec5SDimitry Andric insnContext = IC_64BIT_OPSIZE; 3520b57cec5SDimitry Andric else if (AdSize == X86Local::AdSize32) 3530b57cec5SDimitry Andric insnContext = IC_64BIT_ADSIZE; 35481ad6265SDimitry Andric else if (HasREX_W && OpPrefix == X86Local::XS) 3550b57cec5SDimitry Andric insnContext = IC_64BIT_REXW_XS; 35681ad6265SDimitry Andric else if (HasREX_W && OpPrefix == X86Local::XD) 3570b57cec5SDimitry Andric insnContext = IC_64BIT_REXW_XD; 3580b57cec5SDimitry Andric else if (OpPrefix == X86Local::XD) 3590b57cec5SDimitry Andric insnContext = IC_64BIT_XD; 3600b57cec5SDimitry Andric else if (OpPrefix == X86Local::XS) 3610b57cec5SDimitry Andric insnContext = IC_64BIT_XS; 3625f757f3fSDimitry Andric else if (ExplicitREX2Prefix) 3635f757f3fSDimitry Andric insnContext = IC_64BIT_REX2; 36481ad6265SDimitry Andric else if (HasREX_W) 3650b57cec5SDimitry Andric insnContext = IC_64BIT_REXW; 3660b57cec5SDimitry Andric else 3670b57cec5SDimitry Andric insnContext = IC_64BIT; 3680b57cec5SDimitry Andric } else { 3690b57cec5SDimitry Andric if (OpSize == X86Local::OpSize16 && OpPrefix == X86Local::XD) 3700b57cec5SDimitry Andric insnContext = IC_XD_OPSIZE; 3710b57cec5SDimitry Andric else if (OpSize == X86Local::OpSize16 && OpPrefix == X86Local::XS) 3720b57cec5SDimitry Andric insnContext = IC_XS_OPSIZE; 3730b57cec5SDimitry Andric else if (AdSize == X86Local::AdSize16 && OpPrefix == X86Local::XD) 3740b57cec5SDimitry Andric insnContext = IC_XD_ADSIZE; 3750b57cec5SDimitry Andric else if (AdSize == X86Local::AdSize16 && OpPrefix == X86Local::XS) 3760b57cec5SDimitry Andric insnContext = IC_XS_ADSIZE; 3770b57cec5SDimitry Andric else if (AdSize == X86Local::AdSize16 && OpPrefix == X86Local::PD) 3780b57cec5SDimitry Andric insnContext = IC_OPSIZE_ADSIZE; 3790b57cec5SDimitry Andric else if (OpSize == X86Local::OpSize16 && AdSize == X86Local::AdSize16) 3800b57cec5SDimitry Andric insnContext = IC_OPSIZE_ADSIZE; 3810b57cec5SDimitry Andric else if (OpSize == X86Local::OpSize16 || OpPrefix == X86Local::PD) 3820b57cec5SDimitry Andric insnContext = IC_OPSIZE; 3830b57cec5SDimitry Andric else if (AdSize == X86Local::AdSize16) 3840b57cec5SDimitry Andric insnContext = IC_ADSIZE; 3850b57cec5SDimitry Andric else if (OpPrefix == X86Local::XD) 3860b57cec5SDimitry Andric insnContext = IC_XD; 3870b57cec5SDimitry Andric else if (OpPrefix == X86Local::XS) 3880b57cec5SDimitry Andric insnContext = IC_XS; 3890b57cec5SDimitry Andric else 3900b57cec5SDimitry Andric insnContext = IC; 3910b57cec5SDimitry Andric } 3920b57cec5SDimitry Andric 3930b57cec5SDimitry Andric return insnContext; 3940b57cec5SDimitry Andric } 3950b57cec5SDimitry Andric 3960b57cec5SDimitry Andric void RecognizableInstr::adjustOperandEncoding(OperandEncoding &encoding) { 3970b57cec5SDimitry Andric // The scaling factor for AVX512 compressed displacement encoding is an 3980b57cec5SDimitry Andric // instruction attribute. Adjust the ModRM encoding type to include the 3990b57cec5SDimitry Andric // scale for compressed displacement. 4005f757f3fSDimitry Andric if ((encoding != ENCODING_RM && encoding != ENCODING_VSIB && 4015f757f3fSDimitry Andric encoding != ENCODING_SIB) || 4025f757f3fSDimitry Andric CD8_Scale == 0) 4030b57cec5SDimitry Andric return; 4040b57cec5SDimitry Andric encoding = (OperandEncoding)(encoding + Log2_32(CD8_Scale)); 4050b57cec5SDimitry Andric assert(((encoding >= ENCODING_RM && encoding <= ENCODING_RM_CD64) || 4065ffd83dbSDimitry Andric (encoding == ENCODING_SIB) || 4070b57cec5SDimitry Andric (encoding >= ENCODING_VSIB && encoding <= ENCODING_VSIB_CD64)) && 4080b57cec5SDimitry Andric "Invalid CDisp scaling"); 4090b57cec5SDimitry Andric } 4100b57cec5SDimitry Andric 4115f757f3fSDimitry Andric void RecognizableInstr::handleOperand( 4125f757f3fSDimitry Andric bool optional, unsigned &operandIndex, unsigned &physicalOperandIndex, 4135f757f3fSDimitry Andric unsigned numPhysicalOperands, const unsigned *operandMapping, 4145f757f3fSDimitry Andric OperandEncoding (*encodingFromString)(const std::string &, 4150b57cec5SDimitry Andric uint8_t OpSize)) { 4160b57cec5SDimitry Andric if (optional) { 4170b57cec5SDimitry Andric if (physicalOperandIndex >= numPhysicalOperands) 4180b57cec5SDimitry Andric return; 4190b57cec5SDimitry Andric } else { 4200b57cec5SDimitry Andric assert(physicalOperandIndex < numPhysicalOperands); 4210b57cec5SDimitry Andric } 4220b57cec5SDimitry Andric 4230b57cec5SDimitry Andric while (operandMapping[operandIndex] != operandIndex) { 4240b57cec5SDimitry Andric Spec->operands[operandIndex].encoding = ENCODING_DUP; 4250b57cec5SDimitry Andric Spec->operands[operandIndex].type = 4260b57cec5SDimitry Andric (OperandType)(TYPE_DUP0 + operandMapping[operandIndex]); 4270b57cec5SDimitry Andric ++operandIndex; 4280b57cec5SDimitry Andric } 4290b57cec5SDimitry Andric 4300b57cec5SDimitry Andric StringRef typeName = (*Operands)[operandIndex].Rec->getName(); 4310b57cec5SDimitry Andric 4325ffd83dbSDimitry Andric OperandEncoding encoding = encodingFromString(std::string(typeName), OpSize); 4330b57cec5SDimitry Andric // Adjust the encoding type for an operand based on the instruction. 4340b57cec5SDimitry Andric adjustOperandEncoding(encoding); 4350b57cec5SDimitry Andric Spec->operands[operandIndex].encoding = encoding; 4365ffd83dbSDimitry Andric Spec->operands[operandIndex].type = 43781ad6265SDimitry Andric typeFromString(std::string(typeName), HasREX_W, OpSize); 4380b57cec5SDimitry Andric 4390b57cec5SDimitry Andric ++operandIndex; 4400b57cec5SDimitry Andric ++physicalOperandIndex; 4410b57cec5SDimitry Andric } 4420b57cec5SDimitry Andric 4430b57cec5SDimitry Andric void RecognizableInstr::emitInstructionSpecifier() { 4440b57cec5SDimitry Andric Spec->name = Name; 4450b57cec5SDimitry Andric 4460b57cec5SDimitry Andric Spec->insnContext = insnContext(); 4470b57cec5SDimitry Andric 4480b57cec5SDimitry Andric const std::vector<CGIOperandList::OperandInfo> &OperandList = *Operands; 4490b57cec5SDimitry Andric 4500b57cec5SDimitry Andric unsigned numOperands = OperandList.size(); 4510b57cec5SDimitry Andric unsigned numPhysicalOperands = 0; 4520b57cec5SDimitry Andric 4530b57cec5SDimitry Andric // operandMapping maps from operands in OperandList to their originals. 4540b57cec5SDimitry Andric // If operandMapping[i] != i, then the entry is a duplicate. 4550b57cec5SDimitry Andric unsigned operandMapping[X86_MAX_OPERANDS]; 4565f757f3fSDimitry Andric assert(numOperands <= X86_MAX_OPERANDS && 4575f757f3fSDimitry Andric "X86_MAX_OPERANDS is not large enough"); 4580b57cec5SDimitry Andric 4590b57cec5SDimitry Andric for (unsigned operandIndex = 0; operandIndex < numOperands; ++operandIndex) { 4600b57cec5SDimitry Andric if (!OperandList[operandIndex].Constraints.empty()) { 4610b57cec5SDimitry Andric const CGIOperandList::ConstraintInfo &Constraint = 4620b57cec5SDimitry Andric OperandList[operandIndex].Constraints[0]; 4630b57cec5SDimitry Andric if (Constraint.isTied()) { 4640b57cec5SDimitry Andric operandMapping[operandIndex] = operandIndex; 4650b57cec5SDimitry Andric operandMapping[Constraint.getTiedOperand()] = operandIndex; 4660b57cec5SDimitry Andric } else { 4670b57cec5SDimitry Andric ++numPhysicalOperands; 4680b57cec5SDimitry Andric operandMapping[operandIndex] = operandIndex; 4690b57cec5SDimitry Andric } 4700b57cec5SDimitry Andric } else { 4710b57cec5SDimitry Andric ++numPhysicalOperands; 4720b57cec5SDimitry Andric operandMapping[operandIndex] = operandIndex; 4730b57cec5SDimitry Andric } 4740b57cec5SDimitry Andric } 4750b57cec5SDimitry Andric 4760b57cec5SDimitry Andric #define HANDLE_OPERAND(class) \ 4775f757f3fSDimitry Andric handleOperand(false, operandIndex, physicalOperandIndex, \ 4785f757f3fSDimitry Andric numPhysicalOperands, operandMapping, \ 4790b57cec5SDimitry Andric class##EncodingFromString); 4800b57cec5SDimitry Andric 4810b57cec5SDimitry Andric #define HANDLE_OPTIONAL(class) \ 4825f757f3fSDimitry Andric handleOperand(true, operandIndex, physicalOperandIndex, numPhysicalOperands, \ 4835f757f3fSDimitry Andric operandMapping, class##EncodingFromString); 4840b57cec5SDimitry Andric 4850b57cec5SDimitry Andric // operandIndex should always be < numOperands 4860b57cec5SDimitry Andric unsigned operandIndex = 0; 4870b57cec5SDimitry Andric // physicalOperandIndex should always be < numPhysicalOperands 4880b57cec5SDimitry Andric unsigned physicalOperandIndex = 0; 4890b57cec5SDimitry Andric 4900b57cec5SDimitry Andric #ifndef NDEBUG 4910b57cec5SDimitry Andric // Given the set of prefix bits, how many additional operands does the 4920b57cec5SDimitry Andric // instruction have? 4930b57cec5SDimitry Andric unsigned additionalOperands = 0; 4940b57cec5SDimitry Andric if (HasVEX_4V) 4950b57cec5SDimitry Andric ++additionalOperands; 4960b57cec5SDimitry Andric if (HasEVEX_K) 4970b57cec5SDimitry Andric ++additionalOperands; 498*0fca6ea1SDimitry Andric if (HasTwoConditionalOps) 499*0fca6ea1SDimitry Andric additionalOperands += 2; 5000b57cec5SDimitry Andric #endif 5010b57cec5SDimitry Andric 502647cbc5dSDimitry Andric bool IsND = OpMap == X86Local::T_MAP4 && HasEVEX_B && HasVEX_4V; 5030b57cec5SDimitry Andric switch (Form) { 5045f757f3fSDimitry Andric default: 5055f757f3fSDimitry Andric llvm_unreachable("Unhandled form"); 5065ffd83dbSDimitry Andric case X86Local::PrefixByte: 5075ffd83dbSDimitry Andric return; 5080b57cec5SDimitry Andric case X86Local::RawFrmSrc: 5090b57cec5SDimitry Andric HANDLE_OPERAND(relocation); 5100b57cec5SDimitry Andric return; 5110b57cec5SDimitry Andric case X86Local::RawFrmDst: 5120b57cec5SDimitry Andric HANDLE_OPERAND(relocation); 5130b57cec5SDimitry Andric return; 5140b57cec5SDimitry Andric case X86Local::RawFrmDstSrc: 5150b57cec5SDimitry Andric HANDLE_OPERAND(relocation); 5160b57cec5SDimitry Andric HANDLE_OPERAND(relocation); 5170b57cec5SDimitry Andric return; 5180b57cec5SDimitry Andric case X86Local::RawFrm: 5190b57cec5SDimitry Andric // Operand 1 (optional) is an address or immediate. 5200b57cec5SDimitry Andric assert(numPhysicalOperands <= 1 && 5210b57cec5SDimitry Andric "Unexpected number of operands for RawFrm"); 5220b57cec5SDimitry Andric HANDLE_OPTIONAL(relocation) 5230b57cec5SDimitry Andric break; 5240b57cec5SDimitry Andric case X86Local::RawFrmMemOffs: 5250b57cec5SDimitry Andric // Operand 1 is an address. 5260b57cec5SDimitry Andric HANDLE_OPERAND(relocation); 5270b57cec5SDimitry Andric break; 5280b57cec5SDimitry Andric case X86Local::AddRegFrm: 5290b57cec5SDimitry Andric // Operand 1 is added to the opcode. 5300b57cec5SDimitry Andric // Operand 2 (optional) is an address. 5310b57cec5SDimitry Andric assert(numPhysicalOperands >= 1 && numPhysicalOperands <= 2 && 5320b57cec5SDimitry Andric "Unexpected number of operands for AddRegFrm"); 5330b57cec5SDimitry Andric HANDLE_OPERAND(opcodeModifier) 5340b57cec5SDimitry Andric HANDLE_OPTIONAL(relocation) 5350b57cec5SDimitry Andric break; 5360b57cec5SDimitry Andric case X86Local::AddCCFrm: 5370b57cec5SDimitry Andric // Operand 1 (optional) is an address or immediate. 5380b57cec5SDimitry Andric assert(numPhysicalOperands == 2 && 5390b57cec5SDimitry Andric "Unexpected number of operands for AddCCFrm"); 5400b57cec5SDimitry Andric HANDLE_OPERAND(relocation) 5410b57cec5SDimitry Andric HANDLE_OPERAND(opcodeModifier) 5420b57cec5SDimitry Andric break; 543*0fca6ea1SDimitry Andric case X86Local::MRMDestRegCC: 544*0fca6ea1SDimitry Andric assert(numPhysicalOperands == 3 && 545*0fca6ea1SDimitry Andric "Unexpected number of operands for MRMDestRegCC"); 546*0fca6ea1SDimitry Andric HANDLE_OPERAND(rmRegister) 547*0fca6ea1SDimitry Andric HANDLE_OPERAND(roRegister) 548*0fca6ea1SDimitry Andric HANDLE_OPERAND(opcodeModifier) 549*0fca6ea1SDimitry Andric break; 5500b57cec5SDimitry Andric case X86Local::MRMDestReg: 5510b57cec5SDimitry Andric // Operand 1 is a register operand in the R/M field. 5520b57cec5SDimitry Andric // - In AVX512 there may be a mask operand here - 5530b57cec5SDimitry Andric // Operand 2 is a register operand in the Reg/Opcode field. 5540b57cec5SDimitry Andric // - In AVX, there is a register operand in the VEX.vvvv field here - 5550b57cec5SDimitry Andric // Operand 3 (optional) is an immediate. 5560b57cec5SDimitry Andric assert(numPhysicalOperands >= 2 + additionalOperands && 5570b57cec5SDimitry Andric numPhysicalOperands <= 3 + additionalOperands && 55806c3fb27SDimitry Andric "Unexpected number of operands for MRMDestReg"); 5590b57cec5SDimitry Andric 560647cbc5dSDimitry Andric if (IsND) 561647cbc5dSDimitry Andric HANDLE_OPERAND(vvvvRegister) 562647cbc5dSDimitry Andric 5630b57cec5SDimitry Andric HANDLE_OPERAND(rmRegister) 5640b57cec5SDimitry Andric if (HasEVEX_K) 5650b57cec5SDimitry Andric HANDLE_OPERAND(writemaskRegister) 5660b57cec5SDimitry Andric 567647cbc5dSDimitry Andric if (!IsND && HasVEX_4V) 5680b57cec5SDimitry Andric // FIXME: In AVX, the register below becomes the one encoded 5690b57cec5SDimitry Andric // in ModRMVEX and the one above the one in the VEX.VVVV field 5700b57cec5SDimitry Andric HANDLE_OPERAND(vvvvRegister) 5710b57cec5SDimitry Andric 5720b57cec5SDimitry Andric HANDLE_OPERAND(roRegister) 5730b57cec5SDimitry Andric HANDLE_OPTIONAL(immediate) 574*0fca6ea1SDimitry Andric HANDLE_OPTIONAL(immediate) 575*0fca6ea1SDimitry Andric break; 576*0fca6ea1SDimitry Andric case X86Local::MRMDestMemCC: 577*0fca6ea1SDimitry Andric assert(numPhysicalOperands == 3 && 578*0fca6ea1SDimitry Andric "Unexpected number of operands for MRMDestMemCC"); 579*0fca6ea1SDimitry Andric HANDLE_OPERAND(memory) 580*0fca6ea1SDimitry Andric HANDLE_OPERAND(roRegister) 581*0fca6ea1SDimitry Andric HANDLE_OPERAND(opcodeModifier) 5820b57cec5SDimitry Andric break; 583bdd1243dSDimitry Andric case X86Local::MRMDestMem4VOp3CC: 584bdd1243dSDimitry Andric // Operand 1 is a register operand in the Reg/Opcode field. 585bdd1243dSDimitry Andric // Operand 2 is a register operand in the R/M field. 586bdd1243dSDimitry Andric // Operand 3 is VEX.vvvv 587bdd1243dSDimitry Andric // Operand 4 is condition code. 588bdd1243dSDimitry Andric assert(numPhysicalOperands == 4 && 589bdd1243dSDimitry Andric "Unexpected number of operands for MRMDestMem4VOp3CC"); 590bdd1243dSDimitry Andric HANDLE_OPERAND(roRegister) 591bdd1243dSDimitry Andric HANDLE_OPERAND(memory) 592bdd1243dSDimitry Andric HANDLE_OPERAND(vvvvRegister) 593bdd1243dSDimitry Andric HANDLE_OPERAND(opcodeModifier) 594bdd1243dSDimitry Andric break; 5950b57cec5SDimitry Andric case X86Local::MRMDestMem: 5965ffd83dbSDimitry Andric case X86Local::MRMDestMemFSIB: 5970b57cec5SDimitry Andric // Operand 1 is a memory operand (possibly SIB-extended) 5980b57cec5SDimitry Andric // Operand 2 is a register operand in the Reg/Opcode field. 5990b57cec5SDimitry Andric // - In AVX, there is a register operand in the VEX.vvvv field here - 6000b57cec5SDimitry Andric // Operand 3 (optional) is an immediate. 6010b57cec5SDimitry Andric assert(numPhysicalOperands >= 2 + additionalOperands && 6020b57cec5SDimitry Andric numPhysicalOperands <= 3 + additionalOperands && 6030b57cec5SDimitry Andric "Unexpected number of operands for MRMDestMemFrm with VEX_4V"); 6040b57cec5SDimitry Andric 605647cbc5dSDimitry Andric if (IsND) 606647cbc5dSDimitry Andric HANDLE_OPERAND(vvvvRegister) 607647cbc5dSDimitry Andric 6080b57cec5SDimitry Andric HANDLE_OPERAND(memory) 6090b57cec5SDimitry Andric 6100b57cec5SDimitry Andric if (HasEVEX_K) 6110b57cec5SDimitry Andric HANDLE_OPERAND(writemaskRegister) 6120b57cec5SDimitry Andric 613647cbc5dSDimitry Andric if (!IsND && HasVEX_4V) 6140b57cec5SDimitry Andric // FIXME: In AVX, the register below becomes the one encoded 6150b57cec5SDimitry Andric // in ModRMVEX and the one above the one in the VEX.VVVV field 6160b57cec5SDimitry Andric HANDLE_OPERAND(vvvvRegister) 6170b57cec5SDimitry Andric 6180b57cec5SDimitry Andric HANDLE_OPERAND(roRegister) 6190b57cec5SDimitry Andric HANDLE_OPTIONAL(immediate) 620*0fca6ea1SDimitry Andric HANDLE_OPTIONAL(immediate) 6210b57cec5SDimitry Andric break; 6220b57cec5SDimitry Andric case X86Local::MRMSrcReg: 6230b57cec5SDimitry Andric // Operand 1 is a register operand in the Reg/Opcode field. 6240b57cec5SDimitry Andric // Operand 2 is a register operand in the R/M field. 6250b57cec5SDimitry Andric // - In AVX, there is a register operand in the VEX.vvvv field here - 6260b57cec5SDimitry Andric // Operand 3 (optional) is an immediate. 6270b57cec5SDimitry Andric // Operand 4 (optional) is an immediate. 6280b57cec5SDimitry Andric 6290b57cec5SDimitry Andric assert(numPhysicalOperands >= 2 + additionalOperands && 6300b57cec5SDimitry Andric numPhysicalOperands <= 4 + additionalOperands && 6310b57cec5SDimitry Andric "Unexpected number of operands for MRMSrcRegFrm"); 6320b57cec5SDimitry Andric 633647cbc5dSDimitry Andric if (IsND) 634647cbc5dSDimitry Andric HANDLE_OPERAND(vvvvRegister) 635647cbc5dSDimitry Andric 6360b57cec5SDimitry Andric HANDLE_OPERAND(roRegister) 6370b57cec5SDimitry Andric 6380b57cec5SDimitry Andric if (HasEVEX_K) 6390b57cec5SDimitry Andric HANDLE_OPERAND(writemaskRegister) 6400b57cec5SDimitry Andric 641647cbc5dSDimitry Andric if (!IsND && HasVEX_4V) 6420b57cec5SDimitry Andric // FIXME: In AVX, the register below becomes the one encoded 6430b57cec5SDimitry Andric // in ModRMVEX and the one above the one in the VEX.VVVV field 6440b57cec5SDimitry Andric HANDLE_OPERAND(vvvvRegister) 6450b57cec5SDimitry Andric 6460b57cec5SDimitry Andric HANDLE_OPERAND(rmRegister) 6470b57cec5SDimitry Andric HANDLE_OPTIONAL(immediate) 6480b57cec5SDimitry Andric HANDLE_OPTIONAL(immediate) // above might be a register in 7:4 6490b57cec5SDimitry Andric break; 6500b57cec5SDimitry Andric case X86Local::MRMSrcReg4VOp3: 6510b57cec5SDimitry Andric assert(numPhysicalOperands == 3 && 6520b57cec5SDimitry Andric "Unexpected number of operands for MRMSrcReg4VOp3Frm"); 6530b57cec5SDimitry Andric HANDLE_OPERAND(roRegister) 6540b57cec5SDimitry Andric HANDLE_OPERAND(rmRegister) 6550b57cec5SDimitry Andric HANDLE_OPERAND(vvvvRegister) 6560b57cec5SDimitry Andric break; 6570b57cec5SDimitry Andric case X86Local::MRMSrcRegOp4: 6580b57cec5SDimitry Andric assert(numPhysicalOperands >= 4 && numPhysicalOperands <= 5 && 6590b57cec5SDimitry Andric "Unexpected number of operands for MRMSrcRegOp4Frm"); 6600b57cec5SDimitry Andric HANDLE_OPERAND(roRegister) 6610b57cec5SDimitry Andric HANDLE_OPERAND(vvvvRegister) 6620b57cec5SDimitry Andric HANDLE_OPERAND(immediate) // Register in imm[7:4] 6630b57cec5SDimitry Andric HANDLE_OPERAND(rmRegister) 6640b57cec5SDimitry Andric HANDLE_OPTIONAL(immediate) 6650b57cec5SDimitry Andric break; 6660b57cec5SDimitry Andric case X86Local::MRMSrcRegCC: 667*0fca6ea1SDimitry Andric assert(numPhysicalOperands >= 3 && numPhysicalOperands <= 4 && 6680b57cec5SDimitry Andric "Unexpected number of operands for MRMSrcRegCC"); 669*0fca6ea1SDimitry Andric if (IsND) 670*0fca6ea1SDimitry Andric HANDLE_OPERAND(vvvvRegister) 6710b57cec5SDimitry Andric HANDLE_OPERAND(roRegister) 6720b57cec5SDimitry Andric HANDLE_OPERAND(rmRegister) 6730b57cec5SDimitry Andric HANDLE_OPERAND(opcodeModifier) 6740b57cec5SDimitry Andric break; 6750b57cec5SDimitry Andric case X86Local::MRMSrcMem: 6765ffd83dbSDimitry Andric case X86Local::MRMSrcMemFSIB: 6770b57cec5SDimitry Andric // Operand 1 is a register operand in the Reg/Opcode field. 6780b57cec5SDimitry Andric // Operand 2 is a memory operand (possibly SIB-extended) 6790b57cec5SDimitry Andric // - In AVX, there is a register operand in the VEX.vvvv field here - 6800b57cec5SDimitry Andric // Operand 3 (optional) is an immediate. 6810b57cec5SDimitry Andric 6820b57cec5SDimitry Andric assert(numPhysicalOperands >= 2 + additionalOperands && 6830b57cec5SDimitry Andric numPhysicalOperands <= 4 + additionalOperands && 6840b57cec5SDimitry Andric "Unexpected number of operands for MRMSrcMemFrm"); 685647cbc5dSDimitry Andric if (IsND) 686647cbc5dSDimitry Andric HANDLE_OPERAND(vvvvRegister) 6870b57cec5SDimitry Andric 6880b57cec5SDimitry Andric HANDLE_OPERAND(roRegister) 6890b57cec5SDimitry Andric 6900b57cec5SDimitry Andric if (HasEVEX_K) 6910b57cec5SDimitry Andric HANDLE_OPERAND(writemaskRegister) 6920b57cec5SDimitry Andric 693647cbc5dSDimitry Andric if (!IsND && HasVEX_4V) 6940b57cec5SDimitry Andric // FIXME: In AVX, the register below becomes the one encoded 6950b57cec5SDimitry Andric // in ModRMVEX and the one above the one in the VEX.VVVV field 6960b57cec5SDimitry Andric HANDLE_OPERAND(vvvvRegister) 6970b57cec5SDimitry Andric 6980b57cec5SDimitry Andric HANDLE_OPERAND(memory) 6990b57cec5SDimitry Andric HANDLE_OPTIONAL(immediate) 7000b57cec5SDimitry Andric HANDLE_OPTIONAL(immediate) // above might be a register in 7:4 7010b57cec5SDimitry Andric break; 7020b57cec5SDimitry Andric case X86Local::MRMSrcMem4VOp3: 7030b57cec5SDimitry Andric assert(numPhysicalOperands == 3 && 7040b57cec5SDimitry Andric "Unexpected number of operands for MRMSrcMem4VOp3Frm"); 7050b57cec5SDimitry Andric HANDLE_OPERAND(roRegister) 7060b57cec5SDimitry Andric HANDLE_OPERAND(memory) 7070b57cec5SDimitry Andric HANDLE_OPERAND(vvvvRegister) 7080b57cec5SDimitry Andric break; 7090b57cec5SDimitry Andric case X86Local::MRMSrcMemOp4: 7100b57cec5SDimitry Andric assert(numPhysicalOperands >= 4 && numPhysicalOperands <= 5 && 7110b57cec5SDimitry Andric "Unexpected number of operands for MRMSrcMemOp4Frm"); 7120b57cec5SDimitry Andric HANDLE_OPERAND(roRegister) 7130b57cec5SDimitry Andric HANDLE_OPERAND(vvvvRegister) 7140b57cec5SDimitry Andric HANDLE_OPERAND(immediate) // Register in imm[7:4] 7150b57cec5SDimitry Andric HANDLE_OPERAND(memory) 7160b57cec5SDimitry Andric HANDLE_OPTIONAL(immediate) 7170b57cec5SDimitry Andric break; 7180b57cec5SDimitry Andric case X86Local::MRMSrcMemCC: 719*0fca6ea1SDimitry Andric assert(numPhysicalOperands >= 3 && numPhysicalOperands <= 4 && 7200b57cec5SDimitry Andric "Unexpected number of operands for MRMSrcMemCC"); 721*0fca6ea1SDimitry Andric if (IsND) 722*0fca6ea1SDimitry Andric HANDLE_OPERAND(vvvvRegister) 7230b57cec5SDimitry Andric HANDLE_OPERAND(roRegister) 7240b57cec5SDimitry Andric HANDLE_OPERAND(memory) 7250b57cec5SDimitry Andric HANDLE_OPERAND(opcodeModifier) 7260b57cec5SDimitry Andric break; 7270b57cec5SDimitry Andric case X86Local::MRMXrCC: 7280b57cec5SDimitry Andric assert(numPhysicalOperands == 2 && 7290b57cec5SDimitry Andric "Unexpected number of operands for MRMXrCC"); 7300b57cec5SDimitry Andric HANDLE_OPERAND(rmRegister) 7310b57cec5SDimitry Andric HANDLE_OPERAND(opcodeModifier) 7320b57cec5SDimitry Andric break; 7335ffd83dbSDimitry Andric case X86Local::MRMr0: 7345ffd83dbSDimitry Andric // Operand 1 is a register operand in the R/M field. 7355ffd83dbSDimitry Andric HANDLE_OPERAND(roRegister) 7365ffd83dbSDimitry Andric break; 7370b57cec5SDimitry Andric case X86Local::MRMXr: 7380b57cec5SDimitry Andric case X86Local::MRM0r: 7390b57cec5SDimitry Andric case X86Local::MRM1r: 7400b57cec5SDimitry Andric case X86Local::MRM2r: 7410b57cec5SDimitry Andric case X86Local::MRM3r: 7420b57cec5SDimitry Andric case X86Local::MRM4r: 7430b57cec5SDimitry Andric case X86Local::MRM5r: 7440b57cec5SDimitry Andric case X86Local::MRM6r: 7450b57cec5SDimitry Andric case X86Local::MRM7r: 7460b57cec5SDimitry Andric // Operand 1 is a register operand in the R/M field. 7470b57cec5SDimitry Andric // Operand 2 (optional) is an immediate or relocation. 7480b57cec5SDimitry Andric // Operand 3 (optional) is an immediate. 7490b57cec5SDimitry Andric assert(numPhysicalOperands >= 0 + additionalOperands && 7500b57cec5SDimitry Andric numPhysicalOperands <= 3 + additionalOperands && 7510b57cec5SDimitry Andric "Unexpected number of operands for MRMnr"); 7520b57cec5SDimitry Andric 7530b57cec5SDimitry Andric if (HasVEX_4V) 7540b57cec5SDimitry Andric HANDLE_OPERAND(vvvvRegister) 7550b57cec5SDimitry Andric 7560b57cec5SDimitry Andric if (HasEVEX_K) 7570b57cec5SDimitry Andric HANDLE_OPERAND(writemaskRegister) 7580b57cec5SDimitry Andric HANDLE_OPTIONAL(rmRegister) 7590b57cec5SDimitry Andric HANDLE_OPTIONAL(relocation) 7600b57cec5SDimitry Andric HANDLE_OPTIONAL(immediate) 761*0fca6ea1SDimitry Andric HANDLE_OPTIONAL(immediate) 7620b57cec5SDimitry Andric break; 7630b57cec5SDimitry Andric case X86Local::MRMXmCC: 7640b57cec5SDimitry Andric assert(numPhysicalOperands == 2 && 7650b57cec5SDimitry Andric "Unexpected number of operands for MRMXm"); 7660b57cec5SDimitry Andric HANDLE_OPERAND(memory) 7670b57cec5SDimitry Andric HANDLE_OPERAND(opcodeModifier) 7680b57cec5SDimitry Andric break; 7690b57cec5SDimitry Andric case X86Local::MRMXm: 7700b57cec5SDimitry Andric case X86Local::MRM0m: 7710b57cec5SDimitry Andric case X86Local::MRM1m: 7720b57cec5SDimitry Andric case X86Local::MRM2m: 7730b57cec5SDimitry Andric case X86Local::MRM3m: 7740b57cec5SDimitry Andric case X86Local::MRM4m: 7750b57cec5SDimitry Andric case X86Local::MRM5m: 7760b57cec5SDimitry Andric case X86Local::MRM6m: 7770b57cec5SDimitry Andric case X86Local::MRM7m: 7780b57cec5SDimitry Andric // Operand 1 is a memory operand (possibly SIB-extended) 7790b57cec5SDimitry Andric // Operand 2 (optional) is an immediate or relocation. 7800b57cec5SDimitry Andric assert(numPhysicalOperands >= 1 + additionalOperands && 7810b57cec5SDimitry Andric numPhysicalOperands <= 2 + additionalOperands && 7820b57cec5SDimitry Andric "Unexpected number of operands for MRMnm"); 7830b57cec5SDimitry Andric 7840b57cec5SDimitry Andric if (HasVEX_4V) 7850b57cec5SDimitry Andric HANDLE_OPERAND(vvvvRegister) 7860b57cec5SDimitry Andric if (HasEVEX_K) 7870b57cec5SDimitry Andric HANDLE_OPERAND(writemaskRegister) 7880b57cec5SDimitry Andric HANDLE_OPERAND(memory) 7890b57cec5SDimitry Andric HANDLE_OPTIONAL(relocation) 790*0fca6ea1SDimitry Andric HANDLE_OPTIONAL(immediate) 791*0fca6ea1SDimitry Andric HANDLE_OPTIONAL(immediate) 7920b57cec5SDimitry Andric break; 7930b57cec5SDimitry Andric case X86Local::RawFrmImm8: 7940b57cec5SDimitry Andric // operand 1 is a 16-bit immediate 7950b57cec5SDimitry Andric // operand 2 is an 8-bit immediate 7960b57cec5SDimitry Andric assert(numPhysicalOperands == 2 && 7970b57cec5SDimitry Andric "Unexpected number of operands for X86Local::RawFrmImm8"); 7980b57cec5SDimitry Andric HANDLE_OPERAND(immediate) 7990b57cec5SDimitry Andric HANDLE_OPERAND(immediate) 8000b57cec5SDimitry Andric break; 8010b57cec5SDimitry Andric case X86Local::RawFrmImm16: 8020b57cec5SDimitry Andric // operand 1 is a 16-bit immediate 8030b57cec5SDimitry Andric // operand 2 is a 16-bit immediate 8040b57cec5SDimitry Andric HANDLE_OPERAND(immediate) 8050b57cec5SDimitry Andric HANDLE_OPERAND(immediate) 8060b57cec5SDimitry Andric break; 8075ffd83dbSDimitry Andric case X86Local::MRM0X: 8085ffd83dbSDimitry Andric case X86Local::MRM1X: 8095ffd83dbSDimitry Andric case X86Local::MRM2X: 8105ffd83dbSDimitry Andric case X86Local::MRM3X: 8115ffd83dbSDimitry Andric case X86Local::MRM4X: 8125ffd83dbSDimitry Andric case X86Local::MRM5X: 8135ffd83dbSDimitry Andric case X86Local::MRM6X: 8145ffd83dbSDimitry Andric case X86Local::MRM7X: 8150b57cec5SDimitry Andric #define MAP(from, to) case X86Local::MRM_##from: 8160b57cec5SDimitry Andric X86_INSTR_MRM_MAPPING 8170b57cec5SDimitry Andric #undef MAP 8180b57cec5SDimitry Andric HANDLE_OPTIONAL(relocation) 8190b57cec5SDimitry Andric break; 8200b57cec5SDimitry Andric } 8210b57cec5SDimitry Andric 8220b57cec5SDimitry Andric #undef HANDLE_OPERAND 8230b57cec5SDimitry Andric #undef HANDLE_OPTIONAL 8240b57cec5SDimitry Andric } 8250b57cec5SDimitry Andric 8260b57cec5SDimitry Andric void RecognizableInstr::emitDecodePath(DisassemblerTables &tables) const { 8270b57cec5SDimitry Andric // Special cases where the LLVM tables are not complete 8280b57cec5SDimitry Andric 8295f757f3fSDimitry Andric #define MAP(from, to) case X86Local::MRM_##from: 8300b57cec5SDimitry Andric 831bdd1243dSDimitry Andric std::optional<OpcodeType> opcodeType; 8320b57cec5SDimitry Andric switch (OpMap) { 8335f757f3fSDimitry Andric default: 8345f757f3fSDimitry Andric llvm_unreachable("Invalid map!"); 8355f757f3fSDimitry Andric case X86Local::OB: 8365f757f3fSDimitry Andric opcodeType = ONEBYTE; 8375f757f3fSDimitry Andric break; 8385f757f3fSDimitry Andric case X86Local::TB: 8395f757f3fSDimitry Andric opcodeType = TWOBYTE; 8405f757f3fSDimitry Andric break; 8415f757f3fSDimitry Andric case X86Local::T8: 8425f757f3fSDimitry Andric opcodeType = THREEBYTE_38; 8435f757f3fSDimitry Andric break; 8445f757f3fSDimitry Andric case X86Local::TA: 8455f757f3fSDimitry Andric opcodeType = THREEBYTE_3A; 8465f757f3fSDimitry Andric break; 8475f757f3fSDimitry Andric case X86Local::XOP8: 8485f757f3fSDimitry Andric opcodeType = XOP8_MAP; 8495f757f3fSDimitry Andric break; 8505f757f3fSDimitry Andric case X86Local::XOP9: 8515f757f3fSDimitry Andric opcodeType = XOP9_MAP; 8525f757f3fSDimitry Andric break; 8535f757f3fSDimitry Andric case X86Local::XOPA: 8545f757f3fSDimitry Andric opcodeType = XOPA_MAP; 8555f757f3fSDimitry Andric break; 8565f757f3fSDimitry Andric case X86Local::ThreeDNow: 8575f757f3fSDimitry Andric opcodeType = THREEDNOW_MAP; 8585f757f3fSDimitry Andric break; 8595f757f3fSDimitry Andric case X86Local::T_MAP4: 8605f757f3fSDimitry Andric opcodeType = MAP4; 8615f757f3fSDimitry Andric break; 8625f757f3fSDimitry Andric case X86Local::T_MAP5: 8635f757f3fSDimitry Andric opcodeType = MAP5; 8645f757f3fSDimitry Andric break; 8655f757f3fSDimitry Andric case X86Local::T_MAP6: 8665f757f3fSDimitry Andric opcodeType = MAP6; 8675f757f3fSDimitry Andric break; 8685f757f3fSDimitry Andric case X86Local::T_MAP7: 8695f757f3fSDimitry Andric opcodeType = MAP7; 8705f757f3fSDimitry Andric break; 8710b57cec5SDimitry Andric } 8720b57cec5SDimitry Andric 8730b57cec5SDimitry Andric std::unique_ptr<ModRMFilter> filter; 8740b57cec5SDimitry Andric switch (Form) { 8755f757f3fSDimitry Andric default: 8765f757f3fSDimitry Andric llvm_unreachable("Invalid form!"); 8775f757f3fSDimitry Andric case X86Local::Pseudo: 8785f757f3fSDimitry Andric llvm_unreachable("Pseudo should not be emitted!"); 8790b57cec5SDimitry Andric case X86Local::RawFrm: 8800b57cec5SDimitry Andric case X86Local::AddRegFrm: 8810b57cec5SDimitry Andric case X86Local::RawFrmMemOffs: 8820b57cec5SDimitry Andric case X86Local::RawFrmSrc: 8830b57cec5SDimitry Andric case X86Local::RawFrmDst: 8840b57cec5SDimitry Andric case X86Local::RawFrmDstSrc: 8850b57cec5SDimitry Andric case X86Local::RawFrmImm8: 8860b57cec5SDimitry Andric case X86Local::RawFrmImm16: 8870b57cec5SDimitry Andric case X86Local::AddCCFrm: 8885ffd83dbSDimitry Andric case X86Local::PrefixByte: 8898bcb0991SDimitry Andric filter = std::make_unique<DumbFilter>(); 8900b57cec5SDimitry Andric break; 8910b57cec5SDimitry Andric case X86Local::MRMDestReg: 892*0fca6ea1SDimitry Andric case X86Local::MRMDestRegCC: 8930b57cec5SDimitry Andric case X86Local::MRMSrcReg: 8940b57cec5SDimitry Andric case X86Local::MRMSrcReg4VOp3: 8950b57cec5SDimitry Andric case X86Local::MRMSrcRegOp4: 8960b57cec5SDimitry Andric case X86Local::MRMSrcRegCC: 8970b57cec5SDimitry Andric case X86Local::MRMXrCC: 8980b57cec5SDimitry Andric case X86Local::MRMXr: 8998bcb0991SDimitry Andric filter = std::make_unique<ModFilter>(true); 9000b57cec5SDimitry Andric break; 9010b57cec5SDimitry Andric case X86Local::MRMDestMem: 902*0fca6ea1SDimitry Andric case X86Local::MRMDestMemCC: 903bdd1243dSDimitry Andric case X86Local::MRMDestMem4VOp3CC: 9045ffd83dbSDimitry Andric case X86Local::MRMDestMemFSIB: 9050b57cec5SDimitry Andric case X86Local::MRMSrcMem: 9065ffd83dbSDimitry Andric case X86Local::MRMSrcMemFSIB: 9070b57cec5SDimitry Andric case X86Local::MRMSrcMem4VOp3: 9080b57cec5SDimitry Andric case X86Local::MRMSrcMemOp4: 9090b57cec5SDimitry Andric case X86Local::MRMSrcMemCC: 9100b57cec5SDimitry Andric case X86Local::MRMXmCC: 9110b57cec5SDimitry Andric case X86Local::MRMXm: 9128bcb0991SDimitry Andric filter = std::make_unique<ModFilter>(false); 9130b57cec5SDimitry Andric break; 9145f757f3fSDimitry Andric case X86Local::MRM0r: 9155f757f3fSDimitry Andric case X86Local::MRM1r: 9165f757f3fSDimitry Andric case X86Local::MRM2r: 9175f757f3fSDimitry Andric case X86Local::MRM3r: 9185f757f3fSDimitry Andric case X86Local::MRM4r: 9195f757f3fSDimitry Andric case X86Local::MRM5r: 9205f757f3fSDimitry Andric case X86Local::MRM6r: 9215f757f3fSDimitry Andric case X86Local::MRM7r: 9228bcb0991SDimitry Andric filter = std::make_unique<ExtendedFilter>(true, Form - X86Local::MRM0r); 9230b57cec5SDimitry Andric break; 9245f757f3fSDimitry Andric case X86Local::MRM0X: 9255f757f3fSDimitry Andric case X86Local::MRM1X: 9265f757f3fSDimitry Andric case X86Local::MRM2X: 9275f757f3fSDimitry Andric case X86Local::MRM3X: 9285f757f3fSDimitry Andric case X86Local::MRM4X: 9295f757f3fSDimitry Andric case X86Local::MRM5X: 9305f757f3fSDimitry Andric case X86Local::MRM6X: 9315f757f3fSDimitry Andric case X86Local::MRM7X: 9325ffd83dbSDimitry Andric filter = std::make_unique<ExtendedFilter>(true, Form - X86Local::MRM0X); 9335ffd83dbSDimitry Andric break; 9345ffd83dbSDimitry Andric case X86Local::MRMr0: 9355ffd83dbSDimitry Andric filter = std::make_unique<ExtendedRMFilter>(true, Form - X86Local::MRMr0); 9365ffd83dbSDimitry Andric break; 9375f757f3fSDimitry Andric case X86Local::MRM0m: 9385f757f3fSDimitry Andric case X86Local::MRM1m: 9395f757f3fSDimitry Andric case X86Local::MRM2m: 9405f757f3fSDimitry Andric case X86Local::MRM3m: 9415f757f3fSDimitry Andric case X86Local::MRM4m: 9425f757f3fSDimitry Andric case X86Local::MRM5m: 9435f757f3fSDimitry Andric case X86Local::MRM6m: 9445f757f3fSDimitry Andric case X86Local::MRM7m: 9458bcb0991SDimitry Andric filter = std::make_unique<ExtendedFilter>(false, Form - X86Local::MRM0m); 9460b57cec5SDimitry Andric break; 9470b57cec5SDimitry Andric X86_INSTR_MRM_MAPPING 9488bcb0991SDimitry Andric filter = std::make_unique<ExactFilter>(0xC0 + Form - X86Local::MRM_C0); 9490b57cec5SDimitry Andric break; 9500b57cec5SDimitry Andric } // switch (Form) 9510b57cec5SDimitry Andric 9520b57cec5SDimitry Andric uint8_t opcodeToSet = Opcode; 9530b57cec5SDimitry Andric 9540b57cec5SDimitry Andric unsigned AddressSize = 0; 9550b57cec5SDimitry Andric switch (AdSize) { 9565f757f3fSDimitry Andric case X86Local::AdSize16: 9575f757f3fSDimitry Andric AddressSize = 16; 9585f757f3fSDimitry Andric break; 9595f757f3fSDimitry Andric case X86Local::AdSize32: 9605f757f3fSDimitry Andric AddressSize = 32; 9615f757f3fSDimitry Andric break; 9625f757f3fSDimitry Andric case X86Local::AdSize64: 9635f757f3fSDimitry Andric AddressSize = 64; 9645f757f3fSDimitry Andric break; 9650b57cec5SDimitry Andric } 9660b57cec5SDimitry Andric 9670b57cec5SDimitry Andric assert(opcodeType && "Opcode type not set"); 9680b57cec5SDimitry Andric assert(filter && "Filter not set"); 9690b57cec5SDimitry Andric 9700b57cec5SDimitry Andric if (Form == X86Local::AddRegFrm || Form == X86Local::MRMSrcRegCC || 9710b57cec5SDimitry Andric Form == X86Local::MRMSrcMemCC || Form == X86Local::MRMXrCC || 972bdd1243dSDimitry Andric Form == X86Local::MRMXmCC || Form == X86Local::AddCCFrm || 973*0fca6ea1SDimitry Andric Form == X86Local::MRMDestRegCC || Form == X86Local::MRMDestMemCC || 974bdd1243dSDimitry Andric Form == X86Local::MRMDestMem4VOp3CC) { 97581ad6265SDimitry Andric uint8_t Count = Form == X86Local::AddRegFrm ? 8 : 16; 9760b57cec5SDimitry Andric assert(((opcodeToSet % Count) == 0) && "ADDREG_FRM opcode not aligned"); 9770b57cec5SDimitry Andric 9780b57cec5SDimitry Andric uint8_t currentOpcode; 9790b57cec5SDimitry Andric 98081ad6265SDimitry Andric for (currentOpcode = opcodeToSet; 98181ad6265SDimitry Andric currentOpcode < (uint8_t)(opcodeToSet + Count); ++currentOpcode) 9820b57cec5SDimitry Andric tables.setTableFields(*opcodeType, insnContext(), currentOpcode, *filter, 9830b57cec5SDimitry Andric UID, Is32Bit, OpPrefix == 0, 9845f757f3fSDimitry Andric IgnoresVEX_L || EncodeRC, IgnoresW, AddressSize); 9850b57cec5SDimitry Andric } else { 9860b57cec5SDimitry Andric tables.setTableFields(*opcodeType, insnContext(), opcodeToSet, *filter, UID, 9870b57cec5SDimitry Andric Is32Bit, OpPrefix == 0, IgnoresVEX_L || EncodeRC, 98806c3fb27SDimitry Andric IgnoresW, AddressSize); 9890b57cec5SDimitry Andric } 9900b57cec5SDimitry Andric 9910b57cec5SDimitry Andric #undef MAP 9920b57cec5SDimitry Andric } 9930b57cec5SDimitry Andric 9945f757f3fSDimitry Andric #define TYPE(str, type) \ 9955f757f3fSDimitry Andric if (s == str) \ 9965f757f3fSDimitry Andric return type; 9970b57cec5SDimitry Andric OperandType RecognizableInstr::typeFromString(const std::string &s, 9985f757f3fSDimitry Andric bool hasREX_W, uint8_t OpSize) { 99981ad6265SDimitry Andric if (hasREX_W) { 10000b57cec5SDimitry Andric // For instructions with a REX_W prefix, a declared 32-bit register encoding 10010b57cec5SDimitry Andric // is special. 10020b57cec5SDimitry Andric TYPE("GR32", TYPE_R32) 10030b57cec5SDimitry Andric } 10040b57cec5SDimitry Andric if (OpSize == X86Local::OpSize16) { 10050b57cec5SDimitry Andric // For OpSize16 instructions, a declared 16-bit register or 10060b57cec5SDimitry Andric // immediate encoding is special. 10070b57cec5SDimitry Andric TYPE("GR16", TYPE_Rv) 10080b57cec5SDimitry Andric } else if (OpSize == X86Local::OpSize32) { 10090b57cec5SDimitry Andric // For OpSize32 instructions, a declared 32-bit register or 10100b57cec5SDimitry Andric // immediate encoding is special. 10110b57cec5SDimitry Andric TYPE("GR32", TYPE_Rv) 10120b57cec5SDimitry Andric } 10130b57cec5SDimitry Andric TYPE("i16mem", TYPE_M) 10140b57cec5SDimitry Andric TYPE("i16imm", TYPE_IMM) 10150b57cec5SDimitry Andric TYPE("i16i8imm", TYPE_IMM) 10160b57cec5SDimitry Andric TYPE("GR16", TYPE_R16) 1017590d96feSDimitry Andric TYPE("GR16orGR32orGR64", TYPE_R16) 10180b57cec5SDimitry Andric TYPE("i32mem", TYPE_M) 10190b57cec5SDimitry Andric TYPE("i32imm", TYPE_IMM) 10200b57cec5SDimitry Andric TYPE("i32i8imm", TYPE_IMM) 10210b57cec5SDimitry Andric TYPE("GR32", TYPE_R32) 10220b57cec5SDimitry Andric TYPE("GR32orGR64", TYPE_R32) 10230b57cec5SDimitry Andric TYPE("i64mem", TYPE_M) 10240b57cec5SDimitry Andric TYPE("i64i32imm", TYPE_IMM) 10250b57cec5SDimitry Andric TYPE("i64i8imm", TYPE_IMM) 10260b57cec5SDimitry Andric TYPE("GR64", TYPE_R64) 10270b57cec5SDimitry Andric TYPE("i8mem", TYPE_M) 10280b57cec5SDimitry Andric TYPE("i8imm", TYPE_IMM) 10298bcb0991SDimitry Andric TYPE("u4imm", TYPE_UIMM8) 10300b57cec5SDimitry Andric TYPE("u8imm", TYPE_UIMM8) 10310b57cec5SDimitry Andric TYPE("i16u8imm", TYPE_UIMM8) 10320b57cec5SDimitry Andric TYPE("i32u8imm", TYPE_UIMM8) 10330b57cec5SDimitry Andric TYPE("i64u8imm", TYPE_UIMM8) 10340b57cec5SDimitry Andric TYPE("GR8", TYPE_R8) 10350b57cec5SDimitry Andric TYPE("VR128", TYPE_XMM) 10360b57cec5SDimitry Andric TYPE("VR128X", TYPE_XMM) 10370b57cec5SDimitry Andric TYPE("f128mem", TYPE_M) 10380b57cec5SDimitry Andric TYPE("f256mem", TYPE_M) 10390b57cec5SDimitry Andric TYPE("f512mem", TYPE_M) 10400b57cec5SDimitry Andric TYPE("FR128", TYPE_XMM) 10410b57cec5SDimitry Andric TYPE("FR64", TYPE_XMM) 10420b57cec5SDimitry Andric TYPE("FR64X", TYPE_XMM) 10430b57cec5SDimitry Andric TYPE("f64mem", TYPE_M) 10440b57cec5SDimitry Andric TYPE("sdmem", TYPE_M) 1045349cc55cSDimitry Andric TYPE("FR16X", TYPE_XMM) 10460b57cec5SDimitry Andric TYPE("FR32", TYPE_XMM) 10470b57cec5SDimitry Andric TYPE("FR32X", TYPE_XMM) 10480b57cec5SDimitry Andric TYPE("f32mem", TYPE_M) 1049349cc55cSDimitry Andric TYPE("f16mem", TYPE_M) 10500b57cec5SDimitry Andric TYPE("ssmem", TYPE_M) 1051349cc55cSDimitry Andric TYPE("shmem", TYPE_M) 10520b57cec5SDimitry Andric TYPE("RST", TYPE_ST) 10530b57cec5SDimitry Andric TYPE("RSTi", TYPE_ST) 10540b57cec5SDimitry Andric TYPE("i128mem", TYPE_M) 10550b57cec5SDimitry Andric TYPE("i256mem", TYPE_M) 10560b57cec5SDimitry Andric TYPE("i512mem", TYPE_M) 105706c3fb27SDimitry Andric TYPE("i512mem_GR16", TYPE_M) 105806c3fb27SDimitry Andric TYPE("i512mem_GR32", TYPE_M) 105906c3fb27SDimitry Andric TYPE("i512mem_GR64", TYPE_M) 1060480093f4SDimitry Andric TYPE("i64i32imm_brtarget", TYPE_REL) 1061480093f4SDimitry Andric TYPE("i16imm_brtarget", TYPE_REL) 1062480093f4SDimitry Andric TYPE("i32imm_brtarget", TYPE_REL) 10630b57cec5SDimitry Andric TYPE("ccode", TYPE_IMM) 1064*0fca6ea1SDimitry Andric TYPE("cflags", TYPE_IMM) 10650b57cec5SDimitry Andric TYPE("AVX512RC", TYPE_IMM) 10660b57cec5SDimitry Andric TYPE("brtarget32", TYPE_REL) 10670b57cec5SDimitry Andric TYPE("brtarget16", TYPE_REL) 10680b57cec5SDimitry Andric TYPE("brtarget8", TYPE_REL) 10690b57cec5SDimitry Andric TYPE("f80mem", TYPE_M) 10700b57cec5SDimitry Andric TYPE("lea64_32mem", TYPE_M) 10710b57cec5SDimitry Andric TYPE("lea64mem", TYPE_M) 10720b57cec5SDimitry Andric TYPE("VR64", TYPE_MM64) 10730b57cec5SDimitry Andric TYPE("i64imm", TYPE_IMM) 10740b57cec5SDimitry Andric TYPE("anymem", TYPE_M) 10750b57cec5SDimitry Andric TYPE("opaquemem", TYPE_M) 10765ffd83dbSDimitry Andric TYPE("sibmem", TYPE_MSIB) 10770b57cec5SDimitry Andric TYPE("SEGMENT_REG", TYPE_SEGMENTREG) 10780b57cec5SDimitry Andric TYPE("DEBUG_REG", TYPE_DEBUGREG) 10790b57cec5SDimitry Andric TYPE("CONTROL_REG", TYPE_CONTROLREG) 10800b57cec5SDimitry Andric TYPE("srcidx8", TYPE_SRCIDX) 10810b57cec5SDimitry Andric TYPE("srcidx16", TYPE_SRCIDX) 10820b57cec5SDimitry Andric TYPE("srcidx32", TYPE_SRCIDX) 10830b57cec5SDimitry Andric TYPE("srcidx64", TYPE_SRCIDX) 10840b57cec5SDimitry Andric TYPE("dstidx8", TYPE_DSTIDX) 10850b57cec5SDimitry Andric TYPE("dstidx16", TYPE_DSTIDX) 10860b57cec5SDimitry Andric TYPE("dstidx32", TYPE_DSTIDX) 10870b57cec5SDimitry Andric TYPE("dstidx64", TYPE_DSTIDX) 10880b57cec5SDimitry Andric TYPE("offset16_8", TYPE_MOFFS) 10890b57cec5SDimitry Andric TYPE("offset16_16", TYPE_MOFFS) 10900b57cec5SDimitry Andric TYPE("offset16_32", TYPE_MOFFS) 10910b57cec5SDimitry Andric TYPE("offset32_8", TYPE_MOFFS) 10920b57cec5SDimitry Andric TYPE("offset32_16", TYPE_MOFFS) 10930b57cec5SDimitry Andric TYPE("offset32_32", TYPE_MOFFS) 10940b57cec5SDimitry Andric TYPE("offset32_64", TYPE_MOFFS) 10950b57cec5SDimitry Andric TYPE("offset64_8", TYPE_MOFFS) 10960b57cec5SDimitry Andric TYPE("offset64_16", TYPE_MOFFS) 10970b57cec5SDimitry Andric TYPE("offset64_32", TYPE_MOFFS) 10980b57cec5SDimitry Andric TYPE("offset64_64", TYPE_MOFFS) 10990b57cec5SDimitry Andric TYPE("VR256", TYPE_YMM) 11000b57cec5SDimitry Andric TYPE("VR256X", TYPE_YMM) 11010b57cec5SDimitry Andric TYPE("VR512", TYPE_ZMM) 11020b57cec5SDimitry Andric TYPE("VK1", TYPE_VK) 11030b57cec5SDimitry Andric TYPE("VK1WM", TYPE_VK) 11040b57cec5SDimitry Andric TYPE("VK2", TYPE_VK) 11050b57cec5SDimitry Andric TYPE("VK2WM", TYPE_VK) 11060b57cec5SDimitry Andric TYPE("VK4", TYPE_VK) 11070b57cec5SDimitry Andric TYPE("VK4WM", TYPE_VK) 11080b57cec5SDimitry Andric TYPE("VK8", TYPE_VK) 11090b57cec5SDimitry Andric TYPE("VK8WM", TYPE_VK) 11100b57cec5SDimitry Andric TYPE("VK16", TYPE_VK) 11110b57cec5SDimitry Andric TYPE("VK16WM", TYPE_VK) 11120b57cec5SDimitry Andric TYPE("VK32", TYPE_VK) 11130b57cec5SDimitry Andric TYPE("VK32WM", TYPE_VK) 11140b57cec5SDimitry Andric TYPE("VK64", TYPE_VK) 11150b57cec5SDimitry Andric TYPE("VK64WM", TYPE_VK) 11160b57cec5SDimitry Andric TYPE("VK1Pair", TYPE_VK_PAIR) 11170b57cec5SDimitry Andric TYPE("VK2Pair", TYPE_VK_PAIR) 11180b57cec5SDimitry Andric TYPE("VK4Pair", TYPE_VK_PAIR) 11190b57cec5SDimitry Andric TYPE("VK8Pair", TYPE_VK_PAIR) 11200b57cec5SDimitry Andric TYPE("VK16Pair", TYPE_VK_PAIR) 11210b57cec5SDimitry Andric TYPE("vx64mem", TYPE_MVSIBX) 11220b57cec5SDimitry Andric TYPE("vx128mem", TYPE_MVSIBX) 11230b57cec5SDimitry Andric TYPE("vx256mem", TYPE_MVSIBX) 11240b57cec5SDimitry Andric TYPE("vy128mem", TYPE_MVSIBY) 11250b57cec5SDimitry Andric TYPE("vy256mem", TYPE_MVSIBY) 11260b57cec5SDimitry Andric TYPE("vx64xmem", TYPE_MVSIBX) 11270b57cec5SDimitry Andric TYPE("vx128xmem", TYPE_MVSIBX) 11280b57cec5SDimitry Andric TYPE("vx256xmem", TYPE_MVSIBX) 11290b57cec5SDimitry Andric TYPE("vy128xmem", TYPE_MVSIBY) 11300b57cec5SDimitry Andric TYPE("vy256xmem", TYPE_MVSIBY) 11310b57cec5SDimitry Andric TYPE("vy512xmem", TYPE_MVSIBY) 11320b57cec5SDimitry Andric TYPE("vz256mem", TYPE_MVSIBZ) 11330b57cec5SDimitry Andric TYPE("vz512mem", TYPE_MVSIBZ) 11340b57cec5SDimitry Andric TYPE("BNDR", TYPE_BNDR) 11355ffd83dbSDimitry Andric TYPE("TILE", TYPE_TMM) 11360b57cec5SDimitry Andric errs() << "Unhandled type string " << s << "\n"; 11370b57cec5SDimitry Andric llvm_unreachable("Unhandled type string"); 11380b57cec5SDimitry Andric } 11390b57cec5SDimitry Andric #undef TYPE 11400b57cec5SDimitry Andric 11415f757f3fSDimitry Andric #define ENCODING(str, encoding) \ 11425f757f3fSDimitry Andric if (s == str) \ 11435f757f3fSDimitry Andric return encoding; 11440b57cec5SDimitry Andric OperandEncoding 11450b57cec5SDimitry Andric RecognizableInstr::immediateEncodingFromString(const std::string &s, 11460b57cec5SDimitry Andric uint8_t OpSize) { 11470b57cec5SDimitry Andric if (OpSize != X86Local::OpSize16) { 11480b57cec5SDimitry Andric // For instructions without an OpSize prefix, a declared 16-bit register or 11490b57cec5SDimitry Andric // immediate encoding is special. 11500b57cec5SDimitry Andric ENCODING("i16imm", ENCODING_IW) 11510b57cec5SDimitry Andric } 11520b57cec5SDimitry Andric ENCODING("i32i8imm", ENCODING_IB) 11530b57cec5SDimitry Andric ENCODING("AVX512RC", ENCODING_IRC) 11540b57cec5SDimitry Andric ENCODING("i16imm", ENCODING_Iv) 11550b57cec5SDimitry Andric ENCODING("i16i8imm", ENCODING_IB) 11560b57cec5SDimitry Andric ENCODING("i32imm", ENCODING_Iv) 11570b57cec5SDimitry Andric ENCODING("i64i32imm", ENCODING_ID) 11580b57cec5SDimitry Andric ENCODING("i64i8imm", ENCODING_IB) 11590b57cec5SDimitry Andric ENCODING("i8imm", ENCODING_IB) 1160*0fca6ea1SDimitry Andric ENCODING("ccode", ENCODING_CC) 1161*0fca6ea1SDimitry Andric ENCODING("cflags", ENCODING_CF) 11628bcb0991SDimitry Andric ENCODING("u4imm", ENCODING_IB) 11630b57cec5SDimitry Andric ENCODING("u8imm", ENCODING_IB) 11640b57cec5SDimitry Andric ENCODING("i16u8imm", ENCODING_IB) 11650b57cec5SDimitry Andric ENCODING("i32u8imm", ENCODING_IB) 11660b57cec5SDimitry Andric ENCODING("i64u8imm", ENCODING_IB) 11670b57cec5SDimitry Andric // This is not a typo. Instructions like BLENDVPD put 11680b57cec5SDimitry Andric // register IDs in 8-bit immediates nowadays. 11690b57cec5SDimitry Andric ENCODING("FR32", ENCODING_IB) 11700b57cec5SDimitry Andric ENCODING("FR64", ENCODING_IB) 11710b57cec5SDimitry Andric ENCODING("FR128", ENCODING_IB) 11720b57cec5SDimitry Andric ENCODING("VR128", ENCODING_IB) 11730b57cec5SDimitry Andric ENCODING("VR256", ENCODING_IB) 1174349cc55cSDimitry Andric ENCODING("FR16X", ENCODING_IB) 11750b57cec5SDimitry Andric ENCODING("FR32X", ENCODING_IB) 11760b57cec5SDimitry Andric ENCODING("FR64X", ENCODING_IB) 11770b57cec5SDimitry Andric ENCODING("VR128X", ENCODING_IB) 11780b57cec5SDimitry Andric ENCODING("VR256X", ENCODING_IB) 11790b57cec5SDimitry Andric ENCODING("VR512", ENCODING_IB) 11805ffd83dbSDimitry Andric ENCODING("TILE", ENCODING_IB) 11810b57cec5SDimitry Andric errs() << "Unhandled immediate encoding " << s << "\n"; 11820b57cec5SDimitry Andric llvm_unreachable("Unhandled immediate encoding"); 11830b57cec5SDimitry Andric } 11840b57cec5SDimitry Andric 11850b57cec5SDimitry Andric OperandEncoding 11860b57cec5SDimitry Andric RecognizableInstr::rmRegisterEncodingFromString(const std::string &s, 11870b57cec5SDimitry Andric uint8_t OpSize) { 11880b57cec5SDimitry Andric ENCODING("RST", ENCODING_FP) 11890b57cec5SDimitry Andric ENCODING("RSTi", ENCODING_FP) 11900b57cec5SDimitry Andric ENCODING("GR16", ENCODING_RM) 1191590d96feSDimitry Andric ENCODING("GR16orGR32orGR64", ENCODING_RM) 11920b57cec5SDimitry Andric ENCODING("GR32", ENCODING_RM) 11930b57cec5SDimitry Andric ENCODING("GR32orGR64", ENCODING_RM) 11940b57cec5SDimitry Andric ENCODING("GR64", ENCODING_RM) 11950b57cec5SDimitry Andric ENCODING("GR8", ENCODING_RM) 11960b57cec5SDimitry Andric ENCODING("VR128", ENCODING_RM) 11970b57cec5SDimitry Andric ENCODING("VR128X", ENCODING_RM) 11980b57cec5SDimitry Andric ENCODING("FR128", ENCODING_RM) 11990b57cec5SDimitry Andric ENCODING("FR64", ENCODING_RM) 12000b57cec5SDimitry Andric ENCODING("FR32", ENCODING_RM) 12010b57cec5SDimitry Andric ENCODING("FR64X", ENCODING_RM) 12020b57cec5SDimitry Andric ENCODING("FR32X", ENCODING_RM) 1203349cc55cSDimitry Andric ENCODING("FR16X", ENCODING_RM) 12040b57cec5SDimitry Andric ENCODING("VR64", ENCODING_RM) 12050b57cec5SDimitry Andric ENCODING("VR256", ENCODING_RM) 12060b57cec5SDimitry Andric ENCODING("VR256X", ENCODING_RM) 12070b57cec5SDimitry Andric ENCODING("VR512", ENCODING_RM) 12080b57cec5SDimitry Andric ENCODING("VK1", ENCODING_RM) 12090b57cec5SDimitry Andric ENCODING("VK2", ENCODING_RM) 12100b57cec5SDimitry Andric ENCODING("VK4", ENCODING_RM) 12110b57cec5SDimitry Andric ENCODING("VK8", ENCODING_RM) 12120b57cec5SDimitry Andric ENCODING("VK16", ENCODING_RM) 12130b57cec5SDimitry Andric ENCODING("VK32", ENCODING_RM) 12140b57cec5SDimitry Andric ENCODING("VK64", ENCODING_RM) 12150b57cec5SDimitry Andric ENCODING("BNDR", ENCODING_RM) 12165ffd83dbSDimitry Andric ENCODING("TILE", ENCODING_RM) 12170b57cec5SDimitry Andric errs() << "Unhandled R/M register encoding " << s << "\n"; 12180b57cec5SDimitry Andric llvm_unreachable("Unhandled R/M register encoding"); 12190b57cec5SDimitry Andric } 12200b57cec5SDimitry Andric 12210b57cec5SDimitry Andric OperandEncoding 12220b57cec5SDimitry Andric RecognizableInstr::roRegisterEncodingFromString(const std::string &s, 12230b57cec5SDimitry Andric uint8_t OpSize) { 12240b57cec5SDimitry Andric ENCODING("GR16", ENCODING_REG) 1225590d96feSDimitry Andric ENCODING("GR16orGR32orGR64", ENCODING_REG) 12260b57cec5SDimitry Andric ENCODING("GR32", ENCODING_REG) 12270b57cec5SDimitry Andric ENCODING("GR32orGR64", ENCODING_REG) 12280b57cec5SDimitry Andric ENCODING("GR64", ENCODING_REG) 12290b57cec5SDimitry Andric ENCODING("GR8", ENCODING_REG) 12300b57cec5SDimitry Andric ENCODING("VR128", ENCODING_REG) 12310b57cec5SDimitry Andric ENCODING("FR128", ENCODING_REG) 12320b57cec5SDimitry Andric ENCODING("FR64", ENCODING_REG) 12330b57cec5SDimitry Andric ENCODING("FR32", ENCODING_REG) 12340b57cec5SDimitry Andric ENCODING("VR64", ENCODING_REG) 12350b57cec5SDimitry Andric ENCODING("SEGMENT_REG", ENCODING_REG) 12360b57cec5SDimitry Andric ENCODING("DEBUG_REG", ENCODING_REG) 12370b57cec5SDimitry Andric ENCODING("CONTROL_REG", ENCODING_REG) 12380b57cec5SDimitry Andric ENCODING("VR256", ENCODING_REG) 12390b57cec5SDimitry Andric ENCODING("VR256X", ENCODING_REG) 12400b57cec5SDimitry Andric ENCODING("VR128X", ENCODING_REG) 12410b57cec5SDimitry Andric ENCODING("FR64X", ENCODING_REG) 12420b57cec5SDimitry Andric ENCODING("FR32X", ENCODING_REG) 1243349cc55cSDimitry Andric ENCODING("FR16X", ENCODING_REG) 12440b57cec5SDimitry Andric ENCODING("VR512", ENCODING_REG) 12450b57cec5SDimitry Andric ENCODING("VK1", ENCODING_REG) 12460b57cec5SDimitry Andric ENCODING("VK2", ENCODING_REG) 12470b57cec5SDimitry Andric ENCODING("VK4", ENCODING_REG) 12480b57cec5SDimitry Andric ENCODING("VK8", ENCODING_REG) 12490b57cec5SDimitry Andric ENCODING("VK16", ENCODING_REG) 12500b57cec5SDimitry Andric ENCODING("VK32", ENCODING_REG) 12510b57cec5SDimitry Andric ENCODING("VK64", ENCODING_REG) 12520b57cec5SDimitry Andric ENCODING("VK1Pair", ENCODING_REG) 12530b57cec5SDimitry Andric ENCODING("VK2Pair", ENCODING_REG) 12540b57cec5SDimitry Andric ENCODING("VK4Pair", ENCODING_REG) 12550b57cec5SDimitry Andric ENCODING("VK8Pair", ENCODING_REG) 12560b57cec5SDimitry Andric ENCODING("VK16Pair", ENCODING_REG) 12570b57cec5SDimitry Andric ENCODING("VK1WM", ENCODING_REG) 12580b57cec5SDimitry Andric ENCODING("VK2WM", ENCODING_REG) 12590b57cec5SDimitry Andric ENCODING("VK4WM", ENCODING_REG) 12600b57cec5SDimitry Andric ENCODING("VK8WM", ENCODING_REG) 12610b57cec5SDimitry Andric ENCODING("VK16WM", ENCODING_REG) 12620b57cec5SDimitry Andric ENCODING("VK32WM", ENCODING_REG) 12630b57cec5SDimitry Andric ENCODING("VK64WM", ENCODING_REG) 12640b57cec5SDimitry Andric ENCODING("BNDR", ENCODING_REG) 12655ffd83dbSDimitry Andric ENCODING("TILE", ENCODING_REG) 12660b57cec5SDimitry Andric errs() << "Unhandled reg/opcode register encoding " << s << "\n"; 12670b57cec5SDimitry Andric llvm_unreachable("Unhandled reg/opcode register encoding"); 12680b57cec5SDimitry Andric } 12690b57cec5SDimitry Andric 12700b57cec5SDimitry Andric OperandEncoding 12710b57cec5SDimitry Andric RecognizableInstr::vvvvRegisterEncodingFromString(const std::string &s, 12720b57cec5SDimitry Andric uint8_t OpSize) { 1273647cbc5dSDimitry Andric ENCODING("GR8", ENCODING_VVVV) 1274647cbc5dSDimitry Andric ENCODING("GR16", ENCODING_VVVV) 12750b57cec5SDimitry Andric ENCODING("GR32", ENCODING_VVVV) 12760b57cec5SDimitry Andric ENCODING("GR64", ENCODING_VVVV) 12770b57cec5SDimitry Andric ENCODING("FR32", ENCODING_VVVV) 12780b57cec5SDimitry Andric ENCODING("FR128", ENCODING_VVVV) 12790b57cec5SDimitry Andric ENCODING("FR64", ENCODING_VVVV) 12800b57cec5SDimitry Andric ENCODING("VR128", ENCODING_VVVV) 12810b57cec5SDimitry Andric ENCODING("VR256", ENCODING_VVVV) 1282349cc55cSDimitry Andric ENCODING("FR16X", ENCODING_VVVV) 12830b57cec5SDimitry Andric ENCODING("FR32X", ENCODING_VVVV) 12840b57cec5SDimitry Andric ENCODING("FR64X", ENCODING_VVVV) 12850b57cec5SDimitry Andric ENCODING("VR128X", ENCODING_VVVV) 12860b57cec5SDimitry Andric ENCODING("VR256X", ENCODING_VVVV) 12870b57cec5SDimitry Andric ENCODING("VR512", ENCODING_VVVV) 12880b57cec5SDimitry Andric ENCODING("VK1", ENCODING_VVVV) 12890b57cec5SDimitry Andric ENCODING("VK2", ENCODING_VVVV) 12900b57cec5SDimitry Andric ENCODING("VK4", ENCODING_VVVV) 12910b57cec5SDimitry Andric ENCODING("VK8", ENCODING_VVVV) 12920b57cec5SDimitry Andric ENCODING("VK16", ENCODING_VVVV) 12930b57cec5SDimitry Andric ENCODING("VK32", ENCODING_VVVV) 12940b57cec5SDimitry Andric ENCODING("VK64", ENCODING_VVVV) 12955ffd83dbSDimitry Andric ENCODING("TILE", ENCODING_VVVV) 12960b57cec5SDimitry Andric errs() << "Unhandled VEX.vvvv register encoding " << s << "\n"; 12970b57cec5SDimitry Andric llvm_unreachable("Unhandled VEX.vvvv register encoding"); 12980b57cec5SDimitry Andric } 12990b57cec5SDimitry Andric 13000b57cec5SDimitry Andric OperandEncoding 13010b57cec5SDimitry Andric RecognizableInstr::writemaskRegisterEncodingFromString(const std::string &s, 13020b57cec5SDimitry Andric uint8_t OpSize) { 13030b57cec5SDimitry Andric ENCODING("VK1WM", ENCODING_WRITEMASK) 13040b57cec5SDimitry Andric ENCODING("VK2WM", ENCODING_WRITEMASK) 13050b57cec5SDimitry Andric ENCODING("VK4WM", ENCODING_WRITEMASK) 13060b57cec5SDimitry Andric ENCODING("VK8WM", ENCODING_WRITEMASK) 13070b57cec5SDimitry Andric ENCODING("VK16WM", ENCODING_WRITEMASK) 13080b57cec5SDimitry Andric ENCODING("VK32WM", ENCODING_WRITEMASK) 13090b57cec5SDimitry Andric ENCODING("VK64WM", ENCODING_WRITEMASK) 13100b57cec5SDimitry Andric errs() << "Unhandled mask register encoding " << s << "\n"; 13110b57cec5SDimitry Andric llvm_unreachable("Unhandled mask register encoding"); 13120b57cec5SDimitry Andric } 13130b57cec5SDimitry Andric 13140b57cec5SDimitry Andric OperandEncoding 13150b57cec5SDimitry Andric RecognizableInstr::memoryEncodingFromString(const std::string &s, 13160b57cec5SDimitry Andric uint8_t OpSize) { 13170b57cec5SDimitry Andric ENCODING("i16mem", ENCODING_RM) 13180b57cec5SDimitry Andric ENCODING("i32mem", ENCODING_RM) 13190b57cec5SDimitry Andric ENCODING("i64mem", ENCODING_RM) 13200b57cec5SDimitry Andric ENCODING("i8mem", ENCODING_RM) 1321349cc55cSDimitry Andric ENCODING("shmem", ENCODING_RM) 13220b57cec5SDimitry Andric ENCODING("ssmem", ENCODING_RM) 13230b57cec5SDimitry Andric ENCODING("sdmem", ENCODING_RM) 13240b57cec5SDimitry Andric ENCODING("f128mem", ENCODING_RM) 13250b57cec5SDimitry Andric ENCODING("f256mem", ENCODING_RM) 13260b57cec5SDimitry Andric ENCODING("f512mem", ENCODING_RM) 13270b57cec5SDimitry Andric ENCODING("f64mem", ENCODING_RM) 13280b57cec5SDimitry Andric ENCODING("f32mem", ENCODING_RM) 1329349cc55cSDimitry Andric ENCODING("f16mem", ENCODING_RM) 13300b57cec5SDimitry Andric ENCODING("i128mem", ENCODING_RM) 13310b57cec5SDimitry Andric ENCODING("i256mem", ENCODING_RM) 13320b57cec5SDimitry Andric ENCODING("i512mem", ENCODING_RM) 133306c3fb27SDimitry Andric ENCODING("i512mem_GR16", ENCODING_RM) 133406c3fb27SDimitry Andric ENCODING("i512mem_GR32", ENCODING_RM) 133506c3fb27SDimitry Andric ENCODING("i512mem_GR64", ENCODING_RM) 13360b57cec5SDimitry Andric ENCODING("f80mem", ENCODING_RM) 13370b57cec5SDimitry Andric ENCODING("lea64_32mem", ENCODING_RM) 13380b57cec5SDimitry Andric ENCODING("lea64mem", ENCODING_RM) 13390b57cec5SDimitry Andric ENCODING("anymem", ENCODING_RM) 13400b57cec5SDimitry Andric ENCODING("opaquemem", ENCODING_RM) 13415ffd83dbSDimitry Andric ENCODING("sibmem", ENCODING_SIB) 13420b57cec5SDimitry Andric ENCODING("vx64mem", ENCODING_VSIB) 13430b57cec5SDimitry Andric ENCODING("vx128mem", ENCODING_VSIB) 13440b57cec5SDimitry Andric ENCODING("vx256mem", ENCODING_VSIB) 13450b57cec5SDimitry Andric ENCODING("vy128mem", ENCODING_VSIB) 13460b57cec5SDimitry Andric ENCODING("vy256mem", ENCODING_VSIB) 13470b57cec5SDimitry Andric ENCODING("vx64xmem", ENCODING_VSIB) 13480b57cec5SDimitry Andric ENCODING("vx128xmem", ENCODING_VSIB) 13490b57cec5SDimitry Andric ENCODING("vx256xmem", ENCODING_VSIB) 13500b57cec5SDimitry Andric ENCODING("vy128xmem", ENCODING_VSIB) 13510b57cec5SDimitry Andric ENCODING("vy256xmem", ENCODING_VSIB) 13520b57cec5SDimitry Andric ENCODING("vy512xmem", ENCODING_VSIB) 13530b57cec5SDimitry Andric ENCODING("vz256mem", ENCODING_VSIB) 13540b57cec5SDimitry Andric ENCODING("vz512mem", ENCODING_VSIB) 13550b57cec5SDimitry Andric errs() << "Unhandled memory encoding " << s << "\n"; 13560b57cec5SDimitry Andric llvm_unreachable("Unhandled memory encoding"); 13570b57cec5SDimitry Andric } 13580b57cec5SDimitry Andric 13590b57cec5SDimitry Andric OperandEncoding 13600b57cec5SDimitry Andric RecognizableInstr::relocationEncodingFromString(const std::string &s, 13610b57cec5SDimitry Andric uint8_t OpSize) { 13620b57cec5SDimitry Andric if (OpSize != X86Local::OpSize16) { 13630b57cec5SDimitry Andric // For instructions without an OpSize prefix, a declared 16-bit register or 13640b57cec5SDimitry Andric // immediate encoding is special. 13650b57cec5SDimitry Andric ENCODING("i16imm", ENCODING_IW) 13660b57cec5SDimitry Andric } 13670b57cec5SDimitry Andric ENCODING("i16imm", ENCODING_Iv) 13680b57cec5SDimitry Andric ENCODING("i16i8imm", ENCODING_IB) 13690b57cec5SDimitry Andric ENCODING("i32imm", ENCODING_Iv) 13700b57cec5SDimitry Andric ENCODING("i32i8imm", ENCODING_IB) 13710b57cec5SDimitry Andric ENCODING("i64i32imm", ENCODING_ID) 13720b57cec5SDimitry Andric ENCODING("i64i8imm", ENCODING_IB) 13730b57cec5SDimitry Andric ENCODING("i8imm", ENCODING_IB) 13740b57cec5SDimitry Andric ENCODING("u8imm", ENCODING_IB) 13750b57cec5SDimitry Andric ENCODING("i16u8imm", ENCODING_IB) 13760b57cec5SDimitry Andric ENCODING("i32u8imm", ENCODING_IB) 13770b57cec5SDimitry Andric ENCODING("i64u8imm", ENCODING_IB) 1378480093f4SDimitry Andric ENCODING("i64i32imm_brtarget", ENCODING_ID) 1379480093f4SDimitry Andric ENCODING("i16imm_brtarget", ENCODING_IW) 1380480093f4SDimitry Andric ENCODING("i32imm_brtarget", ENCODING_ID) 13810b57cec5SDimitry Andric ENCODING("brtarget32", ENCODING_ID) 13820b57cec5SDimitry Andric ENCODING("brtarget16", ENCODING_IW) 13830b57cec5SDimitry Andric ENCODING("brtarget8", ENCODING_IB) 13840b57cec5SDimitry Andric ENCODING("i64imm", ENCODING_IO) 13850b57cec5SDimitry Andric ENCODING("offset16_8", ENCODING_Ia) 13860b57cec5SDimitry Andric ENCODING("offset16_16", ENCODING_Ia) 13870b57cec5SDimitry Andric ENCODING("offset16_32", ENCODING_Ia) 13880b57cec5SDimitry Andric ENCODING("offset32_8", ENCODING_Ia) 13890b57cec5SDimitry Andric ENCODING("offset32_16", ENCODING_Ia) 13900b57cec5SDimitry Andric ENCODING("offset32_32", ENCODING_Ia) 13910b57cec5SDimitry Andric ENCODING("offset32_64", ENCODING_Ia) 13920b57cec5SDimitry Andric ENCODING("offset64_8", ENCODING_Ia) 13930b57cec5SDimitry Andric ENCODING("offset64_16", ENCODING_Ia) 13940b57cec5SDimitry Andric ENCODING("offset64_32", ENCODING_Ia) 13950b57cec5SDimitry Andric ENCODING("offset64_64", ENCODING_Ia) 13960b57cec5SDimitry Andric ENCODING("srcidx8", ENCODING_SI) 13970b57cec5SDimitry Andric ENCODING("srcidx16", ENCODING_SI) 13980b57cec5SDimitry Andric ENCODING("srcidx32", ENCODING_SI) 13990b57cec5SDimitry Andric ENCODING("srcidx64", ENCODING_SI) 14000b57cec5SDimitry Andric ENCODING("dstidx8", ENCODING_DI) 14010b57cec5SDimitry Andric ENCODING("dstidx16", ENCODING_DI) 14020b57cec5SDimitry Andric ENCODING("dstidx32", ENCODING_DI) 14030b57cec5SDimitry Andric ENCODING("dstidx64", ENCODING_DI) 14040b57cec5SDimitry Andric errs() << "Unhandled relocation encoding " << s << "\n"; 14050b57cec5SDimitry Andric llvm_unreachable("Unhandled relocation encoding"); 14060b57cec5SDimitry Andric } 14070b57cec5SDimitry Andric 14080b57cec5SDimitry Andric OperandEncoding 14090b57cec5SDimitry Andric RecognizableInstr::opcodeModifierEncodingFromString(const std::string &s, 14100b57cec5SDimitry Andric uint8_t OpSize) { 14110b57cec5SDimitry Andric ENCODING("GR32", ENCODING_Rv) 14120b57cec5SDimitry Andric ENCODING("GR64", ENCODING_RO) 14130b57cec5SDimitry Andric ENCODING("GR16", ENCODING_Rv) 14140b57cec5SDimitry Andric ENCODING("GR8", ENCODING_RB) 14150b57cec5SDimitry Andric ENCODING("ccode", ENCODING_CC) 14160b57cec5SDimitry Andric errs() << "Unhandled opcode modifier encoding " << s << "\n"; 14170b57cec5SDimitry Andric llvm_unreachable("Unhandled opcode modifier encoding"); 14180b57cec5SDimitry Andric } 14190b57cec5SDimitry Andric #undef ENCODING 1420