Intel® X86 Encoder Decoder
Intel® XED command interface

The command line tool called xed or xed.exe is built when you build the examples (Examples of using Intel® XED) that come with Intel® XED. More...

The command line tool called xed or xed.exe is built when you build the examples (Examples of using Intel® XED) that come with Intel® XED.

This tool is useful for encoding and decoding or even decoding-then-re-encoding a single instruction or all the instructions in the text segment of an ELF binary (32 or 64b). For decoding, just jump to the examples.

This section also explains a little language for writing the instructions for encode requests (-e option). This tool is constantly updated. The xed-ex3 (xed-ex3.exe) example is just the encoder portion of the xed command line tool.

The SUPPRESSED operands emitted by the decoder are not used when encoding. They are ignored. They are not required to select an encoding.

The syntax for encodable strings is as follows:

Opcode[/width] [operand [operand]]

The width is a 8, 16, 32 or 64, indicating the effective operand width if it differs from the default. 8b operations generally require this. Or since most operations that default to 32b widths in 64b mode, it is required for 64b operation widths in 64b mode.

The operand specifier is one of the following.

Here is the help message:

% xed -h
Usage: xed [options]
One of the following is required:
-i input_file (decode pecoff-format file)
-ir raw_input_file (decode a raw unformatted binary file)
-ih hex_input_file (decode a raw unformatted ASCII hex file)
-d hex-string (decode a sequence of bytes, must be last)
-j (just decode one instruction when using -d)
-F prefix (decode ascii hex bytes after prefix)
(running in filter mode from stdin)
-ide input_file (decode/encode file)
-e instruction (encode, must be last)
-f (encode force, skip encoder chip check)
-ie file-to-assemble (assemble the contents of the file)
-de hex-string (decode-then-encode, must be last)
Optional arguments:
-v N (0=quiet, 1=errors, 2=useful-info, 3=trace,
5=very verbose)
-xv N (XED engine verbosity, 0...99)
-chip-check CHIP (count instructions that are not valid for CHIP)
-chip-check-list (list the valid chips)
-s section (target section for file disassembly,
PECOFF and ELF formats only)
-n N (number of instructions to decode. Default 100M,
accepts K/M/G qualifiers)
-b addr (Base address offset, for DLLs/shared libraries.
Use 0x for hex addresses)
-as addr (Address to start disassembling.
Use 0x for hex addresses)
-ae addr (Address to end disassembling.
Use 0x for hex addresses)
-no-resync (Disable symbol-based resynchronization algorithm
for disassembly)
-ast (Show the AVX/SSE transition classfication)
-histo (Histogram decode times)
-I (Intel syntax for disassembly)
-A (ATT SYSV syntax for disassembly)
-isa-set (Emit the XED "ISA set" in dissasembly)
-xml (XML formatting)
-uc (upper case hex formatting)
-pmd (positive memory displacement formatting)
-nwm (Format AVX512 without curly braces for writemasks, include k0)
-emit-ignored-branch-hint (emit ignored branch hints during disassembly)
-emit (Output __emit statements for the Intel compiler)
-S file Read symbol table in "nm" format from file
-dot FN (Emit a register dependence graph file in dot format.
Best used with -as ADDR -ae ADDR to limit graph size.)
-r (for REAL_16 mode, 16b addressing (20b addresses),
16b default data size)
-r32 (for REAL_32 mode, 16b addressing (20b addresses),
32b default data size)
-16 (for LEGACY_16 mode, 16b addressing,
16b default data size)
-32 (for LEGACY_32 mode, 32b addressing,
32b default data size -- default)
-64 (for LONG_64 mode w/64b addressing
Optional on windows/linux)
-mpx (Turn on MPX mode for disassembly, default is off)
-cet (Turn on CET mode for disassembly, default is off)
-s32 (32b stack addressing, default, not in LONG_64 mode)
-s16 (16b stack addressing, not in LONG_64 mode)
-set OP VAL (Set a XED operands to some integer value, repeatable)
-version (The version message)
-help (This help message)

Here are a couple of examples:

% xed -d 0000
ICLASS: ADD
CATEGORY: BINARY
EXTENSION: BASE
IFORM: ADD_MEMb_GPR8
ISA_SET: I86
ATTRIBUTES: BYTEOP LOCKABLE
SHORT: add byte ptr [eax], al
% xed -e ADD EAX EBX
Request: ADD MODE:1, REG0:EAX, REG1:EBX, SMODE:1
OPERAND ORDER: REG0 REG1
Encodable! 01D8
.byte 0x01,0xd8
% xed -e ADD EAX MEM4:ESP,EBX,4
Request: ADD EASZ:2, MEM0:dword ptr [ESP+EBX*4], MEM_WIDTH:4, MODE:1, REG0:EAX, SMODE:1
OPERAND ORDER: REG0 MEM0
Encodable! 03049C
.byte 0x03,0x04,0x9c
% xed -d 6a00
ICLASS: PUSH
CATEGORY: PUSH
EXTENSION: BASE
IFORM: PUSH_IMMb
ISA_SET: I186
ATTRIBUTES: FIXED_BASE0 SCALABLE STACKPUSH0
SHORT: push 0x0
% xed -e MOV EAX MEM4:SS:ESP
Request: MOV EASZ:2, MEM0:dword ptr SS[ESP], MEM_WIDTH:4, MODE:1, REG0:EAX, SMODE:1
OPERAND ORDER: REG0 MEM0
Encodable! 8B0424
.byte 0x8b,0x04,0x24
% xed -64 -e CCMPB r8b r9b dfv14
Request: CCMPB MODE:2, REG0:R8B, REG1:R9B, REG2:DFV14, SMODE:2
OPERAND ORDER: REG0 REG1 REG2
Encodable! 6254740238C8
.byte 0x62,0x54,0x74,0x02,0x38,0xc8

Or using the xed-ex3 example tool:

% obj/xed-ex3
Usage: obj/xed-ex3 [-16|-32|-64] [-s16|-s32] encode-string

The -16, -32 or -64 are for specifying the major mode of the machine. The major mode of the machine determines the default data operand size and default addressing width. In 64b mode, the default data size is 32b and the default addressing mode is 64b addressing. In 32b mode, the default addressing width is 32b. In 16b mode, the default addressing width is 16b. In 32b mode or 16b mode, the stack addressing width must also be specified. Usually it matches the major mode. The -s16 option is for specifying 16b stack addressing in 32b mode. The -s32 is for specifying 32b stack addressing in 16 bit mode.

% obj/xed-ex3 -64 PUSH/64 RAX
Encode request:
PUSH EOSZ:3, MODE:2, REG0:RAX, SMODE:2
OPERAND ORDER: REG0
Encodable! 50
% obj/xed-ex3 MOV MEM4:EAX IMM:11223344
Encode request:
MOV EASZ:2, IMM0:0x11223344, IMM_WIDTH:32, MEM0:dword ptr [EAX], MEM_WIDTH:4, MODE:1, SMODE:1
OPERAND ORDER: MEM0 IMM0
Encodable! C70044332211

An example of using the encoder

The encoder language file which is part of the xed command line tool shows how to build up instructions from scratch. The example uses a string to drive the creation of the instruction, but that is just an example. Look at the parse_encode_request function for the required pieces.

/* BEGIN_LEGAL
Copyright (c) 2024 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 */
// This is an example of how to use the encoder from scratch in the context
// of parsing a string from the command line.
#include <assert.h>
#include <string.h>
#include <stdlib.h> // strtol, ...
#include "xed-examples-util.h"
#include "xed-enc-lang.h"
#define BUF_LEN 50
static void upcase(char* s) {
(void)xed_upcase_buf(s);
}
xed_str_list_t*
tokenize(char const* const s,
char const* const delimiter)
{
xed_str_list_t* slist = xed_tokenize(s, delimiter);
return slist;
}
xed_bool_t is_empty_buf(char const* const buffer)
{
// indicate whether given buffer is empty by insuring first element is \0
if (*buffer == '\0')
return 1;
return 0;
}
void slash_split(char const* const src,
char* first, // output
char* second) //output
{
xed_str_list_t* sv = tokenize(src, "/");
xed_str_list_t* p = sv;
*first = 0;
*second = 0;
for(; p ; i++, p=p->next)
{
if (i==0) {
xed_strncpy(first, p->s, BUF_LEN-1);
}
else if (i==1) {
xed_strncpy(second, p->s, BUF_LEN-1);
}
}
xed_free_token_list(sv);
}
typedef struct {
xed_bool_t valid;
unsigned int width_bits;
xed_uint64_t immed_val;
} immed_parser_t;
static void immed_parser_init(immed_parser_t* self,
char const* const s,
char const* const tok0)
{
xed_str_list_t* sv = tokenize(s,":");
xed_uint_t sz = xed_str_list_size(sv);
self->valid = 0;
if (sz==2) {
xed_str_list_t* p = sv;
xed_uint_t i = 0;
for(; p ; i++, p=p->next)
{
if (i == 0 && strcmp(p->s,tok0) != 0)
{
break;
}
else if (i == 1) {
self->immed_val = convert_ascii_hex_to_int(p->s);
// nibbles to bits
self->width_bits = XED_CAST(unsigned int,strlen(p->s)*4);
self->valid = 1;
}
}
}
xed_free_token_list(sv);
}
typedef struct {
xed_bool_t valid;
xed_reg_enum_t segment_reg;
xed_uint_t segno;
} seg_parser_t;
static void seg_parser_init(seg_parser_t* self,
char const* const s)
{
xed_str_list_t* sv = tokenize(s,":");
xed_uint_t ntokens = xed_str_list_size(sv);
self->valid=0;
self->segment_reg= XED_REG_INVALID;
self->segno=0;
if (ntokens == 2)
{
xed_str_list_t* p = sv;
xed_uint_t i = 0;
xed_uint_t segid = 99;
for(; p ; i++, p=p->next)
{
if (i == 0)
{
if (strcmp(p->s,"SEG")==0 || strcmp(p->s,"SEG0")==0)
segid = 0;
else if (strcmp(p->s,"SEG1")==0)
segid = 1;
}
else if (i == 1 && segid < 2)
{
self->segno = segid;
self->segment_reg = str2xed_reg_enum_t(p->s);
if (self->segment_reg != XED_REG_INVALID &&
xed_reg_class(self->segment_reg) == XED_REG_CLASS_SR)
{
self->valid=1;
}
}
}
}
xed_free_token_list(sv);
}
static void
list2array(char** array, xed_str_list_t* sl, xed_uint_t n)
{
xed_str_list_t* p = sl;
for( ; p && i < n ; i++, p=p->next)
array[i] = p->s;
}
static xed_uint_t match(char const* const s, char const* const b)
{
if (strcmp(s,b)==0)
return 1;
return 0;
}
static xed_uint_t skip(char const* const s)
{
if (match(s,"-") || match(s,"NA"))
return 1;
return 0;
}
typedef struct
{
xed_bool_t valid;
xed_bool_t agen;
xed_bool_t disp_valid;
char segment[BUF_LEN];
char base[BUF_LEN];
char indx[BUF_LEN];
char scale[BUF_LEN];
char disp[BUF_LEN]; //displacement
xed_reg_enum_t segment_reg;
xed_reg_enum_t base_reg;
xed_reg_enum_t index_reg;
xed_uint8_t scale_val;
xed_int64_t disp_val;
unsigned int disp_width_bits;
xed_uint_t mem_len;
} mem_bis_parser_t;
// parse: MEMlength:[segment:]base,index,scale[,displacement]
// parse: AGEN:base,index,scale[,displacement]
// The displacement is optional
// split on colons first
// MEM4:FS:EAX,EBX,4,223344 mem4 fs eax,ebx,4,22334455 -> 3 tokens
// MEM4:FS:EAX,EBX,4 mem4 fs eax,ebx,4 -> 3 tokens
// MEM4:EAX,EBX,4,223344 mem4 eax,ebx,4,223344.. -> 2 tokens
// MEM4:FS:EAX,EBX,4 mem4 fs eas,ebx,4 -> 3 tokens
static void mem_bis_parser_init(mem_bis_parser_t* self, char* s)
{
xed_str_list_t* sv=0;
xed_uint_t ntokens=0;
xed_uint_t n_addr_tokens=0;
char addr_token[BUF_LEN]={0};
char main_token[BUF_LEN]={0};
xed_str_list_t* p = 0;
xed_str_list_t* sa = 0;
char* astr[4];
self->valid = 0;
self->mem = 0;
self->agen = 0;
self->disp_valid = 0;
xed_strncpy(self->segment, "INVALID", BUF_LEN-1);
xed_strncpy(self->base, "INVALID", BUF_LEN-1);
xed_strncpy(self->indx, "INVALID", BUF_LEN-1);
xed_strncpy(self->scale, "1", BUF_LEN-1);
xed_strncpy(self->disp, "", BUF_LEN-1);
self->segment_reg = XED_REG_INVALID;
self->base_reg = XED_REG_INVALID;
self->index_reg = XED_REG_INVALID;
self->disp_val = 0;
self->disp_width_bits = 0;
self->mem_len = 0;
self->scale_val = 1;
upcase(s);
// split on colon first
sv = tokenize(s,":");
ntokens = xed_str_list_size(sv);
i=0;
p = sv;
if (ntokens !=2 && ntokens != 3)
{
xed_free_token_list(sv);
return;
}
for( ; p ; i++, p=p->next) {
if (i==0)
xed_strncpy(main_token, p->s, BUF_LEN-1);
else if (i==1 && ntokens == 3)
xed_strncpy(self->segment, p->s, BUF_LEN-1);
else if (i==1 && ntokens == 2)
xed_strncpy(addr_token, p->s, BUF_LEN-1);
else if (i==2)
xed_strncpy(addr_token, p->s, BUF_LEN-1);
}
xed_free_token_list(sv);
assert(!is_empty_buf(main_token));
if (strcmp(main_token,"AGEN")==0)
self->agen=1;
else if (strncmp(main_token,"MEM",3)==0)
self->mem = 1;
else
return;
if (self->mem && strlen(main_token) > 3) {
char* mlen = main_token+3;
self->mem_len = XED_STATIC_CAST(xed_uint_t,strtol(mlen,0,0));
}
if (self->agen && strcmp(self->segment,"INVALID")!=0)
xedex_derror("AGENs cannot have segment overrides");
sa = tokenize(addr_token,",");
n_addr_tokens = xed_str_list_size(sa);
if (n_addr_tokens == 0 || n_addr_tokens > 4)
xedex_derror("Bad addressing mode syntax for memop");
list2array(astr, sa, n_addr_tokens);
if (!skip(astr[0]))
xed_strncpy(self->base, astr[0], BUF_LEN-1);
if (n_addr_tokens >= 2)
if (!skip(astr[1]))
xed_strncpy(self->indx, astr[1], BUF_LEN-1);
if (n_addr_tokens > 2)
xed_strncpy(self->scale, astr[2], BUF_LEN-1);
if (skip(self->scale))
xed_strncpy(self->scale, "1", BUF_LEN-1);
if (match(self->scale,"1") || match(self->scale,"2") ||
match(self->scale,"4") || match(self->scale,"8") ) {
self->valid=1;
self->scale_val = XED_CAST(xed_uint8_t,strtol(self->scale, 0, 10));
self->segment_reg = str2xed_reg_enum_t(self->segment);
self->base_reg = str2xed_reg_enum_t(self->base);
self->index_reg = str2xed_reg_enum_t(self->indx);
// look for a displacement
if (n_addr_tokens == 4 && strcmp(astr[3], "-") != 0) {
xed_uint64_t unsigned64_disp=0;
unsigned int nibbles = 0;
xed_strncpy(self->disp, astr[3], BUF_LEN-1);
self->disp_valid = 1;
nibbles = xed_strlen(self->disp);
if (nibbles & 1)
xedex_derror("Displacement must have an even number of nibbles");
unsigned64_disp = convert_ascii_hex_to_int(self->disp);
self->disp_width_bits = nibbles*4; // nibbles to bits
switch (self->disp_width_bits){
case 8: self->disp_val = xed_sign_extend8_64((xed_int8_t)unsigned64_disp);
break;
case 16: self->disp_val = xed_sign_extend16_64((xed_int16_t)unsigned64_disp);
break;
case 32: self->disp_val = xed_sign_extend32_64((xed_int32_t)unsigned64_disp);
break;
case 64: self->disp_val = (xed_int64_t)unsigned64_disp;
break;
}
}
}
xed_free_token_list(sa);
}
static void find_vl(xed_reg_enum_t reg, xed_int_t* vl)
{
// This will "grow" bad user settings. So if you try to specify /128 on
// the instruction and it sees a YMM or ZMM register operand, then
// it'll grow the VL to the right observed size. The right observed
// size might still be wrong, that is too small (as it can be for
// "shrinking" converts (PD2PS, PD2DQ, etc.).
xed_int_t nvl = *vl;
if (rc == XED_REG_CLASS_XMM && nvl == -1) // not set and see xmm
*vl = 0;
else if (rc == XED_REG_CLASS_YMM && nvl < 1) // not set, set to xmm and then see ymm
*vl = 1;
#if defined(XED_SUPPORTS_AVX512)
else if (rc == XED_REG_CLASS_ZMM && nvl < 2) // not set, set to xmm or ymm and then see zmm
*vl = 2;
#endif
}
static inline void find_64bit_eow(xed_reg_enum_t reg, xed_int_t* eow)
{
// set the effective operand width for 64bit registers.
if (rc == XED_REG_CLASS_GPR64 && *eow < 64)
*eow = 64;
}
parse_encode_request(ascii_encode_request_t areq)
{
unsigned int i;
xed_str_list_t* tokens = 0;
char cfirst[BUF_LEN]={0};
char csecond[BUF_LEN]={0};
unsigned int token_index = 0;
xed_str_list_t* p = 0;
xed_uint_t memop = 0;
xed_uint_t regnum = 0;
xed_uint_t operand_index = 0;
xed_int_t vl = -1;
xed_int_t eow = -1;
xed_int_t uvl = -1; // take VL from cmd
xed_int_t ueow = -1; // take effective operand width from cmd
// this calls xed_encoder_request_zero()
xed_encoder_request_zero_set_mode(&req,&(areq.dstate));
/* This is the important function here. This encodes an instruction
from scratch.
You must set:
the machine mode (machine width, addressing widths)
the iclass
for some instructions you need to specify prefixes (like REP or LOCK).
the operands:
operand kind (XED_OPERAND_{AGEN,MEM0,MEM1,IMM0,IMM1,
RELBR,ABSBR,PTR,REG0...REG15}
operand order
xed_encoder_request_set_operand_order(&req,operand_index,
XED_OPERAND_*);
where the operand_index is a sequential index starting at zero.
operand details
FOR MEMOPS: base,segment,index,scale,
displacement for memops,
FOR REGISTERS: register name
FOR IMMEDIATES: immediate values
*/
tokens = tokenize(areq.command," ");
p = tokens;
if (p)
{
slash_split(p->s, cfirst, csecond);
if (! is_empty_buf(cfirst))
{
upcase(cfirst);
if (CLIENT_VERBOSE3)
printf("[%s][%s][%s]\n", p->s,
(!is_empty_buf(cfirst)?cfirst:"NULL"),
(!is_empty_buf(cfirst)?csecond:"NULL"));
p = p->next; // consumed token, advance
}
}
// we can attempt to override the mode
if (!is_empty_buf(csecond))
{
if (strcmp(csecond,"8")==0)
ueow = 8;
else if (strcmp(csecond,"16")==0)
ueow = 16;
else if (strcmp(csecond, "32")==0)
ueow = 32;
else if (strcmp(csecond,"64")==0)
ueow = 64;
else if (strcmp(csecond,"128")==0)
uvl = 0;
else if (strcmp(csecond,"256")==0)
uvl = 1;
else if (strcmp(csecond,"512")==0)
uvl = 2;
else {
fprintf(stderr,"[XED CLIENT ERROR] Bad operand width/vl: %s\n", csecond);
exit(1);
}
}
assert(!is_empty_buf(cfirst));
iclass = str2xed_iclass_enum_t(cfirst);
if (iclass == XED_ICLASS_INVALID) {
fprintf(stderr,"[XED CLIENT ERROR] Bad instruction name: %s\n",
cfirst);
exit(1);
}
// put the operands in the request. Loop through tokens
// (skip the opcode iclass, handled above)
for( i=token_index; p ; i++, operand_index++, p=p->next ) {
mem_bis_parser_t mem_bis;
seg_parser_t seg_parser;
immed_parser_t imm;
immed_parser_t simm;
immed_parser_t imm2;
immed_parser_t disp;
immed_parser_t ptr_disp;
char cres_reg[BUF_LEN]={0};
char csecond_x[BUF_LEN]={0}; //FIXME: not used
slash_split(p->s, cres_reg, csecond_x);
if (is_empty_buf(cres_reg))
continue;
upcase(cres_reg);
// prune the AGEN or MEM(base,index,scale[,displacement]) text from
// cres_reg
// FIXME: add MEM(immed) for the OC1_A and OC1_O types????
mem_bis_parser_init(&mem_bis,cres_reg);
if (mem_bis.valid) {
if (mem_bis.mem) {
if (memop == 0) {
// Tell XED that we have a memory operand
// Tell XED that the mem0 operand is the next operand:
&req,operand_index, XED_OPERAND_MEM0);
}
else {
// Tell XED that the mem1 operand is the next operand:
&req,operand_index, XED_OPERAND_MEM1);
}
memop++;
}
else if (mem_bis.agen) {
// Tell XED we have an AGEN
// The AGEN is the next operand
&req,operand_index, XED_OPERAND_AGEN);
}
else
assert(mem_bis.agen || mem_bis.mem);
rc = xed_gpr_reg_class(mem_bis.base_reg);
rci = xed_gpr_reg_class(mem_bis.index_reg);
if (mem_bis.base_reg == XED_REG_EIP)
else if (rc == XED_REG_CLASS_GPR32 || rci == XED_REG_CLASS_GPR32)
else if (rc == XED_REG_CLASS_GPR16 || rci == XED_REG_CLASS_GPR16)
// fill in the memory fields
xed_encoder_request_set_base0(&req, mem_bis.base_reg);
xed_encoder_request_set_index(&req, mem_bis.index_reg);
xed_encoder_request_set_scale(&req, mem_bis.scale_val);
xed_encoder_request_set_seg0(&req, mem_bis.segment_reg);
find_vl(mem_bis.index_reg, &vl); // for scatter/gather
if (mem_bis.mem_len)
&req,
mem_bis.mem_len ); // BYTES
if (mem_bis.disp_valid)
&req,
mem_bis.disp_val,
mem_bis.disp_width_bits/8);
continue;
}
seg_parser_init(&seg_parser,cres_reg);
if (seg_parser.valid) {
if (CLIENT_VERBOSE3)
printf("Setting segment to %s\n",
xed_reg_enum_t2str(seg_parser.segment_reg));
if (seg_parser.segno == 0)
xed_encoder_request_set_seg0(&req, seg_parser.segment_reg);
else
/* need SEG1 for MOVS[BWDQ]*/
xed_encoder_request_set_seg1(&req, seg_parser.segment_reg);
/* SEG/SEG0/SEG1 is NOT a normal operand. It is a setting, like
* the lock prefix. Normally the segment will be specified with
* normal memory operations. With memops without MODRM, or
* impliclit memops, we need a way of specifying the segment
* when it is not the default. This is the way. it does not
* change encoding forms. (When segments are "moved", they are
* REG operands, not SEG0/1, and are specified by name like EAX
* is.) */
continue;
}
immed_parser_init(&imm,cres_reg, "IMM");
if (imm.valid) {
if (CLIENT_VERBOSE3)
printf("Setting immediate value to " XED_FMT_LX "\n",
imm.immed_val);
imm.immed_val,
imm.width_bits);
operand_index,
continue;
}
immed_parser_init(&simm,cres_reg, "SIMM");
if (simm.valid) {
if (CLIENT_VERBOSE3)
printf("Setting immediate value to " XED_FMT_LX "\n",
simm.immed_val);
&req,
XED_STATIC_CAST(xed_int32_t,simm.immed_val),
simm.width_bits/8); //FIXME
operand_index,
continue;
}
immed_parser_init(&imm2,cres_reg, "IMM2");
if (imm2.valid) {
if (imm2.width_bits != 8)
xedex_derror("2nd immediate must be just 1 byte long");
xed_encoder_request_set_uimm1(&req, (xed_uint8_t)imm2.immed_val);
operand_index,
continue;
}
immed_parser_init(&disp,cres_reg, "RELBR");
if (disp.valid) {
if (CLIENT_VERBOSE3)
printf("Setting displacement value to " XED_FMT_LX "\n",
disp.immed_val);
&req,
XED_STATIC_CAST(xed_int64_t,disp.immed_val),
disp.width_bits/8); //FIXME
operand_index,
continue;
}
immed_parser_init(&disp,cres_reg, "ABSBR");
if (disp.valid) {
if (CLIENT_VERBOSE3)
printf("Setting displacement value to " XED_FMT_LX "\n",
disp.immed_val);
&req,
XED_STATIC_CAST(xed_int64_t,disp.immed_val),
disp.width_bits/8); //FIXME
operand_index,
continue;
}
immed_parser_init(&ptr_disp,cres_reg, "PTR");
if (ptr_disp.valid) {
if (CLIENT_VERBOSE3)
printf("Setting pointer displacement value to " XED_FMT_LX "\n",
ptr_disp.immed_val);
&req,
XED_STATIC_CAST(xed_int64_t,ptr_disp.immed_val),
ptr_disp.width_bits/8); //FIXME
operand_index,
continue;
}
reg = str2xed_reg_enum_t(cres_reg);
if (reg == XED_REG_INVALID) {
fprintf(stderr,
"[XED CLIENT ERROR] Bad register name: %s on operand %u\n",
cres_reg, i);
exit(1);
}
if (areq.dstate.mmode != XED_MACHINE_MODE_LONG_64)
if (reg == XED_REG_DIL || reg == XED_REG_SPL || reg == XED_REG_BPL || reg == XED_REG_SIL)
{
fprintf(stderr,
"[XED CLIENT ERROR] Cannot use DIL/SPL/BPL/SIL outside of 64b mode\n");
exit(1);
}
// The registers operands are numbered starting from the first one
// as XED_OPERAND_REG0. We increment regnum (below) every time we
// add a register operands.
// store the register identifier in the operand storage field
// store the operand storage field name in the encode-order array
xed_encoder_request_set_operand_order(&req, operand_index, r);
find_vl(reg, &vl);
// Set the effective operand width for 64bit GPRs.
// For 64bit instructions, the default GPR EOSZ (effective operand size) is 32bits,
// We need to set it to 64bit in case we find 64bit register (on 64bit mode).
find_64bit_eow(reg, &eow);
regnum++;
} // for loop
// Set Vector Length if needed
if (uvl == -1)
{
// no user VL setting, so use our observation-based guess.
if (vl>=0)
}
else
{
if (vl >= 0 && uvl < vl)
xedex_derror("User specified VL is smaller than largest observed register.");
// go with the user value. The encoder still might increase it
// based on observed values. But we test for that above so they'll
// get the feedback.
}
// Set Effective Operand Width if needed
{ // No need to set EOSZ if VL is defined
if (ueow == -1)
{
// no user eow, so use our observation-based guess.
if (eow >= 0)
}
else
{
if (eow >= 0 && ueow < eow)
xedex_derror("User specified EOW is smaller than largest observed register.");
// go with the user value
}
}
xed_free_token_list(tokens);
return req;
}
XED_REG_CLASS_XMM
@ XED_REG_CLASS_XMM
Definition: xed-reg-class-enum.h:81
XED_OPERAND_IMM0
@ XED_OPERAND_IMM0
Definition: xed-operand-enum.h:205
xed_encoder_request_set_iclass
XED_DLL_EXPORT void xed_encoder_request_set_iclass(xed_encoder_request_t *p, xed_iclass_enum_t iclass)
xed_reg_class_enum_t
xed_reg_class_enum_t
Definition: xed-reg-class-enum.h:55
xed_encoder_request_set_branch_displacement
XED_DLL_EXPORT void xed_encoder_request_set_branch_displacement(xed_encoder_request_t *p, xed_int64_t brdisp, xed_uint_t nbytes)
XED_REG_CLASS_GPR64
@ XED_REG_CLASS_GPR64
Definition: xed-reg-class-enum.h:66
xed_gpr_reg_class
XED_DLL_EXPORT xed_reg_class_enum_t xed_gpr_reg_class(xed_reg_enum_t r)
Returns the specific width GPR reg class (like XED_REG_CLASS_GPR32 or XED_REG_CLASS_GPR64) for a give...
XED_REG_CLASS_SR
@ XED_REG_CLASS_SR
Definition: xed-reg-class-enum.h:75
xed_encoder_request_set_scale
XED_DLL_EXPORT void xed_encoder_request_set_scale(xed_encoder_request_t *p, xed_uint_t scale)
xed_operand_enum_t
xed_operand_enum_t
Definition: xed-operand-enum.h:168
xed_encoder_request_set_memory_displacement
XED_DLL_EXPORT void xed_encoder_request_set_memory_displacement(xed_encoder_request_t *p, xed_int64_t memdisp, xed_uint_t nbytes)
xed_encoder_request_set_agen
XED_DLL_EXPORT void xed_encoder_request_set_agen(xed_encoder_request_t *p)
xed_encoder_request_set_index
XED_DLL_EXPORT void xed_encoder_request_set_index(xed_encoder_request_t *p, xed_reg_enum_t index_reg)
xed_operand_values_get_long_mode
XED_DLL_EXPORT xed_bool_t xed_operand_values_get_long_mode(const xed_operand_values_t *p)
xed_encoder_request_set_seg0
XED_DLL_EXPORT void xed_encoder_request_set_seg0(xed_encoder_request_t *p, xed_reg_enum_t seg_reg)
XED_REG_BPL
@ XED_REG_BPL
Definition: xed-reg-enum.h:584
XED_REG_CLASS_ZMM
@ XED_REG_CLASS_ZMM
Definition: xed-reg-class-enum.h:83
XED_OPERAND_RELBR
@ XED_OPERAND_RELBR
Definition: xed-operand-enum.h:269
xed_reg_class
XED_DLL_EXPORT xed_reg_class_enum_t xed_reg_class(xed_reg_enum_t r)
Returns the register class of the given input register.
XED_OPERAND_IMM1
@ XED_OPERAND_IMM1
Definition: xed-operand-enum.h:207
xed_encoder_request_set_relbr
XED_DLL_EXPORT void xed_encoder_request_set_relbr(xed_encoder_request_t *p)
XED_REG_DIL
@ XED_REG_DIL
Definition: xed-reg-enum.h:586
XED_REG_CLASS_YMM
@ XED_REG_CLASS_YMM
Definition: xed-reg-class-enum.h:82
XED_REG_SPL
@ XED_REG_SPL
Definition: xed-reg-enum.h:583
xed_encoder_request_set_mem0
XED_DLL_EXPORT void xed_encoder_request_set_mem0(xed_encoder_request_t *p)
xed_encoder_request_set_ptr
XED_DLL_EXPORT void xed_encoder_request_set_ptr(xed_encoder_request_t *p)
xed_encoder_request_set_absbr
XED_DLL_EXPORT void xed_encoder_request_set_absbr(xed_encoder_request_t *p)
xed_uint_t
unsigned int xed_uint_t
Definition: xed-types.h:52
XED_REG_INVALID
@ XED_REG_INVALID
Definition: xed-reg-enum.h:449
XED_REG_CLASS_INVALID
@ XED_REG_CLASS_INVALID
Definition: xed-reg-class-enum.h:56
xed_encoder_request_set_memory_operand_length
XED_DLL_EXPORT void xed_encoder_request_set_memory_operand_length(xed_encoder_request_t *p, xed_uint_t nbytes)
XED_OPERAND_ABSBR
@ XED_OPERAND_ABSBR
Definition: xed-operand-enum.h:170
xed_strncpy
XED_DLL_EXPORT int xed_strncpy(char *dst, const char *src, int len)
returns the number of bytes remaining for the next use of xed_strncpy() or xed_strncat() .
XED_OPERAND_MEM0
@ XED_OPERAND_MEM0
Definition: xed-operand-enum.h:218
XED_ICLASS_INVALID
@ XED_ICLASS_INVALID
Definition: xed-iclass-enum.h:2003
xed_iclass_enum_t
xed_iclass_enum_t
Definition: xed-iclass-enum.h:2002
XED_OPERAND_PTR
@ XED_OPERAND_PTR
Definition: xed-operand-enum.h:256
XED_OPERAND_MEM1
@ XED_OPERAND_MEM1
Definition: xed-operand-enum.h:219
XED_STATIC_CAST
#define XED_STATIC_CAST(x, y)
Definition: xed-portability.h:27
xed_reg_enum_t2str
const XED_DLL_EXPORT char * xed_reg_enum_t2str(const xed_reg_enum_t p)
This converts strings to xed_reg_enum_t types.
xed_bool_t
unsigned int xed_bool_t
Definition: xed-types.h:55
xed_encoder_request_set_base0
XED_DLL_EXPORT void xed_encoder_request_set_base0(xed_encoder_request_t *p, xed_reg_enum_t base_reg)
XED_REG_EIP
@ XED_REG_EIP
Definition: xed-reg-enum.h:617
xed_sign_extend8_64
XED_DLL_EXPORT xed_int64_t xed_sign_extend8_64(xed_int8_t x)
str2xed_reg_enum_t
XED_DLL_EXPORT xed_reg_enum_t str2xed_reg_enum_t(const char *s)
This converts strings to xed_reg_enum_t types.
XED_OPERAND_AGEN
@ XED_OPERAND_AGEN
Definition: xed-operand-enum.h:171
str2xed_iclass_enum_t
XED_DLL_EXPORT xed_iclass_enum_t str2xed_iclass_enum_t(const char *s)
This converts strings to xed_iclass_enum_t types.
XED_REG_CLASS_GPR16
@ XED_REG_CLASS_GPR16
Definition: xed-reg-class-enum.h:64
XED_OPERAND_REG0
@ XED_OPERAND_REG0
Definition: xed-operand-enum.h:259
xed_encoder_request_set_simm
XED_DLL_EXPORT void xed_encoder_request_set_simm(xed_encoder_request_t *p, xed_int32_t simm, xed_uint_t nbytes)
XED_REG_CLASS_GPR32
@ XED_REG_CLASS_GPR32
Definition: xed-reg-class-enum.h:65
XED_REG_SIL
@ XED_REG_SIL
Definition: xed-reg-enum.h:585
xed_sign_extend32_64
XED_DLL_EXPORT xed_int64_t xed_sign_extend32_64(xed_int32_t x)
xed_int_t
int xed_int_t
Definition: xed-types.h:53
xed_encoder_request_set_uimm0_bits
XED_DLL_EXPORT void xed_encoder_request_set_uimm0_bits(xed_encoder_request_t *p, xed_uint64_t uimm, xed_uint_t nbits)
xed3_operand_get_vl
static XED_INLINE xed_bits_t xed3_operand_get_vl(const xed_decoded_inst_t *d)
Definition: xed-operand-accessors.h:1559
xed_strlen
XED_DLL_EXPORT xed_uint_t xed_strlen(const char *s)
xed_encoder_request_set_mem1
XED_DLL_EXPORT void xed_encoder_request_set_mem1(xed_encoder_request_t *p)
xed_encoder_request_set_uimm1
XED_DLL_EXPORT void xed_encoder_request_set_uimm1(xed_encoder_request_t *p, xed_uint8_t uimm)
XED_MACHINE_MODE_LONG_64
@ XED_MACHINE_MODE_LONG_64
64b operating mode
Definition: xed-machine-mode-enum.h:37
xed_encoder_request_zero_set_mode
XED_DLL_EXPORT void xed_encoder_request_zero_set_mode(xed_encoder_request_t *p, const xed_state_t *dstate)
xed_sign_extend16_64
XED_DLL_EXPORT xed_int64_t xed_sign_extend16_64(xed_int16_t x)
xed_reg_enum_t
xed_reg_enum_t
Definition: xed-reg-enum.h:448
xed_encoder_request_set_seg1
XED_DLL_EXPORT void xed_encoder_request_set_seg1(xed_encoder_request_t *p, xed_reg_enum_t seg_reg)
xed_encoder_request_set_operand_order
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)
xed_encoder_request_set_reg
XED_DLL_EXPORT void xed_encoder_request_set_reg(xed_encoder_request_t *p, xed_operand_enum_t operand, xed_reg_enum_t reg)
xed_encoder_request_set_effective_operand_width
XED_DLL_EXPORT void xed_encoder_request_set_effective_operand_width(xed_encoder_request_t *p, xed_uint_t width_bits)
XED_FMT_LX
#define XED_FMT_LX
Definition: xed-portability.h:132
XED_CAST
#define XED_CAST(x, y)
Definition: xed-portability.h:29
xed_encoder_request_set_effective_address_size
XED_DLL_EXPORT void xed_encoder_request_set_effective_address_size(xed_encoder_request_t *p, xed_uint_t width_bits)
xed-interface.h
xed_decoded_inst_s
Definition: xed-decoded-inst.h:53
xed3_operand_set_vl
static XED_INLINE void xed3_operand_set_vl(xed_decoded_inst_t *d, xed_bits_t opval)
Definition: xed-operand-accessors.h:1563