xref: /haiku/headers/libs/zydis/Zydis/Internal/EncoderData.h (revision 909af08f4328301fbdef1ffb41f566c3b5bec0c7)
1 /***************************************************************************************************
2 
3   Zyan Disassembler Library (Zydis)
4 
5   Original Author : Mappa
6 
7  * Permission is hereby granted, free of charge, to any person obtaining a copy
8  * of this software and associated documentation files (the "Software"), to deal
9  * in the Software without restriction, including without limitation the rights
10  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11  * copies of the Software, and to permit persons to whom the Software is
12  * furnished to do so, subject to the following conditions:
13  *
14  * The above copyright notice and this permission notice shall be included in all
15  * copies or substantial portions of the Software.
16  *
17  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23  * SOFTWARE.
24 
25 ***************************************************************************************************/
26 
27 #ifndef ZYDIS_INTERNAL_ENCODERDATA_H
28 #define ZYDIS_INTERNAL_ENCODERDATA_H
29 
30 #include <Zycore/Defines.h>
31 #include <Zydis/Mnemonic.h>
32 #include <Zydis/SharedTypes.h>
33 
34 /**
35  * Used in encoder's table to represent standard ISA sizes in form of bit flags.
36  */
37 typedef enum ZydisWidthFlag_
38 {
39     ZYDIS_WIDTH_INVALID = 0x00,
40     ZYDIS_WIDTH_16      = 0x01,
41     ZYDIS_WIDTH_32      = 0x02,
42     ZYDIS_WIDTH_64      = 0x04,
43 
44     /**
45      * Maximum value of this enum.
46      */
47     ZYDIS_WIDTH_MAX_VALUE = (ZYDIS_WIDTH_64 | (ZYDIS_WIDTH_64 - 1)),
48     /**
49      * The minimum number of bits required to represent all values of this enum.
50      */
51     ZYDIS_WIDTH_REQUIRED_BITS = ZYAN_BITS_TO_REPRESENT(ZYDIS_WIDTH_MAX_VALUE)
52 } ZydisWidthFlag;
53 
54 /**
55  * Used in encoder's table to represent mandatory instruction prefix. Using this enum instead of
56  * actual prefix value saves space.
57  */
58 typedef enum ZydisMandatoryPrefix_
59 {
60     ZYDIS_MANDATORY_PREFIX_NONE,
61     ZYDIS_MANDATORY_PREFIX_66,
62     ZYDIS_MANDATORY_PREFIX_F2,
63     ZYDIS_MANDATORY_PREFIX_F3,
64 
65     /**
66      * Maximum value of this enum.
67      */
68     ZYDIS_MANDATORY_PREFIX_MAX_VALUE = ZYDIS_MANDATORY_PREFIX_F3,
69     /**
70      * The minimum number of bits required to represent all values of this enum.
71      */
72     ZYDIS_MANDATORY_PREFIX_REQUIRED_BITS = ZYAN_BITS_TO_REPRESENT(ZYDIS_MANDATORY_PREFIX_MAX_VALUE)
73 } ZydisMandatoryPrefix;
74 
75 /**
76  * Used in encoder's table to represent vector size supported by instruction definition.
77  */
78 typedef enum ZydisVectorLength_
79 {
80     ZYDIS_VECTOR_LENGTH_INVALID,
81     ZYDIS_VECTOR_LENGTH_128,
82     ZYDIS_VECTOR_LENGTH_256,
83     ZYDIS_VECTOR_LENGTH_512,
84 
85     /**
86      * Maximum value of this enum.
87      */
88     ZYDIS_VECTOR_LENGTH_MAX_VALUE = ZYDIS_VECTOR_LENGTH_512,
89     /**
90      * The minimum number of bits required to represent all values of this enum.
91      */
92     ZYDIS_VECTOR_LENGTH_REQUIRED_BITS = ZYAN_BITS_TO_REPRESENT(ZYDIS_VECTOR_LENGTH_MAX_VALUE)
93 } ZydisVectorLength;
94 
95 /**
96  * Used in encoder's table to represent hint type supported by instruction definition.
97  */
98 typedef enum ZydisSizeHint_
99 {
100     ZYDIS_SIZE_HINT_NONE,
101     ZYDIS_SIZE_HINT_ASZ,
102     ZYDIS_SIZE_HINT_OSZ,
103 
104     /**
105      * Maximum value of this enum.
106      */
107     ZYDIS_SIZE_HINT_MAX_VALUE = ZYDIS_SIZE_HINT_OSZ,
108     /**
109      * The minimum number of bits required to represent all values of this enum.
110      */
111     ZYDIS_SIZE_HINT_REQUIRED_BITS = ZYAN_BITS_TO_REPRESENT(ZYDIS_SIZE_HINT_MAX_VALUE)
112 } ZydisSizeHint;
113 
114 /**
115  * Used in encoder's primary lookup table which allows to access a set of instruction definitions
116  * for specified mnemonic in constant time.
117  */
118 typedef struct ZydisEncoderLookupEntry_
119 {
120     /**
121      * Index to main array of `ZydisEncodableInstruction`.
122      */
123     ZyanU16 encoder_reference;
124     /**
125      * The number of entries.
126      */
127     ZyanU8 instruction_count;
128 } ZydisEncoderLookupEntry;
129 
130 #pragma pack(push, 1)
131 
132 /**
133  * This structure is encoder's internal representation of encodable instruction definition.
134  */
135 typedef struct ZydisEncodableInstruction_
136 {
137     /**
138      * Index to one of decoder's instruction definition arrays.
139      */
140     ZyanU16 instruction_reference;
141     /**
142      * Compressed information about operand count and types. Operand count is stored in lowest bits.
143      * Types of subsequent operands are stored in higher bits.
144      */
145     ZyanU16 operand_mask;
146     /**
147      * The instruction-opcode.
148      */
149     ZyanU8 opcode;
150     /**
151      * The mandatory ModR/M value.
152      */
153     ZyanU8 modrm;
154     /**
155      * The instruction-encoding.
156      */
157     ZyanU8 encoding                 ZYAN_BITFIELD(ZYDIS_INSTRUCTION_ENCODING_REQUIRED_BITS);
158     /**
159      * The opcode map.
160      */
161     ZyanU8 opcode_map               ZYAN_BITFIELD(ZYDIS_OPCODE_MAP_REQUIRED_BITS);
162     /**
163      * The combination of allowed processor modes.
164      */
165     ZyanU8 modes                    ZYAN_BITFIELD(ZYDIS_WIDTH_REQUIRED_BITS);
166     /**
167      * The combination of allowed address sizes.
168      */
169     ZyanU8 address_sizes            ZYAN_BITFIELD(ZYDIS_WIDTH_REQUIRED_BITS);
170     /**
171      * The combination of allowed operand sizes.
172      */
173     ZyanU8 operand_sizes            ZYAN_BITFIELD(ZYDIS_WIDTH_REQUIRED_BITS);
174     /**
175      * The mandatory prefix.
176      */
177     ZyanU8 mandatory_prefix         ZYAN_BITFIELD(ZYDIS_MANDATORY_PREFIX_REQUIRED_BITS);
178     /**
179      * True if `REX.W` is required for this definition.
180      */
181     ZyanU8 rex_w                    ZYAN_BITFIELD(1);
182     /**
183      * The vector length.
184      */
185     ZyanU8 vector_length            ZYAN_BITFIELD(ZYDIS_MANDATORY_PREFIX_REQUIRED_BITS);
186     /**
187      * The accepted sizing hint.
188      */
189     ZyanU8 accepts_hint             ZYAN_BITFIELD(ZYDIS_SIZE_HINT_REQUIRED_BITS);
190     /**
191      * Indicates that next instruction definition can be safely used instead of current one. This
192      * is used with some `VEX` instructions to take advantage of 2-byte `VEX` prefix when possible.
193      * 2-byte `VEX` allows to use high registers only when operand is encoded in `modrm_reg`
194      * (high bit in `REX.R`). Encoder uses swappable definitions to take advantage of this
195      * optimization opportunity.
196      *
197      * Second use of this field is to handle special case for `mov` instruction. This particular
198      * conflict is described in detail inside `ZydisHandleSwappableDefinition`.
199      */
200     ZyanU8 swappable                ZYAN_BITFIELD(1);
201 } ZydisEncodableInstruction;
202 
203 #pragma pack(pop)
204 
205 /**
206  * Contains information used by instruction size prediction algorithm inside
207  * `ZydisEncoderEncodeInstructionAbsolute`.
208  */
209 typedef struct ZydisEncoderRelInfo_
210 {
211     /**
212      * Sizes of instruction variants. First index is effective address size. Second index is
213      * desired immediate size (8, 16 and 32 bits respectively).
214      */
215     ZyanU8 size[3][3];
216     /**
217      * See `ZydisSizeHint`.
218      */
219     ZyanU8 accepts_scaling_hints;
220     /**
221      * True if instruction accepts branch hint prefixes.
222      */
223     ZyanBool accepts_branch_hints;
224     /**
225      * True if instruction accepts bound (`BND`) prefix.
226      */
227     ZyanBool accepts_bound;
228 } ZydisEncoderRelInfo;
229 
230 /**
231  * Fetches array of `ZydisEncodableInstruction` structures and its size for given instruction
232  * mnemonic.
233  *
234  * @param   mnemonic    Instruction mnemonic.
235  * @param   instruction This variable will receive a pointer to the array of
236  *                      `ZydisEncodableInstruction` structures.
237  *
238  * @return  Entry count (0 if function failed).
239  */
240 ZyanU8 ZydisGetEncodableInstructions(ZydisMnemonic mnemonic,
241     const ZydisEncodableInstruction **instruction);
242 
243 /**
244  * Fetches `ZydisEncoderRelInfo` record for given instruction mnemonic.
245  *
246  * @param   mnemonic    Instruction mnemonic.
247  *
248  * @return  Pointer to `ZydisEncoderRelInfo` structure or `ZYAN_NULL` if instruction doesn't have
249  *          relative operands.
250  */
251 const ZydisEncoderRelInfo *ZydisGetRelInfo(ZydisMnemonic mnemonic);
252 
253 #endif /* ZYDIS_INTERNAL_ENCODERDATA_H */
254