1//===- X86ModRMFilters.h - Disassembler ModR/M filterss ---------*- C++ -*-===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// This file is part of the X86 Disassembler Emitter.
10// It contains ModR/M filters that determine which values of the ModR/M byte
11// are valid for a partiuclar instruction.
12// Documentation for the disassembler emitter in general can be found in
13// X86DisassemblerEmitter.h.
14//
15//===----------------------------------------------------------------------===//
16
17#ifndef LLVM_UTILS_TABLEGEN_X86MODRMFILTERS_H
18#define LLVM_UTILS_TABLEGEN_X86MODRMFILTERS_H
19
20#include <cstdint>
21
22namespace llvm::X86Disassembler {
23
24/// ModRMFilter - Abstract base class for clases that recognize patterns in
25/// ModR/M bytes.
26class ModRMFilter {
27 virtual void anchor();
28
29public:
30 /// Destructor - Override as necessary.
31 virtual ~ModRMFilter() = default;
32
33 /// isDumb - Indicates whether this filter returns the same value for
34 /// any value of the ModR/M byte.
35 ///
36 /// @result - True if the filter returns the same value for any ModR/M
37 /// byte; false if not.
38 virtual bool isDumb() const { return false; }
39
40 /// accepts - Indicates whether the filter accepts a particular ModR/M
41 /// byte value.
42 ///
43 /// @result - True if the filter accepts the ModR/M byte; false if not.
44 virtual bool accepts(uint8_t modRM) const = 0;
45};
46
47/// DumbFilter - Accepts any ModR/M byte. Used for instructions that do not
48/// require a ModR/M byte or instructions where the entire ModR/M byte is used
49/// for operands.
50class DumbFilter : public ModRMFilter {
51 void anchor() override;
52
53public:
54 bool isDumb() const override { return true; }
55
56 bool accepts(uint8_t modRM) const override { return true; }
57};
58
59/// ModFilter - Filters based on the mod bits [bits 7-6] of the ModR/M byte.
60/// Some instructions are classified based on whether they are 11 or anything
61/// else. This filter performs that classification.
62class ModFilter : public ModRMFilter {
63 void anchor() override;
64 bool R;
65
66public:
67 /// Constructor
68 ///
69 /// \param r True if the mod bits of the ModR/M byte must be 11; false
70 /// otherwise. The name r derives from the fact that the mod
71 /// bits indicate whether the R/M bits [bits 2-0] signify a
72 /// register or a memory operand.
73 ModFilter(bool r) : R(r) {}
74
75 bool accepts(uint8_t modRM) const override {
76 return (R == ((modRM & 0xc0) == 0xc0));
77 }
78};
79
80/// ExtendedFilter - Extended opcodes are classified based on the value of the
81/// mod field [bits 7-6] and the value of the nnn field [bits 5-3].
82class ExtendedFilter : public ModRMFilter {
83 void anchor() override;
84 bool R;
85 uint8_t NNN;
86
87public:
88 /// Constructor
89 ///
90 /// \param r True if the mod field must be set to 11; false otherwise.
91 /// The name is explained at ModFilter.
92 /// \param nnn The required value of the nnn field.
93 ExtendedFilter(bool r, uint8_t nnn) : R(r), NNN(nnn) {}
94
95 bool accepts(uint8_t modRM) const override {
96 return (
97 ((R && ((modRM & 0xc0) == 0xc0)) || (!R && ((modRM & 0xc0) != 0xc0))) &&
98 (((modRM & 0x38) >> 3) == NNN));
99 }
100};
101
102/// ExtendedRMFilter - Extended opcodes are classified based on the value of the
103/// mod field [bits 7-6] and the value of the nnn field [bits 2-0].
104class ExtendedRMFilter : public ModRMFilter {
105 void anchor() override;
106 bool R;
107 uint8_t NNN;
108
109public:
110 /// Constructor
111 ///
112 /// \param r True if the mod field must be set to 11; false otherwise.
113 /// The name is explained at ModFilter.
114 /// \param nnn The required value of the nnn field.
115 ExtendedRMFilter(bool r, uint8_t nnn) : R(r), NNN(nnn) {}
116
117 bool accepts(uint8_t modRM) const override {
118 return ((R && ((modRM & 0xc0) == 0xc0)) && ((modRM & 0x7) == NNN));
119 }
120};
121/// ExactFilter - The occasional extended opcode (such as VMCALL or MONITOR)
122/// requires the ModR/M byte to have a specific value.
123class ExactFilter : public ModRMFilter {
124 void anchor() override;
125 uint8_t ModRM;
126
127public:
128 /// Constructor
129 ///
130 /// \param modRM The required value of the full ModR/M byte.
131 ExactFilter(uint8_t modRM) : ModRM(modRM) {}
132
133 bool accepts(uint8_t modRM) const override { return (ModRM == modRM); }
134};
135
136} // namespace llvm::X86Disassembler
137
138#endif
139