diff options
Diffstat (limited to 'utils/TableGen/X86ModRMFilters.h')
-rw-r--r-- | utils/TableGen/X86ModRMFilters.h | 197 |
1 files changed, 197 insertions, 0 deletions
diff --git a/utils/TableGen/X86ModRMFilters.h b/utils/TableGen/X86ModRMFilters.h new file mode 100644 index 0000000000..4fe4af3500 --- /dev/null +++ b/utils/TableGen/X86ModRMFilters.h @@ -0,0 +1,197 @@ +//===- X86ModRMFilters.h - Disassembler ModR/M filterss ---------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file is part of the X86 Disassembler Emitter. +// It contains ModR/M filters that determine which values of the ModR/M byte +// are valid for a partiuclar instruction. +// Documentation for the disassembler emitter in general can be found in +// X86DisasemblerEmitter.h. +// +//===----------------------------------------------------------------------===// + +#ifndef X86MODRMFILTERS_H +#define X86MODRMFILTERS_H + +#include "llvm/System/DataTypes.h" + +namespace llvm { + +namespace X86Disassembler { + +/// ModRMFilter - Abstract base class for clases that recognize patterns in +/// ModR/M bytes. +class ModRMFilter { +public: + /// Destructor - Override as necessary. + virtual ~ModRMFilter() { } + + /// isDumb - Indicates whether this filter returns the same value for + /// any value of the ModR/M byte. + /// + /// @result - True if the filter returns the same value for any ModR/M + /// byte; false if not. + virtual bool isDumb() const { return false; } + + /// accepts - Indicates whether the filter accepts a particular ModR/M + /// byte value. + /// + /// @result - True if the filter accepts the ModR/M byte; false if not. + virtual bool accepts(uint8_t modRM) const = 0; +}; + +/// DumbFilter - Accepts any ModR/M byte. Used for instructions that do not +/// require a ModR/M byte or instructions where the entire ModR/M byte is used +/// for operands. +class DumbFilter : public ModRMFilter { +public: + bool isDumb() const { + return true; + } + + bool accepts(uint8_t modRM) const { + return true; + } +}; + +/// ModFilter - Filters based on the mod bits [bits 7-6] of the ModR/M byte. +/// Some instructions are classified based on whether they are 11 or anything +/// else. This filter performs that classification. +class ModFilter : public ModRMFilter { +private: + bool R; +public: + /// Constructor + /// + /// @r - True if the mod bits of the ModR/M byte must be 11; false + /// otherwise. The name r derives from the fact that the mod + /// bits indicate whether the R/M bits [bits 2-0] signify a + /// register or a memory operand. + ModFilter(bool r) : + ModRMFilter(), + R(r) { + } + + bool accepts(uint8_t modRM) const { + if (R == ((modRM & 0xc0) == 0xc0)) + return true; + else + return false; + } +}; + +/// EscapeFilter - Filters escape opcodes, which are classified in two ways. If +/// the ModR/M byte is between 0xc0 and 0xff, then there is one slot for each +/// possible value. Otherwise, there is one instruction for each value of the +/// nnn field [bits 5-3], known elsewhere as the reg field. +class EscapeFilter : public ModRMFilter { +private: + bool C0_FF; + uint8_t NNN_or_ModRM; +public: + /// Constructor + /// + /// @c0_ff - True if the ModR/M byte must fall between 0xc0 and 0xff; + /// false otherwise. + /// @nnn_or_modRM - If c0_ff is true, the required value of the entire ModR/M + /// byte. If c0_ff is false, the required value of the nnn + /// field. + EscapeFilter(bool c0_ff, uint8_t nnn_or_modRM) : + ModRMFilter(), + C0_FF(c0_ff), + NNN_or_ModRM(nnn_or_modRM) { + } + + bool accepts(uint8_t modRM) const { + if ((C0_FF && modRM >= 0xc0 && (modRM == NNN_or_ModRM)) || + (!C0_FF && modRM < 0xc0 && ((modRM & 0x38) >> 3) == NNN_or_ModRM)) + return true; + else + return false; + } +}; + +/// AddRegEscapeFilter - Some escape opcodes have one of the register operands +/// added to the ModR/M byte, meaning that a range of eight ModR/M values +/// maps to a single instruction. Such instructions require the ModR/M byte +/// to fall between 0xc0 and 0xff. +class AddRegEscapeFilter : public ModRMFilter { +private: + uint8_t ModRM; +public: + /// Constructor + /// + /// @modRM - The value of the ModR/M byte when the register operand + /// refers to the first register in the register set. + AddRegEscapeFilter(uint8_t modRM) : ModRM(modRM) { + } + + bool accepts(uint8_t modRM) const { + if (modRM >= ModRM && modRM < ModRM + 8) + return true; + else + return false; + } +}; + +/// ExtendedFilter - Extended opcodes are classified based on the value of the +/// mod field [bits 7-6] and the value of the nnn field [bits 5-3]. +class ExtendedFilter : public ModRMFilter { +private: + bool R; + uint8_t NNN; +public: + /// Constructor + /// + /// @r - True if the mod field must be set to 11; false otherwise. + /// The name is explained at ModFilter. + /// @nnn - The required value of the nnn field. + ExtendedFilter(bool r, uint8_t nnn) : + ModRMFilter(), + R(r), + NNN(nnn) { + } + + bool accepts(uint8_t modRM) const { + if (((R && ((modRM & 0xc0) == 0xc0)) || + (!R && ((modRM & 0xc0) != 0xc0))) && + (((modRM & 0x38) >> 3) == NNN)) + return true; + else + return false; + } +}; + +/// ExactFilter - The occasional extended opcode (such as VMCALL or MONITOR) +/// requires the ModR/M byte to have a specific value. +class ExactFilter : public ModRMFilter +{ +private: + uint8_t ModRM; +public: + /// Constructor + /// + /// @modRM - The required value of the full ModR/M byte. + ExactFilter(uint8_t modRM) : + ModRMFilter(), + ModRM(modRM) { + } + + bool accepts(uint8_t modRM) const { + if (ModRM == modRM) + return true; + else + return false; + } +}; + +} // namespace X86Disassembler + +} // namespace llvm + +#endif
\ No newline at end of file |