#include <xed/xed-interface.h>
#include "vm_guest.h"
#include "test.h"
+
#else
+
#include <palacios/vmm_decoder.h>
#include <palacios/vmm_xed.h>
#include <xed/xed-interface.h>
#include <palacios/vm_guest.h>
#include <palacios/vmm.h>
-
-
#endif
-static xed_state_t decoder_state;
+
+static uint_t tables_inited = 0;
+
#define GPR_REGISTER 0
#define SEGMENT_REGISTER 1
switch (length) { \
case 1: \
mask = mask_1; \
+ break; \
case 2: \
mask = mask_2; \
+ break; \
case 4: \
mask = mask_4; \
+ break; \
case 8: \
mask = mask_8; \
+ break; \
} \
val & mask;}) \
-// This returns a pointer to a V3_OPCODE_[*] array defined in vmm_decoder.h
-static int get_opcode(xed_iform_enum_t iform, addr_t * opcode);
+
+static v3_op_type_t get_opcode(xed_iform_enum_t iform);
static int xed_reg_to_v3_reg(struct guest_info * info, xed_reg_enum_t xed_reg, addr_t * v3_reg, uint_t * reg_len);
static int get_memory_operand(struct guest_info * info, xed_decoded_inst_t * xed_instr, uint_t index, struct x86_operand * operand);
XED_ADDRESS_WIDTH_32b);
}
break;
+ case LONG_32_COMPAT:
+ if (state->mmode != XED_MACHINE_MODE_LONG_COMPAT_32) {
+ xed_state_init(state,
+ XED_MACHINE_MODE_LONG_COMPAT_32,
+ XED_ADDRESS_WIDTH_32b,
+ XED_ADDRESS_WIDTH_32b);
+ }
+ break;
case LONG:
- if (state->mmode != XED_MACHINE_MODE_LONG_64) {
- state->mmode = XED_MACHINE_MODE_LONG_64;
+ if (state->mmode != XED_MACHINE_MODE_LONG_64) {
+ PrintDebug("Setting decoder to long mode\n");
+ // state->mmode = XED_MACHINE_MODE_LONG_64;
+ //xed_state_set_machine_mode(state, XED_MACHINE_MODE_LONG_64);
+ xed_state_init(state,
+ XED_MACHINE_MODE_LONG_64,
+ XED_ADDRESS_WIDTH_64b,
+ XED_ADDRESS_WIDTH_64b);
}
break;
default:
+ PrintError("Unsupported CPU mode: %d\n", info->cpu_mode);
return -1;
}
return 0;
-int v3_init_decoder() {
- xed_tables_init();
- xed_state_zero(&decoder_state);
+int v3_init_decoder(struct guest_info * info) {
+ // Global library initialization, only do it once
+ if (tables_inited == 0) {
+ xed_tables_init();
+ tables_inited = 1;
+ }
+
+ xed_state_t * decoder_state = (xed_state_t *)V3_Malloc(sizeof(xed_state_t));
+ xed_state_zero(decoder_state);
+ xed_state_init(decoder_state,
+ XED_MACHINE_MODE_LEGACY_32,
+ XED_ADDRESS_WIDTH_32b,
+ XED_ADDRESS_WIDTH_32b);
+
+ info->decoder_state = decoder_state;
+
return 0;
}
xed_error_enum_t xed_error;
- if (set_decoder_mode(info, &decoder_state) == -1) {
+ if (set_decoder_mode(info, info->decoder_state) == -1) {
PrintError("Could not set decoder mode\n");
return -1;
}
- xed_decoded_inst_zero_set_mode(&xed_instr, &decoder_state);
+ xed_decoded_inst_zero_set_mode(&xed_instr, info->decoder_state);
xed_error = xed_decode(&xed_instr,
REINTERPRET_CAST(const xed_uint8_t *, instr_ptr),
}
+static int decode_string_op(struct guest_info * info,
+ xed_decoded_inst_t * xed_instr, const xed_inst_t * xi,
+ struct x86_instr * instr) {
+
+ PrintDebug("String operation\n");
+
+ if (instr->op_type == V3_OP_MOVS) {
+ instr->num_operands = 2;
+
+ if (get_memory_operand(info, xed_instr, 0, &(instr->dst_operand)) == -1) {
+ PrintError("Could not get Destination memory operand\n");
+ return -1;
+ }
+
+ if (get_memory_operand(info, xed_instr, 1, &(instr->src_operand)) == -1) {
+ PrintError("Could not get Source memory operand\n");
+ return -1;
+ }
+
+ if (instr->prefixes.rep == 1) {
+ addr_t reg_addr = 0;
+ uint_t reg_length = 0;
+
+ xed_reg_to_v3_reg(info, xed_decoded_inst_get_reg(xed_instr, XED_OPERAND_REG0), ®_addr, ®_length);
+ instr->str_op_length = MASK(*(addr_t *)reg_addr, reg_length);
+ } else {
+ instr->str_op_length = 1;
+ }
+
+ } else if (instr->op_type == V3_OP_STOS) {
+ instr->num_operands = 2;
+
+ if (get_memory_operand(info, xed_instr, 0, &(instr->dst_operand)) == -1) {
+ PrintError("Could not get Destination memory operand\n");
+ return -1;
+ }
+
+ // STOS reads from rax
+ xed_reg_to_v3_reg(info, xed_decoded_inst_get_reg(xed_instr, XED_OPERAND_REG0),
+ &(instr->src_operand.operand),
+ &(instr->src_operand.size));
+ instr->src_operand.type = REG_OPERAND;
+
+ if (instr->prefixes.rep == 1) {
+ addr_t reg_addr = 0;
+ uint_t reg_length = 0;
+
+ xed_reg_to_v3_reg(info, xed_decoded_inst_get_reg(xed_instr, XED_OPERAND_REG1), ®_addr, ®_length);
+ instr->str_op_length = MASK(*(addr_t *)reg_addr, reg_length);
+ } else {
+ instr->str_op_length = 1;
+ }
+
+ } else {
+ PrintError("Unhandled String OP\n");
+ return -1;
+ }
+
+ return 0;
+}
+
+
int v3_decode(struct guest_info * info, addr_t instr_ptr, struct x86_instr * instr) {
xed_decoded_inst_t xed_instr;
xed_error_enum_t xed_error;
+ v3_get_prefixes((uchar_t *)instr_ptr, &(instr->prefixes));
- if (set_decoder_mode(info, &decoder_state) == -1) {
+ if (set_decoder_mode(info, info->decoder_state) == -1) {
PrintError("Could not set decoder mode\n");
return -1;
}
-
-
- xed_decoded_inst_zero_set_mode(&xed_instr, &decoder_state);
+ xed_decoded_inst_zero_set_mode(&xed_instr, info->decoder_state);
xed_error = xed_decode(&xed_instr,
REINTERPRET_CAST(const xed_uint8_t *, instr_ptr),
const xed_inst_t * xi = xed_decoded_inst_inst(&xed_instr);
instr->instr_length = xed_decoded_inst_get_length(&xed_instr);
- instr->num_operands = xed_decoded_inst_noperands(&xed_instr);
+
xed_iform_enum_t iform = xed_decoded_inst_get_iform_enum(&xed_instr);
+#ifdef DEBUG_XED
+ xed_iclass_enum_t iclass = xed_decoded_inst_get_iclass(&xed_instr);
+
+ PrintDebug("iform=%s, iclass=%s\n", xed_iform_enum_t2str(iform), xed_iclass_enum_t2str(iclass));
+#endif
+
- PrintDebug("iform=%s\n", xed_iform_enum_t2str(iform));
+ if ((instr->op_type = get_opcode(iform)) == V3_INVALID_OP) {
+ PrintError("Could not get opcode. (iform=%s)\n", xed_iform_enum_t2str(iform));
+ return -1;
+ }
+ // We special case the string operations...
+ if (xed_decoded_inst_get_category(&xed_instr) == XED_CATEGORY_STRINGOP) {
+ instr->is_str_op = 1;
+ return decode_string_op(info, &xed_instr, xi, instr);
+ } else {
+ instr->is_str_op = 0;
+ instr->str_op_length = 0;
+ }
+
+
+ instr->num_operands = xed_decoded_inst_noperands(&xed_instr);
+
if (instr->num_operands > 3) {
PrintDebug("Special Case Not Handled\n");
return -1;
if ((!xed_operand_is_register(op_enum)) ||
(!is_flags_reg(xed_decoded_inst_get_reg(&xed_instr, op_enum)))) {
// special case
- PrintDebug("Special Case not handled\n");
+ PrintError("Special Case not handled\n");
return -1;
}
}
-
-
- if (get_opcode(iform, &(instr->opcode)) == -1) {
- PrintDebug("Could not get opcode. (iform=%s)\n", xed_iform_enum_t2str(iform));
- return -1;
- }
-
-
-
-
//PrintDebug("Number of operands: %d\n", instr->num_operands);
//PrintDebug("INSTR length: %d\n", instr->instr_length);
xed_reg,
&(v3_op->operand),
&(v3_op->size));
-
+
if (v3_reg_type == -1) {
PrintError("First operand is an Unhandled Operand: %s\n", xed_reg_enum_t2str(xed_reg));
v3_op->type = INVALID_OPERAND;
case XED_OPERAND_MEM0:
{
- /*
- struct x86_operand * operand = &(instr->dst_operand);
-
- if (xed_decoded_inst_mem_read(&xed_instr, 0)) {
- operand = &(instr->src_operand);
- } else if (xed_decoded_inst_mem_written(&xed_instr, 0)) {
- operand = &(instr->dst_operand);
- }
- */
-
if (get_memory_operand(info, &xed_instr, 0, v3_op) == -1) {
PrintError("Could not get first memory operand\n");
return -1;
case XED_OPERAND_MEM0:
{
-
- /*
- if (xed_decoded_inst_mem_read(&xed_instr, 0)) {
- v3_op = &(instr->src_operand);
- } else if (xed_decoded_inst_mem_written(&xed_instr, 0)) {
- v3_op = &(instr->dst_operand);
- }
- */
-
if (get_memory_operand(info, &xed_instr, 0, v3_op) == -1) {
PrintError("Could not get first memory operand\n");
return -1;
// set third operand
if (instr->num_operands >= 3) {
const xed_operand_t * op = xed_inst_operand(xi, 2);
- // xed_operand_type_enum_t op_type = xed_operand_type(op);
+ xed_operand_type_enum_t op_type = xed_operand_type(op);
xed_operand_enum_t op_enum = xed_operand_name(op);
if (xed_operand_is_register(op_enum)) {
} else {
- // PrintError("Unhandled third operand type %s\n", xed_operand_type_enum_t2str(op_type));
+ PrintError("Unhandled third operand type %s\n", xed_operand_type_enum_t2str(op_type));
return -1;
}
ullong_t displacement;
// struct v3_segment * seg_reg;
-
-
+ PrintDebug("Xen mode = %s\n", xed_machine_mode_enum_t2str(xed_state_get_machine_mode(info->decoder_state)));
+ PrintDebug("Address width: %s\n",
+ xed_address_width_enum_t2str(xed_state_get_address_width(info->decoder_state)));
+ PrintDebug("Stack Address width: %s\n",
+ xed_address_width_enum_t2str(xed_state_get_stack_address_width(info->decoder_state)));
memset((void*)&mem_op, '\0', sizeof(struct memory_operand));
if (disp_bits) {
xed_int64_t xed_disp = xed_decoded_inst_get_memory_displacement(xed_instr, op_index);
- mem_op.displacement_size = disp_bits / 8;
+ mem_op.displacement_size = disp_bits;
mem_op.displacement = xed_disp;
-
}
operand->type = MEM_OPERAND;
- PrintDebug("Struct: Seg=%x, base=%x, index=%x, scale=%x, displacement=%x\n",
- mem_op.segment, mem_op.base, mem_op.index, mem_op.scale, mem_op.displacement);
+ PrintDebug("Struct: Seg=%p (size=%d), base=%p, index=%p, scale=%p, displacement=%p (size=%d)\n",
+ (void *)mem_op.segment, mem_op.segment_size, (void*)mem_op.base, (void *)mem_op.index,
+ (void *)mem_op.scale, (void *)(addr_t)mem_op.displacement, mem_op.displacement_size);
- seg = mem_op.segment;
+ PrintDebug("operand size: %d\n", operand->size);
+
+ seg = MASK(mem_op.segment, mem_op.segment_size);
base = MASK(mem_op.base, mem_op.base_size);
index = MASK(mem_op.index, mem_op.index_size);
scale = mem_op.scale;
- displacement = MASK(mem_op.displacement, mem_op.displacement_size);
- PrintDebug("Seg=%x, base=%x, index=%x, scale=%x, displacement=%x\n", seg, base, index, scale, displacement);
+ // This is a horrendous hack...
+ // XED really screwed the pooch in calculating the displacement
+ if (v3_get_cpu_mode(info) == LONG) {
+ displacement = mem_op.displacement;
+ } else {
+ displacement = MASK(mem_op.displacement, mem_op.displacement_size);
+ }
+
+ PrintDebug("Seg=%p, base=%p, index=%p, scale=%p, displacement=%p\n",
+ (void *)seg, (void *)base, (void *)index, (void *)scale, (void *)(addr_t)displacement);
operand->operand = seg + base + (scale * index) + displacement;
return 0;
static int xed_reg_to_v3_reg(struct guest_info * info, xed_reg_enum_t xed_reg, addr_t * v3_reg, uint_t * reg_len) {
+ PrintDebug("Xed Register: %s\n", xed_reg_enum_t2str(xed_reg));
+
switch (xed_reg) {
case XED_REG_INVALID:
*v3_reg = 0;
return GPR_REGISTER;
+
+
+
+ case XED_REG_R8:
+ *v3_reg = (addr_t)&(info->vm_regs.r8);
+ *reg_len = 8;
+ return GPR_REGISTER;
+ case XED_REG_R8D:
+ *v3_reg = (addr_t)&(info->vm_regs.r8);
+ *reg_len = 4;
+ return GPR_REGISTER;
+ case XED_REG_R8W:
+ *v3_reg = (addr_t)&(info->vm_regs.r8);
+ *reg_len = 2;
+ return GPR_REGISTER;
+ case XED_REG_R8B:
+ *v3_reg = (addr_t)&(info->vm_regs.r8);
+ *reg_len = 1;
+ return GPR_REGISTER;
+
+ case XED_REG_R9:
+ *v3_reg = (addr_t)&(info->vm_regs.r9);
+ *reg_len = 8;
+ return GPR_REGISTER;
+ case XED_REG_R9D:
+ *v3_reg = (addr_t)&(info->vm_regs.r9);
+ *reg_len = 4;
+ return GPR_REGISTER;
+ case XED_REG_R9W:
+ *v3_reg = (addr_t)&(info->vm_regs.r9);
+ *reg_len = 2;
+ return GPR_REGISTER;
+ case XED_REG_R9B:
+ *v3_reg = (addr_t)&(info->vm_regs.r9);
+ *reg_len = 1;
+ return GPR_REGISTER;
+
+ case XED_REG_R10:
+ *v3_reg = (addr_t)&(info->vm_regs.r10);
+ *reg_len = 8;
+ return GPR_REGISTER;
+ case XED_REG_R10D:
+ *v3_reg = (addr_t)&(info->vm_regs.r10);
+ *reg_len = 4;
+ return GPR_REGISTER;
+ case XED_REG_R10W:
+ *v3_reg = (addr_t)&(info->vm_regs.r10);
+ *reg_len = 2;
+ return GPR_REGISTER;
+ case XED_REG_R10B:
+ *v3_reg = (addr_t)&(info->vm_regs.r10);
+ *reg_len = 1;
+ return GPR_REGISTER;
+
+ case XED_REG_R11:
+ *v3_reg = (addr_t)&(info->vm_regs.r11);
+ *reg_len = 8;
+ return GPR_REGISTER;
+ case XED_REG_R11D:
+ *v3_reg = (addr_t)&(info->vm_regs.r11);
+ *reg_len = 4;
+ return GPR_REGISTER;
+ case XED_REG_R11W:
+ *v3_reg = (addr_t)&(info->vm_regs.r11);
+ *reg_len = 2;
+ return GPR_REGISTER;
+ case XED_REG_R11B:
+ *v3_reg = (addr_t)&(info->vm_regs.r11);
+ *reg_len = 1;
+ return GPR_REGISTER;
+
+ case XED_REG_R12:
+ *v3_reg = (addr_t)&(info->vm_regs.r12);
+ *reg_len = 8;
+ return GPR_REGISTER;
+ case XED_REG_R12D:
+ *v3_reg = (addr_t)&(info->vm_regs.r12);
+ *reg_len = 4;
+ return GPR_REGISTER;
+ case XED_REG_R12W:
+ *v3_reg = (addr_t)&(info->vm_regs.r12);
+ *reg_len = 2;
+ return GPR_REGISTER;
+ case XED_REG_R12B:
+ *v3_reg = (addr_t)&(info->vm_regs.r12);
+ *reg_len = 1;
+ return GPR_REGISTER;
+
+ case XED_REG_R13:
+ *v3_reg = (addr_t)&(info->vm_regs.r13);
+ *reg_len = 8;
+ return GPR_REGISTER;
+ case XED_REG_R13D:
+ *v3_reg = (addr_t)&(info->vm_regs.r13);
+ *reg_len = 4;
+ return GPR_REGISTER;
+ case XED_REG_R13W:
+ *v3_reg = (addr_t)&(info->vm_regs.r13);
+ *reg_len = 2;
+ return GPR_REGISTER;
+ case XED_REG_R13B:
+ *v3_reg = (addr_t)&(info->vm_regs.r13);
+ *reg_len = 1;
+ return GPR_REGISTER;
+
+ case XED_REG_R14:
+ *v3_reg = (addr_t)&(info->vm_regs.r14);
+ *reg_len = 8;
+ return GPR_REGISTER;
+ case XED_REG_R14D:
+ *v3_reg = (addr_t)&(info->vm_regs.r14);
+ *reg_len = 4;
+ return GPR_REGISTER;
+ case XED_REG_R14W:
+ *v3_reg = (addr_t)&(info->vm_regs.r14);
+ *reg_len = 2;
+ return GPR_REGISTER;
+ case XED_REG_R14B:
+ *v3_reg = (addr_t)&(info->vm_regs.r14);
+ *reg_len = 1;
+ return GPR_REGISTER;
+
+ case XED_REG_R15:
+ *v3_reg = (addr_t)&(info->vm_regs.r15);
+ *reg_len = 8;
+ return GPR_REGISTER;
+ case XED_REG_R15D:
+ *v3_reg = (addr_t)&(info->vm_regs.r15);
+ *reg_len = 4;
+ return GPR_REGISTER;
+ case XED_REG_R15W:
+ *v3_reg = (addr_t)&(info->vm_regs.r15);
+ *reg_len = 2;
+ return GPR_REGISTER;
+ case XED_REG_R15B:
+ *v3_reg = (addr_t)&(info->vm_regs.r15);
+ *reg_len = 1;
+ return GPR_REGISTER;
+
+
/*
* CTRL REGS
*/
return CTRL_REGISTER;
case XED_REG_CR4:
*v3_reg = (addr_t)&(info->ctrl_regs.cr4);
- *reg_len = 4;
+ *reg_len = 4;
return CTRL_REGISTER;
case XED_REG_CR8:
*v3_reg = (addr_t)&(info->ctrl_regs.cr8);
*/
case XED_REG_CS:
*v3_reg = (addr_t)&(info->segments.cs);
+ *reg_len = 8;
return SEGMENT_REGISTER;
case XED_REG_DS:
*v3_reg = (addr_t)&(info->segments.ds);
+ *reg_len = 8;
return SEGMENT_REGISTER;
case XED_REG_ES:
*v3_reg = (addr_t)&(info->segments.es);
+ *reg_len = 8;
return SEGMENT_REGISTER;
case XED_REG_SS:
*v3_reg = (addr_t)&(info->segments.ss);
+ *reg_len = 8;
return SEGMENT_REGISTER;
case XED_REG_FS:
*v3_reg = (addr_t)&(info->segments.fs);
+ *reg_len = 8;
return SEGMENT_REGISTER;
case XED_REG_GS:
*v3_reg = (addr_t)&(info->segments.gs);
+ *reg_len = 8;
return SEGMENT_REGISTER;
- case XED_REG_R8:
- case XED_REG_R8D:
- case XED_REG_R8W:
- case XED_REG_R8B:
-
- case XED_REG_R9:
- case XED_REG_R9D:
- case XED_REG_R9W:
- case XED_REG_R9B:
-
- case XED_REG_R10:
- case XED_REG_R10D:
- case XED_REG_R10W:
- case XED_REG_R10B:
-
- case XED_REG_R11:
- case XED_REG_R11D:
- case XED_REG_R11W:
- case XED_REG_R11B:
-
- case XED_REG_R12:
- case XED_REG_R12D:
- case XED_REG_R12W:
- case XED_REG_R12B:
-
- case XED_REG_R13:
- case XED_REG_R13D:
- case XED_REG_R13W:
- case XED_REG_R13B:
-
- case XED_REG_R14:
- case XED_REG_R14D:
- case XED_REG_R14W:
- case XED_REG_R14B:
- case XED_REG_R15:
- case XED_REG_R15D:
- case XED_REG_R15W:
- case XED_REG_R15B:
case XED_REG_XMM0:
case XED_REG_XMM1:
-static int get_opcode(xed_iform_enum_t iform, addr_t * opcode) {
+static v3_op_type_t get_opcode(xed_iform_enum_t iform) {
switch (iform) {
+
+ /* Control Instructions */
+
case XED_IFORM_MOV_CR_GPR64_CR:
case XED_IFORM_MOV_CR_GPR32_CR:
- *opcode = (addr_t)&V3_OPCODE_MOVCR2;
- break;
+ return V3_OP_MOVCR2;
case XED_IFORM_MOV_CR_CR_GPR64:
case XED_IFORM_MOV_CR_CR_GPR32:
- *opcode = (addr_t)&V3_OPCODE_MOV2CR;
- break;
+ return V3_OP_MOV2CR;
+ case XED_IFORM_SMSW_GPRv:
+ return V3_OP_SMSW;
case XED_IFORM_LMSW_GPR16:
- *opcode = (addr_t)&V3_OPCODE_LMSW;
- break;
+ return V3_OP_LMSW;
case XED_IFORM_CLTS:
- *opcode = (addr_t)&V3_OPCODE_CLTS;
- break;
+ return V3_OP_CLTS;
+
+ case XED_IFORM_INVLPG_MEMb:
+ return V3_OP_INVLPG;
+
+
+ /* Data Instructions */
+
+ // Write
+ case XED_IFORM_ADC_MEMv_GPRv:
+ case XED_IFORM_ADC_MEMv_IMM:
+ case XED_IFORM_ADC_MEMb_GPR8:
+ case XED_IFORM_ADC_MEMb_IMM:
+ // Read
+ case XED_IFORM_ADC_GPRv_MEMv:
+ case XED_IFORM_ADC_GPR8_MEMb:
+ return V3_OP_ADC;
+
+ // Write
+ case XED_IFORM_ADD_MEMv_GPRv:
+ case XED_IFORM_ADD_MEMb_IMM:
+ case XED_IFORM_ADD_MEMb_GPR8:
+ case XED_IFORM_ADD_MEMv_IMM:
+ // Read
+ case XED_IFORM_ADD_GPRv_MEMv:
+ case XED_IFORM_ADD_GPR8_MEMb:
+ return V3_OP_ADD;
+
+ // Write
+ case XED_IFORM_AND_MEMv_IMM:
+ case XED_IFORM_AND_MEMb_GPR8:
+ case XED_IFORM_AND_MEMv_GPRv:
+ case XED_IFORM_AND_MEMb_IMM:
+ // Read
+ case XED_IFORM_AND_GPR8_MEMb:
+ case XED_IFORM_AND_GPRv_MEMv:
+ return V3_OP_AND;
+
+ // Write
+ case XED_IFORM_SUB_MEMv_IMM:
+ case XED_IFORM_SUB_MEMb_GPR8:
+ case XED_IFORM_SUB_MEMb_IMM:
+ case XED_IFORM_SUB_MEMv_GPRv:
+ // Read
+ case XED_IFORM_SUB_GPR8_MEMb:
+ case XED_IFORM_SUB_GPRv_MEMv:
+ return V3_OP_SUB;
+
+ // Write
+ case XED_IFORM_MOV_MEMv_GPRv:
+ case XED_IFORM_MOV_MEMb_GPR8:
+ case XED_IFORM_MOV_MEMb_AL:
+ case XED_IFORM_MOV_MEMv_IMM:
+ case XED_IFORM_MOV_MEMb_IMM:
+ // Read
+ case XED_IFORM_MOV_GPRv_MEMv:
+ case XED_IFORM_MOV_GPR8_MEMb:
+ case XED_IFORM_MOV_AL_MEMb:
+ return V3_OP_MOV;
+
+
+ // Read
+ case XED_IFORM_MOVZX_GPRv_MEMb:
+ case XED_IFORM_MOVZX_GPRv_MEMw:
+ return V3_OP_MOVZX;
+
+ // Read
+ case XED_IFORM_MOVSX_GPRv_MEMb:
+ case XED_IFORM_MOVSX_GPRv_MEMw:
+ return V3_OP_MOVSX;
+
+
+
+ case XED_IFORM_DEC_MEMv:
+ case XED_IFORM_DEC_MEMb:
+ return V3_OP_DEC;
+
+ case XED_IFORM_INC_MEMb:
+ case XED_IFORM_INC_MEMv:
+ return V3_OP_INC;
+
+ // Write
+ case XED_IFORM_OR_MEMv_IMM:
+ case XED_IFORM_OR_MEMb_IMM:
+ case XED_IFORM_OR_MEMv_GPRv:
+ case XED_IFORM_OR_MEMb_GPR8:
+ // Read
+ case XED_IFORM_OR_GPRv_MEMv:
+ case XED_IFORM_OR_GPR8_MEMb:
+ return V3_OP_OR;
+
+ // Write
+ case XED_IFORM_XOR_MEMv_GPRv:
+ case XED_IFORM_XOR_MEMb_IMM:
+ case XED_IFORM_XOR_MEMb_GPR8:
+ case XED_IFORM_XOR_MEMv_IMM:
+ // Read
+ case XED_IFORM_XOR_GPRv_MEMv:
+ case XED_IFORM_XOR_GPR8_MEMb:
+ return V3_OP_XOR;
+
+ case XED_IFORM_NEG_MEMb:
+ case XED_IFORM_NEG_MEMv:
+ return V3_OP_NEG;
+
+ case XED_IFORM_NOT_MEMv:
+ case XED_IFORM_NOT_MEMb:
+ return V3_OP_NOT;
+
+ case XED_IFORM_XCHG_MEMv_GPRv:
+ case XED_IFORM_XCHG_MEMb_GPR8:
+ return V3_OP_XCHG;
+
+ case XED_IFORM_SETB_MEMb:
+ return V3_OP_SETB;
+
+ case XED_IFORM_SETBE_MEMb:
+ return V3_OP_SETBE;
+
+ case XED_IFORM_SETL_MEMb:
+ return V3_OP_SETL;
+
+ case XED_IFORM_SETLE_MEMb:
+ return V3_OP_SETLE;
+
+ case XED_IFORM_SETNB_MEMb:
+ return V3_OP_SETNB;
+
+ case XED_IFORM_SETNBE_MEMb:
+ return V3_OP_SETNBE;
+
+ case XED_IFORM_SETNL_MEMb:
+ return V3_OP_SETNL;
+
+ case XED_IFORM_SETNLE_MEMb:
+ return V3_OP_SETNLE;
+
+ case XED_IFORM_SETNO_MEMb:
+ return V3_OP_SETNO;
+
+ case XED_IFORM_SETNP_MEMb:
+ return V3_OP_SETNP;
+
+ case XED_IFORM_SETNS_MEMb:
+ return V3_OP_SETNS;
+
+ case XED_IFORM_SETNZ_MEMb:
+ return V3_OP_SETNZ;
+
+ case XED_IFORM_SETO_MEMb:
+ return V3_OP_SETO;
+
+ case XED_IFORM_SETP_MEMb:
+ return V3_OP_SETP;
+
+ case XED_IFORM_SETS_MEMb:
+ return V3_OP_SETS;
+
+ case XED_IFORM_SETZ_MEMb:
+ return V3_OP_SETZ;
+
+ case XED_IFORM_MOVSB:
+ case XED_IFORM_MOVSW:
+ case XED_IFORM_MOVSD:
+ case XED_IFORM_MOVSQ:
+ return V3_OP_MOVS;
+
+ case XED_IFORM_STOSB:
+ case XED_IFORM_STOSW:
+ case XED_IFORM_STOSD:
+ case XED_IFORM_STOSQ:
+ return V3_OP_STOS;
+
default:
- *opcode = 0;
- return -1;
+ return V3_INVALID_OP;
}
-
- return 0;
}