1201360Srdivacky//===- X86DisassemblerTables.cpp - Disassembler tables ----------*- C++ -*-===// 2201360Srdivacky// 3353358Sdim// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4353358Sdim// See https://llvm.org/LICENSE.txt for license information. 5353358Sdim// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6201360Srdivacky// 7201360Srdivacky//===----------------------------------------------------------------------===// 8201360Srdivacky// 9201360Srdivacky// This file is part of the X86 Disassembler Emitter. 10201360Srdivacky// It contains the implementation of the disassembler tables. 11201360Srdivacky// Documentation for the disassembler emitter in general can be found in 12321369Sdim// X86DisassemblerEmitter.h. 13201360Srdivacky// 14201360Srdivacky//===----------------------------------------------------------------------===// 15201360Srdivacky 16249423Sdim#include "X86DisassemblerTables.h" 17201360Srdivacky#include "X86DisassemblerShared.h" 18221345Sdim#include "llvm/ADT/STLExtras.h" 19201360Srdivacky#include "llvm/Support/ErrorHandling.h" 20201360Srdivacky#include "llvm/Support/Format.h" 21239462Sdim#include <map> 22201360Srdivacky 23201360Srdivackyusing namespace llvm; 24201360Srdivackyusing namespace X86Disassembler; 25239462Sdim 26276479Sdim/// stringForContext - Returns a string containing the name of a particular 27276479Sdim/// InstructionContext, usually for diagnostic purposes. 28276479Sdim/// 29276479Sdim/// @param insnContext - The instruction class to transform to a string. 30276479Sdim/// @return - A statically-allocated string constant that contains the 31276479Sdim/// name of the instruction class. 32276479Sdimstatic inline const char* stringForContext(InstructionContext insnContext) { 33276479Sdim switch (insnContext) { 34276479Sdim default: 35276479Sdim llvm_unreachable("Unhandled instruction class"); 36276479Sdim#define ENUM_ENTRY(n, r, d) case n: return #n; break; 37276479Sdim#define ENUM_ENTRY_K_B(n, r, d) ENUM_ENTRY(n, r, d) ENUM_ENTRY(n##_K_B, r, d)\ 38276479Sdim ENUM_ENTRY(n##_KZ, r, d) ENUM_ENTRY(n##_K, r, d) ENUM_ENTRY(n##_B, r, d)\ 39276479Sdim ENUM_ENTRY(n##_KZ_B, r, d) 40276479Sdim INSTRUCTION_CONTEXTS 41276479Sdim#undef ENUM_ENTRY 42276479Sdim#undef ENUM_ENTRY_K_B 43276479Sdim } 44276479Sdim} 45276479Sdim 46276479Sdim/// stringForOperandType - Like stringForContext, but for OperandTypes. 47276479Sdimstatic inline const char* stringForOperandType(OperandType type) { 48276479Sdim switch (type) { 49276479Sdim default: 50276479Sdim llvm_unreachable("Unhandled type"); 51276479Sdim#define ENUM_ENTRY(i, d) case i: return #i; 52276479Sdim TYPES 53276479Sdim#undef ENUM_ENTRY 54276479Sdim } 55276479Sdim} 56276479Sdim 57276479Sdim/// stringForOperandEncoding - like stringForContext, but for 58276479Sdim/// OperandEncodings. 59276479Sdimstatic inline const char* stringForOperandEncoding(OperandEncoding encoding) { 60276479Sdim switch (encoding) { 61276479Sdim default: 62276479Sdim llvm_unreachable("Unhandled encoding"); 63276479Sdim#define ENUM_ENTRY(i, d) case i: return #i; 64276479Sdim ENCODINGS 65276479Sdim#undef ENUM_ENTRY 66276479Sdim } 67276479Sdim} 68276479Sdim 69201360Srdivacky/// inheritsFrom - Indicates whether all instructions in one class also belong 70201360Srdivacky/// to another class. 71201360Srdivacky/// 72201360Srdivacky/// @param child - The class that may be the subset 73201360Srdivacky/// @param parent - The class that may be the superset 74201360Srdivacky/// @return - True if child is a subset of parent, false otherwise. 75201360Srdivackystatic inline bool inheritsFrom(InstructionContext child, 76327952Sdim InstructionContext parent, bool noPrefix = true, 77327952Sdim bool VEX_LIG = false, bool VEX_WIG = false, 78327952Sdim bool AdSize64 = false) { 79201360Srdivacky if (child == parent) 80201360Srdivacky return true; 81239462Sdim 82201360Srdivacky switch (parent) { 83201360Srdivacky case IC: 84280031Sdim return(inheritsFrom(child, IC_64BIT, AdSize64) || 85327952Sdim (noPrefix && inheritsFrom(child, IC_OPSIZE, noPrefix)) || 86234353Sdim inheritsFrom(child, IC_ADSIZE) || 87327952Sdim (noPrefix && inheritsFrom(child, IC_XD, noPrefix)) || 88327952Sdim (noPrefix && inheritsFrom(child, IC_XS, noPrefix))); 89201360Srdivacky case IC_64BIT: 90201360Srdivacky return(inheritsFrom(child, IC_64BIT_REXW) || 91327952Sdim (noPrefix && inheritsFrom(child, IC_64BIT_OPSIZE, noPrefix)) || 92280031Sdim (!AdSize64 && inheritsFrom(child, IC_64BIT_ADSIZE)) || 93327952Sdim (noPrefix && inheritsFrom(child, IC_64BIT_XD, noPrefix)) || 94327952Sdim (noPrefix && inheritsFrom(child, IC_64BIT_XS, noPrefix))); 95201360Srdivacky case IC_OPSIZE: 96280031Sdim return inheritsFrom(child, IC_64BIT_OPSIZE) || 97280031Sdim inheritsFrom(child, IC_OPSIZE_ADSIZE); 98234353Sdim case IC_ADSIZE: 99327952Sdim return (noPrefix && inheritsFrom(child, IC_OPSIZE_ADSIZE, noPrefix)); 100280031Sdim case IC_OPSIZE_ADSIZE: 101280031Sdim return false; 102234353Sdim case IC_64BIT_ADSIZE: 103327952Sdim return (noPrefix && inheritsFrom(child, IC_64BIT_OPSIZE_ADSIZE, noPrefix)); 104280031Sdim case IC_64BIT_OPSIZE_ADSIZE: 105234353Sdim return false; 106201360Srdivacky case IC_XD: 107226633Sdim return inheritsFrom(child, IC_64BIT_XD); 108201360Srdivacky case IC_XS: 109226633Sdim return inheritsFrom(child, IC_64BIT_XS); 110226633Sdim case IC_XD_OPSIZE: 111226633Sdim return inheritsFrom(child, IC_64BIT_XD_OPSIZE); 112226633Sdim case IC_XS_OPSIZE: 113226633Sdim return inheritsFrom(child, IC_64BIT_XS_OPSIZE); 114341825Sdim case IC_XD_ADSIZE: 115341825Sdim return inheritsFrom(child, IC_64BIT_XD_ADSIZE); 116341825Sdim case IC_XS_ADSIZE: 117341825Sdim return inheritsFrom(child, IC_64BIT_XS_ADSIZE); 118201360Srdivacky case IC_64BIT_REXW: 119327952Sdim return((noPrefix && inheritsFrom(child, IC_64BIT_REXW_XS, noPrefix)) || 120327952Sdim (noPrefix && inheritsFrom(child, IC_64BIT_REXW_XD, noPrefix)) || 121327952Sdim (noPrefix && inheritsFrom(child, IC_64BIT_REXW_OPSIZE, noPrefix)) || 122280031Sdim (!AdSize64 && inheritsFrom(child, IC_64BIT_REXW_ADSIZE))); 123201360Srdivacky case IC_64BIT_OPSIZE: 124280031Sdim return inheritsFrom(child, IC_64BIT_REXW_OPSIZE) || 125280031Sdim (!AdSize64 && inheritsFrom(child, IC_64BIT_OPSIZE_ADSIZE)) || 126280031Sdim (!AdSize64 && inheritsFrom(child, IC_64BIT_REXW_ADSIZE)); 127201360Srdivacky case IC_64BIT_XD: 128341825Sdim return(inheritsFrom(child, IC_64BIT_REXW_XD) || 129341825Sdim (!AdSize64 && inheritsFrom(child, IC_64BIT_XD_ADSIZE))); 130201360Srdivacky case IC_64BIT_XS: 131341825Sdim return(inheritsFrom(child, IC_64BIT_REXW_XS) || 132341825Sdim (!AdSize64 && inheritsFrom(child, IC_64BIT_XS_ADSIZE))); 133226633Sdim case IC_64BIT_XD_OPSIZE: 134226633Sdim case IC_64BIT_XS_OPSIZE: 135226633Sdim return false; 136341825Sdim case IC_64BIT_XD_ADSIZE: 137341825Sdim case IC_64BIT_XS_ADSIZE: 138341825Sdim return false; 139201360Srdivacky case IC_64BIT_REXW_XD: 140201360Srdivacky case IC_64BIT_REXW_XS: 141201360Srdivacky case IC_64BIT_REXW_OPSIZE: 142280031Sdim case IC_64BIT_REXW_ADSIZE: 143201360Srdivacky return false; 144221345Sdim case IC_VEX: 145327952Sdim return (VEX_LIG && VEX_WIG && inheritsFrom(child, IC_VEX_L_W)) || 146327952Sdim (VEX_WIG && inheritsFrom(child, IC_VEX_W)) || 147226633Sdim (VEX_LIG && inheritsFrom(child, IC_VEX_L)); 148221345Sdim case IC_VEX_XS: 149327952Sdim return (VEX_LIG && VEX_WIG && inheritsFrom(child, IC_VEX_L_W_XS)) || 150327952Sdim (VEX_WIG && inheritsFrom(child, IC_VEX_W_XS)) || 151226633Sdim (VEX_LIG && inheritsFrom(child, IC_VEX_L_XS)); 152221345Sdim case IC_VEX_XD: 153327952Sdim return (VEX_LIG && VEX_WIG && inheritsFrom(child, IC_VEX_L_W_XD)) || 154327952Sdim (VEX_WIG && inheritsFrom(child, IC_VEX_W_XD)) || 155226633Sdim (VEX_LIG && inheritsFrom(child, IC_VEX_L_XD)); 156226633Sdim case IC_VEX_OPSIZE: 157327952Sdim return (VEX_LIG && VEX_WIG && inheritsFrom(child, IC_VEX_L_W_OPSIZE)) || 158327952Sdim (VEX_WIG && inheritsFrom(child, IC_VEX_W_OPSIZE)) || 159226633Sdim (VEX_LIG && inheritsFrom(child, IC_VEX_L_OPSIZE)); 160226633Sdim case IC_VEX_W: 161261991Sdim return VEX_LIG && inheritsFrom(child, IC_VEX_L_W); 162226633Sdim case IC_VEX_W_XS: 163261991Sdim return VEX_LIG && inheritsFrom(child, IC_VEX_L_W_XS); 164226633Sdim case IC_VEX_W_XD: 165261991Sdim return VEX_LIG && inheritsFrom(child, IC_VEX_L_W_XD); 166226633Sdim case IC_VEX_W_OPSIZE: 167261991Sdim return VEX_LIG && inheritsFrom(child, IC_VEX_L_W_OPSIZE); 168221345Sdim case IC_VEX_L: 169327952Sdim return VEX_WIG && inheritsFrom(child, IC_VEX_L_W); 170221345Sdim case IC_VEX_L_XS: 171327952Sdim return VEX_WIG && inheritsFrom(child, IC_VEX_L_W_XS); 172221345Sdim case IC_VEX_L_XD: 173327952Sdim return VEX_WIG && inheritsFrom(child, IC_VEX_L_W_XD); 174226633Sdim case IC_VEX_L_OPSIZE: 175327952Sdim return VEX_WIG && inheritsFrom(child, IC_VEX_L_W_OPSIZE); 176261991Sdim case IC_VEX_L_W: 177261991Sdim case IC_VEX_L_W_XS: 178261991Sdim case IC_VEX_L_W_XD: 179234353Sdim case IC_VEX_L_W_OPSIZE: 180221345Sdim return false; 181261991Sdim case IC_EVEX: 182327952Sdim return (VEX_LIG && VEX_WIG && inheritsFrom(child, IC_EVEX_L_W)) || 183327952Sdim (VEX_LIG && VEX_WIG && inheritsFrom(child, IC_EVEX_L2_W)) || 184327952Sdim (VEX_WIG && inheritsFrom(child, IC_EVEX_W)) || 185327952Sdim (VEX_LIG && inheritsFrom(child, IC_EVEX_L)) || 186327952Sdim (VEX_LIG && inheritsFrom(child, IC_EVEX_L2)); 187261991Sdim case IC_EVEX_XS: 188327952Sdim return (VEX_LIG && VEX_WIG && inheritsFrom(child, IC_EVEX_L_W_XS)) || 189327952Sdim (VEX_LIG && VEX_WIG && inheritsFrom(child, IC_EVEX_L2_W_XS)) || 190327952Sdim (VEX_WIG && inheritsFrom(child, IC_EVEX_W_XS)) || 191327952Sdim (VEX_LIG && inheritsFrom(child, IC_EVEX_L_XS)) || 192327952Sdim (VEX_LIG && inheritsFrom(child, IC_EVEX_L2_XS)); 193261991Sdim case IC_EVEX_XD: 194327952Sdim return (VEX_LIG && VEX_WIG && inheritsFrom(child, IC_EVEX_L_W_XD)) || 195327952Sdim (VEX_LIG && VEX_WIG && inheritsFrom(child, IC_EVEX_L2_W_XD)) || 196327952Sdim (VEX_WIG && inheritsFrom(child, IC_EVEX_W_XD)) || 197327952Sdim (VEX_LIG && inheritsFrom(child, IC_EVEX_L_XD)) || 198327952Sdim (VEX_LIG && inheritsFrom(child, IC_EVEX_L2_XD)); 199261991Sdim case IC_EVEX_OPSIZE: 200327952Sdim return (VEX_LIG && VEX_WIG && inheritsFrom(child, IC_EVEX_L_W_OPSIZE)) || 201327952Sdim (VEX_LIG && VEX_WIG && inheritsFrom(child, IC_EVEX_L2_W_OPSIZE)) || 202327952Sdim (VEX_WIG && inheritsFrom(child, IC_EVEX_W_OPSIZE)) || 203327952Sdim (VEX_LIG && inheritsFrom(child, IC_EVEX_L_OPSIZE)) || 204327952Sdim (VEX_LIG && inheritsFrom(child, IC_EVEX_L2_OPSIZE)); 205327952Sdim case IC_EVEX_K: 206327952Sdim return (VEX_LIG && VEX_WIG && inheritsFrom(child, IC_EVEX_L_W_K)) || 207327952Sdim (VEX_LIG && VEX_WIG && inheritsFrom(child, IC_EVEX_L2_W_K)) || 208327952Sdim (VEX_WIG && inheritsFrom(child, IC_EVEX_W_K)) || 209327952Sdim (VEX_LIG && inheritsFrom(child, IC_EVEX_L_K)) || 210327952Sdim (VEX_LIG && inheritsFrom(child, IC_EVEX_L2_K)); 211327952Sdim case IC_EVEX_XS_K: 212327952Sdim return (VEX_LIG && VEX_WIG && inheritsFrom(child, IC_EVEX_L_W_XS_K)) || 213327952Sdim (VEX_LIG && VEX_WIG && inheritsFrom(child, IC_EVEX_L2_W_XS_K)) || 214327952Sdim (VEX_WIG && inheritsFrom(child, IC_EVEX_W_XS_K)) || 215327952Sdim (VEX_LIG && inheritsFrom(child, IC_EVEX_L_XS_K)) || 216327952Sdim (VEX_LIG && inheritsFrom(child, IC_EVEX_L2_XS_K)); 217327952Sdim case IC_EVEX_XD_K: 218327952Sdim return (VEX_LIG && VEX_WIG && inheritsFrom(child, IC_EVEX_L_W_XD_K)) || 219327952Sdim (VEX_LIG && VEX_WIG && inheritsFrom(child, IC_EVEX_L2_W_XD_K)) || 220327952Sdim (VEX_WIG && inheritsFrom(child, IC_EVEX_W_XD_K)) || 221327952Sdim (VEX_LIG && inheritsFrom(child, IC_EVEX_L_XD_K)) || 222327952Sdim (VEX_LIG && inheritsFrom(child, IC_EVEX_L2_XD_K)); 223327952Sdim case IC_EVEX_OPSIZE_K: 224327952Sdim return (VEX_LIG && VEX_WIG && inheritsFrom(child, IC_EVEX_L_W_OPSIZE_K)) || 225327952Sdim (VEX_LIG && VEX_WIG && inheritsFrom(child, IC_EVEX_L2_W_OPSIZE_K)) || 226327952Sdim (VEX_WIG && inheritsFrom(child, IC_EVEX_W_OPSIZE_K)) || 227327952Sdim (VEX_LIG && inheritsFrom(child, IC_EVEX_L_OPSIZE_K)) || 228327952Sdim (VEX_LIG && inheritsFrom(child, IC_EVEX_L2_OPSIZE_K)); 229327952Sdim case IC_EVEX_KZ: 230327952Sdim return (VEX_LIG && VEX_WIG && inheritsFrom(child, IC_EVEX_L_W_KZ)) || 231327952Sdim (VEX_LIG && VEX_WIG && inheritsFrom(child, IC_EVEX_L2_W_KZ)) || 232327952Sdim (VEX_WIG && inheritsFrom(child, IC_EVEX_W_KZ)) || 233327952Sdim (VEX_LIG && inheritsFrom(child, IC_EVEX_L_KZ)) || 234327952Sdim (VEX_LIG && inheritsFrom(child, IC_EVEX_L2_KZ)); 235327952Sdim case IC_EVEX_XS_KZ: 236327952Sdim return (VEX_LIG && VEX_WIG && inheritsFrom(child, IC_EVEX_L_W_XS_KZ)) || 237327952Sdim (VEX_LIG && VEX_WIG && inheritsFrom(child, IC_EVEX_L2_W_XS_KZ)) || 238327952Sdim (VEX_WIG && inheritsFrom(child, IC_EVEX_W_XS_KZ)) || 239327952Sdim (VEX_LIG && inheritsFrom(child, IC_EVEX_L_XS_KZ)) || 240327952Sdim (VEX_LIG && inheritsFrom(child, IC_EVEX_L2_XS_KZ)); 241327952Sdim case IC_EVEX_XD_KZ: 242327952Sdim return (VEX_LIG && VEX_WIG && inheritsFrom(child, IC_EVEX_L_W_XD_KZ)) || 243327952Sdim (VEX_LIG && VEX_WIG && inheritsFrom(child, IC_EVEX_L2_W_XD_KZ)) || 244327952Sdim (VEX_WIG && inheritsFrom(child, IC_EVEX_W_XD_KZ)) || 245327952Sdim (VEX_LIG && inheritsFrom(child, IC_EVEX_L_XD_KZ)) || 246327952Sdim (VEX_LIG && inheritsFrom(child, IC_EVEX_L2_XD_KZ)); 247327952Sdim case IC_EVEX_OPSIZE_KZ: 248327952Sdim return (VEX_LIG && VEX_WIG && inheritsFrom(child, IC_EVEX_L_W_OPSIZE_KZ)) || 249327952Sdim (VEX_LIG && VEX_WIG && inheritsFrom(child, IC_EVEX_L2_W_OPSIZE_KZ)) || 250327952Sdim (VEX_WIG && inheritsFrom(child, IC_EVEX_W_OPSIZE_KZ)) || 251327952Sdim (VEX_LIG && inheritsFrom(child, IC_EVEX_L_OPSIZE_KZ)) || 252327952Sdim (VEX_LIG && inheritsFrom(child, IC_EVEX_L2_OPSIZE_KZ)); 253261991Sdim case IC_EVEX_W: 254327952Sdim return (VEX_LIG && inheritsFrom(child, IC_EVEX_L_W)) || 255327952Sdim (VEX_LIG && inheritsFrom(child, IC_EVEX_L2_W)); 256261991Sdim case IC_EVEX_W_XS: 257327952Sdim return (VEX_LIG && inheritsFrom(child, IC_EVEX_L_W_XS)) || 258327952Sdim (VEX_LIG && inheritsFrom(child, IC_EVEX_L2_W_XS)); 259261991Sdim case IC_EVEX_W_XD: 260327952Sdim return (VEX_LIG && inheritsFrom(child, IC_EVEX_L_W_XD)) || 261327952Sdim (VEX_LIG && inheritsFrom(child, IC_EVEX_L2_W_XD)); 262261991Sdim case IC_EVEX_W_OPSIZE: 263327952Sdim return (VEX_LIG && inheritsFrom(child, IC_EVEX_L_W_OPSIZE)) || 264327952Sdim (VEX_LIG && inheritsFrom(child, IC_EVEX_L2_W_OPSIZE)); 265327952Sdim case IC_EVEX_W_K: 266327952Sdim return (VEX_LIG && inheritsFrom(child, IC_EVEX_L_W_K)) || 267327952Sdim (VEX_LIG && inheritsFrom(child, IC_EVEX_L2_W_K)); 268327952Sdim case IC_EVEX_W_XS_K: 269327952Sdim return (VEX_LIG && inheritsFrom(child, IC_EVEX_L_W_XS_K)) || 270327952Sdim (VEX_LIG && inheritsFrom(child, IC_EVEX_L2_W_XS_K)); 271327952Sdim case IC_EVEX_W_XD_K: 272327952Sdim return (VEX_LIG && inheritsFrom(child, IC_EVEX_L_W_XD_K)) || 273327952Sdim (VEX_LIG && inheritsFrom(child, IC_EVEX_L2_W_XD_K)); 274327952Sdim case IC_EVEX_W_OPSIZE_K: 275327952Sdim return (VEX_LIG && inheritsFrom(child, IC_EVEX_L_W_OPSIZE_K)) || 276327952Sdim (VEX_LIG && inheritsFrom(child, IC_EVEX_L2_W_OPSIZE_K)); 277327952Sdim case IC_EVEX_W_KZ: 278327952Sdim return (VEX_LIG && inheritsFrom(child, IC_EVEX_L_W_KZ)) || 279327952Sdim (VEX_LIG && inheritsFrom(child, IC_EVEX_L2_W_KZ)); 280327952Sdim case IC_EVEX_W_XS_KZ: 281327952Sdim return (VEX_LIG && inheritsFrom(child, IC_EVEX_L_W_XS_KZ)) || 282327952Sdim (VEX_LIG && inheritsFrom(child, IC_EVEX_L2_W_XS_KZ)); 283327952Sdim case IC_EVEX_W_XD_KZ: 284327952Sdim return (VEX_LIG && inheritsFrom(child, IC_EVEX_L_W_XD_KZ)) || 285327952Sdim (VEX_LIG && inheritsFrom(child, IC_EVEX_L2_W_XD_KZ)); 286327952Sdim case IC_EVEX_W_OPSIZE_KZ: 287327952Sdim return (VEX_LIG && inheritsFrom(child, IC_EVEX_L_W_OPSIZE_KZ)) || 288327952Sdim (VEX_LIG && inheritsFrom(child, IC_EVEX_L2_W_OPSIZE_KZ)); 289261991Sdim case IC_EVEX_L: 290327952Sdim return VEX_WIG && inheritsFrom(child, IC_EVEX_L_W); 291261991Sdim case IC_EVEX_L_XS: 292327952Sdim return VEX_WIG && inheritsFrom(child, IC_EVEX_L_W_XS); 293261991Sdim case IC_EVEX_L_XD: 294327952Sdim return VEX_WIG && inheritsFrom(child, IC_EVEX_L_W_XD); 295261991Sdim case IC_EVEX_L_OPSIZE: 296327952Sdim return VEX_WIG && inheritsFrom(child, IC_EVEX_L_W_OPSIZE); 297327952Sdim case IC_EVEX_L_K: 298327952Sdim return VEX_WIG && inheritsFrom(child, IC_EVEX_L_W_K); 299327952Sdim case IC_EVEX_L_XS_K: 300327952Sdim return VEX_WIG && inheritsFrom(child, IC_EVEX_L_W_XS_K); 301327952Sdim case IC_EVEX_L_XD_K: 302327952Sdim return VEX_WIG && inheritsFrom(child, IC_EVEX_L_W_XD_K); 303327952Sdim case IC_EVEX_L_OPSIZE_K: 304327952Sdim return VEX_WIG && inheritsFrom(child, IC_EVEX_L_W_OPSIZE_K); 305327952Sdim case IC_EVEX_L_KZ: 306327952Sdim return VEX_WIG && inheritsFrom(child, IC_EVEX_L_W_KZ); 307327952Sdim case IC_EVEX_L_XS_KZ: 308327952Sdim return VEX_WIG && inheritsFrom(child, IC_EVEX_L_W_XS_KZ); 309327952Sdim case IC_EVEX_L_XD_KZ: 310327952Sdim return VEX_WIG && inheritsFrom(child, IC_EVEX_L_W_XD_KZ); 311327952Sdim case IC_EVEX_L_OPSIZE_KZ: 312327952Sdim return VEX_WIG && inheritsFrom(child, IC_EVEX_L_W_OPSIZE_KZ); 313261991Sdim case IC_EVEX_L_W: 314261991Sdim case IC_EVEX_L_W_XS: 315261991Sdim case IC_EVEX_L_W_XD: 316261991Sdim case IC_EVEX_L_W_OPSIZE: 317261991Sdim return false; 318327952Sdim case IC_EVEX_L_W_K: 319327952Sdim case IC_EVEX_L_W_XS_K: 320327952Sdim case IC_EVEX_L_W_XD_K: 321327952Sdim case IC_EVEX_L_W_OPSIZE_K: 322327952Sdim return false; 323327952Sdim case IC_EVEX_L_W_KZ: 324327952Sdim case IC_EVEX_L_W_XS_KZ: 325327952Sdim case IC_EVEX_L_W_XD_KZ: 326327952Sdim case IC_EVEX_L_W_OPSIZE_KZ: 327327952Sdim return false; 328261991Sdim case IC_EVEX_L2: 329327952Sdim return VEX_WIG && inheritsFrom(child, IC_EVEX_L2_W); 330261991Sdim case IC_EVEX_L2_XS: 331327952Sdim return VEX_WIG && inheritsFrom(child, IC_EVEX_L2_W_XS); 332261991Sdim case IC_EVEX_L2_XD: 333327952Sdim return VEX_WIG && inheritsFrom(child, IC_EVEX_L2_W_XD); 334261991Sdim case IC_EVEX_L2_OPSIZE: 335327952Sdim return VEX_WIG && inheritsFrom(child, IC_EVEX_L2_W_OPSIZE); 336327952Sdim case IC_EVEX_L2_K: 337327952Sdim return VEX_WIG && inheritsFrom(child, IC_EVEX_L2_W_K); 338327952Sdim case IC_EVEX_L2_XS_K: 339327952Sdim return VEX_WIG && inheritsFrom(child, IC_EVEX_L2_W_XS_K); 340327952Sdim case IC_EVEX_L2_XD_K: 341327952Sdim return VEX_WIG && inheritsFrom(child, IC_EVEX_L2_W_XD_K); 342327952Sdim case IC_EVEX_L2_OPSIZE_K: 343327952Sdim return VEX_WIG && inheritsFrom(child, IC_EVEX_L2_W_OPSIZE_K); 344327952Sdim case IC_EVEX_L2_KZ: 345327952Sdim return VEX_WIG && inheritsFrom(child, IC_EVEX_L2_W_KZ); 346327952Sdim case IC_EVEX_L2_XS_KZ: 347327952Sdim return VEX_WIG && inheritsFrom(child, IC_EVEX_L2_W_XS_KZ); 348327952Sdim case IC_EVEX_L2_XD_KZ: 349327952Sdim return VEX_WIG && inheritsFrom(child, IC_EVEX_L2_W_XD_KZ); 350327952Sdim case IC_EVEX_L2_OPSIZE_KZ: 351327952Sdim return VEX_WIG && inheritsFrom(child, IC_EVEX_L2_W_OPSIZE_KZ); 352261991Sdim case IC_EVEX_L2_W: 353261991Sdim case IC_EVEX_L2_W_XS: 354261991Sdim case IC_EVEX_L2_W_XD: 355261991Sdim case IC_EVEX_L2_W_OPSIZE: 356261991Sdim return false; 357327952Sdim case IC_EVEX_L2_W_K: 358327952Sdim case IC_EVEX_L2_W_XS_K: 359327952Sdim case IC_EVEX_L2_W_XD_K: 360327952Sdim case IC_EVEX_L2_W_OPSIZE_K: 361327952Sdim return false; 362327952Sdim case IC_EVEX_L2_W_KZ: 363327952Sdim case IC_EVEX_L2_W_XS_KZ: 364327952Sdim case IC_EVEX_L2_W_XD_KZ: 365327952Sdim case IC_EVEX_L2_W_OPSIZE_KZ: 366327952Sdim return false; 367327952Sdim case IC_EVEX_B: 368327952Sdim return (VEX_LIG && VEX_WIG && inheritsFrom(child, IC_EVEX_L_W_B)) || 369327952Sdim (VEX_LIG && VEX_WIG && inheritsFrom(child, IC_EVEX_L2_W_B)) || 370327952Sdim (VEX_WIG && inheritsFrom(child, IC_EVEX_W_B)) || 371327952Sdim (VEX_LIG && inheritsFrom(child, IC_EVEX_L_B)) || 372327952Sdim (VEX_LIG && inheritsFrom(child, IC_EVEX_L2_B)); 373288943Sdim case IC_EVEX_XS_B: 374327952Sdim return (VEX_LIG && VEX_WIG && inheritsFrom(child, IC_EVEX_L_W_XS_B)) || 375327952Sdim (VEX_LIG && VEX_WIG && inheritsFrom(child, IC_EVEX_L2_W_XS_B)) || 376327952Sdim (VEX_WIG && inheritsFrom(child, IC_EVEX_W_XS_B)) || 377327952Sdim (VEX_LIG && inheritsFrom(child, IC_EVEX_L_XS_B)) || 378327952Sdim (VEX_LIG && inheritsFrom(child, IC_EVEX_L2_XS_B)); 379288943Sdim case IC_EVEX_XD_B: 380327952Sdim return (VEX_LIG && VEX_WIG && inheritsFrom(child, IC_EVEX_L_W_XD_B)) || 381327952Sdim (VEX_LIG && VEX_WIG && inheritsFrom(child, IC_EVEX_L2_W_XD_B)) || 382327952Sdim (VEX_WIG && inheritsFrom(child, IC_EVEX_W_XD_B)) || 383327952Sdim (VEX_LIG && inheritsFrom(child, IC_EVEX_L_XD_B)) || 384327952Sdim (VEX_LIG && inheritsFrom(child, IC_EVEX_L2_XD_B)); 385327952Sdim case IC_EVEX_OPSIZE_B: 386327952Sdim return (VEX_LIG && VEX_WIG && inheritsFrom(child, IC_EVEX_L_W_OPSIZE_B)) || 387327952Sdim (VEX_LIG && VEX_WIG && inheritsFrom(child, IC_EVEX_L2_W_OPSIZE_B)) || 388327952Sdim (VEX_WIG && inheritsFrom(child, IC_EVEX_W_OPSIZE_B)) || 389327952Sdim (VEX_LIG && inheritsFrom(child, IC_EVEX_L_OPSIZE_B)) || 390327952Sdim (VEX_LIG && inheritsFrom(child, IC_EVEX_L2_OPSIZE_B)); 391280031Sdim case IC_EVEX_K_B: 392327952Sdim return (VEX_LIG && VEX_WIG && inheritsFrom(child, IC_EVEX_L_W_K_B)) || 393327952Sdim (VEX_LIG && VEX_WIG && inheritsFrom(child, IC_EVEX_L2_W_K_B)) || 394327952Sdim (VEX_WIG && inheritsFrom(child, IC_EVEX_W_K_B)) || 395327952Sdim (VEX_LIG && inheritsFrom(child, IC_EVEX_L_K_B)) || 396327952Sdim (VEX_LIG && inheritsFrom(child, IC_EVEX_L2_K_B)); 397327952Sdim case IC_EVEX_XS_K_B: 398327952Sdim return (VEX_LIG && VEX_WIG && inheritsFrom(child, IC_EVEX_L_W_XS_K_B)) || 399327952Sdim (VEX_LIG && VEX_WIG && inheritsFrom(child, IC_EVEX_L2_W_XS_K_B)) || 400327952Sdim (VEX_WIG && inheritsFrom(child, IC_EVEX_W_XS_K_B)) || 401327952Sdim (VEX_LIG && inheritsFrom(child, IC_EVEX_L_XS_K_B)) || 402327952Sdim (VEX_LIG && inheritsFrom(child, IC_EVEX_L2_XS_K_B)); 403327952Sdim case IC_EVEX_XD_K_B: 404327952Sdim return (VEX_LIG && VEX_WIG && inheritsFrom(child, IC_EVEX_L_W_XD_K_B)) || 405327952Sdim (VEX_LIG && VEX_WIG && inheritsFrom(child, IC_EVEX_L2_W_XD_K_B)) || 406327952Sdim (VEX_WIG && inheritsFrom(child, IC_EVEX_W_XD_K_B)) || 407327952Sdim (VEX_LIG && inheritsFrom(child, IC_EVEX_L_XD_K_B)) || 408327952Sdim (VEX_LIG && inheritsFrom(child, IC_EVEX_L2_XD_K_B)); 409327952Sdim case IC_EVEX_OPSIZE_K_B: 410327952Sdim return (VEX_LIG && VEX_WIG && 411327952Sdim inheritsFrom(child, IC_EVEX_L_W_OPSIZE_K_B)) || 412327952Sdim (VEX_LIG && VEX_WIG && 413327952Sdim inheritsFrom(child, IC_EVEX_L2_W_OPSIZE_K_B)) || 414327952Sdim (VEX_WIG && inheritsFrom(child, IC_EVEX_W_OPSIZE_K_B)) || 415327952Sdim (VEX_LIG && inheritsFrom(child, IC_EVEX_L_OPSIZE_K_B)) || 416327952Sdim (VEX_LIG && inheritsFrom(child, IC_EVEX_L2_OPSIZE_K_B)); 417280031Sdim case IC_EVEX_KZ_B: 418327952Sdim return (VEX_LIG && VEX_WIG && inheritsFrom(child, IC_EVEX_L_W_KZ_B)) || 419327952Sdim (VEX_LIG && VEX_WIG && inheritsFrom(child, IC_EVEX_L2_W_KZ_B)) || 420327952Sdim (VEX_WIG && inheritsFrom(child, IC_EVEX_W_KZ_B)) || 421327952Sdim (VEX_LIG && inheritsFrom(child, IC_EVEX_L_KZ_B)) || 422327952Sdim (VEX_LIG && inheritsFrom(child, IC_EVEX_L2_KZ_B)); 423327952Sdim case IC_EVEX_XS_KZ_B: 424327952Sdim return (VEX_LIG && VEX_WIG && inheritsFrom(child, IC_EVEX_L_W_XS_KZ_B)) || 425327952Sdim (VEX_LIG && VEX_WIG && inheritsFrom(child, IC_EVEX_L2_W_XS_KZ_B)) || 426327952Sdim (VEX_WIG && inheritsFrom(child, IC_EVEX_W_XS_KZ_B)) || 427327952Sdim (VEX_LIG && inheritsFrom(child, IC_EVEX_L_XS_KZ_B)) || 428327952Sdim (VEX_LIG && inheritsFrom(child, IC_EVEX_L2_XS_KZ_B)); 429327952Sdim case IC_EVEX_XD_KZ_B: 430327952Sdim return (VEX_LIG && VEX_WIG && inheritsFrom(child, IC_EVEX_L_W_XD_KZ_B)) || 431327952Sdim (VEX_LIG && VEX_WIG && inheritsFrom(child, IC_EVEX_L2_W_XD_KZ_B)) || 432327952Sdim (VEX_WIG && inheritsFrom(child, IC_EVEX_W_XD_KZ_B)) || 433327952Sdim (VEX_LIG && inheritsFrom(child, IC_EVEX_L_XD_KZ_B)) || 434327952Sdim (VEX_LIG && inheritsFrom(child, IC_EVEX_L2_XD_KZ_B)); 435280031Sdim case IC_EVEX_OPSIZE_KZ_B: 436327952Sdim return (VEX_LIG && VEX_WIG && 437327952Sdim inheritsFrom(child, IC_EVEX_L_W_OPSIZE_KZ_B)) || 438327952Sdim (VEX_LIG && VEX_WIG && 439327952Sdim inheritsFrom(child, IC_EVEX_L2_W_OPSIZE_KZ_B)) || 440327952Sdim (VEX_WIG && inheritsFrom(child, IC_EVEX_W_OPSIZE_KZ_B)) || 441327952Sdim (VEX_LIG && inheritsFrom(child, IC_EVEX_L_OPSIZE_KZ_B)) || 442327952Sdim (VEX_LIG && inheritsFrom(child, IC_EVEX_L2_OPSIZE_KZ_B)); 443288943Sdim case IC_EVEX_W_B: 444327952Sdim return (VEX_LIG && inheritsFrom(child, IC_EVEX_L_W_B)) || 445327952Sdim (VEX_LIG && inheritsFrom(child, IC_EVEX_L2_W_B)); 446288943Sdim case IC_EVEX_W_XS_B: 447327952Sdim return (VEX_LIG && inheritsFrom(child, IC_EVEX_L_W_XS_B)) || 448327952Sdim (VEX_LIG && inheritsFrom(child, IC_EVEX_L2_W_XS_B)); 449288943Sdim case IC_EVEX_W_XD_B: 450327952Sdim return (VEX_LIG && inheritsFrom(child, IC_EVEX_L_W_XD_B)) || 451327952Sdim (VEX_LIG && inheritsFrom(child, IC_EVEX_L2_W_XD_B)); 452327952Sdim case IC_EVEX_W_OPSIZE_B: 453327952Sdim return (VEX_LIG && inheritsFrom(child, IC_EVEX_L_W_OPSIZE_B)) || 454327952Sdim (VEX_LIG && inheritsFrom(child, IC_EVEX_L2_W_OPSIZE_B)); 455327952Sdim case IC_EVEX_W_K_B: 456327952Sdim return (VEX_LIG && inheritsFrom(child, IC_EVEX_L_W_K_B)) || 457327952Sdim (VEX_LIG && inheritsFrom(child, IC_EVEX_L2_W_K_B)); 458288943Sdim case IC_EVEX_W_XS_K_B: 459327952Sdim return (VEX_LIG && inheritsFrom(child, IC_EVEX_L_W_XS_K_B)) || 460327952Sdim (VEX_LIG && inheritsFrom(child, IC_EVEX_L2_W_XS_K_B)); 461288943Sdim case IC_EVEX_W_XD_K_B: 462327952Sdim return (VEX_LIG && inheritsFrom(child, IC_EVEX_L_W_XD_K_B)) || 463327952Sdim (VEX_LIG && inheritsFrom(child, IC_EVEX_L2_W_XD_K_B)); 464327952Sdim case IC_EVEX_W_OPSIZE_K_B: 465327952Sdim return (VEX_LIG && inheritsFrom(child, IC_EVEX_L_W_OPSIZE_K_B)) || 466327952Sdim (VEX_LIG && inheritsFrom(child, IC_EVEX_L2_W_OPSIZE_K_B)); 467327952Sdim case IC_EVEX_W_KZ_B: 468327952Sdim return (VEX_LIG && inheritsFrom(child, IC_EVEX_L_W_KZ_B)) || 469327952Sdim (VEX_LIG && inheritsFrom(child, IC_EVEX_L2_W_KZ_B)); 470288943Sdim case IC_EVEX_W_XS_KZ_B: 471327952Sdim return (VEX_LIG && inheritsFrom(child, IC_EVEX_L_W_XS_KZ_B)) || 472327952Sdim (VEX_LIG && inheritsFrom(child, IC_EVEX_L2_W_XS_KZ_B)); 473288943Sdim case IC_EVEX_W_XD_KZ_B: 474327952Sdim return (VEX_LIG && inheritsFrom(child, IC_EVEX_L_W_XD_KZ_B)) || 475327952Sdim (VEX_LIG && inheritsFrom(child, IC_EVEX_L2_W_XD_KZ_B)); 476280031Sdim case IC_EVEX_W_OPSIZE_KZ_B: 477327952Sdim return (VEX_LIG && inheritsFrom(child, IC_EVEX_L_W_OPSIZE_KZ_B)) || 478327952Sdim (VEX_LIG && inheritsFrom(child, IC_EVEX_L2_W_OPSIZE_KZ_B)); 479327952Sdim case IC_EVEX_L_B: 480327952Sdim return VEX_WIG && inheritsFrom(child, IC_EVEX_L_W_B); 481288943Sdim case IC_EVEX_L_XS_B: 482327952Sdim return VEX_WIG && inheritsFrom(child, IC_EVEX_L_W_XS_B); 483327952Sdim case IC_EVEX_L_XD_B: 484327952Sdim return VEX_WIG && inheritsFrom(child, IC_EVEX_L_W_XD_B); 485327952Sdim case IC_EVEX_L_OPSIZE_B: 486327952Sdim return VEX_WIG && inheritsFrom(child, IC_EVEX_L_W_OPSIZE_B); 487327952Sdim case IC_EVEX_L_K_B: 488327952Sdim return VEX_WIG && inheritsFrom(child, IC_EVEX_L_W_K_B); 489288943Sdim case IC_EVEX_L_XS_K_B: 490327952Sdim return VEX_WIG && inheritsFrom(child, IC_EVEX_L_W_XS_K_B); 491327952Sdim case IC_EVEX_L_XD_K_B: 492327952Sdim return VEX_WIG && inheritsFrom(child, IC_EVEX_L_W_XD_K_B); 493327952Sdim case IC_EVEX_L_OPSIZE_K_B: 494327952Sdim return VEX_WIG && inheritsFrom(child, IC_EVEX_L_W_OPSIZE_K_B); 495327952Sdim case IC_EVEX_L_KZ_B: 496327952Sdim return VEX_WIG && inheritsFrom(child, IC_EVEX_L_W_KZ_B); 497288943Sdim case IC_EVEX_L_XS_KZ_B: 498327952Sdim return VEX_WIG && inheritsFrom(child, IC_EVEX_L_W_XS_KZ_B); 499288943Sdim case IC_EVEX_L_XD_KZ_B: 500327952Sdim return VEX_WIG && inheritsFrom(child, IC_EVEX_L_W_XD_KZ_B); 501280031Sdim case IC_EVEX_L_OPSIZE_KZ_B: 502327952Sdim return VEX_WIG && inheritsFrom(child, IC_EVEX_L_W_OPSIZE_KZ_B); 503327952Sdim case IC_EVEX_L_W_B: 504327952Sdim case IC_EVEX_L_W_XS_B: 505327952Sdim case IC_EVEX_L_W_XD_B: 506327952Sdim case IC_EVEX_L_W_OPSIZE_B: 507261991Sdim return false; 508309124Sdim case IC_EVEX_L_W_K_B: 509288943Sdim case IC_EVEX_L_W_XS_K_B: 510327952Sdim case IC_EVEX_L_W_XD_K_B: 511280031Sdim case IC_EVEX_L_W_OPSIZE_K_B: 512327952Sdim return false; 513288943Sdim case IC_EVEX_L_W_KZ_B: 514327952Sdim case IC_EVEX_L_W_XS_KZ_B: 515288943Sdim case IC_EVEX_L_W_XD_KZ_B: 516280031Sdim case IC_EVEX_L_W_OPSIZE_KZ_B: 517261991Sdim return false; 518261991Sdim case IC_EVEX_L2_B: 519327952Sdim return VEX_WIG && inheritsFrom(child, IC_EVEX_L2_W_B); 520327952Sdim case IC_EVEX_L2_XS_B: 521327952Sdim return VEX_WIG && inheritsFrom(child, IC_EVEX_L2_W_XS_B); 522327952Sdim case IC_EVEX_L2_XD_B: 523327952Sdim return VEX_WIG && inheritsFrom(child, IC_EVEX_L2_W_XD_B); 524327952Sdim case IC_EVEX_L2_OPSIZE_B: 525327952Sdim return VEX_WIG && inheritsFrom(child, IC_EVEX_L2_W_OPSIZE_B); 526276479Sdim case IC_EVEX_L2_K_B: 527327952Sdim return VEX_WIG && inheritsFrom(child, IC_EVEX_L2_W_K_B); 528288943Sdim case IC_EVEX_L2_XS_K_B: 529327952Sdim return VEX_WIG && inheritsFrom(child, IC_EVEX_L2_W_XS_K_B); 530288943Sdim case IC_EVEX_L2_XD_K_B: 531327952Sdim return VEX_WIG && inheritsFrom(child, IC_EVEX_L2_W_XD_K_B); 532261991Sdim case IC_EVEX_L2_OPSIZE_K_B: 533327952Sdim return VEX_WIG && inheritsFrom(child, IC_EVEX_L2_W_OPSIZE_K_B); 534327952Sdim case IC_EVEX_L2_KZ_B: 535327952Sdim return VEX_WIG && inheritsFrom(child, IC_EVEX_L2_W_KZ_B); 536288943Sdim case IC_EVEX_L2_XS_KZ_B: 537327952Sdim return VEX_WIG && inheritsFrom(child, IC_EVEX_L2_W_XS_KZ_B); 538288943Sdim case IC_EVEX_L2_XD_KZ_B: 539327952Sdim return VEX_WIG && inheritsFrom(child, IC_EVEX_L2_W_XD_KZ_B); 540261991Sdim case IC_EVEX_L2_OPSIZE_KZ_B: 541327952Sdim return VEX_WIG && inheritsFrom(child, IC_EVEX_L2_W_OPSIZE_KZ_B); 542261991Sdim case IC_EVEX_L2_W_B: 543288943Sdim case IC_EVEX_L2_W_XS_B: 544276479Sdim case IC_EVEX_L2_W_XD_B: 545261991Sdim case IC_EVEX_L2_W_OPSIZE_B: 546327952Sdim return false; 547327952Sdim case IC_EVEX_L2_W_K_B: 548327952Sdim case IC_EVEX_L2_W_XS_K_B: 549327952Sdim case IC_EVEX_L2_W_XD_K_B: 550261991Sdim case IC_EVEX_L2_W_OPSIZE_K_B: 551327952Sdim return false; 552327952Sdim case IC_EVEX_L2_W_KZ_B: 553288943Sdim case IC_EVEX_L2_W_XS_KZ_B: 554288943Sdim case IC_EVEX_L2_W_XD_KZ_B: 555261991Sdim case IC_EVEX_L2_W_OPSIZE_KZ_B: 556261991Sdim return false; 557201360Srdivacky default: 558276479Sdim errs() << "Unknown instruction class: " << 559276479Sdim stringForContext((InstructionContext)parent) << "\n"; 560226633Sdim llvm_unreachable("Unknown instruction class"); 561201360Srdivacky } 562201360Srdivacky} 563201360Srdivacky 564201360Srdivacky/// outranks - Indicates whether, if an instruction has two different applicable 565201360Srdivacky/// classes, which class should be preferred when performing decode. This 566201360Srdivacky/// imposes a total ordering (ties are resolved toward "lower") 567201360Srdivacky/// 568201360Srdivacky/// @param upper - The class that may be preferable 569201360Srdivacky/// @param lower - The class that may be less preferable 570201360Srdivacky/// @return - True if upper is to be preferred, false otherwise. 571239462Sdimstatic inline bool outranks(InstructionContext upper, 572201360Srdivacky InstructionContext lower) { 573201360Srdivacky assert(upper < IC_max); 574201360Srdivacky assert(lower < IC_max); 575239462Sdim 576201360Srdivacky#define ENUM_ENTRY(n, r, d) r, 577261991Sdim#define ENUM_ENTRY_K_B(n, r, d) ENUM_ENTRY(n, r, d) \ 578261991Sdim ENUM_ENTRY(n##_K_B, r, d) ENUM_ENTRY(n##_KZ_B, r, d) \ 579261991Sdim ENUM_ENTRY(n##_KZ, r, d) ENUM_ENTRY(n##_K, r, d) ENUM_ENTRY(n##_B, r, d) 580201360Srdivacky static int ranks[IC_max] = { 581201360Srdivacky INSTRUCTION_CONTEXTS 582201360Srdivacky }; 583201360Srdivacky#undef ENUM_ENTRY 584261991Sdim#undef ENUM_ENTRY_K_B 585239462Sdim 586201360Srdivacky return (ranks[upper] > ranks[lower]); 587201360Srdivacky} 588201360Srdivacky 589201360Srdivacky/// getDecisionType - Determines whether a ModRM decision with 255 entries can 590201360Srdivacky/// be compacted by eliminating redundant information. 591201360Srdivacky/// 592201360Srdivacky/// @param decision - The decision to be compacted. 593201360Srdivacky/// @return - The compactest available representation for the decision. 594239462Sdimstatic ModRMDecisionType getDecisionType(ModRMDecision &decision) { 595201360Srdivacky bool satisfiesOneEntry = true; 596201360Srdivacky bool satisfiesSplitRM = true; 597234353Sdim bool satisfiesSplitReg = true; 598243830Sdim bool satisfiesSplitMisc = true; 599234353Sdim 600239462Sdim for (unsigned index = 0; index < 256; ++index) { 601201360Srdivacky if (decision.instructionIDs[index] != decision.instructionIDs[0]) 602201360Srdivacky satisfiesOneEntry = false; 603234353Sdim 604201360Srdivacky if (((index & 0xc0) == 0xc0) && 605201360Srdivacky (decision.instructionIDs[index] != decision.instructionIDs[0xc0])) 606201360Srdivacky satisfiesSplitRM = false; 607234353Sdim 608201360Srdivacky if (((index & 0xc0) != 0xc0) && 609201360Srdivacky (decision.instructionIDs[index] != decision.instructionIDs[0x00])) 610201360Srdivacky satisfiesSplitRM = false; 611234353Sdim 612234353Sdim if (((index & 0xc0) == 0xc0) && 613234353Sdim (decision.instructionIDs[index] != decision.instructionIDs[index&0xf8])) 614234353Sdim satisfiesSplitReg = false; 615234353Sdim 616234353Sdim if (((index & 0xc0) != 0xc0) && 617234353Sdim (decision.instructionIDs[index] != decision.instructionIDs[index&0x38])) 618243830Sdim satisfiesSplitMisc = false; 619201360Srdivacky } 620234353Sdim 621201360Srdivacky if (satisfiesOneEntry) 622201360Srdivacky return MODRM_ONEENTRY; 623234353Sdim 624201360Srdivacky if (satisfiesSplitRM) 625201360Srdivacky return MODRM_SPLITRM; 626234353Sdim 627243830Sdim if (satisfiesSplitReg && satisfiesSplitMisc) 628234353Sdim return MODRM_SPLITREG; 629234353Sdim 630243830Sdim if (satisfiesSplitMisc) 631243830Sdim return MODRM_SPLITMISC; 632243830Sdim 633201360Srdivacky return MODRM_FULL; 634201360Srdivacky} 635201360Srdivacky 636201360Srdivacky/// stringForDecisionType - Returns a statically-allocated string corresponding 637201360Srdivacky/// to a particular decision type. 638201360Srdivacky/// 639201360Srdivacky/// @param dt - The decision type. 640239462Sdim/// @return - A pointer to the statically-allocated string (e.g., 641201360Srdivacky/// "MODRM_ONEENTRY" for MODRM_ONEENTRY). 642239462Sdimstatic const char* stringForDecisionType(ModRMDecisionType dt) { 643201360Srdivacky#define ENUM_ENTRY(n) case n: return #n; 644201360Srdivacky switch (dt) { 645201360Srdivacky default: 646239462Sdim llvm_unreachable("Unknown decision type"); 647201360Srdivacky MODRMTYPES 648239462Sdim }; 649201360Srdivacky#undef ENUM_ENTRY 650201360Srdivacky} 651239462Sdim 652201360SrdivackyDisassemblerTables::DisassemblerTables() { 653341825Sdim for (unsigned i = 0; i < array_lengthof(Tables); i++) 654360784Sdim Tables[i] = std::make_unique<ContextDecision>(); 655239462Sdim 656201360Srdivacky HasConflicts = false; 657201360Srdivacky} 658239462Sdim 659201360SrdivackyDisassemblerTables::~DisassemblerTables() { 660201360Srdivacky} 661239462Sdim 662239462Sdimvoid DisassemblerTables::emitModRMDecision(raw_ostream &o1, raw_ostream &o2, 663239462Sdim unsigned &i1, unsigned &i2, 664261991Sdim unsigned &ModRMTableNum, 665239462Sdim ModRMDecision &decision) const { 666239462Sdim static uint32_t sTableNumber = 0; 667239462Sdim static uint32_t sEntryNumber = 1; 668201360Srdivacky ModRMDecisionType dt = getDecisionType(decision); 669234353Sdim 670360784Sdim if (dt == MODRM_ONEENTRY && decision.instructionIDs[0] == 0) { 671360784Sdim // Empty table. 672360784Sdim o2 << "{ " << stringForDecisionType(dt) << ", 0 }"; 673201360Srdivacky return; 674201360Srdivacky } 675234353Sdim 676261991Sdim std::vector<unsigned> ModRMDecision; 677234353Sdim 678201360Srdivacky switch (dt) { 679201360Srdivacky default: 680201360Srdivacky llvm_unreachable("Unknown decision type"); 681201360Srdivacky case MODRM_ONEENTRY: 682261991Sdim ModRMDecision.push_back(decision.instructionIDs[0]); 683201360Srdivacky break; 684201360Srdivacky case MODRM_SPLITRM: 685261991Sdim ModRMDecision.push_back(decision.instructionIDs[0x00]); 686261991Sdim ModRMDecision.push_back(decision.instructionIDs[0xc0]); 687201360Srdivacky break; 688234353Sdim case MODRM_SPLITREG: 689239462Sdim for (unsigned index = 0; index < 64; index += 8) 690261991Sdim ModRMDecision.push_back(decision.instructionIDs[index]); 691239462Sdim for (unsigned index = 0xc0; index < 256; index += 8) 692261991Sdim ModRMDecision.push_back(decision.instructionIDs[index]); 693234353Sdim break; 694243830Sdim case MODRM_SPLITMISC: 695243830Sdim for (unsigned index = 0; index < 64; index += 8) 696261991Sdim ModRMDecision.push_back(decision.instructionIDs[index]); 697243830Sdim for (unsigned index = 0xc0; index < 256; ++index) 698261991Sdim ModRMDecision.push_back(decision.instructionIDs[index]); 699243830Sdim break; 700201360Srdivacky case MODRM_FULL: 701239462Sdim for (unsigned index = 0; index < 256; ++index) 702261991Sdim ModRMDecision.push_back(decision.instructionIDs[index]); 703234353Sdim break; 704201360Srdivacky } 705201360Srdivacky 706261991Sdim unsigned &EntryNumber = ModRMTable[ModRMDecision]; 707261991Sdim if (EntryNumber == 0) { 708261991Sdim EntryNumber = ModRMTableNum; 709234353Sdim 710261991Sdim ModRMTableNum += ModRMDecision.size(); 711261991Sdim o1 << "/* Table" << EntryNumber << " */\n"; 712261991Sdim i1++; 713261991Sdim for (std::vector<unsigned>::const_iterator I = ModRMDecision.begin(), 714261991Sdim E = ModRMDecision.end(); I != E; ++I) { 715261991Sdim o1.indent(i1 * 2) << format("0x%hx", *I) << ", /* " 716261991Sdim << InstructionSpecifiers[*I].name << " */\n"; 717261991Sdim } 718261991Sdim i1--; 719261991Sdim } 720261991Sdim 721360784Sdim o2 << "{ " << stringForDecisionType(dt) << ", " << EntryNumber << " /* Table" 722360784Sdim << EntryNumber << " */ }"; 723234353Sdim 724201360Srdivacky switch (dt) { 725201360Srdivacky default: 726201360Srdivacky llvm_unreachable("Unknown decision type"); 727201360Srdivacky case MODRM_ONEENTRY: 728234353Sdim sEntryNumber += 1; 729201360Srdivacky break; 730201360Srdivacky case MODRM_SPLITRM: 731234353Sdim sEntryNumber += 2; 732201360Srdivacky break; 733234353Sdim case MODRM_SPLITREG: 734234353Sdim sEntryNumber += 16; 735234353Sdim break; 736243830Sdim case MODRM_SPLITMISC: 737243830Sdim sEntryNumber += 8 + 64; 738243830Sdim break; 739201360Srdivacky case MODRM_FULL: 740234353Sdim sEntryNumber += 256; 741201360Srdivacky break; 742201360Srdivacky } 743234353Sdim 744243830Sdim // We assume that the index can fit into uint16_t. 745243830Sdim assert(sEntryNumber < 65536U && 746243830Sdim "Index into ModRMDecision is too large for uint16_t!"); 747243830Sdim 748201360Srdivacky ++sTableNumber; 749201360Srdivacky} 750201360Srdivacky 751239462Sdimvoid DisassemblerTables::emitOpcodeDecision(raw_ostream &o1, raw_ostream &o2, 752239462Sdim unsigned &i1, unsigned &i2, 753261991Sdim unsigned &ModRMTableNum, 754360784Sdim OpcodeDecision &opDecision) const { 755360784Sdim o2 << "{"; 756360784Sdim ++i2; 757201360Srdivacky 758360784Sdim unsigned index; 759360784Sdim for (index = 0; index < 256; ++index) { 760360784Sdim auto &decision = opDecision.modRMDecisions[index]; 761360784Sdim ModRMDecisionType dt = getDecisionType(decision); 762360784Sdim if (!(dt == MODRM_ONEENTRY && decision.instructionIDs[0] == 0)) 763360784Sdim break; 764360784Sdim } 765360784Sdim if (index == 256) { 766360784Sdim // If all 256 entries are MODRM_ONEENTRY, omit output. 767360784Sdim assert(MODRM_ONEENTRY == 0); 768360784Sdim --i2; 769360784Sdim o2 << "},\n"; 770360784Sdim } else { 771360784Sdim o2 << " /* struct OpcodeDecision */ {\n"; 772360784Sdim ++i2; 773360784Sdim for (index = 0; index < 256; ++index) { 774360784Sdim o2.indent(i2); 775201360Srdivacky 776360784Sdim o2 << "/* 0x" << format("%02hhx", index) << " */ "; 777201360Srdivacky 778360784Sdim emitModRMDecision(o1, o2, i1, i2, ModRMTableNum, 779360784Sdim opDecision.modRMDecisions[index]); 780201360Srdivacky 781360784Sdim if (index < 255) 782360784Sdim o2 << ","; 783201360Srdivacky 784360784Sdim o2 << "\n"; 785360784Sdim } 786360784Sdim --i2; 787360784Sdim o2.indent(i2) << "}\n"; 788360784Sdim --i2; 789360784Sdim o2.indent(i2) << "},\n"; 790201360Srdivacky } 791201360Srdivacky} 792201360Srdivacky 793239462Sdimvoid DisassemblerTables::emitContextDecision(raw_ostream &o1, raw_ostream &o2, 794239462Sdim unsigned &i1, unsigned &i2, 795261991Sdim unsigned &ModRMTableNum, 796239462Sdim ContextDecision &decision, 797239462Sdim const char* name) const { 798218893Sdim o2.indent(i2) << "static const struct ContextDecision " << name << " = {\n"; 799201360Srdivacky i2++; 800201360Srdivacky o2.indent(i2) << "{ /* opcodeDecisions */" << "\n"; 801201360Srdivacky i2++; 802201360Srdivacky 803239462Sdim for (unsigned index = 0; index < IC_max; ++index) { 804201360Srdivacky o2.indent(i2) << "/* "; 805201360Srdivacky o2 << stringForContext((InstructionContext)index); 806360784Sdim o2 << " */ "; 807201360Srdivacky 808261991Sdim emitOpcodeDecision(o1, o2, i1, i2, ModRMTableNum, 809261991Sdim decision.opcodeDecisions[index]); 810201360Srdivacky } 811201360Srdivacky 812201360Srdivacky i2--; 813201360Srdivacky o2.indent(i2) << "}" << "\n"; 814201360Srdivacky i2--; 815201360Srdivacky o2.indent(i2) << "};" << "\n"; 816201360Srdivacky} 817201360Srdivacky 818239462Sdimvoid DisassemblerTables::emitInstructionInfo(raw_ostream &o, 819239462Sdim unsigned &i) const { 820239462Sdim unsigned NumInstructions = InstructionSpecifiers.size(); 821239462Sdim 822239462Sdim o << "static const struct OperandSpecifier x86OperandSets[][" 823239462Sdim << X86_MAX_OPERANDS << "] = {\n"; 824239462Sdim 825288943Sdim typedef SmallVector<std::pair<OperandEncoding, OperandType>, 826288943Sdim X86_MAX_OPERANDS> OperandListTy; 827239462Sdim std::map<OperandListTy, unsigned> OperandSets; 828239462Sdim 829239462Sdim unsigned OperandSetNum = 0; 830239462Sdim for (unsigned Index = 0; Index < NumInstructions; ++Index) { 831239462Sdim OperandListTy OperandList; 832239462Sdim 833239462Sdim for (unsigned OperandIndex = 0; OperandIndex < X86_MAX_OPERANDS; 834239462Sdim ++OperandIndex) { 835288943Sdim OperandEncoding Encoding = (OperandEncoding)InstructionSpecifiers[Index] 836288943Sdim .operands[OperandIndex].encoding; 837288943Sdim OperandType Type = (OperandType)InstructionSpecifiers[Index] 838288943Sdim .operands[OperandIndex].type; 839239462Sdim OperandList.push_back(std::make_pair(Encoding, Type)); 840239462Sdim } 841239462Sdim unsigned &N = OperandSets[OperandList]; 842239462Sdim if (N != 0) continue; 843239462Sdim 844239462Sdim N = ++OperandSetNum; 845239462Sdim 846239462Sdim o << " { /* " << (OperandSetNum - 1) << " */\n"; 847239462Sdim for (unsigned i = 0, e = OperandList.size(); i != e; ++i) { 848288943Sdim const char *Encoding = stringForOperandEncoding(OperandList[i].first); 849288943Sdim const char *Type = stringForOperandType(OperandList[i].second); 850288943Sdim o << " { " << Encoding << ", " << Type << " },\n"; 851239462Sdim } 852239462Sdim o << " },\n"; 853239462Sdim } 854239462Sdim o << "};" << "\n\n"; 855239462Sdim 856218893Sdim o.indent(i * 2) << "static const struct InstructionSpecifier "; 857218893Sdim o << INSTRUCTIONS_STR "[" << InstructionSpecifiers.size() << "] = {\n"; 858239462Sdim 859201360Srdivacky i++; 860201360Srdivacky 861239462Sdim for (unsigned index = 0; index < NumInstructions; ++index) { 862288943Sdim o.indent(i * 2) << "{ /* " << index << " */\n"; 863201360Srdivacky i++; 864234353Sdim 865239462Sdim OperandListTy OperandList; 866239462Sdim for (unsigned OperandIndex = 0; OperandIndex < X86_MAX_OPERANDS; 867239462Sdim ++OperandIndex) { 868288943Sdim OperandEncoding Encoding = (OperandEncoding)InstructionSpecifiers[index] 869288943Sdim .operands[OperandIndex].encoding; 870288943Sdim OperandType Type = (OperandType)InstructionSpecifiers[index] 871288943Sdim .operands[OperandIndex].type; 872239462Sdim OperandList.push_back(std::make_pair(Encoding, Type)); 873201360Srdivacky } 874239462Sdim o.indent(i * 2) << (OperandSets[OperandList] - 1) << ",\n"; 875201360Srdivacky 876288943Sdim o.indent(i * 2) << "/* " << InstructionSpecifiers[index].name << " */\n"; 877201360Srdivacky 878201360Srdivacky i--; 879288943Sdim o.indent(i * 2) << "},\n"; 880201360Srdivacky } 881201360Srdivacky 882201360Srdivacky i--; 883201360Srdivacky o.indent(i * 2) << "};" << "\n"; 884201360Srdivacky} 885201360Srdivacky 886239462Sdimvoid DisassemblerTables::emitContextTable(raw_ostream &o, unsigned &i) const { 887239462Sdim o.indent(i * 2) << "static const uint8_t " CONTEXTS_STR 888353358Sdim "[" << ATTR_max << "] = {\n"; 889201360Srdivacky i++; 890201360Srdivacky 891353358Sdim for (unsigned index = 0; index < ATTR_max; ++index) { 892201360Srdivacky o.indent(i * 2); 893201360Srdivacky 894353358Sdim if ((index & ATTR_EVEX) || (index & ATTR_VEX) || (index & ATTR_VEXL)) { 895353358Sdim if (index & ATTR_EVEX) 896353358Sdim o << "IC_EVEX"; 897353358Sdim else 898353358Sdim o << "IC_VEX"; 899353358Sdim 900353358Sdim if ((index & ATTR_EVEX) && (index & ATTR_EVEXL2)) 901276479Sdim o << "_L2"; 902353358Sdim else if (index & ATTR_VEXL) 903276479Sdim o << "_L"; 904353358Sdim 905276479Sdim if (index & ATTR_REXW) 906276479Sdim o << "_W"; 907353358Sdim 908276479Sdim if (index & ATTR_OPSIZE) 909276479Sdim o << "_OPSIZE"; 910276479Sdim else if (index & ATTR_XD) 911276479Sdim o << "_XD"; 912276479Sdim else if (index & ATTR_XS) 913276479Sdim o << "_XS"; 914353358Sdim 915353358Sdim if ((index & ATTR_EVEX)) { 916353358Sdim if (index & ATTR_EVEXKZ) 917353358Sdim o << "_KZ"; 918353358Sdim else if (index & ATTR_EVEXK) 919353358Sdim o << "_K"; 920353358Sdim 921353358Sdim if (index & ATTR_EVEXB) 922353358Sdim o << "_B"; 923353358Sdim } 924276479Sdim } 925221345Sdim else if ((index & ATTR_64BIT) && (index & ATTR_REXW) && (index & ATTR_XS)) 926201360Srdivacky o << "IC_64BIT_REXW_XS"; 927201360Srdivacky else if ((index & ATTR_64BIT) && (index & ATTR_REXW) && (index & ATTR_XD)) 928201360Srdivacky o << "IC_64BIT_REXW_XD"; 929239462Sdim else if ((index & ATTR_64BIT) && (index & ATTR_REXW) && 930201360Srdivacky (index & ATTR_OPSIZE)) 931201360Srdivacky o << "IC_64BIT_REXW_OPSIZE"; 932280031Sdim else if ((index & ATTR_64BIT) && (index & ATTR_REXW) && 933280031Sdim (index & ATTR_ADSIZE)) 934280031Sdim o << "IC_64BIT_REXW_ADSIZE"; 935226633Sdim else if ((index & ATTR_64BIT) && (index & ATTR_XD) && (index & ATTR_OPSIZE)) 936226633Sdim o << "IC_64BIT_XD_OPSIZE"; 937341825Sdim else if ((index & ATTR_64BIT) && (index & ATTR_XD) && (index & ATTR_ADSIZE)) 938341825Sdim o << "IC_64BIT_XD_ADSIZE"; 939226633Sdim else if ((index & ATTR_64BIT) && (index & ATTR_XS) && (index & ATTR_OPSIZE)) 940226633Sdim o << "IC_64BIT_XS_OPSIZE"; 941341825Sdim else if ((index & ATTR_64BIT) && (index & ATTR_XS) && (index & ATTR_ADSIZE)) 942341825Sdim o << "IC_64BIT_XS_ADSIZE"; 943201360Srdivacky else if ((index & ATTR_64BIT) && (index & ATTR_XS)) 944201360Srdivacky o << "IC_64BIT_XS"; 945201360Srdivacky else if ((index & ATTR_64BIT) && (index & ATTR_XD)) 946201360Srdivacky o << "IC_64BIT_XD"; 947280031Sdim else if ((index & ATTR_64BIT) && (index & ATTR_OPSIZE) && 948280031Sdim (index & ATTR_ADSIZE)) 949280031Sdim o << "IC_64BIT_OPSIZE_ADSIZE"; 950201360Srdivacky else if ((index & ATTR_64BIT) && (index & ATTR_OPSIZE)) 951201360Srdivacky o << "IC_64BIT_OPSIZE"; 952234353Sdim else if ((index & ATTR_64BIT) && (index & ATTR_ADSIZE)) 953234353Sdim o << "IC_64BIT_ADSIZE"; 954201360Srdivacky else if ((index & ATTR_64BIT) && (index & ATTR_REXW)) 955201360Srdivacky o << "IC_64BIT_REXW"; 956201360Srdivacky else if ((index & ATTR_64BIT)) 957201360Srdivacky o << "IC_64BIT"; 958226633Sdim else if ((index & ATTR_XS) && (index & ATTR_OPSIZE)) 959226633Sdim o << "IC_XS_OPSIZE"; 960226633Sdim else if ((index & ATTR_XD) && (index & ATTR_OPSIZE)) 961226633Sdim o << "IC_XD_OPSIZE"; 962341825Sdim else if ((index & ATTR_XS) && (index & ATTR_ADSIZE)) 963341825Sdim o << "IC_XS_ADSIZE"; 964341825Sdim else if ((index & ATTR_XD) && (index & ATTR_ADSIZE)) 965341825Sdim o << "IC_XD_ADSIZE"; 966201360Srdivacky else if (index & ATTR_XS) 967201360Srdivacky o << "IC_XS"; 968201360Srdivacky else if (index & ATTR_XD) 969201360Srdivacky o << "IC_XD"; 970280031Sdim else if ((index & ATTR_OPSIZE) && (index & ATTR_ADSIZE)) 971280031Sdim o << "IC_OPSIZE_ADSIZE"; 972201360Srdivacky else if (index & ATTR_OPSIZE) 973201360Srdivacky o << "IC_OPSIZE"; 974234353Sdim else if (index & ATTR_ADSIZE) 975234353Sdim o << "IC_ADSIZE"; 976201360Srdivacky else 977201360Srdivacky o << "IC"; 978201360Srdivacky 979353358Sdim o << ", /* " << index << " */"; 980201360Srdivacky 981201360Srdivacky o << "\n"; 982201360Srdivacky } 983201360Srdivacky 984201360Srdivacky i--; 985201360Srdivacky o.indent(i * 2) << "};" << "\n"; 986201360Srdivacky} 987201360Srdivacky 988239462Sdimvoid DisassemblerTables::emitContextDecisions(raw_ostream &o1, raw_ostream &o2, 989261991Sdim unsigned &i1, unsigned &i2, 990261991Sdim unsigned &ModRMTableNum) const { 991261991Sdim emitContextDecision(o1, o2, i1, i2, ModRMTableNum, *Tables[0], ONEBYTE_STR); 992261991Sdim emitContextDecision(o1, o2, i1, i2, ModRMTableNum, *Tables[1], TWOBYTE_STR); 993261991Sdim emitContextDecision(o1, o2, i1, i2, ModRMTableNum, *Tables[2], THREEBYTE38_STR); 994261991Sdim emitContextDecision(o1, o2, i1, i2, ModRMTableNum, *Tables[3], THREEBYTE3A_STR); 995276479Sdim emitContextDecision(o1, o2, i1, i2, ModRMTableNum, *Tables[4], XOP8_MAP_STR); 996276479Sdim emitContextDecision(o1, o2, i1, i2, ModRMTableNum, *Tables[5], XOP9_MAP_STR); 997276479Sdim emitContextDecision(o1, o2, i1, i2, ModRMTableNum, *Tables[6], XOPA_MAP_STR); 998341825Sdim emitContextDecision(o1, o2, i1, i2, ModRMTableNum, *Tables[7], THREEDNOW_MAP_STR); 999201360Srdivacky} 1000201360Srdivacky 1001201360Srdivackyvoid DisassemblerTables::emit(raw_ostream &o) const { 1002239462Sdim unsigned i1 = 0; 1003239462Sdim unsigned i2 = 0; 1004239462Sdim 1005201360Srdivacky std::string s1; 1006201360Srdivacky std::string s2; 1007239462Sdim 1008201360Srdivacky raw_string_ostream o1(s1); 1009201360Srdivacky raw_string_ostream o2(s2); 1010239462Sdim 1011201360Srdivacky emitInstructionInfo(o, i2); 1012201360Srdivacky o << "\n"; 1013201360Srdivacky 1014201360Srdivacky emitContextTable(o, i2); 1015201360Srdivacky o << "\n"; 1016234353Sdim 1017261991Sdim unsigned ModRMTableNum = 0; 1018261991Sdim 1019234353Sdim o << "static const InstrUID modRMTable[] = {\n"; 1020234353Sdim i1++; 1021261991Sdim std::vector<unsigned> EmptyTable(1, 0); 1022261991Sdim ModRMTable[EmptyTable] = ModRMTableNum; 1023261991Sdim ModRMTableNum += EmptyTable.size(); 1024261991Sdim o1 << "/* EmptyTable */\n"; 1025261991Sdim o1.indent(i1 * 2) << "0x0,\n"; 1026234353Sdim i1--; 1027261991Sdim emitContextDecisions(o1, o2, i1, i2, ModRMTableNum); 1028234353Sdim 1029201360Srdivacky o << o1.str(); 1030234353Sdim o << " 0x0\n"; 1031234353Sdim o << "};\n"; 1032201360Srdivacky o << "\n"; 1033201360Srdivacky o << o2.str(); 1034201360Srdivacky o << "\n"; 1035201360Srdivacky o << "\n"; 1036201360Srdivacky} 1037201360Srdivacky 1038201360Srdivackyvoid DisassemblerTables::setTableFields(ModRMDecision &decision, 1039201360Srdivacky const ModRMFilter &filter, 1040201360Srdivacky InstrUID uid, 1041201360Srdivacky uint8_t opcode) { 1042239462Sdim for (unsigned index = 0; index < 256; ++index) { 1043201360Srdivacky if (filter.accepts(index)) { 1044201360Srdivacky if (decision.instructionIDs[index] == uid) 1045201360Srdivacky continue; 1046201360Srdivacky 1047201360Srdivacky if (decision.instructionIDs[index] != 0) { 1048201360Srdivacky InstructionSpecifier &newInfo = 1049201360Srdivacky InstructionSpecifiers[uid]; 1050201360Srdivacky InstructionSpecifier &previousInfo = 1051201360Srdivacky InstructionSpecifiers[decision.instructionIDs[index]]; 1052239462Sdim 1053226633Sdim if(previousInfo.name == "NOOP" && (newInfo.name == "XCHG16ar" || 1054226633Sdim newInfo.name == "XCHG32ar" || 1055226633Sdim newInfo.name == "XCHG64ar")) 1056226633Sdim continue; // special case for XCHG*ar and NOOP 1057201360Srdivacky 1058201360Srdivacky if (outranks(previousInfo.insnContext, newInfo.insnContext)) 1059201360Srdivacky continue; 1060239462Sdim 1061276479Sdim if (previousInfo.insnContext == newInfo.insnContext) { 1062201360Srdivacky errs() << "Error: Primary decode conflict: "; 1063201360Srdivacky errs() << newInfo.name << " would overwrite " << previousInfo.name; 1064201360Srdivacky errs() << "\n"; 1065201360Srdivacky errs() << "ModRM " << index << "\n"; 1066201360Srdivacky errs() << "Opcode " << (uint16_t)opcode << "\n"; 1067201360Srdivacky errs() << "Context " << stringForContext(newInfo.insnContext) << "\n"; 1068201360Srdivacky HasConflicts = true; 1069201360Srdivacky } 1070201360Srdivacky } 1071201360Srdivacky 1072201360Srdivacky decision.instructionIDs[index] = uid; 1073201360Srdivacky } 1074201360Srdivacky } 1075201360Srdivacky} 1076201360Srdivacky 1077201360Srdivackyvoid DisassemblerTables::setTableFields(OpcodeType type, 1078201360Srdivacky InstructionContext insnContext, 1079201360Srdivacky uint8_t opcode, 1080201360Srdivacky const ModRMFilter &filter, 1081226633Sdim InstrUID uid, 1082226633Sdim bool is32bit, 1083327952Sdim bool noPrefix, 1084280031Sdim bool ignoresVEX_L, 1085327952Sdim bool ignoresVEX_W, 1086280031Sdim unsigned addressSize) { 1087201360Srdivacky ContextDecision &decision = *Tables[type]; 1088201360Srdivacky 1089239462Sdim for (unsigned index = 0; index < IC_max; ++index) { 1090280031Sdim if ((is32bit || addressSize == 16) && 1091280031Sdim inheritsFrom((InstructionContext)index, IC_64BIT)) 1092226633Sdim continue; 1093226633Sdim 1094280031Sdim bool adSize64 = addressSize == 64; 1095239462Sdim if (inheritsFrom((InstructionContext)index, 1096327952Sdim InstructionSpecifiers[uid].insnContext, noPrefix, 1097327952Sdim ignoresVEX_L, ignoresVEX_W, adSize64)) 1098239462Sdim setTableFields(decision.opcodeDecisions[index].modRMDecisions[opcode], 1099201360Srdivacky filter, 1100201360Srdivacky uid, 1101201360Srdivacky opcode); 1102201360Srdivacky } 1103201360Srdivacky} 1104