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