You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
280 lines
9.7 KiB
280 lines
9.7 KiB
/* BEGIN_LEGAL
|
|
|
|
Copyright (c) 2021 Intel Corporation
|
|
|
|
Licensed under the Apache License, Version 2.0 (the "License");
|
|
you may not use this file except in compliance with the License.
|
|
You may obtain a copy of the License at
|
|
|
|
http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
Unless required by applicable law or agreed to in writing, software
|
|
distributed under the License is distributed on an "AS IS" BASIS,
|
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
See the License for the specific language governing permissions and
|
|
limitations under the License.
|
|
|
|
END_LEGAL */
|
|
/// @file xed-encode.h
|
|
|
|
|
|
#ifndef XED_ENCODE_H
|
|
# define XED_ENCODE_H
|
|
#include "xed-common-hdrs.h"
|
|
#include "xed-types.h"
|
|
#include "xed-error-enum.h"
|
|
#include "xed-operand-values-interface.h"
|
|
#include "xed-operand-width-enum.h"
|
|
#include "xed-encoder-iforms.h" //generated
|
|
#include "xed-encoder-gen-defs.h" //generated
|
|
|
|
// we now (mostly) share the decode data structure
|
|
#include "xed-decoded-inst.h"
|
|
|
|
|
|
// establish a type equivalence for the xed_encoder_request_t and the
|
|
// corresponding xed_decoded_inst_t.
|
|
|
|
/// @ingroup ENC
|
|
typedef struct xed_decoded_inst_s xed_encoder_request_s;
|
|
/// @ingroup ENC
|
|
typedef xed_decoded_inst_t xed_encoder_request_t;
|
|
|
|
|
|
|
|
/// @ingroup ENC
|
|
XED_DLL_EXPORT xed_iclass_enum_t
|
|
xed_encoder_request_get_iclass( const xed_encoder_request_t* p);
|
|
|
|
/////////////////////////////////////////////////////////
|
|
// set functions
|
|
|
|
/// @ingroup ENC
|
|
XED_DLL_EXPORT void
|
|
xed_encoder_request_set_iclass( xed_encoder_request_t* p,
|
|
xed_iclass_enum_t iclass);
|
|
|
|
|
|
/// @name Primary Encode Functions
|
|
//@{
|
|
/// @ingroup ENC
|
|
XED_DLL_EXPORT void
|
|
xed_encoder_request_set_effective_operand_width( xed_encoder_request_t* p,
|
|
xed_uint_t width_bits);
|
|
/// @ingroup ENC
|
|
XED_DLL_EXPORT void
|
|
xed_encoder_request_set_effective_address_size( xed_encoder_request_t* p,
|
|
xed_uint_t width_bits);
|
|
/*! @ingroup ENC
|
|
*
|
|
* Set the operands array element indexed by operand to the actual register
|
|
* name reg.
|
|
*
|
|
* @param[in] p xed_encoder_request_t
|
|
* @param[in] operand indicates which register operand storage field to use
|
|
* @param[in] reg the actual register represented (EAX, etc.) to store.
|
|
*/
|
|
XED_DLL_EXPORT void xed_encoder_request_set_reg(xed_encoder_request_t* p,
|
|
xed_operand_enum_t operand,
|
|
xed_reg_enum_t reg);
|
|
//@}
|
|
|
|
/// @name Operand Order
|
|
//@{
|
|
/*! @ingroup ENC
|
|
* Specify the name as the n'th operand in the operand order.
|
|
*
|
|
* The complication of this function is that the register operand names are
|
|
* specific to the position of the operand (REG0, REG1, REG2...). One can
|
|
* use this function for registers or one can use the
|
|
* xed_encoder_request_set_operand_name_reg() which takes integers instead
|
|
* of operand names.
|
|
*
|
|
* @param[in] p #xed_encoder_request_t
|
|
* @param[in] operand_index xed_uint_t representing n'th operand position
|
|
* @param[in] name #xed_operand_enum_t operand name.
|
|
*/
|
|
XED_DLL_EXPORT void
|
|
xed_encoder_request_set_operand_order(xed_encoder_request_t* p,
|
|
xed_uint_t operand_index,
|
|
xed_operand_enum_t name);
|
|
|
|
/*! @ingroup ENC
|
|
* Retrieve the name of the n'th operand in the operand order.
|
|
*
|
|
* @param[in] p #xed_encoder_request_t
|
|
* @param[in] operand_index xed_uint_t representing n'th operand position
|
|
* @return The #xed_operand_enum_t operand name.
|
|
*/
|
|
XED_DLL_EXPORT xed_operand_enum_t
|
|
xed_encoder_request_get_operand_order(xed_encoder_request_t* p,
|
|
xed_uint_t operand_index);
|
|
|
|
|
|
/// @ingroup ENC
|
|
/// Retrieve the number of entries in the encoder operand order array
|
|
/// @return The number of entries in the encoder operand order array
|
|
static XED_INLINE xed_uint_t
|
|
xed_encoder_request_operand_order_entries(xed_encoder_request_t* p)
|
|
{
|
|
return p->_n_operand_order;
|
|
}
|
|
|
|
//@}
|
|
|
|
|
|
/// @name branches and far pointers
|
|
//@{
|
|
/// @ingroup ENC
|
|
XED_DLL_EXPORT void xed_encoder_request_set_relbr(xed_encoder_request_t* p);
|
|
/// @ingroup ENC
|
|
XED_DLL_EXPORT void
|
|
xed_encoder_request_set_branch_displacement(xed_encoder_request_t* p,
|
|
xed_int32_t brdisp,
|
|
xed_uint_t nbytes);
|
|
/// @ingroup ENC
|
|
XED_DLL_EXPORT void xed_encoder_request_set_ptr(xed_encoder_request_t* p);
|
|
//@}
|
|
|
|
|
|
/// @name Immediates
|
|
//@{
|
|
/// @ingroup ENC
|
|
/// Set the uimm0 using a BYTE width.
|
|
XED_DLL_EXPORT void xed_encoder_request_set_uimm0(xed_encoder_request_t* p,
|
|
xed_uint64_t uimm,
|
|
xed_uint_t nbytes);
|
|
/// @ingroup ENC
|
|
/// Set the uimm0 using a BIT width.
|
|
XED_DLL_EXPORT void xed_encoder_request_set_uimm0_bits(xed_encoder_request_t* p,
|
|
xed_uint64_t uimm,
|
|
xed_uint_t nbits);
|
|
/// @ingroup ENC
|
|
XED_DLL_EXPORT void xed_encoder_request_set_uimm1(xed_encoder_request_t* p,
|
|
xed_uint8_t uimm);
|
|
/// @ingroup ENC
|
|
/// same storage as uimm0
|
|
XED_DLL_EXPORT void xed_encoder_request_set_simm(xed_encoder_request_t* p,
|
|
xed_int32_t simm,
|
|
xed_uint_t nbytes);
|
|
|
|
/// @name Memory
|
|
//@{
|
|
/// @ingroup ENC
|
|
XED_DLL_EXPORT void
|
|
xed_encoder_request_set_memory_displacement(xed_encoder_request_t* p,
|
|
xed_int64_t memdisp,
|
|
xed_uint_t nbytes);
|
|
|
|
/// @ingroup ENC
|
|
XED_DLL_EXPORT void xed_encoder_request_set_agen(xed_encoder_request_t* p);
|
|
/// @ingroup ENC
|
|
XED_DLL_EXPORT void xed_encoder_request_set_mem0(xed_encoder_request_t* p);
|
|
/// @ingroup ENC
|
|
XED_DLL_EXPORT void xed_encoder_request_set_mem1(xed_encoder_request_t* p);
|
|
/// @ingroup ENC
|
|
XED_DLL_EXPORT void
|
|
xed_encoder_request_set_memory_operand_length(xed_encoder_request_t* p,
|
|
xed_uint_t nbytes);
|
|
/// @ingroup ENC
|
|
XED_DLL_EXPORT void xed_encoder_request_set_seg0(xed_encoder_request_t* p,
|
|
xed_reg_enum_t seg_reg);
|
|
/// @ingroup ENC
|
|
XED_DLL_EXPORT void xed_encoder_request_set_seg1(xed_encoder_request_t* p,
|
|
xed_reg_enum_t seg_reg);
|
|
/// @ingroup ENC
|
|
XED_DLL_EXPORT void xed_encoder_request_set_base0(xed_encoder_request_t* p,
|
|
xed_reg_enum_t base_reg);
|
|
/// @ingroup ENC
|
|
XED_DLL_EXPORT void xed_encoder_request_set_base1(xed_encoder_request_t* p,
|
|
xed_reg_enum_t base_reg) ;
|
|
/// @ingroup ENC
|
|
XED_DLL_EXPORT void xed_encoder_request_set_index(xed_encoder_request_t* p,
|
|
xed_reg_enum_t index_reg);
|
|
/// @ingroup ENC
|
|
XED_DLL_EXPORT void
|
|
xed_encoder_request_set_scale(xed_encoder_request_t* p,
|
|
xed_uint_t scale);
|
|
//@}
|
|
|
|
//////////////////////////////////////////////
|
|
/// @ingroup ENC
|
|
static XED_INLINE const xed_operand_values_t*
|
|
xed_encoder_request_operands_const(const xed_encoder_request_t* p) {
|
|
return p;
|
|
}
|
|
/// @ingroup ENC
|
|
static XED_INLINE xed_operand_values_t*
|
|
xed_encoder_request_operands(xed_encoder_request_t* p) {
|
|
return p;
|
|
}
|
|
|
|
/// @name Initialization
|
|
//@{
|
|
/*! @ingroup ENC
|
|
* clear the operand order array
|
|
* @param[in] p xed_encoder_request_t
|
|
*/
|
|
XED_DLL_EXPORT void
|
|
xed_encoder_request_zero_operand_order(xed_encoder_request_t* p);
|
|
|
|
/// @ingroup ENC
|
|
XED_DLL_EXPORT void
|
|
xed_encoder_request_zero_set_mode(xed_encoder_request_t* p,
|
|
const xed_state_t* dstate);
|
|
/// @ingroup ENC
|
|
XED_DLL_EXPORT void xed_encoder_request_zero(xed_encoder_request_t* p) ;
|
|
//@}
|
|
|
|
struct xed_decoded_inst_s; //fwd decl
|
|
/// @ingroup ENC
|
|
/// Converts an decoder request to a valid encoder request.
|
|
XED_DLL_EXPORT void
|
|
xed_encoder_request_init_from_decode(struct xed_decoded_inst_s* d);
|
|
|
|
/// @name String Printing
|
|
//@{
|
|
/// @ingroup ENC
|
|
XED_DLL_EXPORT void xed_encode_request_print(const xed_encoder_request_t* p,
|
|
char* buf, xed_uint_t buflen);
|
|
//@}
|
|
|
|
|
|
|
|
|
|
/// @name Encoding
|
|
//@{
|
|
/// This is the main interface to the encoder. The array should be
|
|
/// at most 15 bytes long. The ilen parameter should indicate
|
|
/// this length. If the array is too short, the encoder may fail to
|
|
/// encode the request. Failure is indicated by a return value of
|
|
/// type #xed_error_enum_t that is not equal to
|
|
/// #XED_ERROR_NONE. Otherwise, #XED_ERROR_NONE is returned and the
|
|
/// length of the encoded instruction is returned in olen.
|
|
///
|
|
/// @param r encoder request description (#xed_encoder_request_t), includes mode info
|
|
/// @param array the encoded instruction bytes are stored here
|
|
/// @param ilen the input length of array.
|
|
/// @param olen the actual length of array used for encoding
|
|
/// @return success/failure as a #xed_error_enum_t
|
|
/// @ingroup ENC
|
|
XED_DLL_EXPORT xed_error_enum_t
|
|
xed_encode(xed_encoder_request_t* r,
|
|
xed_uint8_t* array,
|
|
const unsigned int ilen,
|
|
unsigned int* olen);
|
|
|
|
/// This function will attempt to encode a NOP of exactly ilen
|
|
/// bytes. If such a NOP is not encodeable, then false will be returned.
|
|
///
|
|
/// @param array the encoded instruction bytes are stored here
|
|
/// @param ilen the input length array.
|
|
/// @return success/failure as a #xed_error_enum_t
|
|
/// @ingroup ENC
|
|
XED_DLL_EXPORT xed_error_enum_t
|
|
xed_encode_nop(xed_uint8_t* array,
|
|
const unsigned int ilen);
|
|
//@}
|
|
|
|
#endif
|