mirror of
https://github.com/Ed94/perfaware.git
synced 2026-09-14 03:39:23 +00:00
1566 lines
35 KiB
C
1566 lines
35 KiB
C
#ifdef INTELLISENSE_DIRECTIVES
|
|
# pragma once
|
|
# include "encoder.h"
|
|
#endif
|
|
|
|
// ============================================================================
|
|
// Encoding Table
|
|
//
|
|
// Part 1 target: the instruction cross-section exercised by Computer Enhance
|
|
// listing 0042. Later Part 1 simulation listings use a subset of this table.
|
|
//
|
|
// Fixed opcode bits are kept in binary/signature form; ModR/M /digit selectors
|
|
// use their encoded enumeration values.
|
|
// ============================================================================
|
|
|
|
RO_ global X8616_Encoding x8616_encodings[] =
|
|
{
|
|
// MOV---------------------------------------------------------------------
|
|
|
|
/* MOV: 100010 d w | mod reg r/m */ {
|
|
.opcode = {
|
|
.bits = x8616_opcode_mov_rm_r << X8616_OPCODE_DW_PREFIX_SHIFT,
|
|
.mask = X8616_OPCODE_DW_PREFIX_MASK,
|
|
},
|
|
.fields = {
|
|
.d = { X8616_OPCODE_DW_D_SHIFT, 1 },
|
|
.w = { X8616_OPCODE_DW_W_SHIFT, 1 },
|
|
},
|
|
.operands = { x8616_operand_rm, x8616_operand_reg_modrm },
|
|
.op = x8616_op_mov,
|
|
},
|
|
|
|
/* MOV imm -> r/m: 1100011 w | mod 000 r/m */ {
|
|
.opcode = {
|
|
.bits = x8616_opcode_mov_rm_i << X8616_OPCODE_W_PREFIX_SHIFT,
|
|
.mask = X8616_OPCODE_W_PREFIX_MASK,
|
|
},
|
|
.mod_rm = {
|
|
.bits = 0b000 << X8616_MODRM_REG_SHIFT,
|
|
.mask = X8616_MODRM_REG_MASK,
|
|
},
|
|
.fields = {
|
|
.w = { X8616_OPCODE_W_W_SHIFT, 1 },
|
|
},
|
|
.operands = { x8616_operand_rm, x8616_operand_imm },
|
|
.op = x8616_op_mov,
|
|
},
|
|
|
|
/* MOV imm -> reg: 1011 w reg */ {
|
|
.opcode = {
|
|
.bits = x8616_opcode_mov_r_i << X8616_OPCODE_WREG_PREFIX_SHIFT,
|
|
.mask = X8616_OPCODE_WREG_PREFIX_MASK,
|
|
},
|
|
.fields = {
|
|
.w = { X8616_OPCODE_WREG_W_SHIFT, 1 },
|
|
.reg = { X8616_OPCODE_WREG_REG_SHIFT, X8616_OPCODE_WREG_REG_WIDTH },
|
|
},
|
|
.operands = { x8616_operand_reg_opcode, x8616_operand_imm },
|
|
.op = x8616_op_mov,
|
|
},
|
|
|
|
/* MOV accumulator <-> direct memory: 101000 d w */ {
|
|
.opcode = {
|
|
.bits = x8616_opcode_mov_acc_mem << X8616_OPCODE_DW_PREFIX_SHIFT,
|
|
.mask = X8616_OPCODE_DW_PREFIX_MASK,
|
|
},
|
|
.fields = {
|
|
.d = { X8616_OPCODE_DW_D_SHIFT, 1 },
|
|
.w = { X8616_OPCODE_DW_W_SHIFT, 1 },
|
|
},
|
|
.operands = { x8616_operand_acc, x8616_operand_mem_direct },
|
|
.op = x8616_op_mov,
|
|
},
|
|
|
|
/* MOV segment <-> r/m: 100011 d 0 | mod 0 sr r/m */ {
|
|
.opcode = {
|
|
.bits = x8616_opcode_mov_seg_rm << X8616_OPCODE_D0_PREFIX_SHIFT,
|
|
.mask = X8616_OPCODE_D0_PREFIX_MASK,
|
|
},
|
|
.mod_rm = {
|
|
.bits = 0,
|
|
.mask = X8616_MODRM_SEG_FIXED_MASK,
|
|
},
|
|
.fields = {
|
|
.d = { X8616_OPCODE_D0_D_SHIFT, 1 },
|
|
},
|
|
.operands = { x8616_operand_rm, x8616_operand_segment_modrm },
|
|
.width = x8616_width_word,
|
|
.op = x8616_op_mov,
|
|
},
|
|
|
|
// Stack / exchange--------------------------------------------------------
|
|
|
|
/* PUSH r/m16: 11111111 | mod 110 r/m */ {
|
|
.opcode = {
|
|
.bits = x8616_opcode_group_ff,
|
|
.mask = X8616_OPCODE_MASK,
|
|
},
|
|
.mod_rm = {
|
|
.bits = x8616_ff_push << X8616_MODRM_REG_SHIFT,
|
|
.mask = X8616_MODRM_REG_MASK,
|
|
},
|
|
.operands = { x8616_operand_rm },
|
|
.width = x8616_width_word,
|
|
.op = x8616_op_push,
|
|
},
|
|
|
|
/* PUSH reg16: 01010 reg */ {
|
|
.opcode = {
|
|
.bits = x8616_opcode_push_reg << X8616_OPCODE_REG_PREFIX_SHIFT,
|
|
.mask = X8616_OPCODE_REG_PREFIX_MASK,
|
|
},
|
|
.fields = {
|
|
.reg = { X8616_OPCODE_REG_REG_SHIFT, X8616_OPCODE_REG_REG_WIDTH },
|
|
},
|
|
.operands = { x8616_operand_reg_opcode },
|
|
.width = x8616_width_word,
|
|
.op = x8616_op_push,
|
|
},
|
|
|
|
/* PUSH segment: 000 sr 110 */ {
|
|
.opcode = {
|
|
.bits = X8616_OPCODE_PUSH_SR_FIXED,
|
|
.mask = X8616_OPCODE_SR_PATTERN_MASK,
|
|
},
|
|
.fields = {
|
|
.sr = { X8616_OPCODE_SR_SHIFT, X8616_OPCODE_SR_WIDTH },
|
|
},
|
|
.operands = { x8616_operand_segment_opcode },
|
|
.width = x8616_width_word,
|
|
.op = x8616_op_push,
|
|
},
|
|
|
|
/* POP r/m16: 10001111 | mod 000 r/m */ {
|
|
.opcode = {
|
|
.bits = x8616_opcode_pop_rm,
|
|
.mask = X8616_OPCODE_MASK,
|
|
},
|
|
.mod_rm = {
|
|
.bits = 0b000 << X8616_MODRM_REG_SHIFT,
|
|
.mask = X8616_MODRM_REG_MASK,
|
|
},
|
|
.operands = { x8616_operand_rm },
|
|
.width = x8616_width_word,
|
|
.op = x8616_op_pop,
|
|
},
|
|
|
|
/* POP reg16: 01011 reg */ {
|
|
.opcode = {
|
|
.bits = x8616_opcode_pop_reg << X8616_OPCODE_REG_PREFIX_SHIFT,
|
|
.mask = X8616_OPCODE_REG_PREFIX_MASK,
|
|
},
|
|
.fields = {
|
|
.reg = { X8616_OPCODE_REG_REG_SHIFT, X8616_OPCODE_REG_REG_WIDTH },
|
|
},
|
|
.operands = { x8616_operand_reg_opcode },
|
|
.width = x8616_width_word,
|
|
.op = x8616_op_pop,
|
|
},
|
|
|
|
/* POP segment: 000 sr 111 */ {
|
|
.opcode = {
|
|
.bits = X8616_OPCODE_POP_SR_FIXED,
|
|
.mask = X8616_OPCODE_SR_PATTERN_MASK,
|
|
},
|
|
.fields = {
|
|
.sr = { X8616_OPCODE_SR_SHIFT, X8616_OPCODE_SR_WIDTH },
|
|
},
|
|
.operands = { x8616_operand_segment_opcode },
|
|
.width = x8616_width_word,
|
|
.op = x8616_op_pop,
|
|
},
|
|
|
|
/* XCHG r/m,reg: 1000011 w | mod reg r/m */ {
|
|
.opcode = {
|
|
.bits = x8616_opcode_xchg_rm_r << X8616_OPCODE_W_PREFIX_SHIFT,
|
|
.mask = X8616_OPCODE_W_PREFIX_MASK,
|
|
},
|
|
.fields = {
|
|
.w = { X8616_OPCODE_W_W_SHIFT, 1 },
|
|
},
|
|
.operands = { x8616_operand_reg_modrm, x8616_operand_rm },
|
|
.op = x8616_op_xchg,
|
|
},
|
|
|
|
/* XCHG AX,reg16: 10010 reg (also encodes NOP at reg=AX) */ {
|
|
.opcode = {
|
|
.bits = x8616_opcode_xchg_ax_reg << X8616_OPCODE_REG_PREFIX_SHIFT,
|
|
.mask = X8616_OPCODE_REG_PREFIX_MASK,
|
|
},
|
|
.fields = {
|
|
.reg = { X8616_OPCODE_REG_REG_SHIFT, X8616_OPCODE_REG_REG_WIDTH },
|
|
},
|
|
.operands = { x8616_operand_acc, x8616_operand_reg_opcode },
|
|
.width = x8616_width_word,
|
|
.op = x8616_op_xchg,
|
|
},
|
|
|
|
// I/O / address / flags---------------------------------------------------
|
|
|
|
/* IN acc,imm8: 1110010 w */ {
|
|
.opcode = {
|
|
.bits = x8616_opcode_in_i << X8616_OPCODE_W_PREFIX_SHIFT,
|
|
.mask = X8616_OPCODE_W_PREFIX_MASK,
|
|
},
|
|
.fields = {
|
|
.w = { X8616_OPCODE_W_W_SHIFT, 1 },
|
|
},
|
|
.operands = { x8616_operand_acc, x8616_operand_imm8 },
|
|
.op = x8616_op_in,
|
|
},
|
|
|
|
/* IN acc,DX: 1110110 w */ {
|
|
.opcode = {
|
|
.bits = x8616_opcode_in_dx << X8616_OPCODE_W_PREFIX_SHIFT,
|
|
.mask = X8616_OPCODE_W_PREFIX_MASK,
|
|
},
|
|
.fields = {
|
|
.w = { X8616_OPCODE_W_W_SHIFT, 1 },
|
|
},
|
|
.operands = { x8616_operand_acc, x8616_operand_dx },
|
|
.op = x8616_op_in,
|
|
},
|
|
|
|
/* OUT imm8,acc: 1110011 w */ {
|
|
.opcode = {
|
|
.bits = x8616_opcode_out_i << X8616_OPCODE_W_PREFIX_SHIFT,
|
|
.mask = X8616_OPCODE_W_PREFIX_MASK,
|
|
},
|
|
.fields = {
|
|
.w = { X8616_OPCODE_W_W_SHIFT, 1 },
|
|
},
|
|
.operands = { x8616_operand_imm8, x8616_operand_acc },
|
|
.op = x8616_op_out,
|
|
},
|
|
|
|
/* OUT DX,acc: 1110111 w */ {
|
|
.opcode = {
|
|
.bits = x8616_opcode_out_dx << X8616_OPCODE_W_PREFIX_SHIFT,
|
|
.mask = X8616_OPCODE_W_PREFIX_MASK,
|
|
},
|
|
.fields = {
|
|
.w = { X8616_OPCODE_W_W_SHIFT, 1 },
|
|
},
|
|
.operands = { x8616_operand_dx, x8616_operand_acc },
|
|
.op = x8616_op_out,
|
|
},
|
|
|
|
/* XLAT */ {
|
|
.opcode = {
|
|
.bits = x8616_opcode_xlat,
|
|
.mask = X8616_OPCODE_MASK,
|
|
},
|
|
.op = x8616_op_xlat,
|
|
},
|
|
|
|
/* LEA: mod reg r/m */ {
|
|
.opcode = {
|
|
.bits = x8616_opcode_lea,
|
|
.mask = X8616_OPCODE_MASK,
|
|
},
|
|
.operands = { x8616_operand_reg_modrm, x8616_operand_rm },
|
|
.width = x8616_width_word,
|
|
.op = x8616_op_lea,
|
|
},
|
|
|
|
/* LDS: mod reg r/m */ {
|
|
.opcode = {
|
|
.bits = x8616_opcode_lds,
|
|
.mask = X8616_OPCODE_MASK,
|
|
},
|
|
.operands = { x8616_operand_reg_modrm, x8616_operand_rm },
|
|
.width = x8616_width_word,
|
|
.op = x8616_op_lds,
|
|
},
|
|
|
|
/* LES: mod reg r/m */ {
|
|
.opcode = {
|
|
.bits = x8616_opcode_les,
|
|
.mask = X8616_OPCODE_MASK,
|
|
},
|
|
.operands = { x8616_operand_reg_modrm, x8616_operand_rm },
|
|
.width = x8616_width_word,
|
|
.op = x8616_op_les,
|
|
},
|
|
|
|
/* LAHF */ {
|
|
.opcode = {
|
|
.bits = x8616_opcode_lahf,
|
|
.mask = X8616_OPCODE_MASK,
|
|
},
|
|
.op = x8616_op_lahf,
|
|
},
|
|
|
|
/* SAHF */ {
|
|
.opcode = {
|
|
.bits = x8616_opcode_sahf,
|
|
.mask = X8616_OPCODE_MASK,
|
|
},
|
|
.op = x8616_op_sahf,
|
|
},
|
|
|
|
/* PUSHF */ {
|
|
.opcode = {
|
|
.bits = x8616_opcode_pushf,
|
|
.mask = X8616_OPCODE_MASK,
|
|
},
|
|
.op = x8616_op_pushf,
|
|
},
|
|
|
|
/* POPF */ {
|
|
.opcode = {
|
|
.bits = x8616_opcode_popf,
|
|
.mask = X8616_OPCODE_MASK,
|
|
},
|
|
.op = x8616_op_popf,
|
|
},
|
|
|
|
// Arithmetic / logical----------------------------------------------------
|
|
|
|
/* ADD r/m,reg: 000000 d w */ {
|
|
.opcode = {
|
|
.bits = 0b000000 << X8616_OPCODE_DW_PREFIX_SHIFT,
|
|
.mask = X8616_OPCODE_DW_PREFIX_MASK,
|
|
},
|
|
.fields = {
|
|
.d = { X8616_OPCODE_DW_D_SHIFT, 1 },
|
|
.w = { X8616_OPCODE_DW_W_SHIFT, 1 },
|
|
},
|
|
.operands = { x8616_operand_rm, x8616_operand_reg_modrm },
|
|
.op = x8616_op_add,
|
|
},
|
|
|
|
/* ADD imm,r/m: 100000 s w /0 */ {
|
|
.opcode = {
|
|
.bits = x8616_opcode_alu_rm_i << X8616_OPCODE_SW_PREFIX_SHIFT,
|
|
.mask = X8616_OPCODE_SW_PREFIX_MASK,
|
|
},
|
|
.mod_rm = {
|
|
.bits = x8616_add << X8616_MODRM_REG_SHIFT,
|
|
.mask = X8616_MODRM_REG_MASK,
|
|
},
|
|
.fields = {
|
|
.s = { X8616_OPCODE_SW_S_SHIFT, 1 },
|
|
.w = { X8616_OPCODE_SW_W_SHIFT, 1 },
|
|
},
|
|
.operands = { x8616_operand_rm, x8616_operand_imm },
|
|
.op = x8616_op_add,
|
|
},
|
|
|
|
/* ADD accumulator,imm: 0000010 w */ {
|
|
.opcode = {
|
|
.bits = 0b0000010 << X8616_OPCODE_W_PREFIX_SHIFT,
|
|
.mask = X8616_OPCODE_W_PREFIX_MASK,
|
|
},
|
|
.fields = {
|
|
.w = { X8616_OPCODE_W_W_SHIFT, 1 },
|
|
},
|
|
.operands = { x8616_operand_acc, x8616_operand_imm },
|
|
.op = x8616_op_add,
|
|
},
|
|
|
|
/* OR r/m,reg: 000010 d w */ {
|
|
.opcode = {
|
|
.bits = 0b000010 << X8616_OPCODE_DW_PREFIX_SHIFT,
|
|
.mask = X8616_OPCODE_DW_PREFIX_MASK,
|
|
},
|
|
.fields = {
|
|
.d = { X8616_OPCODE_DW_D_SHIFT, 1 },
|
|
.w = { X8616_OPCODE_DW_W_SHIFT, 1 },
|
|
},
|
|
.operands = { x8616_operand_rm, x8616_operand_reg_modrm },
|
|
.op = x8616_op_or,
|
|
},
|
|
|
|
/* OR imm,r/m: 1000000 w /1 */ {
|
|
.opcode = {
|
|
.bits = x8616_opcode_logic_rm_i << X8616_OPCODE_W_PREFIX_SHIFT,
|
|
.mask = X8616_OPCODE_W_PREFIX_MASK,
|
|
},
|
|
.mod_rm = {
|
|
.bits = x8616_or << X8616_MODRM_REG_SHIFT,
|
|
.mask = X8616_MODRM_REG_MASK,
|
|
},
|
|
.fields = {
|
|
.w = { X8616_OPCODE_W_W_SHIFT, 1 },
|
|
},
|
|
.operands = { x8616_operand_rm, x8616_operand_imm },
|
|
.op = x8616_op_or,
|
|
},
|
|
|
|
/* OR accumulator,imm: 0000110 w */ {
|
|
.opcode = {
|
|
.bits = 0b0000110 << X8616_OPCODE_W_PREFIX_SHIFT,
|
|
.mask = X8616_OPCODE_W_PREFIX_MASK,
|
|
},
|
|
.fields = {
|
|
.w = { X8616_OPCODE_W_W_SHIFT, 1 },
|
|
},
|
|
.operands = { x8616_operand_acc, x8616_operand_imm },
|
|
.op = x8616_op_or,
|
|
},
|
|
|
|
/* ADC r/m,reg: 000100 d w */ {
|
|
.opcode = {
|
|
.bits = 0b000100 << X8616_OPCODE_DW_PREFIX_SHIFT,
|
|
.mask = X8616_OPCODE_DW_PREFIX_MASK,
|
|
},
|
|
.fields = {
|
|
.d = { X8616_OPCODE_DW_D_SHIFT, 1 },
|
|
.w = { X8616_OPCODE_DW_W_SHIFT, 1 },
|
|
},
|
|
.operands = { x8616_operand_rm, x8616_operand_reg_modrm },
|
|
.op = x8616_op_adc,
|
|
},
|
|
|
|
/* ADC imm,r/m: 100000 s w /2 */ {
|
|
.opcode = {
|
|
.bits = x8616_opcode_alu_rm_i << X8616_OPCODE_SW_PREFIX_SHIFT,
|
|
.mask = X8616_OPCODE_SW_PREFIX_MASK,
|
|
},
|
|
.mod_rm = {
|
|
.bits = x8616_adc << X8616_MODRM_REG_SHIFT,
|
|
.mask = X8616_MODRM_REG_MASK,
|
|
},
|
|
.fields = {
|
|
.s = { X8616_OPCODE_SW_S_SHIFT, 1 },
|
|
.w = { X8616_OPCODE_SW_W_SHIFT, 1 },
|
|
},
|
|
.operands = { x8616_operand_rm, x8616_operand_imm },
|
|
.op = x8616_op_adc,
|
|
},
|
|
|
|
/* ADC accumulator,imm: 0001010 w */ {
|
|
.opcode = {
|
|
.bits = 0b0001010 << X8616_OPCODE_W_PREFIX_SHIFT,
|
|
.mask = X8616_OPCODE_W_PREFIX_MASK,
|
|
},
|
|
.fields = {
|
|
.w = { X8616_OPCODE_W_W_SHIFT, 1 },
|
|
},
|
|
.operands = { x8616_operand_acc, x8616_operand_imm },
|
|
.op = x8616_op_adc,
|
|
},
|
|
|
|
/* SBB r/m,reg: 000110 d w */ {
|
|
.opcode = {
|
|
.bits = 0b000110 << X8616_OPCODE_DW_PREFIX_SHIFT,
|
|
.mask = X8616_OPCODE_DW_PREFIX_MASK,
|
|
},
|
|
.fields = {
|
|
.d = { X8616_OPCODE_DW_D_SHIFT, 1 },
|
|
.w = { X8616_OPCODE_DW_W_SHIFT, 1 },
|
|
},
|
|
.operands = { x8616_operand_rm, x8616_operand_reg_modrm },
|
|
.op = x8616_op_sbb,
|
|
},
|
|
|
|
/* SBB imm,r/m: 100000 s w /3 */ {
|
|
.opcode = {
|
|
.bits = x8616_opcode_alu_rm_i << X8616_OPCODE_SW_PREFIX_SHIFT,
|
|
.mask = X8616_OPCODE_SW_PREFIX_MASK,
|
|
},
|
|
.mod_rm = {
|
|
.bits = x8616_sbb << X8616_MODRM_REG_SHIFT,
|
|
.mask = X8616_MODRM_REG_MASK,
|
|
},
|
|
.fields = {
|
|
.s = { X8616_OPCODE_SW_S_SHIFT, 1 },
|
|
.w = { X8616_OPCODE_SW_W_SHIFT, 1 },
|
|
},
|
|
.operands = { x8616_operand_rm, x8616_operand_imm },
|
|
.op = x8616_op_sbb,
|
|
},
|
|
|
|
/* SBB accumulator,imm: 0001110 w */ {
|
|
.opcode = {
|
|
.bits = 0b0001110 << X8616_OPCODE_W_PREFIX_SHIFT,
|
|
.mask = X8616_OPCODE_W_PREFIX_MASK,
|
|
},
|
|
.fields = {
|
|
.w = { X8616_OPCODE_W_W_SHIFT, 1 },
|
|
},
|
|
.operands = { x8616_operand_acc, x8616_operand_imm },
|
|
.op = x8616_op_sbb,
|
|
},
|
|
|
|
/* AND r/m,reg: 001000 d w */ {
|
|
.opcode = {
|
|
.bits = 0b001000 << X8616_OPCODE_DW_PREFIX_SHIFT,
|
|
.mask = X8616_OPCODE_DW_PREFIX_MASK,
|
|
},
|
|
.fields = {
|
|
.d = { X8616_OPCODE_DW_D_SHIFT, 1 },
|
|
.w = { X8616_OPCODE_DW_W_SHIFT, 1 },
|
|
},
|
|
.operands = { x8616_operand_rm, x8616_operand_reg_modrm },
|
|
.op = x8616_op_and,
|
|
},
|
|
|
|
/* AND imm,r/m: 1000000 w /4 */ {
|
|
.opcode = {
|
|
.bits = x8616_opcode_logic_rm_i << X8616_OPCODE_W_PREFIX_SHIFT,
|
|
.mask = X8616_OPCODE_W_PREFIX_MASK,
|
|
},
|
|
.mod_rm = {
|
|
.bits = x8616_and << X8616_MODRM_REG_SHIFT,
|
|
.mask = X8616_MODRM_REG_MASK,
|
|
},
|
|
.fields = {
|
|
.w = { X8616_OPCODE_W_W_SHIFT, 1 },
|
|
},
|
|
.operands = { x8616_operand_rm, x8616_operand_imm },
|
|
.op = x8616_op_and,
|
|
},
|
|
|
|
/* AND accumulator,imm: 0010010 w */ {
|
|
.opcode = {
|
|
.bits = 0b0010010 << X8616_OPCODE_W_PREFIX_SHIFT,
|
|
.mask = X8616_OPCODE_W_PREFIX_MASK,
|
|
},
|
|
.fields = {
|
|
.w = { X8616_OPCODE_W_W_SHIFT, 1 },
|
|
},
|
|
.operands = { x8616_operand_acc, x8616_operand_imm },
|
|
.op = x8616_op_and,
|
|
},
|
|
|
|
/* SUB r/m,reg: 001010 d w */ {
|
|
.opcode = {
|
|
.bits = 0b001010 << X8616_OPCODE_DW_PREFIX_SHIFT,
|
|
.mask = X8616_OPCODE_DW_PREFIX_MASK,
|
|
},
|
|
.fields = {
|
|
.d = { X8616_OPCODE_DW_D_SHIFT, 1 },
|
|
.w = { X8616_OPCODE_DW_W_SHIFT, 1 },
|
|
},
|
|
.operands = { x8616_operand_rm, x8616_operand_reg_modrm },
|
|
.op = x8616_op_sub,
|
|
},
|
|
|
|
/* SUB imm,r/m: 100000 s w /5 */ {
|
|
.opcode = {
|
|
.bits = x8616_opcode_alu_rm_i << X8616_OPCODE_SW_PREFIX_SHIFT,
|
|
.mask = X8616_OPCODE_SW_PREFIX_MASK,
|
|
},
|
|
.mod_rm = {
|
|
.bits = x8616_sub << X8616_MODRM_REG_SHIFT,
|
|
.mask = X8616_MODRM_REG_MASK,
|
|
},
|
|
.fields = {
|
|
.s = { X8616_OPCODE_SW_S_SHIFT, 1 },
|
|
.w = { X8616_OPCODE_SW_W_SHIFT, 1 },
|
|
},
|
|
.operands = { x8616_operand_rm, x8616_operand_imm },
|
|
.op = x8616_op_sub,
|
|
},
|
|
|
|
/* SUB accumulator,imm: 0010110 w */ {
|
|
.opcode = {
|
|
.bits = 0b0010110 << X8616_OPCODE_W_PREFIX_SHIFT,
|
|
.mask = X8616_OPCODE_W_PREFIX_MASK,
|
|
},
|
|
.fields = {
|
|
.w = { X8616_OPCODE_W_W_SHIFT, 1 },
|
|
},
|
|
.operands = { x8616_operand_acc, x8616_operand_imm },
|
|
.op = x8616_op_sub,
|
|
},
|
|
|
|
/* XOR r/m,reg: 001100 d w */ {
|
|
.opcode = {
|
|
.bits = 0b001100 << X8616_OPCODE_DW_PREFIX_SHIFT,
|
|
.mask = X8616_OPCODE_DW_PREFIX_MASK,
|
|
},
|
|
.fields = {
|
|
.d = { X8616_OPCODE_DW_D_SHIFT, 1 },
|
|
.w = { X8616_OPCODE_DW_W_SHIFT, 1 },
|
|
},
|
|
.operands = { x8616_operand_rm, x8616_operand_reg_modrm },
|
|
.op = x8616_op_xor,
|
|
},
|
|
|
|
/* XOR imm,r/m: 1000000 w /6 */ {
|
|
.opcode = {
|
|
.bits = x8616_opcode_logic_rm_i << X8616_OPCODE_W_PREFIX_SHIFT,
|
|
.mask = X8616_OPCODE_W_PREFIX_MASK,
|
|
},
|
|
.mod_rm = {
|
|
.bits = x8616_xor << X8616_MODRM_REG_SHIFT,
|
|
.mask = X8616_MODRM_REG_MASK,
|
|
},
|
|
.fields = {
|
|
.w = { X8616_OPCODE_W_W_SHIFT, 1 },
|
|
},
|
|
.operands = { x8616_operand_rm, x8616_operand_imm },
|
|
.op = x8616_op_xor,
|
|
},
|
|
|
|
/* XOR accumulator,imm: 0011010 w */ {
|
|
.opcode = {
|
|
.bits = 0b0011010 << X8616_OPCODE_W_PREFIX_SHIFT,
|
|
.mask = X8616_OPCODE_W_PREFIX_MASK,
|
|
},
|
|
.fields = {
|
|
.w = { X8616_OPCODE_W_W_SHIFT, 1 },
|
|
},
|
|
.operands = { x8616_operand_acc, x8616_operand_imm },
|
|
.op = x8616_op_xor,
|
|
},
|
|
|
|
/* CMP r/m,reg: 001110 d w */ {
|
|
.opcode = {
|
|
.bits = 0b001110 << X8616_OPCODE_DW_PREFIX_SHIFT,
|
|
.mask = X8616_OPCODE_DW_PREFIX_MASK,
|
|
},
|
|
.fields = {
|
|
.d = { X8616_OPCODE_DW_D_SHIFT, 1 },
|
|
.w = { X8616_OPCODE_DW_W_SHIFT, 1 },
|
|
},
|
|
.operands = { x8616_operand_rm, x8616_operand_reg_modrm },
|
|
.op = x8616_op_cmp,
|
|
},
|
|
|
|
/* CMP imm,r/m: 100000 s w /7 */ {
|
|
.opcode = {
|
|
.bits = x8616_opcode_alu_rm_i << X8616_OPCODE_SW_PREFIX_SHIFT,
|
|
.mask = X8616_OPCODE_SW_PREFIX_MASK,
|
|
},
|
|
.mod_rm = {
|
|
.bits = x8616_cmp << X8616_MODRM_REG_SHIFT,
|
|
.mask = X8616_MODRM_REG_MASK,
|
|
},
|
|
.fields = {
|
|
.s = { X8616_OPCODE_SW_S_SHIFT, 1 },
|
|
.w = { X8616_OPCODE_SW_W_SHIFT, 1 },
|
|
},
|
|
.operands = { x8616_operand_rm, x8616_operand_imm },
|
|
.op = x8616_op_cmp,
|
|
},
|
|
|
|
/* CMP accumulator,imm: 0011110 w */ {
|
|
.opcode = {
|
|
.bits = 0b0011110 << X8616_OPCODE_W_PREFIX_SHIFT,
|
|
.mask = X8616_OPCODE_W_PREFIX_MASK,
|
|
},
|
|
.fields = {
|
|
.w = { X8616_OPCODE_W_W_SHIFT, 1 },
|
|
},
|
|
.operands = { x8616_operand_acc, x8616_operand_imm },
|
|
.op = x8616_op_cmp,
|
|
},
|
|
|
|
// INC / DEC / unary / adjust---------------------------------------------
|
|
|
|
/* INC r/m: 1111111 w /0 */ {
|
|
.opcode = {
|
|
.bits = x8616_opcode_incdec_rm << X8616_OPCODE_W_PREFIX_SHIFT,
|
|
.mask = X8616_OPCODE_W_PREFIX_MASK,
|
|
},
|
|
.mod_rm = {
|
|
.bits = x8616_inc << X8616_MODRM_REG_SHIFT,
|
|
.mask = X8616_MODRM_REG_MASK,
|
|
},
|
|
.fields = {
|
|
.w = { X8616_OPCODE_W_W_SHIFT, 1 },
|
|
},
|
|
.operands = { x8616_operand_rm },
|
|
.op = x8616_op_inc,
|
|
},
|
|
|
|
/* INC reg16: 01000 reg */ {
|
|
.opcode = {
|
|
.bits = x8616_opcode_inc_reg << X8616_OPCODE_REG_PREFIX_SHIFT,
|
|
.mask = X8616_OPCODE_REG_PREFIX_MASK,
|
|
},
|
|
.fields = {
|
|
.reg = { X8616_OPCODE_REG_REG_SHIFT, X8616_OPCODE_REG_REG_WIDTH },
|
|
},
|
|
.operands = { x8616_operand_reg_opcode },
|
|
.width = x8616_width_word,
|
|
.op = x8616_op_inc,
|
|
},
|
|
|
|
/* AAA */ {
|
|
.opcode = {
|
|
.bits = x8616_opcode_aaa,
|
|
.mask = X8616_OPCODE_MASK,
|
|
},
|
|
.op = x8616_op_aaa,
|
|
},
|
|
|
|
/* DAA */ {
|
|
.opcode = {
|
|
.bits = x8616_opcode_daa,
|
|
.mask = X8616_OPCODE_MASK,
|
|
},
|
|
.op = x8616_op_daa,
|
|
},
|
|
|
|
/* DEC r/m: 1111111 w /1 */ {
|
|
.opcode = {
|
|
.bits = x8616_opcode_incdec_rm << X8616_OPCODE_W_PREFIX_SHIFT,
|
|
.mask = X8616_OPCODE_W_PREFIX_MASK,
|
|
},
|
|
.mod_rm = {
|
|
.bits = x8616_dec << X8616_MODRM_REG_SHIFT,
|
|
.mask = X8616_MODRM_REG_MASK,
|
|
},
|
|
.fields = {
|
|
.w = { X8616_OPCODE_W_W_SHIFT, 1 },
|
|
},
|
|
.operands = { x8616_operand_rm },
|
|
.op = x8616_op_dec,
|
|
},
|
|
|
|
/* DEC reg16: 01001 reg */ {
|
|
.opcode = {
|
|
.bits = x8616_opcode_dec_reg << X8616_OPCODE_REG_PREFIX_SHIFT,
|
|
.mask = X8616_OPCODE_REG_PREFIX_MASK,
|
|
},
|
|
.fields = {
|
|
.reg = { X8616_OPCODE_REG_REG_SHIFT, X8616_OPCODE_REG_REG_WIDTH },
|
|
},
|
|
.operands = { x8616_operand_reg_opcode },
|
|
.width = x8616_width_word,
|
|
.op = x8616_op_dec,
|
|
},
|
|
|
|
/* NEG r/m: 1111011 w /neg */ {
|
|
.opcode = {
|
|
.bits = x8616_opcode_group3 << X8616_OPCODE_W_PREFIX_SHIFT,
|
|
.mask = X8616_OPCODE_W_PREFIX_MASK,
|
|
},
|
|
.mod_rm = {
|
|
.bits = x8616_g3_neg << X8616_MODRM_REG_SHIFT,
|
|
.mask = X8616_MODRM_REG_MASK,
|
|
},
|
|
.fields = {
|
|
.w = { X8616_OPCODE_W_W_SHIFT, 1 },
|
|
},
|
|
.operands = { x8616_operand_rm },
|
|
.op = x8616_op_neg,
|
|
},
|
|
|
|
/* MUL r/m: 1111011 w /mul */ {
|
|
.opcode = {
|
|
.bits = x8616_opcode_group3 << X8616_OPCODE_W_PREFIX_SHIFT,
|
|
.mask = X8616_OPCODE_W_PREFIX_MASK,
|
|
},
|
|
.mod_rm = {
|
|
.bits = x8616_g3_mul << X8616_MODRM_REG_SHIFT,
|
|
.mask = X8616_MODRM_REG_MASK,
|
|
},
|
|
.fields = {
|
|
.w = { X8616_OPCODE_W_W_SHIFT, 1 },
|
|
},
|
|
.operands = { x8616_operand_rm },
|
|
.op = x8616_op_mul,
|
|
},
|
|
|
|
/* IMUL r/m: 1111011 w /imul */ {
|
|
.opcode = {
|
|
.bits = x8616_opcode_group3 << X8616_OPCODE_W_PREFIX_SHIFT,
|
|
.mask = X8616_OPCODE_W_PREFIX_MASK,
|
|
},
|
|
.mod_rm = {
|
|
.bits = x8616_g3_imul << X8616_MODRM_REG_SHIFT,
|
|
.mask = X8616_MODRM_REG_MASK,
|
|
},
|
|
.fields = {
|
|
.w = { X8616_OPCODE_W_W_SHIFT, 1 },
|
|
},
|
|
.operands = { x8616_operand_rm },
|
|
.op = x8616_op_imul,
|
|
},
|
|
|
|
/* DIV r/m: 1111011 w /div */ {
|
|
.opcode = {
|
|
.bits = x8616_opcode_group3 << X8616_OPCODE_W_PREFIX_SHIFT,
|
|
.mask = X8616_OPCODE_W_PREFIX_MASK,
|
|
},
|
|
.mod_rm = {
|
|
.bits = x8616_g3_div << X8616_MODRM_REG_SHIFT,
|
|
.mask = X8616_MODRM_REG_MASK,
|
|
},
|
|
.fields = {
|
|
.w = { X8616_OPCODE_W_W_SHIFT, 1 },
|
|
},
|
|
.operands = { x8616_operand_rm },
|
|
.op = x8616_op_div,
|
|
},
|
|
|
|
/* IDIV r/m: 1111011 w /idiv */ {
|
|
.opcode = {
|
|
.bits = x8616_opcode_group3 << X8616_OPCODE_W_PREFIX_SHIFT,
|
|
.mask = X8616_OPCODE_W_PREFIX_MASK,
|
|
},
|
|
.mod_rm = {
|
|
.bits = x8616_g3_idiv << X8616_MODRM_REG_SHIFT,
|
|
.mask = X8616_MODRM_REG_MASK,
|
|
},
|
|
.fields = {
|
|
.w = { X8616_OPCODE_W_W_SHIFT, 1 },
|
|
},
|
|
.operands = { x8616_operand_rm },
|
|
.op = x8616_op_idiv,
|
|
},
|
|
|
|
/* NOT r/m: 1111011 w /not */ {
|
|
.opcode = {
|
|
.bits = x8616_opcode_group3 << X8616_OPCODE_W_PREFIX_SHIFT,
|
|
.mask = X8616_OPCODE_W_PREFIX_MASK,
|
|
},
|
|
.mod_rm = {
|
|
.bits = x8616_g3_not << X8616_MODRM_REG_SHIFT,
|
|
.mask = X8616_MODRM_REG_MASK,
|
|
},
|
|
.fields = {
|
|
.w = { X8616_OPCODE_W_W_SHIFT, 1 },
|
|
},
|
|
.operands = { x8616_operand_rm },
|
|
.op = x8616_op_not,
|
|
},
|
|
|
|
/* AAS */ {
|
|
.opcode = {
|
|
.bits = x8616_opcode_aas,
|
|
.mask = X8616_OPCODE_MASK,
|
|
},
|
|
.op = x8616_op_aas,
|
|
},
|
|
|
|
/* DAS */ {
|
|
.opcode = {
|
|
.bits = x8616_opcode_das,
|
|
.mask = X8616_OPCODE_MASK,
|
|
},
|
|
.op = x8616_op_das,
|
|
},
|
|
|
|
/* AAM: 11010100 00001010 */ {
|
|
.opcode = {
|
|
.bits = x8616_opcode_aam,
|
|
.mask = X8616_OPCODE_MASK,
|
|
},
|
|
.post_opcode = {
|
|
.bits = X8616_POST_OPCODE_AAM_AAD,
|
|
.mask = X8616_OPCODE_MASK,
|
|
},
|
|
.op = x8616_op_aam,
|
|
},
|
|
|
|
/* AAD: 11010101 00001010 */ {
|
|
.opcode = {
|
|
.bits = x8616_opcode_aad,
|
|
.mask = X8616_OPCODE_MASK,
|
|
},
|
|
.post_opcode = {
|
|
.bits = X8616_POST_OPCODE_AAM_AAD,
|
|
.mask = X8616_OPCODE_MASK,
|
|
},
|
|
.op = x8616_op_aad,
|
|
},
|
|
|
|
/* CBW */ {
|
|
.opcode = {
|
|
.bits = x8616_opcode_cbw,
|
|
.mask = X8616_OPCODE_MASK,
|
|
},
|
|
.op = x8616_op_cbw,
|
|
},
|
|
|
|
/* CWD */ {
|
|
.opcode = {
|
|
.bits = x8616_opcode_cwd,
|
|
.mask = X8616_OPCODE_MASK,
|
|
},
|
|
.op = x8616_op_cwd,
|
|
},
|
|
|
|
// Shift / rotate / TEST---------------------------------------------------
|
|
|
|
/* ROL r/m,1|CL: 110100 v w */ {
|
|
.opcode = {
|
|
.bits = x8616_opcode_shift_rm << X8616_OPCODE_VW_PREFIX_SHIFT,
|
|
.mask = X8616_OPCODE_VW_PREFIX_MASK,
|
|
},
|
|
.mod_rm = {
|
|
.bits = x8616_rol << X8616_MODRM_REG_SHIFT,
|
|
.mask = X8616_MODRM_REG_MASK,
|
|
},
|
|
.fields = {
|
|
.v = { X8616_OPCODE_VW_V_SHIFT, 1 },
|
|
.w = { X8616_OPCODE_VW_W_SHIFT, 1 },
|
|
},
|
|
.operands = { x8616_operand_rm, x8616_operand_shift_count },
|
|
.op = x8616_op_rol,
|
|
},
|
|
|
|
/* ROR r/m,1|CL: 110100 v w */ {
|
|
.opcode = {
|
|
.bits = x8616_opcode_shift_rm << X8616_OPCODE_VW_PREFIX_SHIFT,
|
|
.mask = X8616_OPCODE_VW_PREFIX_MASK,
|
|
},
|
|
.mod_rm = {
|
|
.bits = x8616_ror << X8616_MODRM_REG_SHIFT,
|
|
.mask = X8616_MODRM_REG_MASK,
|
|
},
|
|
.fields = {
|
|
.v = { X8616_OPCODE_VW_V_SHIFT, 1 },
|
|
.w = { X8616_OPCODE_VW_W_SHIFT, 1 },
|
|
},
|
|
.operands = { x8616_operand_rm, x8616_operand_shift_count },
|
|
.op = x8616_op_ror,
|
|
},
|
|
|
|
/* RCL r/m,1|CL: 110100 v w */ {
|
|
.opcode = {
|
|
.bits = x8616_opcode_shift_rm << X8616_OPCODE_VW_PREFIX_SHIFT,
|
|
.mask = X8616_OPCODE_VW_PREFIX_MASK,
|
|
},
|
|
.mod_rm = {
|
|
.bits = x8616_rcl << X8616_MODRM_REG_SHIFT,
|
|
.mask = X8616_MODRM_REG_MASK,
|
|
},
|
|
.fields = {
|
|
.v = { X8616_OPCODE_VW_V_SHIFT, 1 },
|
|
.w = { X8616_OPCODE_VW_W_SHIFT, 1 },
|
|
},
|
|
.operands = { x8616_operand_rm, x8616_operand_shift_count },
|
|
.op = x8616_op_rcl,
|
|
},
|
|
|
|
/* RCR r/m,1|CL: 110100 v w */ {
|
|
.opcode = {
|
|
.bits = x8616_opcode_shift_rm << X8616_OPCODE_VW_PREFIX_SHIFT,
|
|
.mask = X8616_OPCODE_VW_PREFIX_MASK,
|
|
},
|
|
.mod_rm = {
|
|
.bits = x8616_rcr << X8616_MODRM_REG_SHIFT,
|
|
.mask = X8616_MODRM_REG_MASK,
|
|
},
|
|
.fields = {
|
|
.v = { X8616_OPCODE_VW_V_SHIFT, 1 },
|
|
.w = { X8616_OPCODE_VW_W_SHIFT, 1 },
|
|
},
|
|
.operands = { x8616_operand_rm, x8616_operand_shift_count },
|
|
.op = x8616_op_rcr,
|
|
},
|
|
|
|
/* SHL r/m,1|CL: 110100 v w */ {
|
|
.opcode = {
|
|
.bits = x8616_opcode_shift_rm << X8616_OPCODE_VW_PREFIX_SHIFT,
|
|
.mask = X8616_OPCODE_VW_PREFIX_MASK,
|
|
},
|
|
.mod_rm = {
|
|
.bits = x8616_shl << X8616_MODRM_REG_SHIFT,
|
|
.mask = X8616_MODRM_REG_MASK,
|
|
},
|
|
.fields = {
|
|
.v = { X8616_OPCODE_VW_V_SHIFT, 1 },
|
|
.w = { X8616_OPCODE_VW_W_SHIFT, 1 },
|
|
},
|
|
.operands = { x8616_operand_rm, x8616_operand_shift_count },
|
|
.op = x8616_op_shl,
|
|
},
|
|
|
|
/* SHR r/m,1|CL: 110100 v w */ {
|
|
.opcode = {
|
|
.bits = x8616_opcode_shift_rm << X8616_OPCODE_VW_PREFIX_SHIFT,
|
|
.mask = X8616_OPCODE_VW_PREFIX_MASK,
|
|
},
|
|
.mod_rm = {
|
|
.bits = x8616_shr << X8616_MODRM_REG_SHIFT,
|
|
.mask = X8616_MODRM_REG_MASK,
|
|
},
|
|
.fields = {
|
|
.v = { X8616_OPCODE_VW_V_SHIFT, 1 },
|
|
.w = { X8616_OPCODE_VW_W_SHIFT, 1 },
|
|
},
|
|
.operands = { x8616_operand_rm, x8616_operand_shift_count },
|
|
.op = x8616_op_shr,
|
|
},
|
|
|
|
/* SAR r/m,1|CL: 110100 v w */ {
|
|
.opcode = {
|
|
.bits = x8616_opcode_shift_rm << X8616_OPCODE_VW_PREFIX_SHIFT,
|
|
.mask = X8616_OPCODE_VW_PREFIX_MASK,
|
|
},
|
|
.mod_rm = {
|
|
.bits = x8616_sar << X8616_MODRM_REG_SHIFT,
|
|
.mask = X8616_MODRM_REG_MASK,
|
|
},
|
|
.fields = {
|
|
.v = { X8616_OPCODE_VW_V_SHIFT, 1 },
|
|
.w = { X8616_OPCODE_VW_W_SHIFT, 1 },
|
|
},
|
|
.operands = { x8616_operand_rm, x8616_operand_shift_count },
|
|
.op = x8616_op_sar,
|
|
},
|
|
|
|
/* TEST r/m,reg: 1000010 w */ {
|
|
.opcode = {
|
|
.bits = x8616_opcode_test_rm_r << X8616_OPCODE_W_PREFIX_SHIFT,
|
|
.mask = X8616_OPCODE_W_PREFIX_MASK,
|
|
},
|
|
.fields = {
|
|
.w = { X8616_OPCODE_W_W_SHIFT, 1 },
|
|
},
|
|
.operands = { x8616_operand_rm, x8616_operand_reg_modrm },
|
|
.op = x8616_op_test,
|
|
},
|
|
|
|
/* TEST r/m,imm: 1111011 w /0 */ {
|
|
.opcode = {
|
|
.bits = x8616_opcode_group3 << X8616_OPCODE_W_PREFIX_SHIFT,
|
|
.mask = X8616_OPCODE_W_PREFIX_MASK,
|
|
},
|
|
.mod_rm = {
|
|
.bits = x8616_g3_test << X8616_MODRM_REG_SHIFT,
|
|
.mask = X8616_MODRM_REG_MASK,
|
|
},
|
|
.fields = {
|
|
.w = { X8616_OPCODE_W_W_SHIFT, 1 },
|
|
},
|
|
.operands = { x8616_operand_rm, x8616_operand_imm },
|
|
.op = x8616_op_test,
|
|
},
|
|
|
|
/* TEST accumulator,imm: 1010100 w */ {
|
|
.opcode = {
|
|
.bits = x8616_opcode_test_acc_i << X8616_OPCODE_W_PREFIX_SHIFT,
|
|
.mask = X8616_OPCODE_W_PREFIX_MASK,
|
|
},
|
|
.fields = {
|
|
.w = { X8616_OPCODE_W_W_SHIFT, 1 },
|
|
},
|
|
.operands = { x8616_operand_acc, x8616_operand_imm },
|
|
.op = x8616_op_test,
|
|
},
|
|
|
|
// String / prefixes-------------------------------------------------------
|
|
|
|
/* REP/REPNE prefix: 1111001 z */ {
|
|
.opcode = {
|
|
.bits = x8616_opcode_rep << X8616_OPCODE_Z_PREFIX_SHIFT,
|
|
.mask = X8616_OPCODE_Z_PREFIX_MASK,
|
|
},
|
|
.fields = {
|
|
.z = { X8616_OPCODE_Z_Z_SHIFT, 1 },
|
|
},
|
|
.flags = x8616_encoding_prefix,
|
|
.op = x8616_op_rep,
|
|
},
|
|
|
|
/* MOVS: ... w */ {
|
|
.opcode = {
|
|
.bits = x8616_opcode_movs << X8616_OPCODE_W_PREFIX_SHIFT,
|
|
.mask = X8616_OPCODE_W_PREFIX_MASK,
|
|
},
|
|
.fields = {
|
|
.w = { X8616_OPCODE_W_W_SHIFT, 1 },
|
|
},
|
|
.op = x8616_op_movs,
|
|
},
|
|
|
|
/* CMPS: ... w */ {
|
|
.opcode = {
|
|
.bits = x8616_opcode_cmps << X8616_OPCODE_W_PREFIX_SHIFT,
|
|
.mask = X8616_OPCODE_W_PREFIX_MASK,
|
|
},
|
|
.fields = {
|
|
.w = { X8616_OPCODE_W_W_SHIFT, 1 },
|
|
},
|
|
.op = x8616_op_cmps,
|
|
},
|
|
|
|
/* SCAS: ... w */ {
|
|
.opcode = {
|
|
.bits = x8616_opcode_scas << X8616_OPCODE_W_PREFIX_SHIFT,
|
|
.mask = X8616_OPCODE_W_PREFIX_MASK,
|
|
},
|
|
.fields = {
|
|
.w = { X8616_OPCODE_W_W_SHIFT, 1 },
|
|
},
|
|
.op = x8616_op_scas,
|
|
},
|
|
|
|
/* LODS: ... w */ {
|
|
.opcode = {
|
|
.bits = x8616_opcode_lods << X8616_OPCODE_W_PREFIX_SHIFT,
|
|
.mask = X8616_OPCODE_W_PREFIX_MASK,
|
|
},
|
|
.fields = {
|
|
.w = { X8616_OPCODE_W_W_SHIFT, 1 },
|
|
},
|
|
.op = x8616_op_lods,
|
|
},
|
|
|
|
/* STOS: ... w */ {
|
|
.opcode = {
|
|
.bits = x8616_opcode_stos << X8616_OPCODE_W_PREFIX_SHIFT,
|
|
.mask = X8616_OPCODE_W_PREFIX_MASK,
|
|
},
|
|
.fields = {
|
|
.w = { X8616_OPCODE_W_W_SHIFT, 1 },
|
|
},
|
|
.op = x8616_op_stos,
|
|
},
|
|
|
|
/* LOCK prefix */ {
|
|
.opcode = {
|
|
.bits = x8616_opcode_lock,
|
|
.mask = X8616_OPCODE_MASK,
|
|
},
|
|
.flags = x8616_encoding_prefix,
|
|
.op = x8616_op_lock,
|
|
},
|
|
|
|
/* Segment override: 001 sr 110 */ {
|
|
.opcode = {
|
|
.bits = X8616_OPCODE_SEG_FIXED,
|
|
.mask = X8616_OPCODE_SR_PATTERN_MASK,
|
|
},
|
|
.fields = {
|
|
.sr = { X8616_OPCODE_SR_SHIFT, X8616_OPCODE_SR_WIDTH },
|
|
},
|
|
.flags = x8616_encoding_prefix,
|
|
.op = x8616_op_segment,
|
|
},
|
|
|
|
// Control transfer--------------------------------------------------------
|
|
|
|
/* CALL rel16 */ {
|
|
.opcode = {
|
|
.bits = x8616_opcode_call_rel16,
|
|
.mask = X8616_OPCODE_MASK,
|
|
},
|
|
.operands = { x8616_operand_rel16 },
|
|
.op = x8616_op_call,
|
|
},
|
|
|
|
/* CALL r/m16: FF /2 */ {
|
|
.opcode = {
|
|
.bits = x8616_opcode_group_ff,
|
|
.mask = X8616_OPCODE_MASK,
|
|
},
|
|
.mod_rm = {
|
|
.bits = x8616_ff_call_near << X8616_MODRM_REG_SHIFT,
|
|
.mask = X8616_MODRM_REG_MASK,
|
|
},
|
|
.operands = { x8616_operand_rm },
|
|
.width = x8616_width_word,
|
|
.op = x8616_op_call,
|
|
},
|
|
|
|
/* CALL far ptr16:16 */ {
|
|
.opcode = {
|
|
.bits = x8616_opcode_call_far,
|
|
.mask = X8616_OPCODE_MASK,
|
|
},
|
|
.operands = { x8616_operand_far_ptr },
|
|
.flags = x8616_encoding_far,
|
|
.op = x8616_op_call,
|
|
},
|
|
|
|
/* CALL far r/m16: FF /3 */ {
|
|
.opcode = {
|
|
.bits = x8616_opcode_group_ff,
|
|
.mask = X8616_OPCODE_MASK,
|
|
},
|
|
.mod_rm = {
|
|
.bits = x8616_ff_call_far << X8616_MODRM_REG_SHIFT,
|
|
.mask = X8616_MODRM_REG_MASK,
|
|
},
|
|
.operands = { x8616_operand_rm },
|
|
.width = x8616_width_word,
|
|
.flags = x8616_encoding_far,
|
|
.op = x8616_op_call,
|
|
},
|
|
|
|
/* JMP rel16 */ {
|
|
.opcode = {
|
|
.bits = x8616_opcode_jmp_rel16,
|
|
.mask = X8616_OPCODE_MASK,
|
|
},
|
|
.operands = { x8616_operand_rel16 },
|
|
.op = x8616_op_jmp,
|
|
},
|
|
|
|
/* JMP rel8 */ {
|
|
.opcode = {
|
|
.bits = x8616_opcode_jmp_rel8,
|
|
.mask = X8616_OPCODE_MASK,
|
|
},
|
|
.operands = { x8616_operand_rel8 },
|
|
.op = x8616_op_jmp,
|
|
},
|
|
|
|
/* JMP r/m16: FF /4 */ {
|
|
.opcode = {
|
|
.bits = x8616_opcode_group_ff,
|
|
.mask = X8616_OPCODE_MASK,
|
|
},
|
|
.mod_rm = {
|
|
.bits = x8616_ff_jmp_near << X8616_MODRM_REG_SHIFT,
|
|
.mask = X8616_MODRM_REG_MASK,
|
|
},
|
|
.operands = { x8616_operand_rm },
|
|
.width = x8616_width_word,
|
|
.op = x8616_op_jmp,
|
|
},
|
|
|
|
/* JMP far ptr16:16 */ {
|
|
.opcode = {
|
|
.bits = x8616_opcode_jmp_far,
|
|
.mask = X8616_OPCODE_MASK,
|
|
},
|
|
.operands = { x8616_operand_far_ptr },
|
|
.flags = x8616_encoding_far,
|
|
.op = x8616_op_jmp,
|
|
},
|
|
|
|
/* JMP far r/m16: FF /5 */ {
|
|
.opcode = {
|
|
.bits = x8616_opcode_group_ff,
|
|
.mask = X8616_OPCODE_MASK,
|
|
},
|
|
.mod_rm = {
|
|
.bits = x8616_ff_jmp_far << X8616_MODRM_REG_SHIFT,
|
|
.mask = X8616_MODRM_REG_MASK,
|
|
},
|
|
.operands = { x8616_operand_rm },
|
|
.width = x8616_width_word,
|
|
.flags = x8616_encoding_far,
|
|
.op = x8616_op_jmp,
|
|
},
|
|
|
|
/* RET */ {
|
|
.opcode = {
|
|
.bits = x8616_opcode_ret,
|
|
.mask = X8616_OPCODE_MASK,
|
|
},
|
|
.op = x8616_op_ret,
|
|
},
|
|
|
|
/* RET imm16 */ {
|
|
.opcode = {
|
|
.bits = x8616_opcode_ret_i,
|
|
.mask = X8616_OPCODE_MASK,
|
|
},
|
|
.operands = { x8616_operand_imm16 },
|
|
.op = x8616_op_ret,
|
|
},
|
|
|
|
/* RETF */ {
|
|
.opcode = {
|
|
.bits = x8616_opcode_retf,
|
|
.mask = X8616_OPCODE_MASK,
|
|
},
|
|
.op = x8616_op_retf,
|
|
},
|
|
|
|
/* RETF imm16 */ {
|
|
.opcode = {
|
|
.bits = x8616_opcode_retf_i,
|
|
.mask = X8616_OPCODE_MASK,
|
|
},
|
|
.operands = { x8616_operand_imm16 },
|
|
.op = x8616_op_retf,
|
|
},
|
|
|
|
/* JO rel8 */ {
|
|
.opcode = {
|
|
.bits = x8616_enc_jcc(x8616_cc_o),
|
|
.mask = X8616_OPCODE_MASK,
|
|
},
|
|
.operands = { x8616_operand_rel8 },
|
|
.op = x8616_op_jo,
|
|
},
|
|
|
|
/* JNO rel8 */ {
|
|
.opcode = {
|
|
.bits = x8616_enc_jcc(x8616_cc_no),
|
|
.mask = X8616_OPCODE_MASK,
|
|
},
|
|
.operands = { x8616_operand_rel8 },
|
|
.op = x8616_op_jno,
|
|
},
|
|
|
|
/* JB rel8 */ {
|
|
.opcode = {
|
|
.bits = x8616_enc_jcc(x8616_cc_b),
|
|
.mask = X8616_OPCODE_MASK,
|
|
},
|
|
.operands = { x8616_operand_rel8 },
|
|
.op = x8616_op_jb,
|
|
},
|
|
|
|
/* JNB rel8 */ {
|
|
.opcode = {
|
|
.bits = x8616_enc_jcc(x8616_cc_nb),
|
|
.mask = X8616_OPCODE_MASK,
|
|
},
|
|
.operands = { x8616_operand_rel8 },
|
|
.op = x8616_op_jnb,
|
|
},
|
|
|
|
/* JE rel8 */ {
|
|
.opcode = {
|
|
.bits = x8616_enc_jcc(x8616_cc_e),
|
|
.mask = X8616_OPCODE_MASK,
|
|
},
|
|
.operands = { x8616_operand_rel8 },
|
|
.op = x8616_op_je,
|
|
},
|
|
|
|
/* JNE rel8 */ {
|
|
.opcode = {
|
|
.bits = x8616_enc_jcc(x8616_cc_ne),
|
|
.mask = X8616_OPCODE_MASK,
|
|
},
|
|
.operands = { x8616_operand_rel8 },
|
|
.op = x8616_op_jne,
|
|
},
|
|
|
|
/* JBE rel8 */ {
|
|
.opcode = {
|
|
.bits = x8616_enc_jcc(x8616_cc_be),
|
|
.mask = X8616_OPCODE_MASK,
|
|
},
|
|
.operands = { x8616_operand_rel8 },
|
|
.op = x8616_op_jbe,
|
|
},
|
|
|
|
/* JA rel8 */ {
|
|
.opcode = {
|
|
.bits = x8616_enc_jcc(x8616_cc_a),
|
|
.mask = X8616_OPCODE_MASK,
|
|
},
|
|
.operands = { x8616_operand_rel8 },
|
|
.op = x8616_op_ja,
|
|
},
|
|
|
|
/* JS rel8 */ {
|
|
.opcode = {
|
|
.bits = x8616_enc_jcc(x8616_cc_s),
|
|
.mask = X8616_OPCODE_MASK,
|
|
},
|
|
.operands = { x8616_operand_rel8 },
|
|
.op = x8616_op_js,
|
|
},
|
|
|
|
/* JNS rel8 */ {
|
|
.opcode = {
|
|
.bits = x8616_enc_jcc(x8616_cc_ns),
|
|
.mask = X8616_OPCODE_MASK,
|
|
},
|
|
.operands = { x8616_operand_rel8 },
|
|
.op = x8616_op_jns,
|
|
},
|
|
|
|
/* JP rel8 */ {
|
|
.opcode = {
|
|
.bits = x8616_enc_jcc(x8616_cc_p),
|
|
.mask = X8616_OPCODE_MASK,
|
|
},
|
|
.operands = { x8616_operand_rel8 },
|
|
.op = x8616_op_jp,
|
|
},
|
|
|
|
/* JNP rel8 */ {
|
|
.opcode = {
|
|
.bits = x8616_enc_jcc(x8616_cc_np),
|
|
.mask = X8616_OPCODE_MASK,
|
|
},
|
|
.operands = { x8616_operand_rel8 },
|
|
.op = x8616_op_jnp,
|
|
},
|
|
|
|
/* JL rel8 */ {
|
|
.opcode = {
|
|
.bits = x8616_enc_jcc(x8616_cc_l),
|
|
.mask = X8616_OPCODE_MASK,
|
|
},
|
|
.operands = { x8616_operand_rel8 },
|
|
.op = x8616_op_jl,
|
|
},
|
|
|
|
/* JNL rel8 */ {
|
|
.opcode = {
|
|
.bits = x8616_enc_jcc(x8616_cc_nl),
|
|
.mask = X8616_OPCODE_MASK,
|
|
},
|
|
.operands = { x8616_operand_rel8 },
|
|
.op = x8616_op_jnl,
|
|
},
|
|
|
|
/* JLE rel8 */ {
|
|
.opcode = {
|
|
.bits = x8616_enc_jcc(x8616_cc_le),
|
|
.mask = X8616_OPCODE_MASK,
|
|
},
|
|
.operands = { x8616_operand_rel8 },
|
|
.op = x8616_op_jle,
|
|
},
|
|
|
|
/* JG rel8 */ {
|
|
.opcode = {
|
|
.bits = x8616_enc_jcc(x8616_cc_g),
|
|
.mask = X8616_OPCODE_MASK,
|
|
},
|
|
.operands = { x8616_operand_rel8 },
|
|
.op = x8616_op_jg,
|
|
},
|
|
|
|
/* LOOPNZ rel8 */ {
|
|
.opcode = {
|
|
.bits = x8616_opcode_loopnz,
|
|
.mask = X8616_OPCODE_MASK,
|
|
},
|
|
.operands = { x8616_operand_rel8 },
|
|
.op = x8616_op_loopnz,
|
|
},
|
|
|
|
/* LOOPZ rel8 */ {
|
|
.opcode = {
|
|
.bits = x8616_opcode_loopz,
|
|
.mask = X8616_OPCODE_MASK,
|
|
},
|
|
.operands = { x8616_operand_rel8 },
|
|
.op = x8616_op_loopz,
|
|
},
|
|
|
|
/* LOOP rel8 */ {
|
|
.opcode = {
|
|
.bits = x8616_opcode_loop,
|
|
.mask = X8616_OPCODE_MASK,
|
|
},
|
|
.operands = { x8616_operand_rel8 },
|
|
.op = x8616_op_loop,
|
|
},
|
|
|
|
/* JCXZ rel8 */ {
|
|
.opcode = {
|
|
.bits = x8616_opcode_jcxz,
|
|
.mask = X8616_OPCODE_MASK,
|
|
},
|
|
.operands = { x8616_operand_rel8 },
|
|
.op = x8616_op_jcxz,
|
|
},
|
|
|
|
// Interrupt / machine control--------------------------------------------
|
|
|
|
/* INT imm8 */ {
|
|
.opcode = {
|
|
.bits = x8616_opcode_int,
|
|
.mask = X8616_OPCODE_MASK,
|
|
},
|
|
.operands = { x8616_operand_imm8 },
|
|
.op = x8616_op_int,
|
|
},
|
|
|
|
/* INT3 */ {
|
|
.opcode = {
|
|
.bits = x8616_opcode_int3,
|
|
.mask = X8616_OPCODE_MASK,
|
|
},
|
|
.op = x8616_op_int3,
|
|
},
|
|
|
|
/* INTO */ {
|
|
.opcode = {
|
|
.bits = x8616_opcode_into,
|
|
.mask = X8616_OPCODE_MASK,
|
|
},
|
|
.op = x8616_op_into,
|
|
},
|
|
|
|
/* IRET */ {
|
|
.opcode = {
|
|
.bits = x8616_opcode_iret,
|
|
.mask = X8616_OPCODE_MASK,
|
|
},
|
|
.op = x8616_op_iret,
|
|
},
|
|
|
|
/* CLC */ {
|
|
.opcode = {
|
|
.bits = x8616_opcode_clc,
|
|
.mask = X8616_OPCODE_MASK,
|
|
},
|
|
.op = x8616_op_clc,
|
|
},
|
|
|
|
/* CMC */ {
|
|
.opcode = {
|
|
.bits = x8616_opcode_cmc,
|
|
.mask = X8616_OPCODE_MASK,
|
|
},
|
|
.op = x8616_op_cmc,
|
|
},
|
|
|
|
/* STC */ {
|
|
.opcode = {
|
|
.bits = x8616_opcode_stc,
|
|
.mask = X8616_OPCODE_MASK,
|
|
},
|
|
.op = x8616_op_stc,
|
|
},
|
|
|
|
/* CLD */ {
|
|
.opcode = {
|
|
.bits = x8616_opcode_cld,
|
|
.mask = X8616_OPCODE_MASK,
|
|
},
|
|
.op = x8616_op_cld,
|
|
},
|
|
|
|
/* STD */ {
|
|
.opcode = {
|
|
.bits = x8616_opcode_std,
|
|
.mask = X8616_OPCODE_MASK,
|
|
},
|
|
.op = x8616_op_std,
|
|
},
|
|
|
|
/* CLI */ {
|
|
.opcode = {
|
|
.bits = x8616_opcode_cli,
|
|
.mask = X8616_OPCODE_MASK,
|
|
},
|
|
.op = x8616_op_cli,
|
|
},
|
|
|
|
/* STI */ {
|
|
.opcode = {
|
|
.bits = x8616_opcode_sti,
|
|
.mask = X8616_OPCODE_MASK,
|
|
},
|
|
.op = x8616_op_sti,
|
|
},
|
|
|
|
/* HLT */ {
|
|
.opcode = {
|
|
.bits = x8616_opcode_hlt,
|
|
.mask = X8616_OPCODE_MASK,
|
|
},
|
|
.op = x8616_op_hlt,
|
|
},
|
|
|
|
/* WAIT */ {
|
|
.opcode = {
|
|
.bits = x8616_opcode_wait,
|
|
.mask = X8616_OPCODE_MASK,
|
|
},
|
|
.op = x8616_op_wait,
|
|
},
|
|
|
|
};
|
|
|
|
enum {
|
|
X8616_ENCODING_COUNT = S_(x8616_encodings) / S_(x8616_encodings[0]),
|
|
};
|