1 /*BEGIN_LEGAL
2
3 Copyright (c) 2018 Intel Corporation
4
5 Licensed under the Apache License, Version 2.0 (the "License");
6 you may not use this file except in compliance with the License.
7 You may obtain a copy of the License at
8
9 http://www.apache.org/licenses/LICENSE-2.0
10
11 Unless required by applicable law or agreed to in writing, software
12 distributed under the License is distributed on an "AS IS" BASIS,
13 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 See the License for the specific language governing permissions and
15 limitations under the License.
16
17 END_LEGAL */
18 /// @file xed-inst.h
19
20
21 #if !defined(XED_INST_H)
22 # define XED_INST_H
23
24 #include "xed-util.h"
25 #include "xed-portability.h"
26 #include "xed-category-enum.h" // generated
27 #include "xed-extension-enum.h" //generated
28 #include "xed-iclass-enum.h" //generated
29 #include "xed-operand-enum.h" // generated
30 #include "xed-operand-visibility-enum.h" //generated
31 #include "xed-operand-action-enum.h" // generated
32 #include "xed-operand-convert-enum.h" // generated
33 #include "xed-operand-type-enum.h" // generated
34 #include "xed-nonterminal-enum.h" // a generated file
35 #include "xed-operand-width-enum.h" // a generated file
36 #include "xed-operand-element-xtype-enum.h" // a generated file
37 #include "xed-reg-enum.h" // a generated file
38 #include "xed-attribute-enum.h" // a generated file
39 #include "xed-exception-enum.h" // a generated file
40 #include "xed-iform-enum.h" // a generated file
41 #include "xed-iform-map.h"
42 #include "xed-attributes.h"
43
44 struct xed_decoded_inst_s; //fwd-decl
45
46 typedef void (*xed_operand_extractor_fn_t)(struct xed_decoded_inst_s* xds);
47
48
49 /// @ingroup DEC
50 /// Constant information about an individual generic operand, like an
51 ///operand template, describing the operand properties. See @ref DEC for
52 ///API information.
53 typedef struct xed_operand_s
54 {
55 xed_uint8_t _name; // xed_operand_enum_t
56
57 // implicit, explicit, suppressed
58 xed_uint8_t _operand_visibility; // xed_operand_visibility_enum_t
59 xed_uint8_t _rw; // read or written // xed_operand_action_enum_t
60
61 // width code, could be invalid (then use register name)
62 xed_uint8_t _oc2; // xed_operand_width_enum_t
63
64 // IMM, IMM_CONST, NT_LOOKUP_FN, REG, ERROR
65 xed_uint8_t _type; //xed_operand_type_enum_t
66 xed_uint8_t _xtype; // xed data type: u32, f32, etc. //xed_operand_element_xtype_enum_t
67 xed_uint8_t _cvt_idx; // decoration index
68 xed_uint8_t _nt;
69 union {
70 xed_uint32_t _imm; // value for some constant immmed
71 xed_nonterminal_enum_t _nt; // for nt_lookup_fn's
72 xed_reg_enum_t _reg; // register name
73 } _u;
74 } xed_operand_t;
75
76 /// @name xed_inst_t Template Operands Access
77 //@{
78 /// @ingroup DEC
79 static XED_INLINE xed_operand_enum_t
xed_operand_name(const xed_operand_t * p)80 xed_operand_name(const xed_operand_t* p) {
81 return (xed_operand_enum_t)p->_name;
82 }
83
84
85 /// @ingroup DEC
86 static XED_INLINE xed_operand_visibility_enum_t
xed_operand_operand_visibility(const xed_operand_t * p)87 xed_operand_operand_visibility( const xed_operand_t* p) {
88 return (xed_operand_visibility_enum_t)(p->_operand_visibility);
89 }
90
91
92 /// @ingroup DEC
93 /// @return The #xed_operand_type_enum_t of the operand template.
94 /// This is probably not what you want.
95 static XED_INLINE xed_operand_type_enum_t
xed_operand_type(const xed_operand_t * p)96 xed_operand_type(const xed_operand_t* p) {
97 return (xed_operand_type_enum_t)p->_type;
98 }
99
100 /// @ingroup DEC
101 /// @return The #xed_operand_element_xtype_enum_t of the operand template.
102 /// This is probably not what you want.
103 static XED_INLINE xed_operand_element_xtype_enum_t
xed_operand_xtype(const xed_operand_t * p)104 xed_operand_xtype(const xed_operand_t* p) {
105 return (xed_operand_element_xtype_enum_t)p->_xtype;
106 }
107
108
109 /// @ingroup DEC
110 static XED_INLINE xed_operand_width_enum_t
xed_operand_width(const xed_operand_t * p)111 xed_operand_width(const xed_operand_t* p) {
112 return (xed_operand_width_enum_t)p->_oc2;
113 }
114
115 /// @ingroup DEC
116 /// @param p an operand template, #xed_operand_t.
117 /// @param eosz effective operand size of the instruction, 1 | 2 | 3 for
118 /// 16 | 32 | 64 bits respectively. 0 is invalid.
119 /// @return the actual width of operand in bits.
120 /// See xed_decoded_inst_operand_length_bits() for a more general solution.
121 XED_DLL_EXPORT xed_uint32_t
122 xed_operand_width_bits(const xed_operand_t* p,
123 const xed_uint32_t eosz);
124
125 /// @ingroup DEC
126 static XED_INLINE xed_nonterminal_enum_t
xed_operand_nonterminal_name(const xed_operand_t * p)127 xed_operand_nonterminal_name(const xed_operand_t* p) {
128 if (p->_nt)
129 return p->_u._nt;
130 return XED_NONTERMINAL_INVALID;
131 }
132
133 /// @ingroup DEC
134 /// Careful with this one -- use #xed_decoded_inst_get_reg()! This one is
135 /// probably not what you think it is. It is only used for hard-coded
136 /// registers implicit in the instruction encoding. Most likely you want to
137 /// get the #xed_operand_enum_t and then look up the instruction using
138 /// #xed_decoded_inst_get_reg(). The hard-coded registers are also available
139 /// that way.
140 /// @param p an operand template, #xed_operand_t.
141 /// @return the implicit or suppressed registers, type #xed_reg_enum_t
xed_operand_reg(const xed_operand_t * p)142 static XED_INLINE xed_reg_enum_t xed_operand_reg(const xed_operand_t* p) {
143 if (xed_operand_type(p) == XED_OPERAND_TYPE_REG)
144 return p->_u._reg;
145 return XED_REG_INVALID;
146 }
147
148
149
150 /// @ingroup DEC
151 /// Careful with this one; See #xed_operand_is_register().
152 /// @param p an operand template, #xed_operand_t.
153 /// @return 1 if the operand template represents are register-type
154 /// operand.
155 ///
156 /// Related functions:
157 /// Use #xed_decoded_inst_get_reg() to get the decoded name of /// the
158 /// register, #xed_reg_enum_t. Use #xed_operand_is_register() to test
159 /// #xed_operand_enum_t names.
160 static XED_INLINE xed_uint_t
xed_operand_template_is_register(const xed_operand_t * p)161 xed_operand_template_is_register(const xed_operand_t* p) {
162 return p->_nt || p->_type == XED_OPERAND_TYPE_REG;
163 }
164
165 /// @ingroup DEC
166 /// @param p an operand template, #xed_operand_t.
167 /// These operands represent branch displacements, memory displacements and
168 /// various immediates
xed_operand_imm(const xed_operand_t * p)169 static XED_INLINE xed_uint32_t xed_operand_imm(const xed_operand_t* p) {
170 if (xed_operand_type(p) == XED_OPERAND_TYPE_IMM_CONST)
171 return p->_u._imm;
172 return 0;
173 }
174
175 /// @ingroup DEC
176 /// Print the operand p into the buffer buf, of length buflen.
177 /// @param p an operand template, #xed_operand_t.
178 /// @param buf buffer that gets filled in
179 /// @param buflen maximum buffer length
180 XED_DLL_EXPORT void
181 xed_operand_print(const xed_operand_t* p, char* buf, int buflen);
182 //@}
183
184 /// @name xed_inst_t Template Operand Enum Name Classification
185 //@{
186 /// @ingroup DEC
187 /// Tests the enum for inclusion in XED_OPERAND_REG0 through XED_OPERAND_REG15.
188 /// @param name the operand name, type #xed_operand_enum_t
189 /// @return 1 if the operand name is REG0...REG15, 0 otherwise.
190 ///
191 ///Note there are other registers for memory addressing; See
192 /// #xed_operand_is_memory_addressing_register .
xed_operand_is_register(xed_operand_enum_t name)193 static XED_INLINE xed_uint_t xed_operand_is_register(xed_operand_enum_t name) {
194 return name >= XED_OPERAND_REG0 && name <= XED_OPERAND_REG8;
195 }
196 /// @ingroup DEC
197 /// Tests the enum for inclusion in XED_OPERAND_{BASE0,BASE1,INDEX,SEG0,SEG1}
198 /// @param name the operand name, type #xed_operand_enum_t
199 /// @return 1 if the operand name is for a memory addressing register operand, 0
200 /// otherwise. See also #xed_operand_is_register .
201 static XED_INLINE xed_uint_t
xed_operand_is_memory_addressing_register(xed_operand_enum_t name)202 xed_operand_is_memory_addressing_register(xed_operand_enum_t name) {
203 return ( name == XED_OPERAND_BASE0 ||
204 name == XED_OPERAND_INDEX ||
205 name == XED_OPERAND_SEG0 ||
206 name == XED_OPERAND_BASE1 ||
207 name == XED_OPERAND_SEG1 );
208 }
209
210 //@}
211
212 /// @name xed_inst_t Template Operand Read/Written
213 //@{
214 /// @ingroup DEC
215 /// DEPRECATED: Returns the raw R/W action. There are many cases for conditional reads
216 /// and writes. See #xed_decoded_inst_operand_action().
217 static XED_INLINE xed_operand_action_enum_t
xed_operand_rw(const xed_operand_t * p)218 xed_operand_rw(const xed_operand_t* p) {
219 return (xed_operand_action_enum_t)p->_rw;
220 }
221
222 /// @ingroup DEC
223 /// If the operand is read, including conditional reads
224 XED_DLL_EXPORT xed_uint_t xed_operand_read(const xed_operand_t* p);
225 /// @ingroup DEC
226 /// If the operand is read-only, including conditional reads
227 XED_DLL_EXPORT xed_uint_t xed_operand_read_only(const xed_operand_t* p);
228 /// @ingroup DEC
229 /// If the operand is written, including conditional writes
230 XED_DLL_EXPORT xed_uint_t xed_operand_written(const xed_operand_t* p);
231 /// @ingroup DEC
232 /// If the operand is written-only, including conditional writes
233 XED_DLL_EXPORT xed_uint_t xed_operand_written_only(const xed_operand_t* p);
234 /// @ingroup DEC
235 /// If the operand is read-and-written, conditional reads and conditional writes
236 XED_DLL_EXPORT xed_uint_t xed_operand_read_and_written(const xed_operand_t* p);
237 /// @ingroup DEC
238 /// If the operand has a conditional read (may also write)
239 XED_DLL_EXPORT xed_uint_t xed_operand_conditional_read(const xed_operand_t* p);
240 /// @ingroup DEC
241 /// If the operand has a conditional write (may also read)
242 XED_DLL_EXPORT xed_uint_t xed_operand_conditional_write(const xed_operand_t* p);
243 //@}
244
245
246 /// @ingroup DEC
247 /// constant information about a decoded instruction form, including
248 /// the pointer to the constant operand properties #xed_operand_t for this
249 /// instruction form.
250 typedef struct xed_inst_s {
251
252
253 // rflags info -- index in to the 2 tables of flags information.
254 // If _flag_complex is true, then the data are in the
255 // xed_flags_complex_table[]. Otherwise, the data are in the
256 // xed_flags_simple_table[].
257
258 //xed_instruction_fixed_bit_confirmer_fn_t _confirmer;
259
260 // number of operands in the operands array
261 xed_uint8_t _noperands;
262 xed_uint8_t _cpl; // the nominal CPL for the instruction.
263 xed_uint8_t _flag_complex; /* 1/0 valued, bool type */
264 xed_uint8_t _exceptions; //xed_exception_enum_t
265
266 xed_uint16_t _flag_info_index;
267
268 xed_uint16_t _iform_enum; //xed_iform_enum_t
269 // index into the xed_operand[] array of xed_operand_t structures
270 xed_uint16_t _operand_base;
271 // index to table of xed_attributes_t structures
272 xed_uint16_t _attributes;
273
274 } xed_inst_t;
275
276 /// @name xed_inst_t Template Instruction Information
277 //@{
278 /// @ingroup DEC
279 /// xed_inst_cpl() is DEPRECATED. Please use
280 /// "xed_decoded_inst_get_attribute(xedd, XED_ATTRIBUTE_RING0)"
281 /// instead.
282 ///Return the current privilege level (CPL) required for execution, 0 or
283 ///3. If the value is zero, then the instruction can only execute in ring 0.
284 XED_DLL_EXPORT unsigned int xed_inst_cpl(const xed_inst_t* p) ;
285
286
287 //These next few are not doxygen commented because I want people to use the
288 //higher level interface in xed-decoded-inst.h.
xed_inst_iform_enum(const xed_inst_t * p)289 static XED_INLINE xed_iform_enum_t xed_inst_iform_enum(const xed_inst_t* p) {
290 return (xed_iform_enum_t)p->_iform_enum;
291 }
292
xed_inst_iclass(const xed_inst_t * p)293 static XED_INLINE xed_iclass_enum_t xed_inst_iclass(const xed_inst_t* p) {
294 return xed_iform_to_iclass(xed_inst_iform_enum(p));
295 }
296
xed_inst_category(const xed_inst_t * p)297 static XED_INLINE xed_category_enum_t xed_inst_category(const xed_inst_t* p) {
298 return xed_iform_to_category(xed_inst_iform_enum(p));
299 }
300
xed_inst_extension(const xed_inst_t * p)301 static XED_INLINE xed_extension_enum_t xed_inst_extension(const xed_inst_t* p) {
302 return xed_iform_to_extension(xed_inst_iform_enum(p));
303 }
xed_inst_isa_set(const xed_inst_t * p)304 static XED_INLINE xed_isa_set_enum_t xed_inst_isa_set(const xed_inst_t* p) {
305 return xed_iform_to_isa_set(xed_inst_iform_enum(p));
306 }
307
308
309
310 ///@ingroup DEC
311 /// Number of instruction operands
xed_inst_noperands(const xed_inst_t * p)312 static XED_INLINE unsigned int xed_inst_noperands(const xed_inst_t* p) {
313 return p->_noperands;
314 }
315
316 ///@ingroup DEC
317 /// Obtain a pointer to an individual operand
318 XED_DLL_EXPORT const xed_operand_t*
319 xed_inst_operand(const xed_inst_t* p, unsigned int i);
320
321
322
323 XED_DLL_EXPORT xed_uint32_t xed_inst_flag_info_index(const xed_inst_t* p);
324
325 //@}
326
327 /// @name xed_inst_t Attribute access
328 //@{
329 /// @ingroup DEC
330 /// Scan for the attribute attr and return 1 if it is found, 0 otherwise.
331 XED_DLL_EXPORT xed_uint32_t
332 xed_inst_get_attribute(const xed_inst_t* p,
333 xed_attribute_enum_t attr);
334
335 /// @ingroup DEC
336 /// Return the attributes bit vector
337 XED_DLL_EXPORT xed_attributes_t
338 xed_inst_get_attributes(const xed_inst_t* p);
339
340
341 /// @ingroup DEC
342 /// Return the maximum number of defined attributes, independent of any
343 /// instruction.
344 XED_DLL_EXPORT unsigned int xed_attribute_max(void);
345
346 /// @ingroup DEC
347 /// Return the i'th global attribute in a linear sequence, independent of
348 /// any instruction. This is used for scanning and printing all attributes.
349 XED_DLL_EXPORT xed_attribute_enum_t xed_attribute(unsigned int i);
350
351 //@}
352
353 /// @name Exceptions
354 //@{
355 /// @ingroup DEC
356 /// Return #xed_exception_enum_t if present for the specified instruction.
357 /// This is currently only used for SSE and AVX instructions.
358 static XED_INLINE
xed_inst_exception(const xed_inst_t * p)359 xed_exception_enum_t xed_inst_exception(const xed_inst_t* p) {
360 return (xed_exception_enum_t)p->_exceptions;
361 }
362
363 //@}
364 /// @ingroup DEC
365 /// Return the base of instruction table.
366 XED_DLL_EXPORT const xed_inst_t* xed_inst_table_base(void);
367
368 #endif
369