Path: blob/main/contrib/llvm-project/llvm/utils/TableGen/X86DisassemblerTables.cpp
35258 views
//===- X86DisassemblerTables.cpp - Disassembler tables ----------*- C++ -*-===//1//2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.3// See https://llvm.org/LICENSE.txt for license information.4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5//6//===----------------------------------------------------------------------===//7//8// This file is part of the X86 Disassembler Emitter.9// It contains the implementation of the disassembler tables.10// Documentation for the disassembler emitter in general can be found in11// X86DisassemblerEmitter.h.12//13//===----------------------------------------------------------------------===//1415#include "X86DisassemblerTables.h"16#include "X86DisassemblerShared.h"17#include "X86ModRMFilters.h"18#include "llvm/ADT/SmallVector.h"19#include "llvm/Support/ErrorHandling.h"20#include "llvm/Support/Format.h"21#include "llvm/Support/raw_ostream.h"22#include <map>2324using namespace llvm;25using namespace X86Disassembler;2627/// stringForContext - Returns a string containing the name of a particular28/// InstructionContext, usually for diagnostic purposes.29///30/// @param insnContext - The instruction class to transform to a string.31/// @return - A statically-allocated string constant that contains the32/// name of the instruction class.33static inline const char *stringForContext(InstructionContext insnContext) {34switch (insnContext) {35default:36llvm_unreachable("Unhandled instruction class");37#define ENUM_ENTRY(n, r, d) \38case n: \39return #n; \40break;41#define ENUM_ENTRY_K_B(n, r, d) \42ENUM_ENTRY(n, r, d) \43ENUM_ENTRY(n##_K_B, r, d) \44ENUM_ENTRY(n##_KZ, r, d) \45ENUM_ENTRY(n##_K, r, d) ENUM_ENTRY(n##_B, r, d) ENUM_ENTRY(n##_KZ_B, r, d)46INSTRUCTION_CONTEXTS47#undef ENUM_ENTRY48#undef ENUM_ENTRY_K_B49}50}5152/// stringForOperandType - Like stringForContext, but for OperandTypes.53static inline const char *stringForOperandType(OperandType type) {54switch (type) {55default:56llvm_unreachable("Unhandled type");57#define ENUM_ENTRY(i, d) \58case i: \59return #i;60TYPES61#undef ENUM_ENTRY62}63}6465/// stringForOperandEncoding - like stringForContext, but for66/// OperandEncodings.67static inline const char *stringForOperandEncoding(OperandEncoding encoding) {68switch (encoding) {69default:70llvm_unreachable("Unhandled encoding");71#define ENUM_ENTRY(i, d) \72case i: \73return #i;74ENCODINGS75#undef ENUM_ENTRY76}77}7879/// inheritsFrom - Indicates whether all instructions in one class also belong80/// to another class.81///82/// @param child - The class that may be the subset83/// @param parent - The class that may be the superset84/// @return - True if child is a subset of parent, false otherwise.85static inline bool inheritsFrom(InstructionContext child,86InstructionContext parent, bool noPrefix = true,87bool VEX_LIG = false, bool WIG = false,88bool AdSize64 = false) {89if (child == parent)90return true;9192switch (parent) {93case IC:94return (inheritsFrom(child, IC_64BIT, AdSize64) ||95(noPrefix && inheritsFrom(child, IC_OPSIZE, noPrefix)) ||96inheritsFrom(child, IC_ADSIZE) ||97(noPrefix && inheritsFrom(child, IC_XD, noPrefix)) ||98(noPrefix && inheritsFrom(child, IC_XS, noPrefix)));99case IC_64BIT:100return (inheritsFrom(child, IC_64BIT_REXW) ||101(noPrefix && inheritsFrom(child, IC_64BIT_OPSIZE, noPrefix)) ||102(!AdSize64 && inheritsFrom(child, IC_64BIT_ADSIZE)) ||103(noPrefix && inheritsFrom(child, IC_64BIT_XD, noPrefix)) ||104(noPrefix && inheritsFrom(child, IC_64BIT_XS, noPrefix)));105case IC_OPSIZE:106return inheritsFrom(child, IC_64BIT_OPSIZE) ||107inheritsFrom(child, IC_OPSIZE_ADSIZE);108case IC_ADSIZE:109return (noPrefix && inheritsFrom(child, IC_OPSIZE_ADSIZE, noPrefix));110case IC_OPSIZE_ADSIZE:111return false;112case IC_64BIT_ADSIZE:113return (noPrefix && inheritsFrom(child, IC_64BIT_OPSIZE_ADSIZE, noPrefix));114case IC_64BIT_OPSIZE_ADSIZE:115return false;116case IC_XD:117return inheritsFrom(child, IC_64BIT_XD);118case IC_XS:119return inheritsFrom(child, IC_64BIT_XS);120case IC_XD_OPSIZE:121return inheritsFrom(child, IC_64BIT_XD_OPSIZE);122case IC_XS_OPSIZE:123return inheritsFrom(child, IC_64BIT_XS_OPSIZE);124case IC_XD_ADSIZE:125return inheritsFrom(child, IC_64BIT_XD_ADSIZE);126case IC_XS_ADSIZE:127return inheritsFrom(child, IC_64BIT_XS_ADSIZE);128case IC_64BIT_REXW:129return ((noPrefix && inheritsFrom(child, IC_64BIT_REXW_XS, noPrefix)) ||130(noPrefix && inheritsFrom(child, IC_64BIT_REXW_XD, noPrefix)) ||131(noPrefix && inheritsFrom(child, IC_64BIT_REXW_OPSIZE, noPrefix)) ||132(!AdSize64 && inheritsFrom(child, IC_64BIT_REXW_ADSIZE)));133case IC_64BIT_OPSIZE:134return inheritsFrom(child, IC_64BIT_REXW_OPSIZE) ||135(!AdSize64 && inheritsFrom(child, IC_64BIT_OPSIZE_ADSIZE)) ||136(!AdSize64 && inheritsFrom(child, IC_64BIT_REXW_ADSIZE));137case IC_64BIT_XD:138return (inheritsFrom(child, IC_64BIT_REXW_XD) ||139(!AdSize64 && inheritsFrom(child, IC_64BIT_XD_ADSIZE)));140case IC_64BIT_XS:141return (inheritsFrom(child, IC_64BIT_REXW_XS) ||142(!AdSize64 && inheritsFrom(child, IC_64BIT_XS_ADSIZE)));143case IC_64BIT_XD_OPSIZE:144case IC_64BIT_XS_OPSIZE:145return false;146case IC_64BIT_XD_ADSIZE:147case IC_64BIT_XS_ADSIZE:148return false;149case IC_64BIT_REXW_XD:150case IC_64BIT_REXW_XS:151case IC_64BIT_REXW_OPSIZE:152case IC_64BIT_REXW_ADSIZE:153case IC_64BIT_REX2:154return false;155case IC_VEX:156return (VEX_LIG && WIG && inheritsFrom(child, IC_VEX_L_W)) ||157(WIG && inheritsFrom(child, IC_VEX_W)) ||158(VEX_LIG && inheritsFrom(child, IC_VEX_L));159case IC_VEX_XS:160return (VEX_LIG && WIG && inheritsFrom(child, IC_VEX_L_W_XS)) ||161(WIG && inheritsFrom(child, IC_VEX_W_XS)) ||162(VEX_LIG && inheritsFrom(child, IC_VEX_L_XS));163case IC_VEX_XD:164return (VEX_LIG && WIG && inheritsFrom(child, IC_VEX_L_W_XD)) ||165(WIG && inheritsFrom(child, IC_VEX_W_XD)) ||166(VEX_LIG && inheritsFrom(child, IC_VEX_L_XD));167case IC_VEX_OPSIZE:168return (VEX_LIG && WIG && inheritsFrom(child, IC_VEX_L_W_OPSIZE)) ||169(WIG && inheritsFrom(child, IC_VEX_W_OPSIZE)) ||170(VEX_LIG && inheritsFrom(child, IC_VEX_L_OPSIZE));171case IC_VEX_W:172return VEX_LIG && inheritsFrom(child, IC_VEX_L_W);173case IC_VEX_W_XS:174return VEX_LIG && inheritsFrom(child, IC_VEX_L_W_XS);175case IC_VEX_W_XD:176return VEX_LIG && inheritsFrom(child, IC_VEX_L_W_XD);177case IC_VEX_W_OPSIZE:178return VEX_LIG && inheritsFrom(child, IC_VEX_L_W_OPSIZE);179case IC_VEX_L:180return WIG && inheritsFrom(child, IC_VEX_L_W);181case IC_VEX_L_XS:182return WIG && inheritsFrom(child, IC_VEX_L_W_XS);183case IC_VEX_L_XD:184return WIG && inheritsFrom(child, IC_VEX_L_W_XD);185case IC_VEX_L_OPSIZE:186return WIG && inheritsFrom(child, IC_VEX_L_W_OPSIZE);187case IC_VEX_L_W:188case IC_VEX_L_W_XS:189case IC_VEX_L_W_XD:190case IC_VEX_L_W_OPSIZE:191return false;192case IC_EVEX:193return (VEX_LIG && WIG && inheritsFrom(child, IC_EVEX_L_W)) ||194(VEX_LIG && WIG && inheritsFrom(child, IC_EVEX_L2_W)) ||195(WIG && inheritsFrom(child, IC_EVEX_W)) ||196(VEX_LIG && inheritsFrom(child, IC_EVEX_L)) ||197(VEX_LIG && inheritsFrom(child, IC_EVEX_L2));198case IC_EVEX_XS:199return (VEX_LIG && WIG && inheritsFrom(child, IC_EVEX_L_W_XS)) ||200(VEX_LIG && WIG && inheritsFrom(child, IC_EVEX_L2_W_XS)) ||201(WIG && inheritsFrom(child, IC_EVEX_W_XS)) ||202(VEX_LIG && inheritsFrom(child, IC_EVEX_L_XS)) ||203(VEX_LIG && inheritsFrom(child, IC_EVEX_L2_XS));204case IC_EVEX_XD:205return (VEX_LIG && WIG && inheritsFrom(child, IC_EVEX_L_W_XD)) ||206(VEX_LIG && WIG && inheritsFrom(child, IC_EVEX_L2_W_XD)) ||207(WIG && inheritsFrom(child, IC_EVEX_W_XD)) ||208(VEX_LIG && inheritsFrom(child, IC_EVEX_L_XD)) ||209(VEX_LIG && inheritsFrom(child, IC_EVEX_L2_XD));210case IC_EVEX_OPSIZE:211return (VEX_LIG && WIG && inheritsFrom(child, IC_EVEX_L_W_OPSIZE)) ||212(VEX_LIG && WIG && inheritsFrom(child, IC_EVEX_L2_W_OPSIZE)) ||213(WIG && inheritsFrom(child, IC_EVEX_W_OPSIZE)) ||214(VEX_LIG && inheritsFrom(child, IC_EVEX_L_OPSIZE)) ||215(VEX_LIG && inheritsFrom(child, IC_EVEX_L2_OPSIZE));216case IC_EVEX_OPSIZE_ADSIZE:217case IC_EVEX_XS_ADSIZE:218case IC_EVEX_XD_ADSIZE:219return false;220case IC_EVEX_K:221return (VEX_LIG && WIG && inheritsFrom(child, IC_EVEX_L_W_K)) ||222(VEX_LIG && WIG && inheritsFrom(child, IC_EVEX_L2_W_K)) ||223(WIG && inheritsFrom(child, IC_EVEX_W_K)) ||224(VEX_LIG && inheritsFrom(child, IC_EVEX_L_K)) ||225(VEX_LIG && inheritsFrom(child, IC_EVEX_L2_K));226case IC_EVEX_XS_K:227return (VEX_LIG && WIG && inheritsFrom(child, IC_EVEX_L_W_XS_K)) ||228(VEX_LIG && WIG && inheritsFrom(child, IC_EVEX_L2_W_XS_K)) ||229(WIG && inheritsFrom(child, IC_EVEX_W_XS_K)) ||230(VEX_LIG && inheritsFrom(child, IC_EVEX_L_XS_K)) ||231(VEX_LIG && inheritsFrom(child, IC_EVEX_L2_XS_K));232case IC_EVEX_XD_K:233return (VEX_LIG && WIG && inheritsFrom(child, IC_EVEX_L_W_XD_K)) ||234(VEX_LIG && WIG && inheritsFrom(child, IC_EVEX_L2_W_XD_K)) ||235(WIG && inheritsFrom(child, IC_EVEX_W_XD_K)) ||236(VEX_LIG && inheritsFrom(child, IC_EVEX_L_XD_K)) ||237(VEX_LIG && inheritsFrom(child, IC_EVEX_L2_XD_K));238case IC_EVEX_OPSIZE_K:239return (VEX_LIG && WIG && inheritsFrom(child, IC_EVEX_L_W_OPSIZE_K)) ||240(VEX_LIG && WIG && inheritsFrom(child, IC_EVEX_L2_W_OPSIZE_K)) ||241(WIG && inheritsFrom(child, IC_EVEX_W_OPSIZE_K)) ||242(VEX_LIG && inheritsFrom(child, IC_EVEX_L_OPSIZE_K)) ||243(VEX_LIG && inheritsFrom(child, IC_EVEX_L2_OPSIZE_K));244case IC_EVEX_KZ:245return (VEX_LIG && WIG && inheritsFrom(child, IC_EVEX_L_W_KZ)) ||246(VEX_LIG && WIG && inheritsFrom(child, IC_EVEX_L2_W_KZ)) ||247(WIG && inheritsFrom(child, IC_EVEX_W_KZ)) ||248(VEX_LIG && inheritsFrom(child, IC_EVEX_L_KZ)) ||249(VEX_LIG && inheritsFrom(child, IC_EVEX_L2_KZ));250case IC_EVEX_XS_KZ:251return (VEX_LIG && WIG && inheritsFrom(child, IC_EVEX_L_W_XS_KZ)) ||252(VEX_LIG && WIG && inheritsFrom(child, IC_EVEX_L2_W_XS_KZ)) ||253(WIG && inheritsFrom(child, IC_EVEX_W_XS_KZ)) ||254(VEX_LIG && inheritsFrom(child, IC_EVEX_L_XS_KZ)) ||255(VEX_LIG && inheritsFrom(child, IC_EVEX_L2_XS_KZ));256case IC_EVEX_XD_KZ:257return (VEX_LIG && WIG && inheritsFrom(child, IC_EVEX_L_W_XD_KZ)) ||258(VEX_LIG && WIG && inheritsFrom(child, IC_EVEX_L2_W_XD_KZ)) ||259(WIG && inheritsFrom(child, IC_EVEX_W_XD_KZ)) ||260(VEX_LIG && inheritsFrom(child, IC_EVEX_L_XD_KZ)) ||261(VEX_LIG && inheritsFrom(child, IC_EVEX_L2_XD_KZ));262case IC_EVEX_OPSIZE_KZ:263return (VEX_LIG && WIG && inheritsFrom(child, IC_EVEX_L_W_OPSIZE_KZ)) ||264(VEX_LIG && WIG && inheritsFrom(child, IC_EVEX_L2_W_OPSIZE_KZ)) ||265(WIG && inheritsFrom(child, IC_EVEX_W_OPSIZE_KZ)) ||266(VEX_LIG && inheritsFrom(child, IC_EVEX_L_OPSIZE_KZ)) ||267(VEX_LIG && inheritsFrom(child, IC_EVEX_L2_OPSIZE_KZ));268case IC_EVEX_W:269return (VEX_LIG && inheritsFrom(child, IC_EVEX_L_W)) ||270(VEX_LIG && inheritsFrom(child, IC_EVEX_L2_W));271case IC_EVEX_W_XS:272return (VEX_LIG && inheritsFrom(child, IC_EVEX_L_W_XS)) ||273(VEX_LIG && inheritsFrom(child, IC_EVEX_L2_W_XS));274case IC_EVEX_W_XD:275return (VEX_LIG && inheritsFrom(child, IC_EVEX_L_W_XD)) ||276(VEX_LIG && inheritsFrom(child, IC_EVEX_L2_W_XD));277case IC_EVEX_W_OPSIZE:278return (VEX_LIG && inheritsFrom(child, IC_EVEX_L_W_OPSIZE)) ||279(VEX_LIG && inheritsFrom(child, IC_EVEX_L2_W_OPSIZE));280case IC_EVEX_W_K:281return (VEX_LIG && inheritsFrom(child, IC_EVEX_L_W_K)) ||282(VEX_LIG && inheritsFrom(child, IC_EVEX_L2_W_K));283case IC_EVEX_W_XS_K:284return (VEX_LIG && inheritsFrom(child, IC_EVEX_L_W_XS_K)) ||285(VEX_LIG && inheritsFrom(child, IC_EVEX_L2_W_XS_K));286case IC_EVEX_W_XD_K:287return (VEX_LIG && inheritsFrom(child, IC_EVEX_L_W_XD_K)) ||288(VEX_LIG && inheritsFrom(child, IC_EVEX_L2_W_XD_K));289case IC_EVEX_W_OPSIZE_K:290return (VEX_LIG && inheritsFrom(child, IC_EVEX_L_W_OPSIZE_K)) ||291(VEX_LIG && inheritsFrom(child, IC_EVEX_L2_W_OPSIZE_K));292case IC_EVEX_W_KZ:293return (VEX_LIG && inheritsFrom(child, IC_EVEX_L_W_KZ)) ||294(VEX_LIG && inheritsFrom(child, IC_EVEX_L2_W_KZ));295case IC_EVEX_W_XS_KZ:296return (VEX_LIG && inheritsFrom(child, IC_EVEX_L_W_XS_KZ)) ||297(VEX_LIG && inheritsFrom(child, IC_EVEX_L2_W_XS_KZ));298case IC_EVEX_W_XD_KZ:299return (VEX_LIG && inheritsFrom(child, IC_EVEX_L_W_XD_KZ)) ||300(VEX_LIG && inheritsFrom(child, IC_EVEX_L2_W_XD_KZ));301case IC_EVEX_W_OPSIZE_KZ:302return (VEX_LIG && inheritsFrom(child, IC_EVEX_L_W_OPSIZE_KZ)) ||303(VEX_LIG && inheritsFrom(child, IC_EVEX_L2_W_OPSIZE_KZ));304case IC_EVEX_L:305return WIG && inheritsFrom(child, IC_EVEX_L_W);306case IC_EVEX_L_XS:307return WIG && inheritsFrom(child, IC_EVEX_L_W_XS);308case IC_EVEX_L_XD:309return WIG && inheritsFrom(child, IC_EVEX_L_W_XD);310case IC_EVEX_L_OPSIZE:311return WIG && inheritsFrom(child, IC_EVEX_L_W_OPSIZE);312case IC_EVEX_L_K:313return WIG && inheritsFrom(child, IC_EVEX_L_W_K);314case IC_EVEX_L_XS_K:315return WIG && inheritsFrom(child, IC_EVEX_L_W_XS_K);316case IC_EVEX_L_XD_K:317return WIG && inheritsFrom(child, IC_EVEX_L_W_XD_K);318case IC_EVEX_L_OPSIZE_K:319return WIG && inheritsFrom(child, IC_EVEX_L_W_OPSIZE_K);320case IC_EVEX_L_KZ:321return WIG && inheritsFrom(child, IC_EVEX_L_W_KZ);322case IC_EVEX_L_XS_KZ:323return WIG && inheritsFrom(child, IC_EVEX_L_W_XS_KZ);324case IC_EVEX_L_XD_KZ:325return WIG && inheritsFrom(child, IC_EVEX_L_W_XD_KZ);326case IC_EVEX_L_OPSIZE_KZ:327return WIG && inheritsFrom(child, IC_EVEX_L_W_OPSIZE_KZ);328case IC_EVEX_L_W:329case IC_EVEX_L_W_XS:330case IC_EVEX_L_W_XD:331case IC_EVEX_L_W_OPSIZE:332return false;333case IC_EVEX_L_W_K:334case IC_EVEX_L_W_XS_K:335case IC_EVEX_L_W_XD_K:336case IC_EVEX_L_W_OPSIZE_K:337return false;338case IC_EVEX_L_W_KZ:339case IC_EVEX_L_W_XS_KZ:340case IC_EVEX_L_W_XD_KZ:341case IC_EVEX_L_W_OPSIZE_KZ:342return false;343case IC_EVEX_L2:344return WIG && inheritsFrom(child, IC_EVEX_L2_W);345case IC_EVEX_L2_XS:346return WIG && inheritsFrom(child, IC_EVEX_L2_W_XS);347case IC_EVEX_L2_XD:348return WIG && inheritsFrom(child, IC_EVEX_L2_W_XD);349case IC_EVEX_L2_OPSIZE:350return WIG && inheritsFrom(child, IC_EVEX_L2_W_OPSIZE);351case IC_EVEX_L2_K:352return WIG && inheritsFrom(child, IC_EVEX_L2_W_K);353case IC_EVEX_L2_XS_K:354return WIG && inheritsFrom(child, IC_EVEX_L2_W_XS_K);355case IC_EVEX_L2_XD_K:356return WIG && inheritsFrom(child, IC_EVEX_L2_W_XD_K);357case IC_EVEX_L2_OPSIZE_K:358return WIG && inheritsFrom(child, IC_EVEX_L2_W_OPSIZE_K);359case IC_EVEX_L2_KZ:360return WIG && inheritsFrom(child, IC_EVEX_L2_W_KZ);361case IC_EVEX_L2_XS_KZ:362return WIG && inheritsFrom(child, IC_EVEX_L2_W_XS_KZ);363case IC_EVEX_L2_XD_KZ:364return WIG && inheritsFrom(child, IC_EVEX_L2_W_XD_KZ);365case IC_EVEX_L2_OPSIZE_KZ:366return WIG && inheritsFrom(child, IC_EVEX_L2_W_OPSIZE_KZ);367case IC_EVEX_L2_W:368case IC_EVEX_L2_W_XS:369case IC_EVEX_L2_W_XD:370case IC_EVEX_L2_W_OPSIZE:371return false;372case IC_EVEX_L2_W_K:373case IC_EVEX_L2_W_XS_K:374case IC_EVEX_L2_W_XD_K:375case IC_EVEX_L2_W_OPSIZE_K:376return false;377case IC_EVEX_L2_W_KZ:378case IC_EVEX_L2_W_XS_KZ:379case IC_EVEX_L2_W_XD_KZ:380case IC_EVEX_L2_W_OPSIZE_KZ:381return false;382case IC_EVEX_B:383return (VEX_LIG && WIG && inheritsFrom(child, IC_EVEX_L_W_B)) ||384(VEX_LIG && WIG && inheritsFrom(child, IC_EVEX_L2_W_B)) ||385(WIG && inheritsFrom(child, IC_EVEX_W_B)) ||386(VEX_LIG && inheritsFrom(child, IC_EVEX_L_B)) ||387(VEX_LIG && inheritsFrom(child, IC_EVEX_L2_B));388case IC_EVEX_XS_B:389return (VEX_LIG && WIG && inheritsFrom(child, IC_EVEX_L_W_XS_B)) ||390(VEX_LIG && WIG && inheritsFrom(child, IC_EVEX_L2_W_XS_B)) ||391(WIG && inheritsFrom(child, IC_EVEX_W_XS_B)) ||392(VEX_LIG && inheritsFrom(child, IC_EVEX_L_XS_B)) ||393(VEX_LIG && inheritsFrom(child, IC_EVEX_L2_XS_B));394case IC_EVEX_XD_B:395return (VEX_LIG && WIG && inheritsFrom(child, IC_EVEX_L_W_XD_B)) ||396(VEX_LIG && WIG && inheritsFrom(child, IC_EVEX_L2_W_XD_B)) ||397(WIG && inheritsFrom(child, IC_EVEX_W_XD_B)) ||398(VEX_LIG && inheritsFrom(child, IC_EVEX_L_XD_B)) ||399(VEX_LIG && inheritsFrom(child, IC_EVEX_L2_XD_B));400case IC_EVEX_OPSIZE_B:401return (VEX_LIG && WIG && inheritsFrom(child, IC_EVEX_L_W_OPSIZE_B)) ||402(VEX_LIG && WIG && inheritsFrom(child, IC_EVEX_L2_W_OPSIZE_B)) ||403(WIG && inheritsFrom(child, IC_EVEX_W_OPSIZE_B)) ||404(VEX_LIG && inheritsFrom(child, IC_EVEX_L_OPSIZE_B)) ||405(VEX_LIG && inheritsFrom(child, IC_EVEX_L2_OPSIZE_B));406case IC_EVEX_K_B:407return (VEX_LIG && WIG && inheritsFrom(child, IC_EVEX_L_W_K_B)) ||408(VEX_LIG && WIG && inheritsFrom(child, IC_EVEX_L2_W_K_B)) ||409(WIG && inheritsFrom(child, IC_EVEX_W_K_B)) ||410(VEX_LIG && inheritsFrom(child, IC_EVEX_L_K_B)) ||411(VEX_LIG && inheritsFrom(child, IC_EVEX_L2_K_B));412case IC_EVEX_XS_K_B:413return (VEX_LIG && WIG && inheritsFrom(child, IC_EVEX_L_W_XS_K_B)) ||414(VEX_LIG && WIG && inheritsFrom(child, IC_EVEX_L2_W_XS_K_B)) ||415(WIG && inheritsFrom(child, IC_EVEX_W_XS_K_B)) ||416(VEX_LIG && inheritsFrom(child, IC_EVEX_L_XS_K_B)) ||417(VEX_LIG && inheritsFrom(child, IC_EVEX_L2_XS_K_B));418case IC_EVEX_XD_K_B:419return (VEX_LIG && WIG && inheritsFrom(child, IC_EVEX_L_W_XD_K_B)) ||420(VEX_LIG && WIG && inheritsFrom(child, IC_EVEX_L2_W_XD_K_B)) ||421(WIG && inheritsFrom(child, IC_EVEX_W_XD_K_B)) ||422(VEX_LIG && inheritsFrom(child, IC_EVEX_L_XD_K_B)) ||423(VEX_LIG && inheritsFrom(child, IC_EVEX_L2_XD_K_B));424case IC_EVEX_OPSIZE_K_B:425return (VEX_LIG && WIG && inheritsFrom(child, IC_EVEX_L_W_OPSIZE_K_B)) ||426(VEX_LIG && WIG && inheritsFrom(child, IC_EVEX_L2_W_OPSIZE_K_B)) ||427(WIG && inheritsFrom(child, IC_EVEX_W_OPSIZE_K_B)) ||428(VEX_LIG && inheritsFrom(child, IC_EVEX_L_OPSIZE_K_B)) ||429(VEX_LIG && inheritsFrom(child, IC_EVEX_L2_OPSIZE_K_B));430case IC_EVEX_KZ_B:431return (VEX_LIG && WIG && inheritsFrom(child, IC_EVEX_L_W_KZ_B)) ||432(VEX_LIG && WIG && inheritsFrom(child, IC_EVEX_L2_W_KZ_B)) ||433(WIG && inheritsFrom(child, IC_EVEX_W_KZ_B)) ||434(VEX_LIG && inheritsFrom(child, IC_EVEX_L_KZ_B)) ||435(VEX_LIG && inheritsFrom(child, IC_EVEX_L2_KZ_B));436case IC_EVEX_XS_KZ_B:437return (VEX_LIG && WIG && inheritsFrom(child, IC_EVEX_L_W_XS_KZ_B)) ||438(VEX_LIG && WIG && inheritsFrom(child, IC_EVEX_L2_W_XS_KZ_B)) ||439(WIG && inheritsFrom(child, IC_EVEX_W_XS_KZ_B)) ||440(VEX_LIG && inheritsFrom(child, IC_EVEX_L_XS_KZ_B)) ||441(VEX_LIG && inheritsFrom(child, IC_EVEX_L2_XS_KZ_B));442case IC_EVEX_XD_KZ_B:443return (VEX_LIG && WIG && inheritsFrom(child, IC_EVEX_L_W_XD_KZ_B)) ||444(VEX_LIG && WIG && inheritsFrom(child, IC_EVEX_L2_W_XD_KZ_B)) ||445(WIG && inheritsFrom(child, IC_EVEX_W_XD_KZ_B)) ||446(VEX_LIG && inheritsFrom(child, IC_EVEX_L_XD_KZ_B)) ||447(VEX_LIG && inheritsFrom(child, IC_EVEX_L2_XD_KZ_B));448case IC_EVEX_OPSIZE_KZ_B:449return (VEX_LIG && WIG && inheritsFrom(child, IC_EVEX_L_W_OPSIZE_KZ_B)) ||450(VEX_LIG && WIG && inheritsFrom(child, IC_EVEX_L2_W_OPSIZE_KZ_B)) ||451(WIG && inheritsFrom(child, IC_EVEX_W_OPSIZE_KZ_B)) ||452(VEX_LIG && inheritsFrom(child, IC_EVEX_L_OPSIZE_KZ_B)) ||453(VEX_LIG && inheritsFrom(child, IC_EVEX_L2_OPSIZE_KZ_B));454case IC_EVEX_W_B:455return (VEX_LIG && inheritsFrom(child, IC_EVEX_L_W_B)) ||456(VEX_LIG && inheritsFrom(child, IC_EVEX_L2_W_B));457case IC_EVEX_W_XS_B:458return (VEX_LIG && inheritsFrom(child, IC_EVEX_L_W_XS_B)) ||459(VEX_LIG && inheritsFrom(child, IC_EVEX_L2_W_XS_B));460case IC_EVEX_W_XD_B:461return (VEX_LIG && inheritsFrom(child, IC_EVEX_L_W_XD_B)) ||462(VEX_LIG && inheritsFrom(child, IC_EVEX_L2_W_XD_B));463case IC_EVEX_W_OPSIZE_B:464return (VEX_LIG && inheritsFrom(child, IC_EVEX_L_W_OPSIZE_B)) ||465(VEX_LIG && inheritsFrom(child, IC_EVEX_L2_W_OPSIZE_B));466case IC_EVEX_W_K_B:467return (VEX_LIG && inheritsFrom(child, IC_EVEX_L_W_K_B)) ||468(VEX_LIG && inheritsFrom(child, IC_EVEX_L2_W_K_B));469case IC_EVEX_W_XS_K_B:470return (VEX_LIG && inheritsFrom(child, IC_EVEX_L_W_XS_K_B)) ||471(VEX_LIG && inheritsFrom(child, IC_EVEX_L2_W_XS_K_B));472case IC_EVEX_W_XD_K_B:473return (VEX_LIG && inheritsFrom(child, IC_EVEX_L_W_XD_K_B)) ||474(VEX_LIG && inheritsFrom(child, IC_EVEX_L2_W_XD_K_B));475case IC_EVEX_W_OPSIZE_K_B:476return (VEX_LIG && inheritsFrom(child, IC_EVEX_L_W_OPSIZE_K_B)) ||477(VEX_LIG && inheritsFrom(child, IC_EVEX_L2_W_OPSIZE_K_B));478case IC_EVEX_W_KZ_B:479return (VEX_LIG && inheritsFrom(child, IC_EVEX_L_W_KZ_B)) ||480(VEX_LIG && inheritsFrom(child, IC_EVEX_L2_W_KZ_B));481case IC_EVEX_W_XS_KZ_B:482return (VEX_LIG && inheritsFrom(child, IC_EVEX_L_W_XS_KZ_B)) ||483(VEX_LIG && inheritsFrom(child, IC_EVEX_L2_W_XS_KZ_B));484case IC_EVEX_W_XD_KZ_B:485return (VEX_LIG && inheritsFrom(child, IC_EVEX_L_W_XD_KZ_B)) ||486(VEX_LIG && inheritsFrom(child, IC_EVEX_L2_W_XD_KZ_B));487case IC_EVEX_W_OPSIZE_KZ_B:488return (VEX_LIG && inheritsFrom(child, IC_EVEX_L_W_OPSIZE_KZ_B)) ||489(VEX_LIG && inheritsFrom(child, IC_EVEX_L2_W_OPSIZE_KZ_B));490case IC_EVEX_L_B:491return WIG && inheritsFrom(child, IC_EVEX_L_W_B);492case IC_EVEX_L_XS_B:493return WIG && inheritsFrom(child, IC_EVEX_L_W_XS_B);494case IC_EVEX_L_XD_B:495return WIG && inheritsFrom(child, IC_EVEX_L_W_XD_B);496case IC_EVEX_L_OPSIZE_B:497return WIG && inheritsFrom(child, IC_EVEX_L_W_OPSIZE_B);498case IC_EVEX_L_K_B:499return WIG && inheritsFrom(child, IC_EVEX_L_W_K_B);500case IC_EVEX_L_XS_K_B:501return WIG && inheritsFrom(child, IC_EVEX_L_W_XS_K_B);502case IC_EVEX_L_XD_K_B:503return WIG && inheritsFrom(child, IC_EVEX_L_W_XD_K_B);504case IC_EVEX_L_OPSIZE_K_B:505return WIG && inheritsFrom(child, IC_EVEX_L_W_OPSIZE_K_B);506case IC_EVEX_L_KZ_B:507return WIG && inheritsFrom(child, IC_EVEX_L_W_KZ_B);508case IC_EVEX_L_XS_KZ_B:509return WIG && inheritsFrom(child, IC_EVEX_L_W_XS_KZ_B);510case IC_EVEX_L_XD_KZ_B:511return WIG && inheritsFrom(child, IC_EVEX_L_W_XD_KZ_B);512case IC_EVEX_L_OPSIZE_KZ_B:513return WIG && inheritsFrom(child, IC_EVEX_L_W_OPSIZE_KZ_B);514case IC_EVEX_L_W_B:515case IC_EVEX_L_W_XS_B:516case IC_EVEX_L_W_XD_B:517case IC_EVEX_L_W_OPSIZE_B:518return false;519case IC_EVEX_L_W_K_B:520case IC_EVEX_L_W_XS_K_B:521case IC_EVEX_L_W_XD_K_B:522case IC_EVEX_L_W_OPSIZE_K_B:523return false;524case IC_EVEX_L_W_KZ_B:525case IC_EVEX_L_W_XS_KZ_B:526case IC_EVEX_L_W_XD_KZ_B:527case IC_EVEX_L_W_OPSIZE_KZ_B:528return false;529case IC_EVEX_L2_B:530return WIG && inheritsFrom(child, IC_EVEX_L2_W_B);531case IC_EVEX_L2_XS_B:532return WIG && inheritsFrom(child, IC_EVEX_L2_W_XS_B);533case IC_EVEX_L2_XD_B:534return WIG && inheritsFrom(child, IC_EVEX_L2_W_XD_B);535case IC_EVEX_L2_OPSIZE_B:536return WIG && inheritsFrom(child, IC_EVEX_L2_W_OPSIZE_B);537case IC_EVEX_L2_K_B:538return WIG && inheritsFrom(child, IC_EVEX_L2_W_K_B);539case IC_EVEX_L2_XS_K_B:540return WIG && inheritsFrom(child, IC_EVEX_L2_W_XS_K_B);541case IC_EVEX_L2_XD_K_B:542return WIG && inheritsFrom(child, IC_EVEX_L2_W_XD_K_B);543case IC_EVEX_L2_OPSIZE_K_B:544return WIG && inheritsFrom(child, IC_EVEX_L2_W_OPSIZE_K_B);545case IC_EVEX_L2_KZ_B:546return WIG && inheritsFrom(child, IC_EVEX_L2_W_KZ_B);547case IC_EVEX_L2_XS_KZ_B:548return WIG && inheritsFrom(child, IC_EVEX_L2_W_XS_KZ_B);549case IC_EVEX_L2_XD_KZ_B:550return WIG && inheritsFrom(child, IC_EVEX_L2_W_XD_KZ_B);551case IC_EVEX_L2_OPSIZE_KZ_B:552return WIG && inheritsFrom(child, IC_EVEX_L2_W_OPSIZE_KZ_B);553case IC_EVEX_L2_W_B:554case IC_EVEX_L2_W_XS_B:555case IC_EVEX_L2_W_XD_B:556case IC_EVEX_L2_W_OPSIZE_B:557return false;558case IC_EVEX_L2_W_K_B:559case IC_EVEX_L2_W_XS_K_B:560case IC_EVEX_L2_W_XD_K_B:561case IC_EVEX_L2_W_OPSIZE_K_B:562return false;563case IC_EVEX_L2_W_KZ_B:564case IC_EVEX_L2_W_XS_KZ_B:565case IC_EVEX_L2_W_XD_KZ_B:566case IC_EVEX_L2_W_OPSIZE_KZ_B:567return false;568case IC_EVEX_NF:569return WIG && inheritsFrom(child, IC_EVEX_W_NF);570case IC_EVEX_B_NF:571return WIG && inheritsFrom(child, IC_EVEX_W_B_NF);572case IC_EVEX_OPSIZE_NF:573case IC_EVEX_OPSIZE_B_NF:574case IC_EVEX_W_NF:575case IC_EVEX_W_B_NF:576return false;577default:578errs() << "Unknown instruction class: "579<< stringForContext((InstructionContext)parent) << "\n";580llvm_unreachable("Unknown instruction class");581}582}583584/// outranks - Indicates whether, if an instruction has two different applicable585/// classes, which class should be preferred when performing decode. This586/// imposes a total ordering (ties are resolved toward "lower")587///588/// @param upper - The class that may be preferable589/// @param lower - The class that may be less preferable590/// @return - True if upper is to be preferred, false otherwise.591static inline bool outranks(InstructionContext upper,592InstructionContext lower) {593assert(upper < IC_max);594assert(lower < IC_max);595596#define ENUM_ENTRY(n, r, d) r,597#define ENUM_ENTRY_K_B(n, r, d) \598ENUM_ENTRY(n, r, d) \599ENUM_ENTRY(n##_K_B, r, d) \600ENUM_ENTRY(n##_KZ_B, r, d) \601ENUM_ENTRY(n##_KZ, r, d) ENUM_ENTRY(n##_K, r, d) ENUM_ENTRY(n##_B, r, d)602static int ranks[IC_max] = {INSTRUCTION_CONTEXTS};603#undef ENUM_ENTRY604#undef ENUM_ENTRY_K_B605606return (ranks[upper] > ranks[lower]);607}608609/// getDecisionType - Determines whether a ModRM decision with 255 entries can610/// be compacted by eliminating redundant information.611///612/// @param decision - The decision to be compacted.613/// @return - The compactest available representation for the decision.614static ModRMDecisionType getDecisionType(ModRMDecision &decision) {615bool satisfiesOneEntry = true;616bool satisfiesSplitRM = true;617bool satisfiesSplitReg = true;618bool satisfiesSplitMisc = true;619620for (unsigned index = 0; index < 256; ++index) {621if (decision.instructionIDs[index] != decision.instructionIDs[0])622satisfiesOneEntry = false;623624if (((index & 0xc0) == 0xc0) &&625(decision.instructionIDs[index] != decision.instructionIDs[0xc0]))626satisfiesSplitRM = false;627628if (((index & 0xc0) != 0xc0) &&629(decision.instructionIDs[index] != decision.instructionIDs[0x00]))630satisfiesSplitRM = false;631632if (((index & 0xc0) == 0xc0) && (decision.instructionIDs[index] !=633decision.instructionIDs[index & 0xf8]))634satisfiesSplitReg = false;635636if (((index & 0xc0) != 0xc0) && (decision.instructionIDs[index] !=637decision.instructionIDs[index & 0x38]))638satisfiesSplitMisc = false;639}640641if (satisfiesOneEntry)642return MODRM_ONEENTRY;643644if (satisfiesSplitRM)645return MODRM_SPLITRM;646647if (satisfiesSplitReg && satisfiesSplitMisc)648return MODRM_SPLITREG;649650if (satisfiesSplitMisc)651return MODRM_SPLITMISC;652653return MODRM_FULL;654}655656/// stringForDecisionType - Returns a statically-allocated string corresponding657/// to a particular decision type.658///659/// @param dt - The decision type.660/// @return - A pointer to the statically-allocated string (e.g.,661/// "MODRM_ONEENTRY" for MODRM_ONEENTRY).662static const char *stringForDecisionType(ModRMDecisionType dt) {663#define ENUM_ENTRY(n) \664case n: \665return #n;666switch (dt) {667default:668llvm_unreachable("Unknown decision type");669MODRMTYPES670};671#undef ENUM_ENTRY672}673674DisassemblerTables::DisassemblerTables() {675for (unsigned i = 0; i < std::size(Tables); i++)676Tables[i] = std::make_unique<ContextDecision>();677678HasConflicts = false;679}680681DisassemblerTables::~DisassemblerTables() {}682683void DisassemblerTables::emitModRMDecision(raw_ostream &o1, raw_ostream &o2,684unsigned &i1, unsigned &i2,685unsigned &ModRMTableNum,686ModRMDecision &decision) const {687static uint32_t sEntryNumber = 1;688ModRMDecisionType dt = getDecisionType(decision);689690if (dt == MODRM_ONEENTRY && decision.instructionIDs[0] == 0) {691// Empty table.692o2 << "{" << stringForDecisionType(dt) << ", 0}";693return;694}695696std::vector<unsigned> ModRMDecision;697698switch (dt) {699default:700llvm_unreachable("Unknown decision type");701case MODRM_ONEENTRY:702ModRMDecision.push_back(decision.instructionIDs[0]);703break;704case MODRM_SPLITRM:705ModRMDecision.push_back(decision.instructionIDs[0x00]);706ModRMDecision.push_back(decision.instructionIDs[0xc0]);707break;708case MODRM_SPLITREG:709for (unsigned index = 0; index < 64; index += 8)710ModRMDecision.push_back(decision.instructionIDs[index]);711for (unsigned index = 0xc0; index < 256; index += 8)712ModRMDecision.push_back(decision.instructionIDs[index]);713break;714case MODRM_SPLITMISC:715for (unsigned index = 0; index < 64; index += 8)716ModRMDecision.push_back(decision.instructionIDs[index]);717for (unsigned index = 0xc0; index < 256; ++index)718ModRMDecision.push_back(decision.instructionIDs[index]);719break;720case MODRM_FULL:721for (unsigned short InstructionID : decision.instructionIDs)722ModRMDecision.push_back(InstructionID);723break;724}725726unsigned &EntryNumber = ModRMTable[ModRMDecision];727if (EntryNumber == 0) {728EntryNumber = ModRMTableNum;729730ModRMTableNum += ModRMDecision.size();731o1 << "/*Table" << EntryNumber << "*/\n";732i1++;733for (unsigned I : ModRMDecision) {734o1.indent(i1 * 2) << format("0x%hx", I) << ", /*"735<< InstructionSpecifiers[I].name << "*/\n";736}737i1--;738}739740o2 << "{" << stringForDecisionType(dt) << ", " << EntryNumber << "}";741742switch (dt) {743default:744llvm_unreachable("Unknown decision type");745case MODRM_ONEENTRY:746sEntryNumber += 1;747break;748case MODRM_SPLITRM:749sEntryNumber += 2;750break;751case MODRM_SPLITREG:752sEntryNumber += 16;753break;754case MODRM_SPLITMISC:755sEntryNumber += 8 + 64;756break;757case MODRM_FULL:758sEntryNumber += 256;759break;760}761762// We assume that the index can fit into uint16_t.763assert(sEntryNumber < 65536U &&764"Index into ModRMDecision is too large for uint16_t!");765(void)sEntryNumber;766}767768void DisassemblerTables::emitOpcodeDecision(raw_ostream &o1, raw_ostream &o2,769unsigned &i1, unsigned &i2,770unsigned &ModRMTableNum,771OpcodeDecision &opDecision) const {772o2 << "{";773++i2;774775unsigned index;776for (index = 0; index < 256; ++index) {777auto &decision = opDecision.modRMDecisions[index];778ModRMDecisionType dt = getDecisionType(decision);779if (!(dt == MODRM_ONEENTRY && decision.instructionIDs[0] == 0))780break;781}782if (index == 256) {783// If all 256 entries are MODRM_ONEENTRY, omit output.784static_assert(MODRM_ONEENTRY == 0);785--i2;786o2 << "},\n";787} else {788o2 << " /* struct OpcodeDecision */ {\n";789for (index = 0; index < 256; ++index) {790o2.indent(i2);791792o2 << "/*0x" << format("%02hhx", index) << "*/";793794emitModRMDecision(o1, o2, i1, i2, ModRMTableNum,795opDecision.modRMDecisions[index]);796797if (index < 255)798o2 << ",";799800o2 << "\n";801}802o2.indent(i2) << "}\n";803--i2;804o2.indent(i2) << "},\n";805}806}807808void DisassemblerTables::emitContextDecision(raw_ostream &o1, raw_ostream &o2,809unsigned &i1, unsigned &i2,810unsigned &ModRMTableNum,811ContextDecision &decision,812const char *name) const {813o2.indent(i2) << "static const struct ContextDecision " << name814<< " = {{/* opcodeDecisions */\n";815i2++;816817for (unsigned index = 0; index < IC_max; ++index) {818o2.indent(i2) << "/*";819o2 << stringForContext((InstructionContext)index);820o2 << "*/ ";821822emitOpcodeDecision(o1, o2, i1, i2, ModRMTableNum,823decision.opcodeDecisions[index]);824}825826i2--;827o2.indent(i2) << "}};"828<< "\n";829}830831void DisassemblerTables::emitInstructionInfo(raw_ostream &o,832unsigned &i) const {833unsigned NumInstructions = InstructionSpecifiers.size();834835o << "static const struct OperandSpecifier x86OperandSets[]["836<< X86_MAX_OPERANDS << "] = {\n";837838typedef SmallVector<std::pair<OperandEncoding, OperandType>, X86_MAX_OPERANDS>839OperandListTy;840std::map<OperandListTy, unsigned> OperandSets;841842unsigned OperandSetNum = 0;843for (unsigned Index = 0; Index < NumInstructions; ++Index) {844OperandListTy OperandList;845846for (auto Operand : InstructionSpecifiers[Index].operands) {847OperandEncoding Encoding = (OperandEncoding)Operand.encoding;848OperandType Type = (OperandType)Operand.type;849OperandList.push_back(std::pair(Encoding, Type));850}851unsigned &N = OperandSets[OperandList];852if (N != 0)853continue;854855N = ++OperandSetNum;856857o << " { /* " << (OperandSetNum - 1) << " */\n";858for (unsigned i = 0, e = OperandList.size(); i != e; ++i) {859const char *Encoding = stringForOperandEncoding(OperandList[i].first);860const char *Type = stringForOperandType(OperandList[i].second);861o << " { " << Encoding << ", " << Type << " },\n";862}863o << " },\n";864}865o << "};"866<< "\n\n";867868o.indent(i * 2) << "static const struct InstructionSpecifier ";869o << INSTRUCTIONS_STR "[" << InstructionSpecifiers.size() << "] = {\n";870871i++;872873for (unsigned index = 0; index < NumInstructions; ++index) {874o.indent(i * 2) << "{ /* " << index << " */\n";875i++;876877OperandListTy OperandList;878for (auto Operand : InstructionSpecifiers[index].operands) {879OperandEncoding Encoding = (OperandEncoding)Operand.encoding;880OperandType Type = (OperandType)Operand.type;881OperandList.push_back(std::pair(Encoding, Type));882}883o.indent(i * 2) << (OperandSets[OperandList] - 1) << ",\n";884885o.indent(i * 2) << "/* " << InstructionSpecifiers[index].name << " */\n";886887i--;888o.indent(i * 2) << "},\n";889}890891i--;892o.indent(i * 2) << "};"893<< "\n";894}895896void DisassemblerTables::emitContextTable(raw_ostream &o, unsigned &i) const {897o.indent(i * 2) << "static const uint8_t " CONTEXTS_STR "[" << ATTR_max898<< "] = {\n";899i++;900901for (unsigned index = 0; index < ATTR_max; ++index) {902o.indent(i * 2);903904if ((index & ATTR_EVEX) && (index & ATTR_ADSIZE) && (index & ATTR_OPSIZE))905o << "IC_EVEX_OPSIZE_ADSIZE";906else if ((index & ATTR_EVEX) && (index & ATTR_ADSIZE) && (index & ATTR_XD))907o << "IC_EVEX_XD_ADSIZE";908else if ((index & ATTR_EVEX) && (index & ATTR_ADSIZE) && (index & ATTR_XS))909o << "IC_EVEX_XS_ADSIZE";910else if (index & ATTR_EVEXNF) {911o << "IC_EVEX";912if (index & ATTR_REXW)913o << "_W";914else if (index & ATTR_OPSIZE)915o << "_OPSIZE";916917if (index & ATTR_EVEXB)918o << "_B";919920o << "_NF";921} else if ((index & ATTR_EVEX) || (index & ATTR_VEX) ||922(index & ATTR_VEXL)) {923if (index & ATTR_EVEX)924o << "IC_EVEX";925else926o << "IC_VEX";927928if ((index & ATTR_EVEX) && (index & ATTR_EVEXL2))929o << "_L2";930else if (index & ATTR_VEXL)931o << "_L";932933if (index & ATTR_REXW)934o << "_W";935936if (index & ATTR_OPSIZE)937o << "_OPSIZE";938else if (index & ATTR_XD)939o << "_XD";940else if (index & ATTR_XS)941o << "_XS";942943if (index & ATTR_EVEX) {944if (index & ATTR_EVEXKZ)945o << "_KZ";946else if (index & ATTR_EVEXK)947o << "_K";948949if (index & ATTR_EVEXB)950o << "_B";951}952} else if ((index & ATTR_64BIT) && (index & ATTR_REX2))953o << "IC_64BIT_REX2";954else if ((index & ATTR_64BIT) && (index & ATTR_REXW) && (index & ATTR_XS))955o << "IC_64BIT_REXW_XS";956else if ((index & ATTR_64BIT) && (index & ATTR_REXW) && (index & ATTR_XD))957o << "IC_64BIT_REXW_XD";958else if ((index & ATTR_64BIT) && (index & ATTR_REXW) &&959(index & ATTR_OPSIZE))960o << "IC_64BIT_REXW_OPSIZE";961else if ((index & ATTR_64BIT) && (index & ATTR_REXW) &&962(index & ATTR_ADSIZE))963o << "IC_64BIT_REXW_ADSIZE";964else if ((index & ATTR_64BIT) && (index & ATTR_XD) && (index & ATTR_OPSIZE))965o << "IC_64BIT_XD_OPSIZE";966else if ((index & ATTR_64BIT) && (index & ATTR_XD) && (index & ATTR_ADSIZE))967o << "IC_64BIT_XD_ADSIZE";968else if ((index & ATTR_64BIT) && (index & ATTR_XS) && (index & ATTR_OPSIZE))969o << "IC_64BIT_XS_OPSIZE";970else if ((index & ATTR_64BIT) && (index & ATTR_XS) && (index & ATTR_ADSIZE))971o << "IC_64BIT_XS_ADSIZE";972else if ((index & ATTR_64BIT) && (index & ATTR_XS))973o << "IC_64BIT_XS";974else if ((index & ATTR_64BIT) && (index & ATTR_XD))975o << "IC_64BIT_XD";976else if ((index & ATTR_64BIT) && (index & ATTR_OPSIZE) &&977(index & ATTR_ADSIZE))978o << "IC_64BIT_OPSIZE_ADSIZE";979else if ((index & ATTR_64BIT) && (index & ATTR_OPSIZE))980o << "IC_64BIT_OPSIZE";981else if ((index & ATTR_64BIT) && (index & ATTR_ADSIZE))982o << "IC_64BIT_ADSIZE";983else if ((index & ATTR_64BIT) && (index & ATTR_REXW))984o << "IC_64BIT_REXW";985else if ((index & ATTR_64BIT))986o << "IC_64BIT";987else if ((index & ATTR_XS) && (index & ATTR_OPSIZE))988o << "IC_XS_OPSIZE";989else if ((index & ATTR_XD) && (index & ATTR_OPSIZE))990o << "IC_XD_OPSIZE";991else if ((index & ATTR_XS) && (index & ATTR_ADSIZE))992o << "IC_XS_ADSIZE";993else if ((index & ATTR_XD) && (index & ATTR_ADSIZE))994o << "IC_XD_ADSIZE";995else if (index & ATTR_XS)996o << "IC_XS";997else if (index & ATTR_XD)998o << "IC_XD";999else if ((index & ATTR_OPSIZE) && (index & ATTR_ADSIZE))1000o << "IC_OPSIZE_ADSIZE";1001else if (index & ATTR_OPSIZE)1002o << "IC_OPSIZE";1003else if (index & ATTR_ADSIZE)1004o << "IC_ADSIZE";1005else1006o << "IC";10071008o << ", // " << index << "\n";1009}10101011i--;1012o.indent(i * 2) << "};"1013<< "\n";1014}10151016void DisassemblerTables::emitContextDecisions(raw_ostream &o1, raw_ostream &o2,1017unsigned &i1, unsigned &i2,1018unsigned &ModRMTableNum) const {1019emitContextDecision(o1, o2, i1, i2, ModRMTableNum, *Tables[0], ONEBYTE_STR);1020emitContextDecision(o1, o2, i1, i2, ModRMTableNum, *Tables[1], TWOBYTE_STR);1021emitContextDecision(o1, o2, i1, i2, ModRMTableNum, *Tables[2],1022THREEBYTE38_STR);1023emitContextDecision(o1, o2, i1, i2, ModRMTableNum, *Tables[3],1024THREEBYTE3A_STR);1025emitContextDecision(o1, o2, i1, i2, ModRMTableNum, *Tables[4], XOP8_MAP_STR);1026emitContextDecision(o1, o2, i1, i2, ModRMTableNum, *Tables[5], XOP9_MAP_STR);1027emitContextDecision(o1, o2, i1, i2, ModRMTableNum, *Tables[6], XOPA_MAP_STR);1028emitContextDecision(o1, o2, i1, i2, ModRMTableNum, *Tables[7],1029THREEDNOW_MAP_STR);1030emitContextDecision(o1, o2, i1, i2, ModRMTableNum, *Tables[8], MAP4_STR);1031emitContextDecision(o1, o2, i1, i2, ModRMTableNum, *Tables[9], MAP5_STR);1032emitContextDecision(o1, o2, i1, i2, ModRMTableNum, *Tables[10], MAP6_STR);1033emitContextDecision(o1, o2, i1, i2, ModRMTableNum, *Tables[11], MAP7_STR);1034}10351036void DisassemblerTables::emit(raw_ostream &o) const {1037unsigned i1 = 0;1038unsigned i2 = 0;10391040std::string s1;1041std::string s2;10421043raw_string_ostream o1(s1);1044raw_string_ostream o2(s2);10451046emitInstructionInfo(o, i2);1047o << "\n";10481049emitContextTable(o, i2);1050o << "\n";10511052unsigned ModRMTableNum = 0;10531054o << "static const InstrUID modRMTable[] = {\n";1055i1++;1056std::vector<unsigned> EmptyTable(1, 0);1057ModRMTable[EmptyTable] = ModRMTableNum;1058ModRMTableNum += EmptyTable.size();1059o1 << "/*EmptyTable*/\n";1060o1.indent(i1 * 2) << "0x0,\n";1061i1--;1062emitContextDecisions(o1, o2, i1, i2, ModRMTableNum);10631064o << s1;1065o << " 0x0\n";1066o << "};\n";1067o << "\n";1068o << s2;1069o << "\n";1070o << "\n";1071}10721073void DisassemblerTables::setTableFields(ModRMDecision &decision,1074const ModRMFilter &filter, InstrUID uid,1075uint8_t opcode) {1076for (unsigned index = 0; index < 256; ++index) {1077if (filter.accepts(index)) {1078if (decision.instructionIDs[index] == uid)1079continue;10801081if (decision.instructionIDs[index] != 0) {1082InstructionSpecifier &newInfo = InstructionSpecifiers[uid];1083InstructionSpecifier &previousInfo =1084InstructionSpecifiers[decision.instructionIDs[index]];10851086if (previousInfo.name == "NOOP" &&1087(newInfo.name == "XCHG16ar" || newInfo.name == "XCHG32ar" ||1088newInfo.name == "XCHG64ar"))1089continue; // special case for XCHG*ar and NOOP10901091if (outranks(previousInfo.insnContext, newInfo.insnContext))1092continue;10931094if (previousInfo.insnContext == newInfo.insnContext) {1095errs() << "Error: Primary decode conflict: ";1096errs() << newInfo.name << " would overwrite " << previousInfo.name;1097errs() << "\n";1098errs() << "ModRM " << index << "\n";1099errs() << "Opcode " << (uint16_t)opcode << "\n";1100errs() << "Context " << stringForContext(newInfo.insnContext) << "\n";1101HasConflicts = true;1102}1103}11041105decision.instructionIDs[index] = uid;1106}1107}1108}11091110void DisassemblerTables::setTableFields(1111OpcodeType type, InstructionContext insnContext, uint8_t opcode,1112const ModRMFilter &filter, InstrUID uid, bool is32bit, bool noPrefix,1113bool ignoresVEX_L, bool ignoresW, unsigned addressSize) {1114ContextDecision &decision = *Tables[type];11151116for (unsigned index = 0; index < IC_max; ++index) {1117if ((is32bit || addressSize == 16) &&1118inheritsFrom((InstructionContext)index, IC_64BIT))1119continue;11201121bool adSize64 = addressSize == 64;1122if (inheritsFrom((InstructionContext)index,1123InstructionSpecifiers[uid].insnContext, noPrefix,1124ignoresVEX_L, ignoresW, adSize64))1125setTableFields(decision.opcodeDecisions[index].modRMDecisions[opcode],1126filter, uid, opcode);1127}1128}112911301131