xref: /freebsd-src/contrib/llvm-project/llvm/utils/TableGen/X86RecognizableInstr.cpp (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
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