2 Intel Open Source License
4 Copyright (c) 2002-2007 Intel Corporation
6 Redistribution and use in source and binary forms, with or without
7 modification, are permitted provided that the following conditions are
10 Redistributions of source code must retain the above copyright notice,
11 this list of conditions and the following disclaimer. Redistributions
12 in binary form must reproduce the above copyright notice, this list of
13 conditions and the following disclaimer in the documentation and/or
14 other materials provided with the distribution. Neither the name of
15 the Intel Corporation nor the names of its contributors may be used to
16 endorse or promote products derived from this software without
17 specific prior written permission.
19 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20 ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE INTEL OR
23 ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24 SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25 LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 /// @file xed-decoded-inst.h
32 /// @author Mark Charney <mark.charney@intel.com>
34 #if !defined(_XED_DECODER_STATE_H_)
35 # define _XED_DECODER_STATE_H_
36 #include "xed-common-hdrs.h"
37 #include "xed-common-defs.h"
38 #include "xed-portability.h"
40 #include "xed-types.h"
41 #include "xed-operand-values-interface.h"
43 #include "xed-flags.h"
44 #include "xed-encoder-gen-defs.h" //generated
47 // fwd-decl xed_simple_flag_t;
48 // fwd-decl xed_inst_t;
51 struct xed_encoder_vars_s;
52 struct xed_decoder_vars_s;
55 /// The main container for instructions. After decode, it holds an array of
56 /// operands with derived information from decode and also valid
57 /// #xed_inst_t pointer which describes the operand templates and the
58 /// operand order. See @ref DEC for API documentation.
59 typedef struct XED_DLL_EXPORT xed_decoded_inst_s {
60 /// The operand storage fields discovered during decoding. This same array is used by encode.
61 xed_operand_values_t _operands[XED_OPERAND_LAST]; // FIXME: can further squeeze down 16b units
63 /// Used for encode operand ordering. Not set by decode.
64 xed_uint8_t _operand_order[XED_ENCODE_ORDER_MAX_OPERANDS];
66 xed_uint8_t _decoded_length;
67 // Length of the _operand_order[] array.
68 xed_uint8_t _n_operand_order;
70 /// when we decode an instruction, we set the _inst and get the
71 /// properites of that instruction here. This also points to the
72 /// operands template array.
73 const xed_inst_t* _inst;
75 // decoder does not change it, encoder does
78 const xed_uint8_t* _dec;
81 // These are stack allocated by xed_encode() or xed_decode(). These are
82 // per-encode or per-decode transitory data.
85 /* user_data is available as a user data storage field after
86 * decoding. It does not live across re-encodes or re-decodes. */
87 xed_uint64_t user_data;
88 struct xed_decoder_vars_s* dv;
89 struct xed_encoder_vars_s* ev;
98 /// @name xed_decoded_inst_t Operands array access
101 /// Obtain a constant pointer to the operands
102 static XED_INLINE const xed_operand_values_t*
103 xed_decoded_inst_operands_const(const xed_decoded_inst_t* p) {
104 return STATIC_CAST(xed_operand_values_t*,p->_operands);
107 /// Obtain a non-constant pointer to the operands
108 static XED_INLINE xed_operand_values_t*
109 xed_decoded_inst_operands(xed_decoded_inst_t* p) {
110 return STATIC_CAST(xed_operand_values_t*,p->_operands);
114 /// @name xed_decoded_inst_t Initialization
117 /// Zero the decode structure, but set the machine state/mode information
118 XED_DLL_EXPORT void xed_decoded_inst_zero_set_mode(xed_decoded_inst_t* p, const xed_state_t* dstate);
120 /// Zero the decode structure, but preserve the existing machine state/mode information
121 XED_DLL_EXPORT void xed_decoded_inst_zero_keep_mode(xed_decoded_inst_t* p);
123 /// Zero the decode structure completely.
124 XED_DLL_EXPORT void xed_decoded_inst_zero(xed_decoded_inst_t* p);
126 /// Zero the decode structure, but copy the existing machine state/mode information from the supplied operands pointer.
127 XED_DLL_EXPORT void xed_decoded_inst_zero_keep_mode_from_operands(xed_decoded_inst_t* p,
128 const xed_operand_values_t* operands);
131 /// @name xed_decoded_inst_t Length
134 /// Return the length of the decoded instruction in bytes.
135 static XED_INLINE xed_uint_t
136 xed_decoded_inst_get_length(const xed_decoded_inst_t* p) {
137 return p->_decoded_length;
146 static XED_INLINE xed_uint_t xed_decoded_inst_get_mode(const xed_decoded_inst_t* p) {
147 return p->_operands[XED_OPERAND_MODE];
150 static XED_INLINE xed_uint_t xed_decoded_inst_get_address_mode(const xed_decoded_inst_t* p) {
151 return p->_operands[XED_OPERAND_AMODE];
154 static XED_INLINE xed_uint_t xed_decoded_inst_get_stack_address_mode(const xed_decoded_inst_t* p) {
155 return p->_operands[XED_OPERAND_SMODE];
160 ///////////////////////////////////////////////////////
162 ///////////////////////////////////////////////////////
164 /// @name xed_decoded_inst_t High-level accessors
167 /// Return true if the instruction is valid
168 static XED_INLINE xed_bool_t xed_decoded_inst_valid(const xed_decoded_inst_t* p ) {
169 return STATIC_CAST(xed_bool_t,(p->_inst != 0));
172 /// Return the #xed_inst_t structure for this instruction. This is the route to the basic operands form information.
173 static XED_INLINE const xed_inst_t* xed_decoded_inst_inst( const xed_decoded_inst_t* p) {
179 /// Return the instruction category enumeration
180 static XED_INLINE xed_category_enum_t xed_decoded_inst_get_category(const xed_decoded_inst_t* p) {
181 xed_assert(p->_inst != 0);
182 return xed_inst_category(p->_inst);
185 /// Return the instruction extension enumeration
186 static XED_INLINE xed_extension_enum_t xed_decoded_inst_get_extension( const xed_decoded_inst_t* p) {
187 xed_assert(p->_inst != 0);
188 return xed_inst_extension(p->_inst);
191 /// Return the instruction class enumeration.
192 static XED_INLINE xed_iclass_enum_t xed_decoded_inst_get_iclass( const xed_decoded_inst_t* p){
193 xed_assert(p->_inst != 0);
194 return xed_inst_iclass(p->_inst);
198 /// Returns 1 if the attribute is defined for this instruction.
199 XED_DLL_EXPORT xed_uint32_t xed_decoded_inst_get_attribute(const xed_decoded_inst_t* p, xed_attribute_enum_t attr);
202 /// Returns the attribute bitvector
203 XED_DLL_EXPORT xed_uint32_t xed_decoded_inst_get_attributes(const xed_decoded_inst_t* p);
206 /// @name IFORM handling
210 /// Return the instruction iform enum of type #xed_iform_enum_t .
211 static XED_INLINE xed_iform_enum_t xed_decoded_inst_get_iform_enum(const xed_decoded_inst_t* p) {
212 xed_assert(p->_inst != 0);
213 return xed_inst_iform_enum(p->_inst);
218 /// Return the instruction zero-based iform number based on masking the
219 /// corresponding #xed_iform_enum_t. This value is suitable for
220 /// dispatching. The maximum value for a particular iclass is provided by
221 /// #xed_iform_max_per_iclass() .
222 static XED_INLINE unsigned int xed_decoded_inst_get_iform_enum_dispatch(const xed_decoded_inst_t* p) {
223 xed_assert(p->_inst != 0);
224 return xed_inst_iform_enum(p->_inst) & 0xFF;
228 /// Return the maximum number of iforms for a particular iclass. This
229 /// function returns valid data as soon as global data is initialized. (This
230 /// function does not require a decoded instruction as input).
231 XED_DLL_EXPORT xed_uint32_t xed_iform_max_per_iclass(xed_iclass_enum_t iclass);
233 #define XED_MASK_IFORM(x) ((x) & 0xFF)
236 /// DEPRECATED Return the instruction iform number. The iform is zero-based number of
237 /// the different instances of each iclass.
238 static XED_INLINE xed_uint_t xed_decoded_inst_get_old_iform( const xed_decoded_inst_t* p){
239 xed_assert(p->_inst != 0);
240 return xed_inst_iform(p->_inst);
247 /// @name xed_decoded_inst_t Operands: Number and Length
249 /// Return the length in bytes of the operand_index'th operand.
251 XED_DLL_EXPORT unsigned int xed_decoded_inst_operand_length(const xed_decoded_inst_t* p,
252 unsigned int operand_index);
253 /// Return the number of operands
255 static XED_INLINE unsigned int xed_decoded_inst_noperands(const xed_decoded_inst_t* p) {
256 unsigned int noperands = xed_inst_noperands(xed_decoded_inst_inst(p));
261 /// @name xed_decoded_inst_t Printers
264 /// Print out all the information about the decoded instruction to the buffer buf whose length is maximally buflen.
265 XED_DLL_EXPORT void xed_decoded_inst_dump(const xed_decoded_inst_t* p, char* buf, int buflen);
268 /// Print the instructions with the destination on the left. Use PTR qualifiers for memory access widths.
269 /// Recommendation: buflen must be more than 16 bytes, preferably at least 100 bytes.
270 /// @param p a #xed_decoded_inst_t for a decoded instruction
271 /// @param buf a buffer to write the disassembly in to.
272 /// @param buflen maximum length of the disassembly buffer
273 /// @param runtime_address the address of the instruction being disassembled
274 /// @return Returns 0 if the disassembly fails, 1 otherwise.
275 XED_DLL_EXPORT xed_bool_t xed_decoded_inst_dump_intel_format(const xed_decoded_inst_t* p,
278 xed_uint64_t runtime_address);
280 /// Print the instructions with the destination on the left. Use PTR qualifiers for memory access widths.
281 /// Recommendation: buflen must be more than 16 bytes, preferably at least 100 bytes.
282 /// @param p a #xed_decoded_inst_t for a decoded instruction
283 /// @param buf a buffer to write the disassembly in to.
284 /// @param buflen maximum length of the disassembly buffer
285 /// @param runtime_address the address of the instruction being disassembled
286 /// @param context A void* used only for the call back routine for symbolic disassembly if one is registered.
287 /// @return Returns 0 if the disassembly fails, 1 otherwise.
288 XED_DLL_EXPORT xed_bool_t xed_decoded_inst_dump_intel_format_context(const xed_decoded_inst_t* p,
291 xed_uint64_t runtime_address,
295 /// Print the instructions with the destination operand on the right, with
296 /// several exceptions (bound, invlpga, enter, and other instructions with
297 /// two immediate operands). Also use instruction name suffixes to
298 /// indicate operation width. Several instructions names are different as
300 /// Recommendation: buflen must be more than 16 bytes, preferably at least 100 bytes.
301 /// @param p a #xed_decoded_inst_t for a decoded instruction
302 /// @param buf a buffer to write the disassembly in to.
303 /// @param buflen maximum length of the disassembly buffer
304 /// @param runtime_address the address of the instruction being disassembled
305 /// @return Returns 0 if the disassembly fails, 1 otherwise.
306 XED_DLL_EXPORT xed_bool_t xed_decoded_inst_dump_att_format(const xed_decoded_inst_t* p,
309 xed_uint64_t runtime_address);
312 /// Print the instructions with the destination operand on the right, with
313 /// several exceptions (bound, invlpga, enter, and other instructions with
314 /// two immediate operands). Also use instruction name suffixes to
315 /// indicate operation width. Several instructions names are different as
316 /// well. buflen must be at least 100 bytes.
317 /// @param p a #xed_decoded_inst_t for a decoded instruction
318 /// @param buf a buffer to write the disassembly in to.
319 /// @param buflen maximum length of the disassembly buffer
320 /// @param runtime_address the address of the instruction being disassembled
321 /// @param context A void* used only for the call back routine for symbolic disassembly if one is registered.
322 /// @return Returns 0 if the disassembly fails, 1 otherwise.
323 XED_DLL_EXPORT xed_bool_t xed_decoded_inst_dump_att_format_context(const xed_decoded_inst_t* p,
326 xed_uint64_t runtime_address,
330 /// @param p a #xed_decoded_inst_t for a decoded instruction
331 /// @param buf a buffer to write the disassembly in to.
332 /// @param buflen maximum length of the disassembly buffer
333 /// @param runtime_address the address of the instruction being disassembled
334 /// @return Returns 0 if the disassembly fails, 1 otherwise.
335 XED_DLL_EXPORT xed_bool_t xed_decoded_inst_dump_xed_format(const xed_decoded_inst_t* p,
337 int buflen, xed_uint64_t runtime_address) ;
340 /// @name xed_decoded_inst_t Operand Field Details
343 XED_DLL_EXPORT xed_reg_enum_t xed_decoded_inst_get_seg_reg(const xed_decoded_inst_t* p, unsigned int mem_idx);
345 XED_DLL_EXPORT xed_reg_enum_t xed_decoded_inst_get_base_reg(const xed_decoded_inst_t* p, unsigned int mem_idx);
346 XED_DLL_EXPORT xed_reg_enum_t xed_decoded_inst_get_index_reg(const xed_decoded_inst_t* p, unsigned int mem_idx);
348 XED_DLL_EXPORT xed_uint_t xed_decoded_inst_get_scale(const xed_decoded_inst_t* p, unsigned int mem_idx);
350 XED_DLL_EXPORT xed_int64_t xed_decoded_inst_get_memory_displacement(const xed_decoded_inst_t* p, unsigned int mem_idx);
353 XED_DLL_EXPORT xed_uint_t xed_decoded_inst_get_memory_displacement_width(const xed_decoded_inst_t* p, unsigned int mem_idx);
356 XED_DLL_EXPORT xed_uint_t xed_decoded_inst_get_memory_displacement_width_bits(const xed_decoded_inst_t* p, unsigned int mem_idx);
358 XED_DLL_EXPORT xed_int32_t xed_decoded_inst_get_branch_displacement(const xed_decoded_inst_t* p);
361 XED_DLL_EXPORT xed_uint_t xed_decoded_inst_get_branch_displacement_width(const xed_decoded_inst_t* p);
364 XED_DLL_EXPORT xed_uint_t xed_decoded_inst_get_branch_displacement_width_bits(const xed_decoded_inst_t* p);
366 XED_DLL_EXPORT xed_uint64_t xed_decoded_inst_get_unsigned_immediate(const xed_decoded_inst_t* p);
368 /// Return true if the first immediate (IMM0) is signed
369 XED_DLL_EXPORT xed_uint_t xed_decoded_inst_get_immediate_is_signed(const xed_decoded_inst_t* p);
371 /// Return the immediate width in BYTES.
372 XED_DLL_EXPORT xed_uint_t xed_decoded_inst_get_immediate_width(const xed_decoded_inst_t* p);
374 /// Return the immediate width in BITS.
375 XED_DLL_EXPORT xed_uint_t xed_decoded_inst_get_immediate_width_bits(const xed_decoded_inst_t* p);
377 XED_DLL_EXPORT xed_int32_t xed_decoded_inst_get_signed_immediate(const xed_decoded_inst_t* p);
379 /// Return the second immediate.
380 static XED_INLINE xed_uint8_t xed_decoded_inst_get_second_immediate(const xed_decoded_inst_t* p) {
381 return STATIC_CAST(xed_uint8_t,p->_operands[XED_OPERAND_UIMM1]);
385 /// Return the specified register operand. The specifier is of type #xed_operand_enum_t .
386 static XED_INLINE xed_reg_enum_t xed_decoded_inst_get_reg(const xed_decoded_inst_t* p,
387 xed_operand_enum_t reg_operand) {
388 return STATIC_CAST(xed_reg_enum_t,p->_operands[reg_operand]);
394 XED_DLL_EXPORT const xed_simple_flag_t* xed_decoded_inst_get_rflags_info( const xed_decoded_inst_t* p );
396 XED_DLL_EXPORT xed_bool_t xed_decoded_inst_uses_rflags(const xed_decoded_inst_t* p);
398 XED_DLL_EXPORT xed_uint_t xed_decoded_inst_number_of_memory_operands(const xed_decoded_inst_t* p);
400 XED_DLL_EXPORT xed_bool_t xed_decoded_inst_mem_read(const xed_decoded_inst_t* p, unsigned int mem_idx);
402 XED_DLL_EXPORT xed_bool_t xed_decoded_inst_mem_written(const xed_decoded_inst_t* p, unsigned int mem_idx);
404 XED_DLL_EXPORT xed_bool_t xed_decoded_inst_mem_written_only(const xed_decoded_inst_t* p, unsigned int mem_idx);
406 XED_DLL_EXPORT xed_bool_t xed_decoded_inst_conditionally_writes_registers(const xed_decoded_inst_t* p);
408 XED_DLL_EXPORT unsigned int xed_decoded_inst_get_memory_operand_length(const xed_decoded_inst_t* p,
409 unsigned int memop_idx);
413 /// Returns true if the instruction is a prefetch
414 XED_DLL_EXPORT xed_bool_t xed_decoded_inst_is_prefetch(const xed_decoded_inst_t* p);
418 /// @name xed_decoded_inst_t Modification
420 // Modifying decoded instructions before re-encoding
422 XED_DLL_EXPORT void xed_decoded_inst_set_scale(xed_decoded_inst_t* p, xed_uint_t scale);
424 /// Set the memory displacement using a BYTE length
425 XED_DLL_EXPORT void xed_decoded_inst_set_memory_displacement(xed_decoded_inst_t* p, xed_int64_t disp, xed_uint_t length_bytes);
427 /// Set the branch displacement using a BYTE length
428 XED_DLL_EXPORT void xed_decoded_inst_set_branch_displacement(xed_decoded_inst_t* p, xed_int32_t disp, xed_uint_t length_bytes);
430 /// Set the signed immediate a BYTE length
431 XED_DLL_EXPORT void xed_decoded_inst_set_immediate_signed(xed_decoded_inst_t* p, xed_int32_t x, xed_uint_t length_bytes);
433 /// Set the unsigned immediate a BYTE length
434 XED_DLL_EXPORT void xed_decoded_inst_set_immediate_unsigned(xed_decoded_inst_t* p, xed_uint64_t x, xed_uint_t length_bytes);
438 /// Set the memory displacement a BITS length
439 XED_DLL_EXPORT void xed_decoded_inst_set_memory_displacement_bits(xed_decoded_inst_t* p, xed_int64_t disp, xed_uint_t length_bits);
441 /// Set the branch displacement a BITS length
442 XED_DLL_EXPORT void xed_decoded_inst_set_branch_displacement_bits(xed_decoded_inst_t* p, xed_int32_t disp, xed_uint_t length_bits);
444 /// Set the signed immediate a BITS length
445 XED_DLL_EXPORT void xed_decoded_inst_set_immediate_signed_bits(xed_decoded_inst_t* p, xed_int32_t x, xed_uint_t length_bits);
447 /// Set the unsigned immediate a BITS length
448 XED_DLL_EXPORT void xed_decoded_inst_set_immediate_unsigned_bits(xed_decoded_inst_t* p, xed_uint64_t x, xed_uint_t length_bits);
452 /// @name xed_decoded_inst_t User Data Field
455 /// Return a user data field for arbitrary use by the user after decoding.
456 static XED_INLINE xed_uint64_t xed_decoded_inst_get_user_data(xed_decoded_inst_t* p) {
457 return p->u.user_data;
460 /// Modify the user data field.
461 static XED_INLINE void xed_decoded_inst_set_user_data(xed_decoded_inst_t* p, xed_uint64_t new_value) {
462 p->u.user_data = new_value;
467 //pref: "../../xed-decoded-inst.c"