10b57cec5SDimitry Andric //===- X86DisassemblerTables.cpp - Disassembler tables ----------*- 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 the disassembler tables. 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 "X86DisassemblerTables.h" 170b57cec5SDimitry Andric #include "X86DisassemblerShared.h" 181fd87a68SDimitry Andric #include "X86ModRMFilters.h" 191fd87a68SDimitry Andric #include "llvm/ADT/SmallVector.h" 200b57cec5SDimitry Andric #include "llvm/Support/ErrorHandling.h" 210b57cec5SDimitry Andric #include "llvm/Support/Format.h" 221fd87a68SDimitry Andric #include "llvm/Support/raw_ostream.h" 230b57cec5SDimitry Andric #include <map> 240b57cec5SDimitry Andric 250b57cec5SDimitry Andric using namespace llvm; 260b57cec5SDimitry Andric using namespace X86Disassembler; 270b57cec5SDimitry Andric 280b57cec5SDimitry Andric /// stringForContext - Returns a string containing the name of a particular 290b57cec5SDimitry Andric /// InstructionContext, usually for diagnostic purposes. 300b57cec5SDimitry Andric /// 310b57cec5SDimitry Andric /// @param insnContext - The instruction class to transform to a string. 320b57cec5SDimitry Andric /// @return - A statically-allocated string constant that contains the 330b57cec5SDimitry Andric /// name of the instruction class. 340b57cec5SDimitry Andric static inline const char *stringForContext(InstructionContext insnContext) { 350b57cec5SDimitry Andric switch (insnContext) { 360b57cec5SDimitry Andric default: 370b57cec5SDimitry Andric llvm_unreachable("Unhandled instruction class"); 385f757f3fSDimitry Andric #define ENUM_ENTRY(n, r, d) \ 395f757f3fSDimitry Andric case n: \ 405f757f3fSDimitry Andric return #n; \ 415f757f3fSDimitry Andric break; 425f757f3fSDimitry Andric #define ENUM_ENTRY_K_B(n, r, d) \ 435f757f3fSDimitry Andric ENUM_ENTRY(n, r, d) \ 44*0fca6ea1SDimitry Andric ENUM_ENTRY(n##_K_B, r, d) \ 45*0fca6ea1SDimitry Andric ENUM_ENTRY(n##_KZ, r, d) \ 46*0fca6ea1SDimitry Andric ENUM_ENTRY(n##_K, r, d) ENUM_ENTRY(n##_B, r, d) ENUM_ENTRY(n##_KZ_B, r, d) 470b57cec5SDimitry Andric INSTRUCTION_CONTEXTS 480b57cec5SDimitry Andric #undef ENUM_ENTRY 490b57cec5SDimitry Andric #undef ENUM_ENTRY_K_B 500b57cec5SDimitry Andric } 510b57cec5SDimitry Andric } 520b57cec5SDimitry Andric 530b57cec5SDimitry Andric /// stringForOperandType - Like stringForContext, but for OperandTypes. 540b57cec5SDimitry Andric static inline const char *stringForOperandType(OperandType type) { 550b57cec5SDimitry Andric switch (type) { 560b57cec5SDimitry Andric default: 570b57cec5SDimitry Andric llvm_unreachable("Unhandled type"); 585f757f3fSDimitry Andric #define ENUM_ENTRY(i, d) \ 595f757f3fSDimitry Andric case i: \ 605f757f3fSDimitry Andric return #i; 610b57cec5SDimitry Andric TYPES 620b57cec5SDimitry Andric #undef ENUM_ENTRY 630b57cec5SDimitry Andric } 640b57cec5SDimitry Andric } 650b57cec5SDimitry Andric 660b57cec5SDimitry Andric /// stringForOperandEncoding - like stringForContext, but for 670b57cec5SDimitry Andric /// OperandEncodings. 680b57cec5SDimitry Andric static inline const char *stringForOperandEncoding(OperandEncoding encoding) { 690b57cec5SDimitry Andric switch (encoding) { 700b57cec5SDimitry Andric default: 710b57cec5SDimitry Andric llvm_unreachable("Unhandled encoding"); 725f757f3fSDimitry Andric #define ENUM_ENTRY(i, d) \ 735f757f3fSDimitry Andric case i: \ 745f757f3fSDimitry Andric return #i; 750b57cec5SDimitry Andric ENCODINGS 760b57cec5SDimitry Andric #undef ENUM_ENTRY 770b57cec5SDimitry Andric } 780b57cec5SDimitry Andric } 790b57cec5SDimitry Andric 800b57cec5SDimitry Andric /// inheritsFrom - Indicates whether all instructions in one class also belong 810b57cec5SDimitry Andric /// to another class. 820b57cec5SDimitry Andric /// 830b57cec5SDimitry Andric /// @param child - The class that may be the subset 840b57cec5SDimitry Andric /// @param parent - The class that may be the superset 850b57cec5SDimitry Andric /// @return - True if child is a subset of parent, false otherwise. 860b57cec5SDimitry Andric static inline bool inheritsFrom(InstructionContext child, 870b57cec5SDimitry Andric InstructionContext parent, bool noPrefix = true, 8806c3fb27SDimitry Andric bool VEX_LIG = false, bool WIG = false, 890b57cec5SDimitry Andric bool AdSize64 = false) { 900b57cec5SDimitry Andric if (child == parent) 910b57cec5SDimitry Andric return true; 920b57cec5SDimitry Andric 930b57cec5SDimitry Andric switch (parent) { 940b57cec5SDimitry Andric case IC: 950b57cec5SDimitry Andric return (inheritsFrom(child, IC_64BIT, AdSize64) || 960b57cec5SDimitry Andric (noPrefix && inheritsFrom(child, IC_OPSIZE, noPrefix)) || 970b57cec5SDimitry Andric inheritsFrom(child, IC_ADSIZE) || 980b57cec5SDimitry Andric (noPrefix && inheritsFrom(child, IC_XD, noPrefix)) || 990b57cec5SDimitry Andric (noPrefix && inheritsFrom(child, IC_XS, noPrefix))); 1000b57cec5SDimitry Andric case IC_64BIT: 1010b57cec5SDimitry Andric return (inheritsFrom(child, IC_64BIT_REXW) || 1020b57cec5SDimitry Andric (noPrefix && inheritsFrom(child, IC_64BIT_OPSIZE, noPrefix)) || 1030b57cec5SDimitry Andric (!AdSize64 && inheritsFrom(child, IC_64BIT_ADSIZE)) || 1040b57cec5SDimitry Andric (noPrefix && inheritsFrom(child, IC_64BIT_XD, noPrefix)) || 1050b57cec5SDimitry Andric (noPrefix && inheritsFrom(child, IC_64BIT_XS, noPrefix))); 1060b57cec5SDimitry Andric case IC_OPSIZE: 1070b57cec5SDimitry Andric return inheritsFrom(child, IC_64BIT_OPSIZE) || 1080b57cec5SDimitry Andric inheritsFrom(child, IC_OPSIZE_ADSIZE); 1090b57cec5SDimitry Andric case IC_ADSIZE: 1100b57cec5SDimitry Andric return (noPrefix && inheritsFrom(child, IC_OPSIZE_ADSIZE, noPrefix)); 1110b57cec5SDimitry Andric case IC_OPSIZE_ADSIZE: 1120b57cec5SDimitry Andric return false; 1130b57cec5SDimitry Andric case IC_64BIT_ADSIZE: 1140b57cec5SDimitry Andric return (noPrefix && inheritsFrom(child, IC_64BIT_OPSIZE_ADSIZE, noPrefix)); 1150b57cec5SDimitry Andric case IC_64BIT_OPSIZE_ADSIZE: 11681ad6265SDimitry Andric return false; 1170b57cec5SDimitry Andric case IC_XD: 1180b57cec5SDimitry Andric return inheritsFrom(child, IC_64BIT_XD); 1190b57cec5SDimitry Andric case IC_XS: 1200b57cec5SDimitry Andric return inheritsFrom(child, IC_64BIT_XS); 1210b57cec5SDimitry Andric case IC_XD_OPSIZE: 1220b57cec5SDimitry Andric return inheritsFrom(child, IC_64BIT_XD_OPSIZE); 1230b57cec5SDimitry Andric case IC_XS_OPSIZE: 1240b57cec5SDimitry Andric return inheritsFrom(child, IC_64BIT_XS_OPSIZE); 1250b57cec5SDimitry Andric case IC_XD_ADSIZE: 1260b57cec5SDimitry Andric return inheritsFrom(child, IC_64BIT_XD_ADSIZE); 1270b57cec5SDimitry Andric case IC_XS_ADSIZE: 1280b57cec5SDimitry Andric return inheritsFrom(child, IC_64BIT_XS_ADSIZE); 1290b57cec5SDimitry Andric case IC_64BIT_REXW: 1300b57cec5SDimitry Andric return ((noPrefix && inheritsFrom(child, IC_64BIT_REXW_XS, noPrefix)) || 1310b57cec5SDimitry Andric (noPrefix && inheritsFrom(child, IC_64BIT_REXW_XD, noPrefix)) || 1320b57cec5SDimitry Andric (noPrefix && inheritsFrom(child, IC_64BIT_REXW_OPSIZE, noPrefix)) || 1330b57cec5SDimitry Andric (!AdSize64 && inheritsFrom(child, IC_64BIT_REXW_ADSIZE))); 1340b57cec5SDimitry Andric case IC_64BIT_OPSIZE: 1350b57cec5SDimitry Andric return inheritsFrom(child, IC_64BIT_REXW_OPSIZE) || 1360b57cec5SDimitry Andric (!AdSize64 && inheritsFrom(child, IC_64BIT_OPSIZE_ADSIZE)) || 13781ad6265SDimitry Andric (!AdSize64 && inheritsFrom(child, IC_64BIT_REXW_ADSIZE)); 1380b57cec5SDimitry Andric case IC_64BIT_XD: 1390b57cec5SDimitry Andric return (inheritsFrom(child, IC_64BIT_REXW_XD) || 1400b57cec5SDimitry Andric (!AdSize64 && inheritsFrom(child, IC_64BIT_XD_ADSIZE))); 1410b57cec5SDimitry Andric case IC_64BIT_XS: 1420b57cec5SDimitry Andric return (inheritsFrom(child, IC_64BIT_REXW_XS) || 1430b57cec5SDimitry Andric (!AdSize64 && inheritsFrom(child, IC_64BIT_XS_ADSIZE))); 1440b57cec5SDimitry Andric case IC_64BIT_XD_OPSIZE: 1450b57cec5SDimitry Andric case IC_64BIT_XS_OPSIZE: 1460b57cec5SDimitry Andric return false; 1470b57cec5SDimitry Andric case IC_64BIT_XD_ADSIZE: 1480b57cec5SDimitry Andric case IC_64BIT_XS_ADSIZE: 1490b57cec5SDimitry Andric return false; 1500b57cec5SDimitry Andric case IC_64BIT_REXW_XD: 1510b57cec5SDimitry Andric case IC_64BIT_REXW_XS: 1520b57cec5SDimitry Andric case IC_64BIT_REXW_OPSIZE: 1530b57cec5SDimitry Andric case IC_64BIT_REXW_ADSIZE: 1545f757f3fSDimitry Andric case IC_64BIT_REX2: 1550b57cec5SDimitry Andric return false; 1560b57cec5SDimitry Andric case IC_VEX: 15706c3fb27SDimitry Andric return (VEX_LIG && WIG && inheritsFrom(child, IC_VEX_L_W)) || 15806c3fb27SDimitry Andric (WIG && inheritsFrom(child, IC_VEX_W)) || 1590b57cec5SDimitry Andric (VEX_LIG && inheritsFrom(child, IC_VEX_L)); 1600b57cec5SDimitry Andric case IC_VEX_XS: 16106c3fb27SDimitry Andric return (VEX_LIG && WIG && inheritsFrom(child, IC_VEX_L_W_XS)) || 16206c3fb27SDimitry Andric (WIG && inheritsFrom(child, IC_VEX_W_XS)) || 1630b57cec5SDimitry Andric (VEX_LIG && inheritsFrom(child, IC_VEX_L_XS)); 1640b57cec5SDimitry Andric case IC_VEX_XD: 16506c3fb27SDimitry Andric return (VEX_LIG && WIG && inheritsFrom(child, IC_VEX_L_W_XD)) || 16606c3fb27SDimitry Andric (WIG && inheritsFrom(child, IC_VEX_W_XD)) || 1670b57cec5SDimitry Andric (VEX_LIG && inheritsFrom(child, IC_VEX_L_XD)); 1680b57cec5SDimitry Andric case IC_VEX_OPSIZE: 16906c3fb27SDimitry Andric return (VEX_LIG && WIG && inheritsFrom(child, IC_VEX_L_W_OPSIZE)) || 17006c3fb27SDimitry Andric (WIG && inheritsFrom(child, IC_VEX_W_OPSIZE)) || 17181ad6265SDimitry Andric (VEX_LIG && inheritsFrom(child, IC_VEX_L_OPSIZE)); 1720b57cec5SDimitry Andric case IC_VEX_W: 1730b57cec5SDimitry Andric return VEX_LIG && inheritsFrom(child, IC_VEX_L_W); 1740b57cec5SDimitry Andric case IC_VEX_W_XS: 1750b57cec5SDimitry Andric return VEX_LIG && inheritsFrom(child, IC_VEX_L_W_XS); 1760b57cec5SDimitry Andric case IC_VEX_W_XD: 1770b57cec5SDimitry Andric return VEX_LIG && inheritsFrom(child, IC_VEX_L_W_XD); 1780b57cec5SDimitry Andric case IC_VEX_W_OPSIZE: 1790b57cec5SDimitry Andric return VEX_LIG && inheritsFrom(child, IC_VEX_L_W_OPSIZE); 1800b57cec5SDimitry Andric case IC_VEX_L: 18106c3fb27SDimitry Andric return WIG && inheritsFrom(child, IC_VEX_L_W); 1820b57cec5SDimitry Andric case IC_VEX_L_XS: 18306c3fb27SDimitry Andric return WIG && inheritsFrom(child, IC_VEX_L_W_XS); 1840b57cec5SDimitry Andric case IC_VEX_L_XD: 18506c3fb27SDimitry Andric return WIG && inheritsFrom(child, IC_VEX_L_W_XD); 1860b57cec5SDimitry Andric case IC_VEX_L_OPSIZE: 18706c3fb27SDimitry Andric return WIG && inheritsFrom(child, IC_VEX_L_W_OPSIZE); 1880b57cec5SDimitry Andric case IC_VEX_L_W: 1890b57cec5SDimitry Andric case IC_VEX_L_W_XS: 1900b57cec5SDimitry Andric case IC_VEX_L_W_XD: 1910b57cec5SDimitry Andric case IC_VEX_L_W_OPSIZE: 1920b57cec5SDimitry Andric return false; 1930b57cec5SDimitry Andric case IC_EVEX: 19406c3fb27SDimitry Andric return (VEX_LIG && WIG && inheritsFrom(child, IC_EVEX_L_W)) || 19506c3fb27SDimitry Andric (VEX_LIG && WIG && inheritsFrom(child, IC_EVEX_L2_W)) || 19606c3fb27SDimitry Andric (WIG && inheritsFrom(child, IC_EVEX_W)) || 1970b57cec5SDimitry Andric (VEX_LIG && inheritsFrom(child, IC_EVEX_L)) || 1980b57cec5SDimitry Andric (VEX_LIG && inheritsFrom(child, IC_EVEX_L2)); 1990b57cec5SDimitry Andric case IC_EVEX_XS: 20006c3fb27SDimitry Andric return (VEX_LIG && WIG && inheritsFrom(child, IC_EVEX_L_W_XS)) || 20106c3fb27SDimitry Andric (VEX_LIG && WIG && inheritsFrom(child, IC_EVEX_L2_W_XS)) || 20206c3fb27SDimitry Andric (WIG && inheritsFrom(child, IC_EVEX_W_XS)) || 2030b57cec5SDimitry Andric (VEX_LIG && inheritsFrom(child, IC_EVEX_L_XS)) || 2040b57cec5SDimitry Andric (VEX_LIG && inheritsFrom(child, IC_EVEX_L2_XS)); 2050b57cec5SDimitry Andric case IC_EVEX_XD: 20606c3fb27SDimitry Andric return (VEX_LIG && WIG && inheritsFrom(child, IC_EVEX_L_W_XD)) || 20706c3fb27SDimitry Andric (VEX_LIG && WIG && inheritsFrom(child, IC_EVEX_L2_W_XD)) || 20806c3fb27SDimitry Andric (WIG && inheritsFrom(child, IC_EVEX_W_XD)) || 2090b57cec5SDimitry Andric (VEX_LIG && inheritsFrom(child, IC_EVEX_L_XD)) || 2100b57cec5SDimitry Andric (VEX_LIG && inheritsFrom(child, IC_EVEX_L2_XD)); 2110b57cec5SDimitry Andric case IC_EVEX_OPSIZE: 21206c3fb27SDimitry Andric return (VEX_LIG && WIG && inheritsFrom(child, IC_EVEX_L_W_OPSIZE)) || 21306c3fb27SDimitry Andric (VEX_LIG && WIG && inheritsFrom(child, IC_EVEX_L2_W_OPSIZE)) || 21406c3fb27SDimitry Andric (WIG && inheritsFrom(child, IC_EVEX_W_OPSIZE)) || 2150b57cec5SDimitry Andric (VEX_LIG && inheritsFrom(child, IC_EVEX_L_OPSIZE)) || 2160b57cec5SDimitry Andric (VEX_LIG && inheritsFrom(child, IC_EVEX_L2_OPSIZE)); 2175f757f3fSDimitry Andric case IC_EVEX_OPSIZE_ADSIZE: 218*0fca6ea1SDimitry Andric case IC_EVEX_XS_ADSIZE: 219*0fca6ea1SDimitry Andric case IC_EVEX_XD_ADSIZE: 2205f757f3fSDimitry Andric return false; 2210b57cec5SDimitry Andric case IC_EVEX_K: 22206c3fb27SDimitry Andric return (VEX_LIG && WIG && inheritsFrom(child, IC_EVEX_L_W_K)) || 22306c3fb27SDimitry Andric (VEX_LIG && WIG && inheritsFrom(child, IC_EVEX_L2_W_K)) || 22406c3fb27SDimitry Andric (WIG && inheritsFrom(child, IC_EVEX_W_K)) || 2250b57cec5SDimitry Andric (VEX_LIG && inheritsFrom(child, IC_EVEX_L_K)) || 2260b57cec5SDimitry Andric (VEX_LIG && inheritsFrom(child, IC_EVEX_L2_K)); 2270b57cec5SDimitry Andric case IC_EVEX_XS_K: 22806c3fb27SDimitry Andric return (VEX_LIG && WIG && inheritsFrom(child, IC_EVEX_L_W_XS_K)) || 22906c3fb27SDimitry Andric (VEX_LIG && WIG && inheritsFrom(child, IC_EVEX_L2_W_XS_K)) || 23006c3fb27SDimitry Andric (WIG && inheritsFrom(child, IC_EVEX_W_XS_K)) || 2310b57cec5SDimitry Andric (VEX_LIG && inheritsFrom(child, IC_EVEX_L_XS_K)) || 2320b57cec5SDimitry Andric (VEX_LIG && inheritsFrom(child, IC_EVEX_L2_XS_K)); 2330b57cec5SDimitry Andric case IC_EVEX_XD_K: 23406c3fb27SDimitry Andric return (VEX_LIG && WIG && inheritsFrom(child, IC_EVEX_L_W_XD_K)) || 23506c3fb27SDimitry Andric (VEX_LIG && WIG && inheritsFrom(child, IC_EVEX_L2_W_XD_K)) || 23606c3fb27SDimitry Andric (WIG && inheritsFrom(child, IC_EVEX_W_XD_K)) || 2370b57cec5SDimitry Andric (VEX_LIG && inheritsFrom(child, IC_EVEX_L_XD_K)) || 2380b57cec5SDimitry Andric (VEX_LIG && inheritsFrom(child, IC_EVEX_L2_XD_K)); 2390b57cec5SDimitry Andric case IC_EVEX_OPSIZE_K: 24006c3fb27SDimitry Andric return (VEX_LIG && WIG && inheritsFrom(child, IC_EVEX_L_W_OPSIZE_K)) || 24106c3fb27SDimitry Andric (VEX_LIG && WIG && inheritsFrom(child, IC_EVEX_L2_W_OPSIZE_K)) || 24206c3fb27SDimitry Andric (WIG && inheritsFrom(child, IC_EVEX_W_OPSIZE_K)) || 2430b57cec5SDimitry Andric (VEX_LIG && inheritsFrom(child, IC_EVEX_L_OPSIZE_K)) || 2440b57cec5SDimitry Andric (VEX_LIG && inheritsFrom(child, IC_EVEX_L2_OPSIZE_K)); 2450b57cec5SDimitry Andric case IC_EVEX_KZ: 24606c3fb27SDimitry Andric return (VEX_LIG && WIG && inheritsFrom(child, IC_EVEX_L_W_KZ)) || 24706c3fb27SDimitry Andric (VEX_LIG && WIG && inheritsFrom(child, IC_EVEX_L2_W_KZ)) || 24806c3fb27SDimitry Andric (WIG && inheritsFrom(child, IC_EVEX_W_KZ)) || 2490b57cec5SDimitry Andric (VEX_LIG && inheritsFrom(child, IC_EVEX_L_KZ)) || 2500b57cec5SDimitry Andric (VEX_LIG && inheritsFrom(child, IC_EVEX_L2_KZ)); 2510b57cec5SDimitry Andric case IC_EVEX_XS_KZ: 25206c3fb27SDimitry Andric return (VEX_LIG && WIG && inheritsFrom(child, IC_EVEX_L_W_XS_KZ)) || 25306c3fb27SDimitry Andric (VEX_LIG && WIG && inheritsFrom(child, IC_EVEX_L2_W_XS_KZ)) || 25406c3fb27SDimitry Andric (WIG && inheritsFrom(child, IC_EVEX_W_XS_KZ)) || 2550b57cec5SDimitry Andric (VEX_LIG && inheritsFrom(child, IC_EVEX_L_XS_KZ)) || 2560b57cec5SDimitry Andric (VEX_LIG && inheritsFrom(child, IC_EVEX_L2_XS_KZ)); 2570b57cec5SDimitry Andric case IC_EVEX_XD_KZ: 25806c3fb27SDimitry Andric return (VEX_LIG && WIG && inheritsFrom(child, IC_EVEX_L_W_XD_KZ)) || 25906c3fb27SDimitry Andric (VEX_LIG && WIG && inheritsFrom(child, IC_EVEX_L2_W_XD_KZ)) || 26006c3fb27SDimitry Andric (WIG && inheritsFrom(child, IC_EVEX_W_XD_KZ)) || 2610b57cec5SDimitry Andric (VEX_LIG && inheritsFrom(child, IC_EVEX_L_XD_KZ)) || 2620b57cec5SDimitry Andric (VEX_LIG && inheritsFrom(child, IC_EVEX_L2_XD_KZ)); 2630b57cec5SDimitry Andric case IC_EVEX_OPSIZE_KZ: 26406c3fb27SDimitry Andric return (VEX_LIG && WIG && inheritsFrom(child, IC_EVEX_L_W_OPSIZE_KZ)) || 26506c3fb27SDimitry Andric (VEX_LIG && WIG && inheritsFrom(child, IC_EVEX_L2_W_OPSIZE_KZ)) || 26606c3fb27SDimitry Andric (WIG && inheritsFrom(child, IC_EVEX_W_OPSIZE_KZ)) || 2670b57cec5SDimitry Andric (VEX_LIG && inheritsFrom(child, IC_EVEX_L_OPSIZE_KZ)) || 2680b57cec5SDimitry Andric (VEX_LIG && inheritsFrom(child, IC_EVEX_L2_OPSIZE_KZ)); 2690b57cec5SDimitry Andric case IC_EVEX_W: 2700b57cec5SDimitry Andric return (VEX_LIG && inheritsFrom(child, IC_EVEX_L_W)) || 2710b57cec5SDimitry Andric (VEX_LIG && inheritsFrom(child, IC_EVEX_L2_W)); 2720b57cec5SDimitry Andric case IC_EVEX_W_XS: 2730b57cec5SDimitry Andric return (VEX_LIG && inheritsFrom(child, IC_EVEX_L_W_XS)) || 2740b57cec5SDimitry Andric (VEX_LIG && inheritsFrom(child, IC_EVEX_L2_W_XS)); 2750b57cec5SDimitry Andric case IC_EVEX_W_XD: 2760b57cec5SDimitry Andric return (VEX_LIG && inheritsFrom(child, IC_EVEX_L_W_XD)) || 2770b57cec5SDimitry Andric (VEX_LIG && inheritsFrom(child, IC_EVEX_L2_W_XD)); 2780b57cec5SDimitry Andric case IC_EVEX_W_OPSIZE: 2790b57cec5SDimitry Andric return (VEX_LIG && inheritsFrom(child, IC_EVEX_L_W_OPSIZE)) || 2800b57cec5SDimitry Andric (VEX_LIG && inheritsFrom(child, IC_EVEX_L2_W_OPSIZE)); 2810b57cec5SDimitry Andric case IC_EVEX_W_K: 2820b57cec5SDimitry Andric return (VEX_LIG && inheritsFrom(child, IC_EVEX_L_W_K)) || 2830b57cec5SDimitry Andric (VEX_LIG && inheritsFrom(child, IC_EVEX_L2_W_K)); 2840b57cec5SDimitry Andric case IC_EVEX_W_XS_K: 2850b57cec5SDimitry Andric return (VEX_LIG && inheritsFrom(child, IC_EVEX_L_W_XS_K)) || 2860b57cec5SDimitry Andric (VEX_LIG && inheritsFrom(child, IC_EVEX_L2_W_XS_K)); 2870b57cec5SDimitry Andric case IC_EVEX_W_XD_K: 2880b57cec5SDimitry Andric return (VEX_LIG && inheritsFrom(child, IC_EVEX_L_W_XD_K)) || 2890b57cec5SDimitry Andric (VEX_LIG && inheritsFrom(child, IC_EVEX_L2_W_XD_K)); 2900b57cec5SDimitry Andric case IC_EVEX_W_OPSIZE_K: 2910b57cec5SDimitry Andric return (VEX_LIG && inheritsFrom(child, IC_EVEX_L_W_OPSIZE_K)) || 2920b57cec5SDimitry Andric (VEX_LIG && inheritsFrom(child, IC_EVEX_L2_W_OPSIZE_K)); 2930b57cec5SDimitry Andric case IC_EVEX_W_KZ: 2940b57cec5SDimitry Andric return (VEX_LIG && inheritsFrom(child, IC_EVEX_L_W_KZ)) || 2950b57cec5SDimitry Andric (VEX_LIG && inheritsFrom(child, IC_EVEX_L2_W_KZ)); 2960b57cec5SDimitry Andric case IC_EVEX_W_XS_KZ: 2970b57cec5SDimitry Andric return (VEX_LIG && inheritsFrom(child, IC_EVEX_L_W_XS_KZ)) || 2980b57cec5SDimitry Andric (VEX_LIG && inheritsFrom(child, IC_EVEX_L2_W_XS_KZ)); 2990b57cec5SDimitry Andric case IC_EVEX_W_XD_KZ: 3000b57cec5SDimitry Andric return (VEX_LIG && inheritsFrom(child, IC_EVEX_L_W_XD_KZ)) || 3010b57cec5SDimitry Andric (VEX_LIG && inheritsFrom(child, IC_EVEX_L2_W_XD_KZ)); 3020b57cec5SDimitry Andric case IC_EVEX_W_OPSIZE_KZ: 3030b57cec5SDimitry Andric return (VEX_LIG && inheritsFrom(child, IC_EVEX_L_W_OPSIZE_KZ)) || 3040b57cec5SDimitry Andric (VEX_LIG && inheritsFrom(child, IC_EVEX_L2_W_OPSIZE_KZ)); 3050b57cec5SDimitry Andric case IC_EVEX_L: 30606c3fb27SDimitry Andric return WIG && inheritsFrom(child, IC_EVEX_L_W); 3070b57cec5SDimitry Andric case IC_EVEX_L_XS: 30806c3fb27SDimitry Andric return WIG && inheritsFrom(child, IC_EVEX_L_W_XS); 3090b57cec5SDimitry Andric case IC_EVEX_L_XD: 31006c3fb27SDimitry Andric return WIG && inheritsFrom(child, IC_EVEX_L_W_XD); 3110b57cec5SDimitry Andric case IC_EVEX_L_OPSIZE: 31206c3fb27SDimitry Andric return WIG && inheritsFrom(child, IC_EVEX_L_W_OPSIZE); 3130b57cec5SDimitry Andric case IC_EVEX_L_K: 31406c3fb27SDimitry Andric return WIG && inheritsFrom(child, IC_EVEX_L_W_K); 3150b57cec5SDimitry Andric case IC_EVEX_L_XS_K: 31606c3fb27SDimitry Andric return WIG && inheritsFrom(child, IC_EVEX_L_W_XS_K); 3170b57cec5SDimitry Andric case IC_EVEX_L_XD_K: 31806c3fb27SDimitry Andric return WIG && inheritsFrom(child, IC_EVEX_L_W_XD_K); 3190b57cec5SDimitry Andric case IC_EVEX_L_OPSIZE_K: 32006c3fb27SDimitry Andric return WIG && inheritsFrom(child, IC_EVEX_L_W_OPSIZE_K); 3210b57cec5SDimitry Andric case IC_EVEX_L_KZ: 32206c3fb27SDimitry Andric return WIG && inheritsFrom(child, IC_EVEX_L_W_KZ); 3230b57cec5SDimitry Andric case IC_EVEX_L_XS_KZ: 32406c3fb27SDimitry Andric return WIG && inheritsFrom(child, IC_EVEX_L_W_XS_KZ); 3250b57cec5SDimitry Andric case IC_EVEX_L_XD_KZ: 32606c3fb27SDimitry Andric return WIG && inheritsFrom(child, IC_EVEX_L_W_XD_KZ); 3270b57cec5SDimitry Andric case IC_EVEX_L_OPSIZE_KZ: 32806c3fb27SDimitry Andric return WIG && inheritsFrom(child, IC_EVEX_L_W_OPSIZE_KZ); 3290b57cec5SDimitry Andric case IC_EVEX_L_W: 3300b57cec5SDimitry Andric case IC_EVEX_L_W_XS: 3310b57cec5SDimitry Andric case IC_EVEX_L_W_XD: 3320b57cec5SDimitry Andric case IC_EVEX_L_W_OPSIZE: 3330b57cec5SDimitry Andric return false; 3340b57cec5SDimitry Andric case IC_EVEX_L_W_K: 3350b57cec5SDimitry Andric case IC_EVEX_L_W_XS_K: 3360b57cec5SDimitry Andric case IC_EVEX_L_W_XD_K: 3370b57cec5SDimitry Andric case IC_EVEX_L_W_OPSIZE_K: 3380b57cec5SDimitry Andric return false; 3390b57cec5SDimitry Andric case IC_EVEX_L_W_KZ: 3400b57cec5SDimitry Andric case IC_EVEX_L_W_XS_KZ: 3410b57cec5SDimitry Andric case IC_EVEX_L_W_XD_KZ: 3420b57cec5SDimitry Andric case IC_EVEX_L_W_OPSIZE_KZ: 3430b57cec5SDimitry Andric return false; 3440b57cec5SDimitry Andric case IC_EVEX_L2: 34506c3fb27SDimitry Andric return WIG && inheritsFrom(child, IC_EVEX_L2_W); 3460b57cec5SDimitry Andric case IC_EVEX_L2_XS: 34706c3fb27SDimitry Andric return WIG && inheritsFrom(child, IC_EVEX_L2_W_XS); 3480b57cec5SDimitry Andric case IC_EVEX_L2_XD: 34906c3fb27SDimitry Andric return WIG && inheritsFrom(child, IC_EVEX_L2_W_XD); 3500b57cec5SDimitry Andric case IC_EVEX_L2_OPSIZE: 35106c3fb27SDimitry Andric return WIG && inheritsFrom(child, IC_EVEX_L2_W_OPSIZE); 3520b57cec5SDimitry Andric case IC_EVEX_L2_K: 35306c3fb27SDimitry Andric return WIG && inheritsFrom(child, IC_EVEX_L2_W_K); 3540b57cec5SDimitry Andric case IC_EVEX_L2_XS_K: 35506c3fb27SDimitry Andric return WIG && inheritsFrom(child, IC_EVEX_L2_W_XS_K); 3560b57cec5SDimitry Andric case IC_EVEX_L2_XD_K: 35706c3fb27SDimitry Andric return WIG && inheritsFrom(child, IC_EVEX_L2_W_XD_K); 3580b57cec5SDimitry Andric case IC_EVEX_L2_OPSIZE_K: 35906c3fb27SDimitry Andric return WIG && inheritsFrom(child, IC_EVEX_L2_W_OPSIZE_K); 3600b57cec5SDimitry Andric case IC_EVEX_L2_KZ: 36106c3fb27SDimitry Andric return WIG && inheritsFrom(child, IC_EVEX_L2_W_KZ); 3620b57cec5SDimitry Andric case IC_EVEX_L2_XS_KZ: 36306c3fb27SDimitry Andric return WIG && inheritsFrom(child, IC_EVEX_L2_W_XS_KZ); 3640b57cec5SDimitry Andric case IC_EVEX_L2_XD_KZ: 36506c3fb27SDimitry Andric return WIG && inheritsFrom(child, IC_EVEX_L2_W_XD_KZ); 3660b57cec5SDimitry Andric case IC_EVEX_L2_OPSIZE_KZ: 36706c3fb27SDimitry Andric return WIG && inheritsFrom(child, IC_EVEX_L2_W_OPSIZE_KZ); 3680b57cec5SDimitry Andric case IC_EVEX_L2_W: 3690b57cec5SDimitry Andric case IC_EVEX_L2_W_XS: 3700b57cec5SDimitry Andric case IC_EVEX_L2_W_XD: 3710b57cec5SDimitry Andric case IC_EVEX_L2_W_OPSIZE: 3720b57cec5SDimitry Andric return false; 3730b57cec5SDimitry Andric case IC_EVEX_L2_W_K: 3740b57cec5SDimitry Andric case IC_EVEX_L2_W_XS_K: 3750b57cec5SDimitry Andric case IC_EVEX_L2_W_XD_K: 3760b57cec5SDimitry Andric case IC_EVEX_L2_W_OPSIZE_K: 3770b57cec5SDimitry Andric return false; 3780b57cec5SDimitry Andric case IC_EVEX_L2_W_KZ: 3790b57cec5SDimitry Andric case IC_EVEX_L2_W_XS_KZ: 3800b57cec5SDimitry Andric case IC_EVEX_L2_W_XD_KZ: 3810b57cec5SDimitry Andric case IC_EVEX_L2_W_OPSIZE_KZ: 3820b57cec5SDimitry Andric return false; 3830b57cec5SDimitry Andric case IC_EVEX_B: 38406c3fb27SDimitry Andric return (VEX_LIG && WIG && inheritsFrom(child, IC_EVEX_L_W_B)) || 38506c3fb27SDimitry Andric (VEX_LIG && WIG && inheritsFrom(child, IC_EVEX_L2_W_B)) || 38606c3fb27SDimitry Andric (WIG && inheritsFrom(child, IC_EVEX_W_B)) || 3870b57cec5SDimitry Andric (VEX_LIG && inheritsFrom(child, IC_EVEX_L_B)) || 3880b57cec5SDimitry Andric (VEX_LIG && inheritsFrom(child, IC_EVEX_L2_B)); 3890b57cec5SDimitry Andric case IC_EVEX_XS_B: 39006c3fb27SDimitry Andric return (VEX_LIG && WIG && inheritsFrom(child, IC_EVEX_L_W_XS_B)) || 39106c3fb27SDimitry Andric (VEX_LIG && WIG && inheritsFrom(child, IC_EVEX_L2_W_XS_B)) || 39206c3fb27SDimitry Andric (WIG && inheritsFrom(child, IC_EVEX_W_XS_B)) || 3930b57cec5SDimitry Andric (VEX_LIG && inheritsFrom(child, IC_EVEX_L_XS_B)) || 3940b57cec5SDimitry Andric (VEX_LIG && inheritsFrom(child, IC_EVEX_L2_XS_B)); 3950b57cec5SDimitry Andric case IC_EVEX_XD_B: 39606c3fb27SDimitry Andric return (VEX_LIG && WIG && inheritsFrom(child, IC_EVEX_L_W_XD_B)) || 39706c3fb27SDimitry Andric (VEX_LIG && WIG && inheritsFrom(child, IC_EVEX_L2_W_XD_B)) || 39806c3fb27SDimitry Andric (WIG && inheritsFrom(child, IC_EVEX_W_XD_B)) || 3990b57cec5SDimitry Andric (VEX_LIG && inheritsFrom(child, IC_EVEX_L_XD_B)) || 4000b57cec5SDimitry Andric (VEX_LIG && inheritsFrom(child, IC_EVEX_L2_XD_B)); 4010b57cec5SDimitry Andric case IC_EVEX_OPSIZE_B: 40206c3fb27SDimitry Andric return (VEX_LIG && WIG && inheritsFrom(child, IC_EVEX_L_W_OPSIZE_B)) || 40306c3fb27SDimitry Andric (VEX_LIG && WIG && inheritsFrom(child, IC_EVEX_L2_W_OPSIZE_B)) || 40406c3fb27SDimitry Andric (WIG && inheritsFrom(child, IC_EVEX_W_OPSIZE_B)) || 4050b57cec5SDimitry Andric (VEX_LIG && inheritsFrom(child, IC_EVEX_L_OPSIZE_B)) || 4060b57cec5SDimitry Andric (VEX_LIG && inheritsFrom(child, IC_EVEX_L2_OPSIZE_B)); 4070b57cec5SDimitry Andric case IC_EVEX_K_B: 40806c3fb27SDimitry Andric return (VEX_LIG && WIG && inheritsFrom(child, IC_EVEX_L_W_K_B)) || 40906c3fb27SDimitry Andric (VEX_LIG && WIG && inheritsFrom(child, IC_EVEX_L2_W_K_B)) || 41006c3fb27SDimitry Andric (WIG && inheritsFrom(child, IC_EVEX_W_K_B)) || 4110b57cec5SDimitry Andric (VEX_LIG && inheritsFrom(child, IC_EVEX_L_K_B)) || 4120b57cec5SDimitry Andric (VEX_LIG && inheritsFrom(child, IC_EVEX_L2_K_B)); 4130b57cec5SDimitry Andric case IC_EVEX_XS_K_B: 41406c3fb27SDimitry Andric return (VEX_LIG && WIG && inheritsFrom(child, IC_EVEX_L_W_XS_K_B)) || 41506c3fb27SDimitry Andric (VEX_LIG && WIG && inheritsFrom(child, IC_EVEX_L2_W_XS_K_B)) || 41606c3fb27SDimitry Andric (WIG && inheritsFrom(child, IC_EVEX_W_XS_K_B)) || 4170b57cec5SDimitry Andric (VEX_LIG && inheritsFrom(child, IC_EVEX_L_XS_K_B)) || 4180b57cec5SDimitry Andric (VEX_LIG && inheritsFrom(child, IC_EVEX_L2_XS_K_B)); 4190b57cec5SDimitry Andric case IC_EVEX_XD_K_B: 42006c3fb27SDimitry Andric return (VEX_LIG && WIG && inheritsFrom(child, IC_EVEX_L_W_XD_K_B)) || 42106c3fb27SDimitry Andric (VEX_LIG && WIG && inheritsFrom(child, IC_EVEX_L2_W_XD_K_B)) || 42206c3fb27SDimitry Andric (WIG && inheritsFrom(child, IC_EVEX_W_XD_K_B)) || 4230b57cec5SDimitry Andric (VEX_LIG && inheritsFrom(child, IC_EVEX_L_XD_K_B)) || 4240b57cec5SDimitry Andric (VEX_LIG && inheritsFrom(child, IC_EVEX_L2_XD_K_B)); 4250b57cec5SDimitry Andric case IC_EVEX_OPSIZE_K_B: 4265f757f3fSDimitry Andric return (VEX_LIG && WIG && inheritsFrom(child, IC_EVEX_L_W_OPSIZE_K_B)) || 4275f757f3fSDimitry Andric (VEX_LIG && WIG && inheritsFrom(child, IC_EVEX_L2_W_OPSIZE_K_B)) || 42806c3fb27SDimitry Andric (WIG && inheritsFrom(child, IC_EVEX_W_OPSIZE_K_B)) || 4290b57cec5SDimitry Andric (VEX_LIG && inheritsFrom(child, IC_EVEX_L_OPSIZE_K_B)) || 4300b57cec5SDimitry Andric (VEX_LIG && inheritsFrom(child, IC_EVEX_L2_OPSIZE_K_B)); 4310b57cec5SDimitry Andric case IC_EVEX_KZ_B: 43206c3fb27SDimitry Andric return (VEX_LIG && WIG && inheritsFrom(child, IC_EVEX_L_W_KZ_B)) || 43306c3fb27SDimitry Andric (VEX_LIG && WIG && inheritsFrom(child, IC_EVEX_L2_W_KZ_B)) || 43406c3fb27SDimitry Andric (WIG && inheritsFrom(child, IC_EVEX_W_KZ_B)) || 4350b57cec5SDimitry Andric (VEX_LIG && inheritsFrom(child, IC_EVEX_L_KZ_B)) || 4360b57cec5SDimitry Andric (VEX_LIG && inheritsFrom(child, IC_EVEX_L2_KZ_B)); 4370b57cec5SDimitry Andric case IC_EVEX_XS_KZ_B: 43806c3fb27SDimitry Andric return (VEX_LIG && WIG && inheritsFrom(child, IC_EVEX_L_W_XS_KZ_B)) || 43906c3fb27SDimitry Andric (VEX_LIG && WIG && inheritsFrom(child, IC_EVEX_L2_W_XS_KZ_B)) || 44006c3fb27SDimitry Andric (WIG && inheritsFrom(child, IC_EVEX_W_XS_KZ_B)) || 4410b57cec5SDimitry Andric (VEX_LIG && inheritsFrom(child, IC_EVEX_L_XS_KZ_B)) || 4420b57cec5SDimitry Andric (VEX_LIG && inheritsFrom(child, IC_EVEX_L2_XS_KZ_B)); 4430b57cec5SDimitry Andric case IC_EVEX_XD_KZ_B: 44406c3fb27SDimitry Andric return (VEX_LIG && WIG && inheritsFrom(child, IC_EVEX_L_W_XD_KZ_B)) || 44506c3fb27SDimitry Andric (VEX_LIG && WIG && inheritsFrom(child, IC_EVEX_L2_W_XD_KZ_B)) || 44606c3fb27SDimitry Andric (WIG && inheritsFrom(child, IC_EVEX_W_XD_KZ_B)) || 4470b57cec5SDimitry Andric (VEX_LIG && inheritsFrom(child, IC_EVEX_L_XD_KZ_B)) || 4480b57cec5SDimitry Andric (VEX_LIG && inheritsFrom(child, IC_EVEX_L2_XD_KZ_B)); 4490b57cec5SDimitry Andric case IC_EVEX_OPSIZE_KZ_B: 4505f757f3fSDimitry Andric return (VEX_LIG && WIG && inheritsFrom(child, IC_EVEX_L_W_OPSIZE_KZ_B)) || 4515f757f3fSDimitry Andric (VEX_LIG && WIG && inheritsFrom(child, IC_EVEX_L2_W_OPSIZE_KZ_B)) || 45206c3fb27SDimitry Andric (WIG && inheritsFrom(child, IC_EVEX_W_OPSIZE_KZ_B)) || 4530b57cec5SDimitry Andric (VEX_LIG && inheritsFrom(child, IC_EVEX_L_OPSIZE_KZ_B)) || 4540b57cec5SDimitry Andric (VEX_LIG && inheritsFrom(child, IC_EVEX_L2_OPSIZE_KZ_B)); 4550b57cec5SDimitry Andric case IC_EVEX_W_B: 4560b57cec5SDimitry Andric return (VEX_LIG && inheritsFrom(child, IC_EVEX_L_W_B)) || 4570b57cec5SDimitry Andric (VEX_LIG && inheritsFrom(child, IC_EVEX_L2_W_B)); 4580b57cec5SDimitry Andric case IC_EVEX_W_XS_B: 4590b57cec5SDimitry Andric return (VEX_LIG && inheritsFrom(child, IC_EVEX_L_W_XS_B)) || 4600b57cec5SDimitry Andric (VEX_LIG && inheritsFrom(child, IC_EVEX_L2_W_XS_B)); 4610b57cec5SDimitry Andric case IC_EVEX_W_XD_B: 4620b57cec5SDimitry Andric return (VEX_LIG && inheritsFrom(child, IC_EVEX_L_W_XD_B)) || 4630b57cec5SDimitry Andric (VEX_LIG && inheritsFrom(child, IC_EVEX_L2_W_XD_B)); 4640b57cec5SDimitry Andric case IC_EVEX_W_OPSIZE_B: 4650b57cec5SDimitry Andric return (VEX_LIG && inheritsFrom(child, IC_EVEX_L_W_OPSIZE_B)) || 4660b57cec5SDimitry Andric (VEX_LIG && inheritsFrom(child, IC_EVEX_L2_W_OPSIZE_B)); 4670b57cec5SDimitry Andric case IC_EVEX_W_K_B: 4680b57cec5SDimitry Andric return (VEX_LIG && inheritsFrom(child, IC_EVEX_L_W_K_B)) || 4690b57cec5SDimitry Andric (VEX_LIG && inheritsFrom(child, IC_EVEX_L2_W_K_B)); 4700b57cec5SDimitry Andric case IC_EVEX_W_XS_K_B: 4710b57cec5SDimitry Andric return (VEX_LIG && inheritsFrom(child, IC_EVEX_L_W_XS_K_B)) || 4720b57cec5SDimitry Andric (VEX_LIG && inheritsFrom(child, IC_EVEX_L2_W_XS_K_B)); 4730b57cec5SDimitry Andric case IC_EVEX_W_XD_K_B: 4740b57cec5SDimitry Andric return (VEX_LIG && inheritsFrom(child, IC_EVEX_L_W_XD_K_B)) || 4750b57cec5SDimitry Andric (VEX_LIG && inheritsFrom(child, IC_EVEX_L2_W_XD_K_B)); 4760b57cec5SDimitry Andric case IC_EVEX_W_OPSIZE_K_B: 4770b57cec5SDimitry Andric return (VEX_LIG && inheritsFrom(child, IC_EVEX_L_W_OPSIZE_K_B)) || 4780b57cec5SDimitry Andric (VEX_LIG && inheritsFrom(child, IC_EVEX_L2_W_OPSIZE_K_B)); 4790b57cec5SDimitry Andric case IC_EVEX_W_KZ_B: 4800b57cec5SDimitry Andric return (VEX_LIG && inheritsFrom(child, IC_EVEX_L_W_KZ_B)) || 4810b57cec5SDimitry Andric (VEX_LIG && inheritsFrom(child, IC_EVEX_L2_W_KZ_B)); 4820b57cec5SDimitry Andric case IC_EVEX_W_XS_KZ_B: 4830b57cec5SDimitry Andric return (VEX_LIG && inheritsFrom(child, IC_EVEX_L_W_XS_KZ_B)) || 4840b57cec5SDimitry Andric (VEX_LIG && inheritsFrom(child, IC_EVEX_L2_W_XS_KZ_B)); 4850b57cec5SDimitry Andric case IC_EVEX_W_XD_KZ_B: 4860b57cec5SDimitry Andric return (VEX_LIG && inheritsFrom(child, IC_EVEX_L_W_XD_KZ_B)) || 4870b57cec5SDimitry Andric (VEX_LIG && inheritsFrom(child, IC_EVEX_L2_W_XD_KZ_B)); 4880b57cec5SDimitry Andric case IC_EVEX_W_OPSIZE_KZ_B: 4890b57cec5SDimitry Andric return (VEX_LIG && inheritsFrom(child, IC_EVEX_L_W_OPSIZE_KZ_B)) || 4900b57cec5SDimitry Andric (VEX_LIG && inheritsFrom(child, IC_EVEX_L2_W_OPSIZE_KZ_B)); 4910b57cec5SDimitry Andric case IC_EVEX_L_B: 49206c3fb27SDimitry Andric return WIG && inheritsFrom(child, IC_EVEX_L_W_B); 4930b57cec5SDimitry Andric case IC_EVEX_L_XS_B: 49406c3fb27SDimitry Andric return WIG && inheritsFrom(child, IC_EVEX_L_W_XS_B); 4950b57cec5SDimitry Andric case IC_EVEX_L_XD_B: 49606c3fb27SDimitry Andric return WIG && inheritsFrom(child, IC_EVEX_L_W_XD_B); 4970b57cec5SDimitry Andric case IC_EVEX_L_OPSIZE_B: 49806c3fb27SDimitry Andric return WIG && inheritsFrom(child, IC_EVEX_L_W_OPSIZE_B); 4990b57cec5SDimitry Andric case IC_EVEX_L_K_B: 50006c3fb27SDimitry Andric return WIG && inheritsFrom(child, IC_EVEX_L_W_K_B); 5010b57cec5SDimitry Andric case IC_EVEX_L_XS_K_B: 50206c3fb27SDimitry Andric return WIG && inheritsFrom(child, IC_EVEX_L_W_XS_K_B); 5030b57cec5SDimitry Andric case IC_EVEX_L_XD_K_B: 50406c3fb27SDimitry Andric return WIG && inheritsFrom(child, IC_EVEX_L_W_XD_K_B); 5050b57cec5SDimitry Andric case IC_EVEX_L_OPSIZE_K_B: 50606c3fb27SDimitry Andric return WIG && inheritsFrom(child, IC_EVEX_L_W_OPSIZE_K_B); 5070b57cec5SDimitry Andric case IC_EVEX_L_KZ_B: 50806c3fb27SDimitry Andric return WIG && inheritsFrom(child, IC_EVEX_L_W_KZ_B); 5090b57cec5SDimitry Andric case IC_EVEX_L_XS_KZ_B: 51006c3fb27SDimitry Andric return WIG && inheritsFrom(child, IC_EVEX_L_W_XS_KZ_B); 5110b57cec5SDimitry Andric case IC_EVEX_L_XD_KZ_B: 51206c3fb27SDimitry Andric return WIG && inheritsFrom(child, IC_EVEX_L_W_XD_KZ_B); 5130b57cec5SDimitry Andric case IC_EVEX_L_OPSIZE_KZ_B: 51406c3fb27SDimitry Andric return WIG && inheritsFrom(child, IC_EVEX_L_W_OPSIZE_KZ_B); 5150b57cec5SDimitry Andric case IC_EVEX_L_W_B: 5160b57cec5SDimitry Andric case IC_EVEX_L_W_XS_B: 5170b57cec5SDimitry Andric case IC_EVEX_L_W_XD_B: 5180b57cec5SDimitry Andric case IC_EVEX_L_W_OPSIZE_B: 5190b57cec5SDimitry Andric return false; 5200b57cec5SDimitry Andric case IC_EVEX_L_W_K_B: 5210b57cec5SDimitry Andric case IC_EVEX_L_W_XS_K_B: 5220b57cec5SDimitry Andric case IC_EVEX_L_W_XD_K_B: 5230b57cec5SDimitry Andric case IC_EVEX_L_W_OPSIZE_K_B: 5240b57cec5SDimitry Andric return false; 5250b57cec5SDimitry Andric case IC_EVEX_L_W_KZ_B: 5260b57cec5SDimitry Andric case IC_EVEX_L_W_XS_KZ_B: 5270b57cec5SDimitry Andric case IC_EVEX_L_W_XD_KZ_B: 5280b57cec5SDimitry Andric case IC_EVEX_L_W_OPSIZE_KZ_B: 5290b57cec5SDimitry Andric return false; 5300b57cec5SDimitry Andric case IC_EVEX_L2_B: 53106c3fb27SDimitry Andric return WIG && inheritsFrom(child, IC_EVEX_L2_W_B); 5320b57cec5SDimitry Andric case IC_EVEX_L2_XS_B: 53306c3fb27SDimitry Andric return WIG && inheritsFrom(child, IC_EVEX_L2_W_XS_B); 5340b57cec5SDimitry Andric case IC_EVEX_L2_XD_B: 53506c3fb27SDimitry Andric return WIG && inheritsFrom(child, IC_EVEX_L2_W_XD_B); 5360b57cec5SDimitry Andric case IC_EVEX_L2_OPSIZE_B: 53706c3fb27SDimitry Andric return WIG && inheritsFrom(child, IC_EVEX_L2_W_OPSIZE_B); 5380b57cec5SDimitry Andric case IC_EVEX_L2_K_B: 53906c3fb27SDimitry Andric return WIG && inheritsFrom(child, IC_EVEX_L2_W_K_B); 5400b57cec5SDimitry Andric case IC_EVEX_L2_XS_K_B: 54106c3fb27SDimitry Andric return WIG && inheritsFrom(child, IC_EVEX_L2_W_XS_K_B); 5420b57cec5SDimitry Andric case IC_EVEX_L2_XD_K_B: 54306c3fb27SDimitry Andric return WIG && inheritsFrom(child, IC_EVEX_L2_W_XD_K_B); 5440b57cec5SDimitry Andric case IC_EVEX_L2_OPSIZE_K_B: 54506c3fb27SDimitry Andric return WIG && inheritsFrom(child, IC_EVEX_L2_W_OPSIZE_K_B); 5460b57cec5SDimitry Andric case IC_EVEX_L2_KZ_B: 54706c3fb27SDimitry Andric return WIG && inheritsFrom(child, IC_EVEX_L2_W_KZ_B); 5480b57cec5SDimitry Andric case IC_EVEX_L2_XS_KZ_B: 54906c3fb27SDimitry Andric return WIG && inheritsFrom(child, IC_EVEX_L2_W_XS_KZ_B); 5500b57cec5SDimitry Andric case IC_EVEX_L2_XD_KZ_B: 55106c3fb27SDimitry Andric return WIG && inheritsFrom(child, IC_EVEX_L2_W_XD_KZ_B); 5520b57cec5SDimitry Andric case IC_EVEX_L2_OPSIZE_KZ_B: 55306c3fb27SDimitry Andric return WIG && inheritsFrom(child, IC_EVEX_L2_W_OPSIZE_KZ_B); 5540b57cec5SDimitry Andric case IC_EVEX_L2_W_B: 5550b57cec5SDimitry Andric case IC_EVEX_L2_W_XS_B: 5560b57cec5SDimitry Andric case IC_EVEX_L2_W_XD_B: 5570b57cec5SDimitry Andric case IC_EVEX_L2_W_OPSIZE_B: 5580b57cec5SDimitry Andric return false; 5590b57cec5SDimitry Andric case IC_EVEX_L2_W_K_B: 5600b57cec5SDimitry Andric case IC_EVEX_L2_W_XS_K_B: 5610b57cec5SDimitry Andric case IC_EVEX_L2_W_XD_K_B: 5620b57cec5SDimitry Andric case IC_EVEX_L2_W_OPSIZE_K_B: 5630b57cec5SDimitry Andric return false; 5640b57cec5SDimitry Andric case IC_EVEX_L2_W_KZ_B: 5650b57cec5SDimitry Andric case IC_EVEX_L2_W_XS_KZ_B: 5660b57cec5SDimitry Andric case IC_EVEX_L2_W_XD_KZ_B: 5670b57cec5SDimitry Andric case IC_EVEX_L2_W_OPSIZE_KZ_B: 5680b57cec5SDimitry Andric return false; 569647cbc5dSDimitry Andric case IC_EVEX_NF: 570*0fca6ea1SDimitry Andric return WIG && inheritsFrom(child, IC_EVEX_W_NF); 571647cbc5dSDimitry Andric case IC_EVEX_B_NF: 572*0fca6ea1SDimitry Andric return WIG && inheritsFrom(child, IC_EVEX_W_B_NF); 573647cbc5dSDimitry Andric case IC_EVEX_OPSIZE_NF: 574647cbc5dSDimitry Andric case IC_EVEX_OPSIZE_B_NF: 575647cbc5dSDimitry Andric case IC_EVEX_W_NF: 576647cbc5dSDimitry Andric case IC_EVEX_W_B_NF: 577647cbc5dSDimitry Andric return false; 5780b57cec5SDimitry Andric default: 5795f757f3fSDimitry Andric errs() << "Unknown instruction class: " 5805f757f3fSDimitry Andric << stringForContext((InstructionContext)parent) << "\n"; 5810b57cec5SDimitry Andric llvm_unreachable("Unknown instruction class"); 5820b57cec5SDimitry Andric } 5830b57cec5SDimitry Andric } 5840b57cec5SDimitry Andric 5850b57cec5SDimitry Andric /// outranks - Indicates whether, if an instruction has two different applicable 5860b57cec5SDimitry Andric /// classes, which class should be preferred when performing decode. This 5870b57cec5SDimitry Andric /// imposes a total ordering (ties are resolved toward "lower") 5880b57cec5SDimitry Andric /// 5890b57cec5SDimitry Andric /// @param upper - The class that may be preferable 5900b57cec5SDimitry Andric /// @param lower - The class that may be less preferable 5910b57cec5SDimitry Andric /// @return - True if upper is to be preferred, false otherwise. 5920b57cec5SDimitry Andric static inline bool outranks(InstructionContext upper, 5930b57cec5SDimitry Andric InstructionContext lower) { 5940b57cec5SDimitry Andric assert(upper < IC_max); 5950b57cec5SDimitry Andric assert(lower < IC_max); 5960b57cec5SDimitry Andric 5970b57cec5SDimitry Andric #define ENUM_ENTRY(n, r, d) r, 5985f757f3fSDimitry Andric #define ENUM_ENTRY_K_B(n, r, d) \ 5995f757f3fSDimitry Andric ENUM_ENTRY(n, r, d) \ 6005f757f3fSDimitry Andric ENUM_ENTRY(n##_K_B, r, d) \ 601*0fca6ea1SDimitry Andric ENUM_ENTRY(n##_KZ_B, r, d) \ 602*0fca6ea1SDimitry Andric ENUM_ENTRY(n##_KZ, r, d) ENUM_ENTRY(n##_K, r, d) ENUM_ENTRY(n##_B, r, d) 6035f757f3fSDimitry Andric static int ranks[IC_max] = {INSTRUCTION_CONTEXTS}; 6040b57cec5SDimitry Andric #undef ENUM_ENTRY 6050b57cec5SDimitry Andric #undef ENUM_ENTRY_K_B 6060b57cec5SDimitry Andric 6070b57cec5SDimitry Andric return (ranks[upper] > ranks[lower]); 6080b57cec5SDimitry Andric } 6090b57cec5SDimitry Andric 6100b57cec5SDimitry Andric /// getDecisionType - Determines whether a ModRM decision with 255 entries can 6110b57cec5SDimitry Andric /// be compacted by eliminating redundant information. 6120b57cec5SDimitry Andric /// 6130b57cec5SDimitry Andric /// @param decision - The decision to be compacted. 6140b57cec5SDimitry Andric /// @return - The compactest available representation for the decision. 6150b57cec5SDimitry Andric static ModRMDecisionType getDecisionType(ModRMDecision &decision) { 6160b57cec5SDimitry Andric bool satisfiesOneEntry = true; 6170b57cec5SDimitry Andric bool satisfiesSplitRM = true; 6180b57cec5SDimitry Andric bool satisfiesSplitReg = true; 6190b57cec5SDimitry Andric bool satisfiesSplitMisc = true; 6200b57cec5SDimitry Andric 6210b57cec5SDimitry Andric for (unsigned index = 0; index < 256; ++index) { 6220b57cec5SDimitry Andric if (decision.instructionIDs[index] != decision.instructionIDs[0]) 6230b57cec5SDimitry Andric satisfiesOneEntry = false; 6240b57cec5SDimitry Andric 6250b57cec5SDimitry Andric if (((index & 0xc0) == 0xc0) && 6260b57cec5SDimitry Andric (decision.instructionIDs[index] != decision.instructionIDs[0xc0])) 6270b57cec5SDimitry Andric satisfiesSplitRM = false; 6280b57cec5SDimitry Andric 6290b57cec5SDimitry Andric if (((index & 0xc0) != 0xc0) && 6300b57cec5SDimitry Andric (decision.instructionIDs[index] != decision.instructionIDs[0x00])) 6310b57cec5SDimitry Andric satisfiesSplitRM = false; 6320b57cec5SDimitry Andric 6335f757f3fSDimitry Andric if (((index & 0xc0) == 0xc0) && (decision.instructionIDs[index] != 6345f757f3fSDimitry Andric decision.instructionIDs[index & 0xf8])) 6350b57cec5SDimitry Andric satisfiesSplitReg = false; 6360b57cec5SDimitry Andric 6375f757f3fSDimitry Andric if (((index & 0xc0) != 0xc0) && (decision.instructionIDs[index] != 6385f757f3fSDimitry Andric decision.instructionIDs[index & 0x38])) 6390b57cec5SDimitry Andric satisfiesSplitMisc = false; 6400b57cec5SDimitry Andric } 6410b57cec5SDimitry Andric 6420b57cec5SDimitry Andric if (satisfiesOneEntry) 6430b57cec5SDimitry Andric return MODRM_ONEENTRY; 6440b57cec5SDimitry Andric 6450b57cec5SDimitry Andric if (satisfiesSplitRM) 6460b57cec5SDimitry Andric return MODRM_SPLITRM; 6470b57cec5SDimitry Andric 6480b57cec5SDimitry Andric if (satisfiesSplitReg && satisfiesSplitMisc) 6490b57cec5SDimitry Andric return MODRM_SPLITREG; 6500b57cec5SDimitry Andric 6510b57cec5SDimitry Andric if (satisfiesSplitMisc) 6520b57cec5SDimitry Andric return MODRM_SPLITMISC; 6530b57cec5SDimitry Andric 6540b57cec5SDimitry Andric return MODRM_FULL; 6550b57cec5SDimitry Andric } 6560b57cec5SDimitry Andric 6570b57cec5SDimitry Andric /// stringForDecisionType - Returns a statically-allocated string corresponding 6580b57cec5SDimitry Andric /// to a particular decision type. 6590b57cec5SDimitry Andric /// 6600b57cec5SDimitry Andric /// @param dt - The decision type. 6610b57cec5SDimitry Andric /// @return - A pointer to the statically-allocated string (e.g., 6620b57cec5SDimitry Andric /// "MODRM_ONEENTRY" for MODRM_ONEENTRY). 6630b57cec5SDimitry Andric static const char *stringForDecisionType(ModRMDecisionType dt) { 6645f757f3fSDimitry Andric #define ENUM_ENTRY(n) \ 6655f757f3fSDimitry Andric case n: \ 6665f757f3fSDimitry Andric return #n; 6670b57cec5SDimitry Andric switch (dt) { 6680b57cec5SDimitry Andric default: 6690b57cec5SDimitry Andric llvm_unreachable("Unknown decision type"); 6700b57cec5SDimitry Andric MODRMTYPES 6710b57cec5SDimitry Andric }; 6720b57cec5SDimitry Andric #undef ENUM_ENTRY 6730b57cec5SDimitry Andric } 6740b57cec5SDimitry Andric 6750b57cec5SDimitry Andric DisassemblerTables::DisassemblerTables() { 676bdd1243dSDimitry Andric for (unsigned i = 0; i < std::size(Tables); i++) 6778bcb0991SDimitry Andric Tables[i] = std::make_unique<ContextDecision>(); 6780b57cec5SDimitry Andric 6790b57cec5SDimitry Andric HasConflicts = false; 6800b57cec5SDimitry Andric } 6810b57cec5SDimitry Andric 6825f757f3fSDimitry Andric DisassemblerTables::~DisassemblerTables() {} 6830b57cec5SDimitry Andric 6840b57cec5SDimitry Andric void DisassemblerTables::emitModRMDecision(raw_ostream &o1, raw_ostream &o2, 6850b57cec5SDimitry Andric unsigned &i1, unsigned &i2, 6860b57cec5SDimitry Andric unsigned &ModRMTableNum, 6870b57cec5SDimitry Andric ModRMDecision &decision) const { 6880b57cec5SDimitry Andric static uint32_t sEntryNumber = 1; 6890b57cec5SDimitry Andric ModRMDecisionType dt = getDecisionType(decision); 6900b57cec5SDimitry Andric 691480093f4SDimitry Andric if (dt == MODRM_ONEENTRY && decision.instructionIDs[0] == 0) { 692480093f4SDimitry Andric // Empty table. 693480093f4SDimitry Andric o2 << "{" << stringForDecisionType(dt) << ", 0}"; 6940b57cec5SDimitry Andric return; 6950b57cec5SDimitry Andric } 6960b57cec5SDimitry Andric 6970b57cec5SDimitry Andric std::vector<unsigned> ModRMDecision; 6980b57cec5SDimitry Andric 6990b57cec5SDimitry Andric switch (dt) { 7000b57cec5SDimitry Andric default: 7010b57cec5SDimitry Andric llvm_unreachable("Unknown decision type"); 7020b57cec5SDimitry Andric case MODRM_ONEENTRY: 7030b57cec5SDimitry Andric ModRMDecision.push_back(decision.instructionIDs[0]); 7040b57cec5SDimitry Andric break; 7050b57cec5SDimitry Andric case MODRM_SPLITRM: 7060b57cec5SDimitry Andric ModRMDecision.push_back(decision.instructionIDs[0x00]); 7070b57cec5SDimitry Andric ModRMDecision.push_back(decision.instructionIDs[0xc0]); 7080b57cec5SDimitry Andric break; 7090b57cec5SDimitry Andric case MODRM_SPLITREG: 7100b57cec5SDimitry Andric for (unsigned index = 0; index < 64; index += 8) 7110b57cec5SDimitry Andric ModRMDecision.push_back(decision.instructionIDs[index]); 7120b57cec5SDimitry Andric for (unsigned index = 0xc0; index < 256; index += 8) 7130b57cec5SDimitry Andric ModRMDecision.push_back(decision.instructionIDs[index]); 7140b57cec5SDimitry Andric break; 7150b57cec5SDimitry Andric case MODRM_SPLITMISC: 7160b57cec5SDimitry Andric for (unsigned index = 0; index < 64; index += 8) 7170b57cec5SDimitry Andric ModRMDecision.push_back(decision.instructionIDs[index]); 7180b57cec5SDimitry Andric for (unsigned index = 0xc0; index < 256; ++index) 7190b57cec5SDimitry Andric ModRMDecision.push_back(decision.instructionIDs[index]); 7200b57cec5SDimitry Andric break; 7210b57cec5SDimitry Andric case MODRM_FULL: 722fe6060f1SDimitry Andric for (unsigned short InstructionID : decision.instructionIDs) 723fe6060f1SDimitry Andric ModRMDecision.push_back(InstructionID); 7240b57cec5SDimitry Andric break; 7250b57cec5SDimitry Andric } 7260b57cec5SDimitry Andric 7270b57cec5SDimitry Andric unsigned &EntryNumber = ModRMTable[ModRMDecision]; 7280b57cec5SDimitry Andric if (EntryNumber == 0) { 7290b57cec5SDimitry Andric EntryNumber = ModRMTableNum; 7300b57cec5SDimitry Andric 7310b57cec5SDimitry Andric ModRMTableNum += ModRMDecision.size(); 7320b57cec5SDimitry Andric o1 << "/*Table" << EntryNumber << "*/\n"; 7330b57cec5SDimitry Andric i1++; 734fe6060f1SDimitry Andric for (unsigned I : ModRMDecision) { 735fe6060f1SDimitry Andric o1.indent(i1 * 2) << format("0x%hx", I) << ", /*" 736fe6060f1SDimitry Andric << InstructionSpecifiers[I].name << "*/\n"; 7370b57cec5SDimitry Andric } 7380b57cec5SDimitry Andric i1--; 7390b57cec5SDimitry Andric } 7400b57cec5SDimitry Andric 7415ffd83dbSDimitry Andric o2 << "{" << stringForDecisionType(dt) << ", " << EntryNumber << "}"; 7420b57cec5SDimitry Andric 7430b57cec5SDimitry Andric switch (dt) { 7440b57cec5SDimitry Andric default: 7450b57cec5SDimitry Andric llvm_unreachable("Unknown decision type"); 7460b57cec5SDimitry Andric case MODRM_ONEENTRY: 7470b57cec5SDimitry Andric sEntryNumber += 1; 7480b57cec5SDimitry Andric break; 7490b57cec5SDimitry Andric case MODRM_SPLITRM: 7500b57cec5SDimitry Andric sEntryNumber += 2; 7510b57cec5SDimitry Andric break; 7520b57cec5SDimitry Andric case MODRM_SPLITREG: 7530b57cec5SDimitry Andric sEntryNumber += 16; 7540b57cec5SDimitry Andric break; 7550b57cec5SDimitry Andric case MODRM_SPLITMISC: 7560b57cec5SDimitry Andric sEntryNumber += 8 + 64; 7570b57cec5SDimitry Andric break; 7580b57cec5SDimitry Andric case MODRM_FULL: 7590b57cec5SDimitry Andric sEntryNumber += 256; 7600b57cec5SDimitry Andric break; 7610b57cec5SDimitry Andric } 7620b57cec5SDimitry Andric 7630b57cec5SDimitry Andric // We assume that the index can fit into uint16_t. 7640b57cec5SDimitry Andric assert(sEntryNumber < 65536U && 7650b57cec5SDimitry Andric "Index into ModRMDecision is too large for uint16_t!"); 766fe6060f1SDimitry Andric (void)sEntryNumber; 7670b57cec5SDimitry Andric } 7680b57cec5SDimitry Andric 7690b57cec5SDimitry Andric void DisassemblerTables::emitOpcodeDecision(raw_ostream &o1, raw_ostream &o2, 7700b57cec5SDimitry Andric unsigned &i1, unsigned &i2, 7710b57cec5SDimitry Andric unsigned &ModRMTableNum, 772480093f4SDimitry Andric OpcodeDecision &opDecision) const { 773480093f4SDimitry Andric o2 << "{"; 774480093f4SDimitry Andric ++i2; 7750b57cec5SDimitry Andric 776480093f4SDimitry Andric unsigned index; 777480093f4SDimitry Andric for (index = 0; index < 256; ++index) { 778480093f4SDimitry Andric auto &decision = opDecision.modRMDecisions[index]; 779480093f4SDimitry Andric ModRMDecisionType dt = getDecisionType(decision); 780480093f4SDimitry Andric if (!(dt == MODRM_ONEENTRY && decision.instructionIDs[0] == 0)) 781480093f4SDimitry Andric break; 782480093f4SDimitry Andric } 783480093f4SDimitry Andric if (index == 256) { 784480093f4SDimitry Andric // If all 256 entries are MODRM_ONEENTRY, omit output. 785bdd1243dSDimitry Andric static_assert(MODRM_ONEENTRY == 0); 786480093f4SDimitry Andric --i2; 787480093f4SDimitry Andric o2 << "},\n"; 788480093f4SDimitry Andric } else { 789480093f4SDimitry Andric o2 << " /* struct OpcodeDecision */ {\n"; 790480093f4SDimitry Andric for (index = 0; index < 256; ++index) { 7910b57cec5SDimitry Andric o2.indent(i2); 7920b57cec5SDimitry Andric 793480093f4SDimitry Andric o2 << "/*0x" << format("%02hhx", index) << "*/"; 7940b57cec5SDimitry Andric 7950b57cec5SDimitry Andric emitModRMDecision(o1, o2, i1, i2, ModRMTableNum, 796480093f4SDimitry Andric opDecision.modRMDecisions[index]); 7970b57cec5SDimitry Andric 7980b57cec5SDimitry Andric if (index < 255) 7990b57cec5SDimitry Andric o2 << ","; 8000b57cec5SDimitry Andric 8010b57cec5SDimitry Andric o2 << "\n"; 8020b57cec5SDimitry Andric } 803480093f4SDimitry Andric o2.indent(i2) << "}\n"; 804480093f4SDimitry Andric --i2; 805480093f4SDimitry Andric o2.indent(i2) << "},\n"; 806480093f4SDimitry Andric } 8070b57cec5SDimitry Andric } 8080b57cec5SDimitry Andric 8090b57cec5SDimitry Andric void DisassemblerTables::emitContextDecision(raw_ostream &o1, raw_ostream &o2, 8100b57cec5SDimitry Andric unsigned &i1, unsigned &i2, 8110b57cec5SDimitry Andric unsigned &ModRMTableNum, 8120b57cec5SDimitry Andric ContextDecision &decision, 8130b57cec5SDimitry Andric const char *name) const { 8145f757f3fSDimitry Andric o2.indent(i2) << "static const struct ContextDecision " << name 8155f757f3fSDimitry Andric << " = {{/* opcodeDecisions */\n"; 8160b57cec5SDimitry Andric i2++; 8170b57cec5SDimitry Andric 8180b57cec5SDimitry Andric for (unsigned index = 0; index < IC_max; ++index) { 8190b57cec5SDimitry Andric o2.indent(i2) << "/*"; 8200b57cec5SDimitry Andric o2 << stringForContext((InstructionContext)index); 8210b57cec5SDimitry Andric o2 << "*/ "; 8220b57cec5SDimitry Andric 8230b57cec5SDimitry Andric emitOpcodeDecision(o1, o2, i1, i2, ModRMTableNum, 8240b57cec5SDimitry Andric decision.opcodeDecisions[index]); 8250b57cec5SDimitry Andric } 8260b57cec5SDimitry Andric 8270b57cec5SDimitry Andric i2--; 828*0fca6ea1SDimitry Andric o2.indent(i2) << "}};" 829*0fca6ea1SDimitry Andric << "\n"; 8300b57cec5SDimitry Andric } 8310b57cec5SDimitry Andric 8320b57cec5SDimitry Andric void DisassemblerTables::emitInstructionInfo(raw_ostream &o, 8330b57cec5SDimitry Andric unsigned &i) const { 8340b57cec5SDimitry Andric unsigned NumInstructions = InstructionSpecifiers.size(); 8350b57cec5SDimitry Andric 8360b57cec5SDimitry Andric o << "static const struct OperandSpecifier x86OperandSets[][" 8370b57cec5SDimitry Andric << X86_MAX_OPERANDS << "] = {\n"; 8380b57cec5SDimitry Andric 8395f757f3fSDimitry Andric typedef SmallVector<std::pair<OperandEncoding, OperandType>, X86_MAX_OPERANDS> 8405f757f3fSDimitry Andric OperandListTy; 8410b57cec5SDimitry Andric std::map<OperandListTy, unsigned> OperandSets; 8420b57cec5SDimitry Andric 8430b57cec5SDimitry Andric unsigned OperandSetNum = 0; 8440b57cec5SDimitry Andric for (unsigned Index = 0; Index < NumInstructions; ++Index) { 8450b57cec5SDimitry Andric OperandListTy OperandList; 8460b57cec5SDimitry Andric 847fe6060f1SDimitry Andric for (auto Operand : InstructionSpecifiers[Index].operands) { 848fe6060f1SDimitry Andric OperandEncoding Encoding = (OperandEncoding)Operand.encoding; 849fe6060f1SDimitry Andric OperandType Type = (OperandType)Operand.type; 850*0fca6ea1SDimitry Andric OperandList.push_back(std::pair(Encoding, Type)); 8510b57cec5SDimitry Andric } 8520b57cec5SDimitry Andric unsigned &N = OperandSets[OperandList]; 8535f757f3fSDimitry Andric if (N != 0) 8545f757f3fSDimitry Andric continue; 8550b57cec5SDimitry Andric 8560b57cec5SDimitry Andric N = ++OperandSetNum; 8570b57cec5SDimitry Andric 8580b57cec5SDimitry Andric o << " { /* " << (OperandSetNum - 1) << " */\n"; 8590b57cec5SDimitry Andric for (unsigned i = 0, e = OperandList.size(); i != e; ++i) { 8600b57cec5SDimitry Andric const char *Encoding = stringForOperandEncoding(OperandList[i].first); 8610b57cec5SDimitry Andric const char *Type = stringForOperandType(OperandList[i].second); 8620b57cec5SDimitry Andric o << " { " << Encoding << ", " << Type << " },\n"; 8630b57cec5SDimitry Andric } 8640b57cec5SDimitry Andric o << " },\n"; 8650b57cec5SDimitry Andric } 866*0fca6ea1SDimitry Andric o << "};" 867*0fca6ea1SDimitry Andric << "\n\n"; 8680b57cec5SDimitry Andric 8690b57cec5SDimitry Andric o.indent(i * 2) << "static const struct InstructionSpecifier "; 8700b57cec5SDimitry Andric o << INSTRUCTIONS_STR "[" << InstructionSpecifiers.size() << "] = {\n"; 8710b57cec5SDimitry Andric 8720b57cec5SDimitry Andric i++; 8730b57cec5SDimitry Andric 8740b57cec5SDimitry Andric for (unsigned index = 0; index < NumInstructions; ++index) { 8750b57cec5SDimitry Andric o.indent(i * 2) << "{ /* " << index << " */\n"; 8760b57cec5SDimitry Andric i++; 8770b57cec5SDimitry Andric 8780b57cec5SDimitry Andric OperandListTy OperandList; 879fe6060f1SDimitry Andric for (auto Operand : InstructionSpecifiers[index].operands) { 880fe6060f1SDimitry Andric OperandEncoding Encoding = (OperandEncoding)Operand.encoding; 881fe6060f1SDimitry Andric OperandType Type = (OperandType)Operand.type; 882*0fca6ea1SDimitry Andric OperandList.push_back(std::pair(Encoding, Type)); 8830b57cec5SDimitry Andric } 8840b57cec5SDimitry Andric o.indent(i * 2) << (OperandSets[OperandList] - 1) << ",\n"; 8850b57cec5SDimitry Andric 8860b57cec5SDimitry Andric o.indent(i * 2) << "/* " << InstructionSpecifiers[index].name << " */\n"; 8870b57cec5SDimitry Andric 8880b57cec5SDimitry Andric i--; 8890b57cec5SDimitry Andric o.indent(i * 2) << "},\n"; 8900b57cec5SDimitry Andric } 8910b57cec5SDimitry Andric 8920b57cec5SDimitry Andric i--; 893*0fca6ea1SDimitry Andric o.indent(i * 2) << "};" 894*0fca6ea1SDimitry Andric << "\n"; 8950b57cec5SDimitry Andric } 8960b57cec5SDimitry Andric 8970b57cec5SDimitry Andric void DisassemblerTables::emitContextTable(raw_ostream &o, unsigned &i) const { 8985f757f3fSDimitry Andric o.indent(i * 2) << "static const uint8_t " CONTEXTS_STR "[" << ATTR_max 8995f757f3fSDimitry Andric << "] = {\n"; 9000b57cec5SDimitry Andric i++; 9010b57cec5SDimitry Andric 9020b57cec5SDimitry Andric for (unsigned index = 0; index < ATTR_max; ++index) { 9030b57cec5SDimitry Andric o.indent(i * 2); 9040b57cec5SDimitry Andric 905*0fca6ea1SDimitry Andric if ((index & ATTR_EVEX) && (index & ATTR_ADSIZE) && (index & ATTR_OPSIZE)) 9065f757f3fSDimitry Andric o << "IC_EVEX_OPSIZE_ADSIZE"; 907*0fca6ea1SDimitry Andric else if ((index & ATTR_EVEX) && (index & ATTR_ADSIZE) && (index & ATTR_XD)) 908*0fca6ea1SDimitry Andric o << "IC_EVEX_XD_ADSIZE"; 909*0fca6ea1SDimitry Andric else if ((index & ATTR_EVEX) && (index & ATTR_ADSIZE) && (index & ATTR_XS)) 910*0fca6ea1SDimitry Andric o << "IC_EVEX_XS_ADSIZE"; 911647cbc5dSDimitry Andric else if (index & ATTR_EVEXNF) { 912647cbc5dSDimitry Andric o << "IC_EVEX"; 913647cbc5dSDimitry Andric if (index & ATTR_REXW) 914647cbc5dSDimitry Andric o << "_W"; 915647cbc5dSDimitry Andric else if (index & ATTR_OPSIZE) 916647cbc5dSDimitry Andric o << "_OPSIZE"; 917647cbc5dSDimitry Andric 918647cbc5dSDimitry Andric if (index & ATTR_EVEXB) 919647cbc5dSDimitry Andric o << "_B"; 920647cbc5dSDimitry Andric 921647cbc5dSDimitry Andric o << "_NF"; 922647cbc5dSDimitry Andric } else if ((index & ATTR_EVEX) || (index & ATTR_VEX) || 923647cbc5dSDimitry Andric (index & ATTR_VEXL)) { 9240b57cec5SDimitry Andric if (index & ATTR_EVEX) 9250b57cec5SDimitry Andric o << "IC_EVEX"; 9260b57cec5SDimitry Andric else 9270b57cec5SDimitry Andric o << "IC_VEX"; 9280b57cec5SDimitry Andric 9290b57cec5SDimitry Andric if ((index & ATTR_EVEX) && (index & ATTR_EVEXL2)) 9300b57cec5SDimitry Andric o << "_L2"; 9310b57cec5SDimitry Andric else if (index & ATTR_VEXL) 9320b57cec5SDimitry Andric o << "_L"; 9330b57cec5SDimitry Andric 9340b57cec5SDimitry Andric if (index & ATTR_REXW) 9350b57cec5SDimitry Andric o << "_W"; 9360b57cec5SDimitry Andric 93781ad6265SDimitry Andric if (index & ATTR_OPSIZE) 9380b57cec5SDimitry Andric o << "_OPSIZE"; 93981ad6265SDimitry Andric else if (index & ATTR_XD) 9400b57cec5SDimitry Andric o << "_XD"; 9410b57cec5SDimitry Andric else if (index & ATTR_XS) 9420b57cec5SDimitry Andric o << "_XS"; 9430b57cec5SDimitry Andric 9445f757f3fSDimitry Andric if (index & ATTR_EVEX) { 9450b57cec5SDimitry Andric if (index & ATTR_EVEXKZ) 9460b57cec5SDimitry Andric o << "_KZ"; 9470b57cec5SDimitry Andric else if (index & ATTR_EVEXK) 9480b57cec5SDimitry Andric o << "_K"; 9490b57cec5SDimitry Andric 9500b57cec5SDimitry Andric if (index & ATTR_EVEXB) 9510b57cec5SDimitry Andric o << "_B"; 9520b57cec5SDimitry Andric } 9535f757f3fSDimitry Andric } else if ((index & ATTR_64BIT) && (index & ATTR_REX2)) 9545f757f3fSDimitry Andric o << "IC_64BIT_REX2"; 95581ad6265SDimitry Andric else if ((index & ATTR_64BIT) && (index & ATTR_REXW) && (index & ATTR_XS)) 9560b57cec5SDimitry Andric o << "IC_64BIT_REXW_XS"; 9570b57cec5SDimitry Andric else if ((index & ATTR_64BIT) && (index & ATTR_REXW) && (index & ATTR_XD)) 9580b57cec5SDimitry Andric o << "IC_64BIT_REXW_XD"; 9590b57cec5SDimitry Andric else if ((index & ATTR_64BIT) && (index & ATTR_REXW) && 9600b57cec5SDimitry Andric (index & ATTR_OPSIZE)) 9610b57cec5SDimitry Andric o << "IC_64BIT_REXW_OPSIZE"; 9620b57cec5SDimitry Andric else if ((index & ATTR_64BIT) && (index & ATTR_REXW) && 9630b57cec5SDimitry Andric (index & ATTR_ADSIZE)) 9640b57cec5SDimitry Andric o << "IC_64BIT_REXW_ADSIZE"; 9650b57cec5SDimitry Andric else if ((index & ATTR_64BIT) && (index & ATTR_XD) && (index & ATTR_OPSIZE)) 9660b57cec5SDimitry Andric o << "IC_64BIT_XD_OPSIZE"; 9670b57cec5SDimitry Andric else if ((index & ATTR_64BIT) && (index & ATTR_XD) && (index & ATTR_ADSIZE)) 9680b57cec5SDimitry Andric o << "IC_64BIT_XD_ADSIZE"; 9690b57cec5SDimitry Andric else if ((index & ATTR_64BIT) && (index & ATTR_XS) && (index & ATTR_OPSIZE)) 9700b57cec5SDimitry Andric o << "IC_64BIT_XS_OPSIZE"; 9710b57cec5SDimitry Andric else if ((index & ATTR_64BIT) && (index & ATTR_XS) && (index & ATTR_ADSIZE)) 9720b57cec5SDimitry Andric o << "IC_64BIT_XS_ADSIZE"; 9730b57cec5SDimitry Andric else if ((index & ATTR_64BIT) && (index & ATTR_XS)) 9740b57cec5SDimitry Andric o << "IC_64BIT_XS"; 9750b57cec5SDimitry Andric else if ((index & ATTR_64BIT) && (index & ATTR_XD)) 9760b57cec5SDimitry Andric o << "IC_64BIT_XD"; 9770b57cec5SDimitry Andric else if ((index & ATTR_64BIT) && (index & ATTR_OPSIZE) && 9780b57cec5SDimitry Andric (index & ATTR_ADSIZE)) 9790b57cec5SDimitry Andric o << "IC_64BIT_OPSIZE_ADSIZE"; 9800b57cec5SDimitry Andric else if ((index & ATTR_64BIT) && (index & ATTR_OPSIZE)) 9810b57cec5SDimitry Andric o << "IC_64BIT_OPSIZE"; 9820b57cec5SDimitry Andric else if ((index & ATTR_64BIT) && (index & ATTR_ADSIZE)) 9830b57cec5SDimitry Andric o << "IC_64BIT_ADSIZE"; 9840b57cec5SDimitry Andric else if ((index & ATTR_64BIT) && (index & ATTR_REXW)) 9850b57cec5SDimitry Andric o << "IC_64BIT_REXW"; 9860b57cec5SDimitry Andric else if ((index & ATTR_64BIT)) 9870b57cec5SDimitry Andric o << "IC_64BIT"; 9880b57cec5SDimitry Andric else if ((index & ATTR_XS) && (index & ATTR_OPSIZE)) 9890b57cec5SDimitry Andric o << "IC_XS_OPSIZE"; 9900b57cec5SDimitry Andric else if ((index & ATTR_XD) && (index & ATTR_OPSIZE)) 9910b57cec5SDimitry Andric o << "IC_XD_OPSIZE"; 9920b57cec5SDimitry Andric else if ((index & ATTR_XS) && (index & ATTR_ADSIZE)) 9930b57cec5SDimitry Andric o << "IC_XS_ADSIZE"; 9940b57cec5SDimitry Andric else if ((index & ATTR_XD) && (index & ATTR_ADSIZE)) 9950b57cec5SDimitry Andric o << "IC_XD_ADSIZE"; 9960b57cec5SDimitry Andric else if (index & ATTR_XS) 9970b57cec5SDimitry Andric o << "IC_XS"; 9980b57cec5SDimitry Andric else if (index & ATTR_XD) 9990b57cec5SDimitry Andric o << "IC_XD"; 10000b57cec5SDimitry Andric else if ((index & ATTR_OPSIZE) && (index & ATTR_ADSIZE)) 10010b57cec5SDimitry Andric o << "IC_OPSIZE_ADSIZE"; 10020b57cec5SDimitry Andric else if (index & ATTR_OPSIZE) 10030b57cec5SDimitry Andric o << "IC_OPSIZE"; 10040b57cec5SDimitry Andric else if (index & ATTR_ADSIZE) 10050b57cec5SDimitry Andric o << "IC_ADSIZE"; 10060b57cec5SDimitry Andric else 10070b57cec5SDimitry Andric o << "IC"; 10080b57cec5SDimitry Andric 10095ffd83dbSDimitry Andric o << ", // " << index << "\n"; 10100b57cec5SDimitry Andric } 10110b57cec5SDimitry Andric 10120b57cec5SDimitry Andric i--; 1013*0fca6ea1SDimitry Andric o.indent(i * 2) << "};" 1014*0fca6ea1SDimitry Andric << "\n"; 10150b57cec5SDimitry Andric } 10160b57cec5SDimitry Andric 10170b57cec5SDimitry Andric void DisassemblerTables::emitContextDecisions(raw_ostream &o1, raw_ostream &o2, 10180b57cec5SDimitry Andric unsigned &i1, unsigned &i2, 10190b57cec5SDimitry Andric unsigned &ModRMTableNum) const { 10200b57cec5SDimitry Andric emitContextDecision(o1, o2, i1, i2, ModRMTableNum, *Tables[0], ONEBYTE_STR); 10210b57cec5SDimitry Andric emitContextDecision(o1, o2, i1, i2, ModRMTableNum, *Tables[1], TWOBYTE_STR); 10225f757f3fSDimitry Andric emitContextDecision(o1, o2, i1, i2, ModRMTableNum, *Tables[2], 10235f757f3fSDimitry Andric THREEBYTE38_STR); 10245f757f3fSDimitry Andric emitContextDecision(o1, o2, i1, i2, ModRMTableNum, *Tables[3], 10255f757f3fSDimitry Andric THREEBYTE3A_STR); 10260b57cec5SDimitry Andric emitContextDecision(o1, o2, i1, i2, ModRMTableNum, *Tables[4], XOP8_MAP_STR); 10270b57cec5SDimitry Andric emitContextDecision(o1, o2, i1, i2, ModRMTableNum, *Tables[5], XOP9_MAP_STR); 10280b57cec5SDimitry Andric emitContextDecision(o1, o2, i1, i2, ModRMTableNum, *Tables[6], XOPA_MAP_STR); 10295f757f3fSDimitry Andric emitContextDecision(o1, o2, i1, i2, ModRMTableNum, *Tables[7], 10305f757f3fSDimitry Andric THREEDNOW_MAP_STR); 10315f757f3fSDimitry Andric emitContextDecision(o1, o2, i1, i2, ModRMTableNum, *Tables[8], MAP4_STR); 10325f757f3fSDimitry Andric emitContextDecision(o1, o2, i1, i2, ModRMTableNum, *Tables[9], MAP5_STR); 10335f757f3fSDimitry Andric emitContextDecision(o1, o2, i1, i2, ModRMTableNum, *Tables[10], MAP6_STR); 10345f757f3fSDimitry Andric emitContextDecision(o1, o2, i1, i2, ModRMTableNum, *Tables[11], MAP7_STR); 10350b57cec5SDimitry Andric } 10360b57cec5SDimitry Andric 10370b57cec5SDimitry Andric void DisassemblerTables::emit(raw_ostream &o) const { 10380b57cec5SDimitry Andric unsigned i1 = 0; 10390b57cec5SDimitry Andric unsigned i2 = 0; 10400b57cec5SDimitry Andric 10410b57cec5SDimitry Andric std::string s1; 10420b57cec5SDimitry Andric std::string s2; 10430b57cec5SDimitry Andric 10440b57cec5SDimitry Andric raw_string_ostream o1(s1); 10450b57cec5SDimitry Andric raw_string_ostream o2(s2); 10460b57cec5SDimitry Andric 10470b57cec5SDimitry Andric emitInstructionInfo(o, i2); 10480b57cec5SDimitry Andric o << "\n"; 10490b57cec5SDimitry Andric 10500b57cec5SDimitry Andric emitContextTable(o, i2); 10510b57cec5SDimitry Andric o << "\n"; 10520b57cec5SDimitry Andric 10530b57cec5SDimitry Andric unsigned ModRMTableNum = 0; 10540b57cec5SDimitry Andric 10550b57cec5SDimitry Andric o << "static const InstrUID modRMTable[] = {\n"; 10560b57cec5SDimitry Andric i1++; 10570b57cec5SDimitry Andric std::vector<unsigned> EmptyTable(1, 0); 10580b57cec5SDimitry Andric ModRMTable[EmptyTable] = ModRMTableNum; 10590b57cec5SDimitry Andric ModRMTableNum += EmptyTable.size(); 10600b57cec5SDimitry Andric o1 << "/*EmptyTable*/\n"; 10610b57cec5SDimitry Andric o1.indent(i1 * 2) << "0x0,\n"; 10620b57cec5SDimitry Andric i1--; 10630b57cec5SDimitry Andric emitContextDecisions(o1, o2, i1, i2, ModRMTableNum); 10640b57cec5SDimitry Andric 1065*0fca6ea1SDimitry Andric o << s1; 10660b57cec5SDimitry Andric o << " 0x0\n"; 10670b57cec5SDimitry Andric o << "};\n"; 10680b57cec5SDimitry Andric o << "\n"; 1069*0fca6ea1SDimitry Andric o << s2; 10700b57cec5SDimitry Andric o << "\n"; 10710b57cec5SDimitry Andric o << "\n"; 10720b57cec5SDimitry Andric } 10730b57cec5SDimitry Andric 10740b57cec5SDimitry Andric void DisassemblerTables::setTableFields(ModRMDecision &decision, 10755f757f3fSDimitry Andric const ModRMFilter &filter, InstrUID uid, 10760b57cec5SDimitry Andric uint8_t opcode) { 10770b57cec5SDimitry Andric for (unsigned index = 0; index < 256; ++index) { 10780b57cec5SDimitry Andric if (filter.accepts(index)) { 10790b57cec5SDimitry Andric if (decision.instructionIDs[index] == uid) 10800b57cec5SDimitry Andric continue; 10810b57cec5SDimitry Andric 10820b57cec5SDimitry Andric if (decision.instructionIDs[index] != 0) { 10835f757f3fSDimitry Andric InstructionSpecifier &newInfo = InstructionSpecifiers[uid]; 10840b57cec5SDimitry Andric InstructionSpecifier &previousInfo = 10850b57cec5SDimitry Andric InstructionSpecifiers[decision.instructionIDs[index]]; 10860b57cec5SDimitry Andric 10875f757f3fSDimitry Andric if (previousInfo.name == "NOOP" && 10885f757f3fSDimitry Andric (newInfo.name == "XCHG16ar" || newInfo.name == "XCHG32ar" || 10890b57cec5SDimitry Andric newInfo.name == "XCHG64ar")) 10900b57cec5SDimitry Andric continue; // special case for XCHG*ar and NOOP 10910b57cec5SDimitry Andric 10920b57cec5SDimitry Andric if (outranks(previousInfo.insnContext, newInfo.insnContext)) 10930b57cec5SDimitry Andric continue; 10940b57cec5SDimitry Andric 10950b57cec5SDimitry Andric if (previousInfo.insnContext == newInfo.insnContext) { 10960b57cec5SDimitry Andric errs() << "Error: Primary decode conflict: "; 10970b57cec5SDimitry Andric errs() << newInfo.name << " would overwrite " << previousInfo.name; 10980b57cec5SDimitry Andric errs() << "\n"; 10990b57cec5SDimitry Andric errs() << "ModRM " << index << "\n"; 11000b57cec5SDimitry Andric errs() << "Opcode " << (uint16_t)opcode << "\n"; 11010b57cec5SDimitry Andric errs() << "Context " << stringForContext(newInfo.insnContext) << "\n"; 11020b57cec5SDimitry Andric HasConflicts = true; 11030b57cec5SDimitry Andric } 11040b57cec5SDimitry Andric } 11050b57cec5SDimitry Andric 11060b57cec5SDimitry Andric decision.instructionIDs[index] = uid; 11070b57cec5SDimitry Andric } 11080b57cec5SDimitry Andric } 11090b57cec5SDimitry Andric } 11100b57cec5SDimitry Andric 11115f757f3fSDimitry Andric void DisassemblerTables::setTableFields( 11125f757f3fSDimitry Andric OpcodeType type, InstructionContext insnContext, uint8_t opcode, 11135f757f3fSDimitry Andric const ModRMFilter &filter, InstrUID uid, bool is32bit, bool noPrefix, 11145f757f3fSDimitry Andric bool ignoresVEX_L, bool ignoresW, unsigned addressSize) { 11150b57cec5SDimitry Andric ContextDecision &decision = *Tables[type]; 11160b57cec5SDimitry Andric 11170b57cec5SDimitry Andric for (unsigned index = 0; index < IC_max; ++index) { 11180b57cec5SDimitry Andric if ((is32bit || addressSize == 16) && 11190b57cec5SDimitry Andric inheritsFrom((InstructionContext)index, IC_64BIT)) 11200b57cec5SDimitry Andric continue; 11210b57cec5SDimitry Andric 11220b57cec5SDimitry Andric bool adSize64 = addressSize == 64; 11230b57cec5SDimitry Andric if (inheritsFrom((InstructionContext)index, 11240b57cec5SDimitry Andric InstructionSpecifiers[uid].insnContext, noPrefix, 112506c3fb27SDimitry Andric ignoresVEX_L, ignoresW, adSize64)) 11260b57cec5SDimitry Andric setTableFields(decision.opcodeDecisions[index].modRMDecisions[opcode], 11275f757f3fSDimitry Andric filter, uid, opcode); 11280b57cec5SDimitry Andric } 11290b57cec5SDimitry Andric } 1130