X86ModRMFilters.h revision 218893
1183840Sraj//===- X86ModRMFilters.h - Disassembler ModR/M filterss ---------*- C++ -*-===// 2239277Sgonzo// 3183840Sraj// The LLVM Compiler Infrastructure 4183840Sraj// 5183840Sraj// This file is distributed under the University of Illinois Open Source 6183840Sraj// License. See LICENSE.TXT for details. 7183840Sraj// 8183840Sraj//===----------------------------------------------------------------------===// 9183840Sraj// 10183840Sraj// This file is part of the X86 Disassembler Emitter. 11183840Sraj// It contains ModR/M filters that determine which values of the ModR/M byte 12183840Sraj// are valid for a partiuclar instruction. 13183840Sraj// Documentation for the disassembler emitter in general can be found in 14183840Sraj// X86DisasemblerEmitter.h. 15183840Sraj// 16183840Sraj//===----------------------------------------------------------------------===// 17183840Sraj 18183840Sraj#ifndef X86MODRMFILTERS_H 19183840Sraj#define X86MODRMFILTERS_H 20183840Sraj 21183840Sraj#include "llvm/Support/DataTypes.h" 22183840Sraj 23183840Srajnamespace llvm { 24183840Sraj 25183840Srajnamespace X86Disassembler { 26183840Sraj 27183840Sraj/// ModRMFilter - Abstract base class for clases that recognize patterns in 28183840Sraj/// ModR/M bytes. 29183840Srajclass ModRMFilter { 30183840Srajpublic: 31183840Sraj /// Destructor - Override as necessary. 32183840Sraj virtual ~ModRMFilter() { } 33183840Sraj 34183840Sraj /// isDumb - Indicates whether this filter returns the same value for 35183840Sraj /// any value of the ModR/M byte. 36183840Sraj /// 37183840Sraj /// @result - True if the filter returns the same value for any ModR/M 38183840Sraj /// byte; false if not. 39183840Sraj virtual bool isDumb() const { return false; } 40183840Sraj 41183840Sraj /// accepts - Indicates whether the filter accepts a particular ModR/M 42183840Sraj /// byte value. 43183840Sraj /// 44183840Sraj /// @result - True if the filter accepts the ModR/M byte; false if not. 45183840Sraj virtual bool accepts(uint8_t modRM) const = 0; 46183840Sraj}; 47183840Sraj 48183840Sraj/// DumbFilter - Accepts any ModR/M byte. Used for instructions that do not 49239277Sgonzo/// require a ModR/M byte or instructions where the entire ModR/M byte is used 50239277Sgonzo/// for operands. 51239277Sgonzoclass DumbFilter : public ModRMFilter { 52183840Srajpublic: 53239277Sgonzo bool isDumb() const { 54183840Sraj return true; 55183840Sraj } 56183840Sraj 57239277Sgonzo bool accepts(uint8_t modRM) const { 58239277Sgonzo return true; 59239277Sgonzo } 60239277Sgonzo}; 61239277Sgonzo 62239277Sgonzo/// ModFilter - Filters based on the mod bits [bits 7-6] of the ModR/M byte. 63239277Sgonzo/// Some instructions are classified based on whether they are 11 or anything 64239277Sgonzo/// else. This filter performs that classification. 65239277Sgonzoclass ModFilter : public ModRMFilter { 66239277Sgonzoprivate: 67239277Sgonzo bool R; 68239277Sgonzopublic: 69239277Sgonzo /// Constructor 70239277Sgonzo /// 71239277Sgonzo /// @r - True if the mod bits of the ModR/M byte must be 11; false 72239277Sgonzo /// otherwise. The name r derives from the fact that the mod 73183840Sraj /// bits indicate whether the R/M bits [bits 2-0] signify a 74183840Sraj /// register or a memory operand. 75183840Sraj ModFilter(bool r) : 76239277Sgonzo ModRMFilter(), 77239277Sgonzo R(r) { 78183840Sraj } 79183840Sraj 80183840Sraj bool accepts(uint8_t modRM) const { 81183840Sraj if (R == ((modRM & 0xc0) == 0xc0)) 82239277Sgonzo return true; 83239277Sgonzo else 84239277Sgonzo return false; 85239277Sgonzo } 86239277Sgonzo}; 87239277Sgonzo 88239277Sgonzo/// EscapeFilter - Filters escape opcodes, which are classified in two ways. If 89239277Sgonzo/// the ModR/M byte is between 0xc0 and 0xff, then there is one slot for each 90239277Sgonzo/// possible value. Otherwise, there is one instruction for each value of the 91239277Sgonzo/// nnn field [bits 5-3], known elsewhere as the reg field. 92239277Sgonzoclass EscapeFilter : public ModRMFilter { 93239277Sgonzoprivate: 94239277Sgonzo bool C0_FF; 95239277Sgonzo uint8_t NNN_or_ModRM; 96239277Sgonzopublic: 97239277Sgonzo /// Constructor 98183840Sraj /// 99183840Sraj /// @c0_ff - True if the ModR/M byte must fall between 0xc0 and 0xff; 100183840Sraj /// false otherwise. 101183840Sraj /// @nnn_or_modRM - If c0_ff is true, the required value of the entire ModR/M 102183840Sraj /// byte. If c0_ff is false, the required value of the nnn 103183840Sraj /// field. 104183840Sraj EscapeFilter(bool c0_ff, uint8_t nnn_or_modRM) : 105183840Sraj ModRMFilter(), 106183840Sraj C0_FF(c0_ff), 107183840Sraj NNN_or_ModRM(nnn_or_modRM) { 108183840Sraj } 109239277Sgonzo 110183840Sraj bool accepts(uint8_t modRM) const { 111239277Sgonzo if ((C0_FF && modRM >= 0xc0 && (modRM == NNN_or_ModRM)) || 112239277Sgonzo (!C0_FF && modRM < 0xc0 && ((modRM & 0x38) >> 3) == NNN_or_ModRM)) 113239277Sgonzo return true; 114239277Sgonzo else 115239277Sgonzo return false; 116239277Sgonzo } 117239277Sgonzo}; 118239277Sgonzo 119239277Sgonzo/// AddRegEscapeFilter - Some escape opcodes have one of the register operands 120239277Sgonzo/// added to the ModR/M byte, meaning that a range of eight ModR/M values 121239277Sgonzo/// maps to a single instruction. Such instructions require the ModR/M byte 122239277Sgonzo/// to fall between 0xc0 and 0xff. 123183840Srajclass AddRegEscapeFilter : public ModRMFilter { 124183840Srajprivate: 125183840Sraj uint8_t ModRM; 126240488Sgberpublic: 127240488Sgber /// Constructor 128240488Sgber /// 129240488Sgber /// @modRM - The value of the ModR/M byte when the register operand 130240488Sgber /// refers to the first register in the register set. 131240488Sgber AddRegEscapeFilter(uint8_t modRM) : ModRM(modRM) { 132240488Sgber } 133240488Sgber 134240488Sgber bool accepts(uint8_t modRM) const { 135183840Sraj if (modRM >= ModRM && modRM < ModRM + 8) 136183840Sraj return true; 137183840Sraj else 138183840Sraj return false; 139183840Sraj } 140240488Sgber}; 141183840Sraj 142183840Sraj/// ExtendedFilter - Extended opcodes are classified based on the value of the 143183840Sraj/// mod field [bits 7-6] and the value of the nnn field [bits 5-3]. 144183840Srajclass ExtendedFilter : public ModRMFilter { 145183840Srajprivate: 146183840Sraj bool R; 147196532Sraj uint8_t NNN; 148183840Srajpublic: 149183840Sraj /// Constructor 150183840Sraj /// 151183840Sraj /// @r - True if the mod field must be set to 11; false otherwise. 152183840Sraj /// The name is explained at ModFilter. 153183840Sraj /// @nnn - The required value of the nnn field. 154183840Sraj ExtendedFilter(bool r, uint8_t nnn) : 155183840Sraj ModRMFilter(), 156183840Sraj R(r), 157183840Sraj NNN(nnn) { 158183840Sraj } 159183840Sraj 160183840Sraj bool accepts(uint8_t modRM) const { 161183840Sraj if (((R && ((modRM & 0xc0) == 0xc0)) || 162183840Sraj (!R && ((modRM & 0xc0) != 0xc0))) && 163183840Sraj (((modRM & 0x38) >> 3) == NNN)) 164196532Sraj return true; 165196532Sraj else 166196532Sraj return false; 167196532Sraj } 168196532Sraj}; 169209131Sraj 170209131Sraj/// ExactFilter - The occasional extended opcode (such as VMCALL or MONITOR) 171209131Sraj/// requires the ModR/M byte to have a specific value. 172183840Srajclass ExactFilter : public ModRMFilter 173183840Sraj{ 174183840Srajprivate: 175183840Sraj uint8_t ModRM; 176183840Srajpublic: 177183840Sraj /// Constructor 178183840Sraj /// 179183840Sraj /// @modRM - The required value of the full ModR/M byte. 180183840Sraj ExactFilter(uint8_t modRM) : 181183840Sraj ModRMFilter(), 182183840Sraj ModRM(modRM) { 183183840Sraj } 184183840Sraj 185183840Sraj bool accepts(uint8_t modRM) const { 186183840Sraj if (ModRM == modRM) 187183840Sraj return true; 188183840Sraj else 189183840Sraj return false; 190183840Sraj } 191183840Sraj}; 192183840Sraj 193183840Sraj} // namespace X86Disassembler 194196532Sraj 195196532Sraj} // namespace llvm 196209131Sraj 197209131Sraj#endif 198196532Sraj