1201360Srdivacky//===- X86ModRMFilters.h - Disassembler ModR/M filterss ---------*- C++ -*-===// 2201360Srdivacky// 3201360Srdivacky// The LLVM Compiler Infrastructure 4201360Srdivacky// 5201360Srdivacky// This file is distributed under the University of Illinois Open Source 6201360Srdivacky// License. See LICENSE.TXT for details. 7201360Srdivacky// 8201360Srdivacky//===----------------------------------------------------------------------===// 9201360Srdivacky// 10201360Srdivacky// This file is part of the X86 Disassembler Emitter. 11201360Srdivacky// It contains ModR/M filters that determine which values of the ModR/M byte 12201360Srdivacky// are valid for a partiuclar instruction. 13201360Srdivacky// Documentation for the disassembler emitter in general can be found in 14201360Srdivacky// X86DisasemblerEmitter.h. 15201360Srdivacky// 16201360Srdivacky//===----------------------------------------------------------------------===// 17201360Srdivacky 18201360Srdivacky#ifndef X86MODRMFILTERS_H 19201360Srdivacky#define X86MODRMFILTERS_H 20201360Srdivacky 21218893Sdim#include "llvm/Support/DataTypes.h" 22201360Srdivacky 23201360Srdivackynamespace llvm { 24201360Srdivacky 25201360Srdivackynamespace X86Disassembler { 26201360Srdivacky 27201360Srdivacky/// ModRMFilter - Abstract base class for clases that recognize patterns in 28201360Srdivacky/// ModR/M bytes. 29201360Srdivackyclass ModRMFilter { 30234353Sdim virtual void anchor(); 31201360Srdivackypublic: 32201360Srdivacky /// Destructor - Override as necessary. 33201360Srdivacky virtual ~ModRMFilter() { } 34201360Srdivacky 35201360Srdivacky /// isDumb - Indicates whether this filter returns the same value for 36201360Srdivacky /// any value of the ModR/M byte. 37201360Srdivacky /// 38201360Srdivacky /// @result - True if the filter returns the same value for any ModR/M 39201360Srdivacky /// byte; false if not. 40201360Srdivacky virtual bool isDumb() const { return false; } 41201360Srdivacky 42201360Srdivacky /// accepts - Indicates whether the filter accepts a particular ModR/M 43201360Srdivacky /// byte value. 44201360Srdivacky /// 45201360Srdivacky /// @result - True if the filter accepts the ModR/M byte; false if not. 46201360Srdivacky virtual bool accepts(uint8_t modRM) const = 0; 47201360Srdivacky}; 48201360Srdivacky 49201360Srdivacky/// DumbFilter - Accepts any ModR/M byte. Used for instructions that do not 50201360Srdivacky/// require a ModR/M byte or instructions where the entire ModR/M byte is used 51201360Srdivacky/// for operands. 52201360Srdivackyclass DumbFilter : public ModRMFilter { 53234353Sdim virtual void anchor(); 54201360Srdivackypublic: 55201360Srdivacky bool isDumb() const { 56201360Srdivacky return true; 57201360Srdivacky } 58201360Srdivacky 59201360Srdivacky bool accepts(uint8_t modRM) const { 60201360Srdivacky return true; 61201360Srdivacky } 62201360Srdivacky}; 63201360Srdivacky 64201360Srdivacky/// ModFilter - Filters based on the mod bits [bits 7-6] of the ModR/M byte. 65201360Srdivacky/// Some instructions are classified based on whether they are 11 or anything 66201360Srdivacky/// else. This filter performs that classification. 67201360Srdivackyclass ModFilter : public ModRMFilter { 68234353Sdim virtual void anchor(); 69201360Srdivacky bool R; 70201360Srdivackypublic: 71201360Srdivacky /// Constructor 72201360Srdivacky /// 73243830Sdim /// \param r True if the mod bits of the ModR/M byte must be 11; false 74201360Srdivacky /// otherwise. The name r derives from the fact that the mod 75201360Srdivacky /// bits indicate whether the R/M bits [bits 2-0] signify a 76201360Srdivacky /// register or a memory operand. 77201360Srdivacky ModFilter(bool r) : 78201360Srdivacky ModRMFilter(), 79201360Srdivacky R(r) { 80201360Srdivacky } 81201360Srdivacky 82201360Srdivacky bool accepts(uint8_t modRM) const { 83201360Srdivacky if (R == ((modRM & 0xc0) == 0xc0)) 84201360Srdivacky return true; 85201360Srdivacky else 86201360Srdivacky return false; 87201360Srdivacky } 88201360Srdivacky}; 89201360Srdivacky 90201360Srdivacky/// EscapeFilter - Filters escape opcodes, which are classified in two ways. If 91201360Srdivacky/// the ModR/M byte is between 0xc0 and 0xff, then there is one slot for each 92201360Srdivacky/// possible value. Otherwise, there is one instruction for each value of the 93201360Srdivacky/// nnn field [bits 5-3], known elsewhere as the reg field. 94201360Srdivackyclass EscapeFilter : public ModRMFilter { 95234353Sdim virtual void anchor(); 96201360Srdivacky bool C0_FF; 97201360Srdivacky uint8_t NNN_or_ModRM; 98201360Srdivackypublic: 99201360Srdivacky /// Constructor 100201360Srdivacky /// 101243830Sdim /// \param c0_ff True if the ModR/M byte must fall between 0xc0 and 0xff; 102243830Sdim /// false otherwise. 103243830Sdim /// 104243830Sdim /// \param nnn_or_modRM If c0_ff is true, the required value of the entire 105243830Sdim /// ModR/M byte. If c0_ff is false, the required value 106243830Sdim /// of the nnn field. 107201360Srdivacky EscapeFilter(bool c0_ff, uint8_t nnn_or_modRM) : 108201360Srdivacky ModRMFilter(), 109201360Srdivacky C0_FF(c0_ff), 110201360Srdivacky NNN_or_ModRM(nnn_or_modRM) { 111201360Srdivacky } 112201360Srdivacky 113201360Srdivacky bool accepts(uint8_t modRM) const { 114201360Srdivacky if ((C0_FF && modRM >= 0xc0 && (modRM == NNN_or_ModRM)) || 115201360Srdivacky (!C0_FF && modRM < 0xc0 && ((modRM & 0x38) >> 3) == NNN_or_ModRM)) 116201360Srdivacky return true; 117201360Srdivacky else 118201360Srdivacky return false; 119201360Srdivacky } 120201360Srdivacky}; 121201360Srdivacky 122201360Srdivacky/// AddRegEscapeFilter - Some escape opcodes have one of the register operands 123201360Srdivacky/// added to the ModR/M byte, meaning that a range of eight ModR/M values 124201360Srdivacky/// maps to a single instruction. Such instructions require the ModR/M byte 125201360Srdivacky/// to fall between 0xc0 and 0xff. 126201360Srdivackyclass AddRegEscapeFilter : public ModRMFilter { 127234353Sdim virtual void anchor(); 128201360Srdivacky uint8_t ModRM; 129201360Srdivackypublic: 130201360Srdivacky /// Constructor 131201360Srdivacky /// 132243830Sdim /// \param modRM The value of the ModR/M byte when the register operand 133243830Sdim /// refers to the first register in the register set. 134201360Srdivacky AddRegEscapeFilter(uint8_t modRM) : ModRM(modRM) { 135201360Srdivacky } 136201360Srdivacky 137201360Srdivacky bool accepts(uint8_t modRM) const { 138201360Srdivacky if (modRM >= ModRM && modRM < ModRM + 8) 139201360Srdivacky return true; 140201360Srdivacky else 141201360Srdivacky return false; 142201360Srdivacky } 143201360Srdivacky}; 144201360Srdivacky 145201360Srdivacky/// ExtendedFilter - Extended opcodes are classified based on the value of the 146201360Srdivacky/// mod field [bits 7-6] and the value of the nnn field [bits 5-3]. 147201360Srdivackyclass ExtendedFilter : public ModRMFilter { 148234353Sdim virtual void anchor(); 149201360Srdivacky bool R; 150201360Srdivacky uint8_t NNN; 151201360Srdivackypublic: 152201360Srdivacky /// Constructor 153201360Srdivacky /// 154243830Sdim /// \param r True if the mod field must be set to 11; false otherwise. 155243830Sdim /// The name is explained at ModFilter. 156243830Sdim /// \param nnn The required value of the nnn field. 157201360Srdivacky ExtendedFilter(bool r, uint8_t nnn) : 158201360Srdivacky ModRMFilter(), 159201360Srdivacky R(r), 160201360Srdivacky NNN(nnn) { 161201360Srdivacky } 162201360Srdivacky 163201360Srdivacky bool accepts(uint8_t modRM) const { 164201360Srdivacky if (((R && ((modRM & 0xc0) == 0xc0)) || 165201360Srdivacky (!R && ((modRM & 0xc0) != 0xc0))) && 166201360Srdivacky (((modRM & 0x38) >> 3) == NNN)) 167201360Srdivacky return true; 168201360Srdivacky else 169201360Srdivacky return false; 170201360Srdivacky } 171201360Srdivacky}; 172201360Srdivacky 173201360Srdivacky/// ExactFilter - The occasional extended opcode (such as VMCALL or MONITOR) 174201360Srdivacky/// requires the ModR/M byte to have a specific value. 175234353Sdimclass ExactFilter : public ModRMFilter { 176234353Sdim virtual void anchor(); 177201360Srdivacky uint8_t ModRM; 178201360Srdivackypublic: 179201360Srdivacky /// Constructor 180201360Srdivacky /// 181243830Sdim /// \param modRM The required value of the full ModR/M byte. 182201360Srdivacky ExactFilter(uint8_t modRM) : 183201360Srdivacky ModRMFilter(), 184201360Srdivacky ModRM(modRM) { 185201360Srdivacky } 186201360Srdivacky 187201360Srdivacky bool accepts(uint8_t modRM) const { 188201360Srdivacky if (ModRM == modRM) 189201360Srdivacky return true; 190201360Srdivacky else 191201360Srdivacky return false; 192201360Srdivacky } 193201360Srdivacky}; 194201360Srdivacky 195201360Srdivacky} // namespace X86Disassembler 196201360Srdivacky 197201360Srdivacky} // namespace llvm 198201360Srdivacky 199201360Srdivacky#endif 200