18ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan//===- X86ModRMFilters.h - Disassembler ModR/M filterss ---------*- C++ -*-===// 28ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan// 38ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan// The LLVM Compiler Infrastructure 48ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan// 58ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan// This file is distributed under the University of Illinois Open Source 68ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan// License. See LICENSE.TXT for details. 78ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan// 88ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan//===----------------------------------------------------------------------===// 98ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan// 108ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan// This file is part of the X86 Disassembler Emitter. 118ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan// It contains ModR/M filters that determine which values of the ModR/M byte 128ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan// are valid for a partiuclar instruction. 138ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan// Documentation for the disassembler emitter in general can be found in 148ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan// X86DisasemblerEmitter.h. 158ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan// 168ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan//===----------------------------------------------------------------------===// 178ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan 188ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan#ifndef X86MODRMFILTERS_H 198ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan#define X86MODRMFILTERS_H 208ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan 213cc52ea33c0b96d1682f14fc45c45b57df0f39b6Michael J. Spencer#include "llvm/Support/DataTypes.h" 228ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan 238ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanannamespace llvm { 248ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan 258ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanannamespace X86Disassembler { 268ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan 278ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan/// ModRMFilter - Abstract base class for clases that recognize patterns in 288ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan/// ModR/M bytes. 298ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callananclass ModRMFilter { 302d24e2a396a1d211baaeedf32148a3b657240170David Blaikie virtual void anchor(); 318ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callananpublic: 328ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan /// Destructor - Override as necessary. 338ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan virtual ~ModRMFilter() { } 348ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan 358ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan /// isDumb - Indicates whether this filter returns the same value for 368ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan /// any value of the ModR/M byte. 378ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan /// 388ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan /// @result - True if the filter returns the same value for any ModR/M 398ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan /// byte; false if not. 408ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan virtual bool isDumb() const { return false; } 418ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan 428ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan /// accepts - Indicates whether the filter accepts a particular ModR/M 438ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan /// byte value. 448ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan /// 458ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan /// @result - True if the filter accepts the ModR/M byte; false if not. 468ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan virtual bool accepts(uint8_t modRM) const = 0; 478ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan}; 488ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan 498ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan/// DumbFilter - Accepts any ModR/M byte. Used for instructions that do not 508ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan/// require a ModR/M byte or instructions where the entire ModR/M byte is used 518ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan/// for operands. 528ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callananclass DumbFilter : public ModRMFilter { 5336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines void anchor() override; 548ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callananpublic: 5536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines bool isDumb() const override { 568ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan return true; 578ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan } 5836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 5936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines bool accepts(uint8_t modRM) const override { 608ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan return true; 618ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan } 628ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan}; 638ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan 648ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan/// ModFilter - Filters based on the mod bits [bits 7-6] of the ModR/M byte. 658ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan/// Some instructions are classified based on whether they are 11 or anything 668ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan/// else. This filter performs that classification. 678ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callananclass ModFilter : public ModRMFilter { 6836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines void anchor() override; 698ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan bool R; 708ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callananpublic: 718ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan /// Constructor 728ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan /// 732d9eb72178af8e79dc6432cd1b7d29bde16da1b9Dmitri Gribenko /// \param r True if the mod bits of the ModR/M byte must be 11; false 748ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan /// otherwise. The name r derives from the fact that the mod 758ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan /// bits indicate whether the R/M bits [bits 2-0] signify a 768ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan /// register or a memory operand. 778ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan ModFilter(bool r) : 788ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan ModRMFilter(), 798ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan R(r) { 808ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan } 818ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan 8236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines bool accepts(uint8_t modRM) const override { 8336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return (R == ((modRM & 0xc0) == 0xc0)); 848ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan } 858ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan}; 868ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan 878ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan/// ExtendedFilter - Extended opcodes are classified based on the value of the 888ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan/// mod field [bits 7-6] and the value of the nnn field [bits 5-3]. 898ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callananclass ExtendedFilter : public ModRMFilter { 9036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines void anchor() override; 918ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan bool R; 928ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan uint8_t NNN; 938ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callananpublic: 948ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan /// Constructor 958ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan /// 962d9eb72178af8e79dc6432cd1b7d29bde16da1b9Dmitri Gribenko /// \param r True if the mod field must be set to 11; false otherwise. 972d9eb72178af8e79dc6432cd1b7d29bde16da1b9Dmitri Gribenko /// The name is explained at ModFilter. 982d9eb72178af8e79dc6432cd1b7d29bde16da1b9Dmitri Gribenko /// \param nnn The required value of the nnn field. 998ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan ExtendedFilter(bool r, uint8_t nnn) : 1008ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan ModRMFilter(), 1018ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan R(r), 1028ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan NNN(nnn) { 1038ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan } 10436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 10536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines bool accepts(uint8_t modRM) const override { 10636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return (((R && ((modRM & 0xc0) == 0xc0)) || 10736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines (!R && ((modRM & 0xc0) != 0xc0))) && 10836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines (((modRM & 0x38) >> 3) == NNN)); 1098ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan } 1108ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan}; 1118ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan 1128ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan/// ExactFilter - The occasional extended opcode (such as VMCALL or MONITOR) 1138ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan/// requires the ModR/M byte to have a specific value. 1142d24e2a396a1d211baaeedf32148a3b657240170David Blaikieclass ExactFilter : public ModRMFilter { 11536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines void anchor() override; 1168ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan uint8_t ModRM; 1178ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callananpublic: 1188ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan /// Constructor 1198ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan /// 1202d9eb72178af8e79dc6432cd1b7d29bde16da1b9Dmitri Gribenko /// \param modRM The required value of the full ModR/M byte. 1218ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan ExactFilter(uint8_t modRM) : 1228ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan ModRMFilter(), 1238ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan ModRM(modRM) { 1248ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan } 12536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 12636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines bool accepts(uint8_t modRM) const override { 12736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return (ModRM == modRM); 1288ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan } 1298ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan}; 1308ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan 1318ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan} // namespace X86Disassembler 1328ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan 1338ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan} // namespace llvm 1348ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan 1359e6d1d1f5034347d237941f1bf08fba5c1583cd3Daniel Dunbar#endif 136