|
|
/*++
Copyright (c) 1995 Microsoft Corporation
Module Name:
comm1632.c
Abstract: Instructions with common (shared) WORD, and DWORD flavors (but not BYTE).
Author:
29-Jun-1995 BarryBo
Revision History:
--*/
#include <nt.h>
#include <ntrtl.h>
#include <nturtl.h>
#include <windows.h>
#include <stdio.h>
#include "wx86.h"
#include "config.h"
#include "threadst.h"
#include "instr.h"
#include "decoderp.h"
#include "comm1632.h"
extern OPERATION MANGLENAME(Group1Map)[];
// ---------------- single-byte functions -------------------------------
DISPATCHCOMMON(dispatch2) { eipTemp++; #if MSB==0x8000
((pfnDispatchInstruction)(Dispatch216[GET_BYTE(eipTemp)]))(State, Instr); #else
((pfnDispatchInstruction)(Dispatch232[GET_BYTE(eipTemp)]))(State, Instr); #endif
} DISPATCHCOMMON(LOCKdispatch2) { eipTemp++; #if MSB==0x8000
((pfnDispatchInstruction)(LockDispatch216[GET_BYTE(eipTemp)]))(State, Instr); #else
((pfnDispatchInstruction)(LockDispatch232[GET_BYTE(eipTemp)]))(State, Instr); #endif
} DISPATCHCOMMON(pushf) { Instr->Operation = OPNAME(Pushf); } DISPATCHCOMMON(popf) { Instr->Operation = OPNAME(Popf); } DISPATCHCOMMON(pusha) { Instr->Operation = OPNAME(PushA); } DISPATCHCOMMON(popa) { Instr->Operation = OPNAME(PopA); } DISPATCHCOMMON(push_iw) { Instr->Operation = OPNAME(Push); Instr->Operand1.Type = OPND_IMM; Instr->Operand1.Immed = GET_VAL(eipTemp+1); Instr->Size = 1+sizeof(UTYPE); } DISPATCHCOMMON(push_ibs) { Instr->Operation = OPNAME(Push); Instr->Operand1.Type = OPND_IMM; Instr->Operand1.Immed = (UTYPE)(STYPE)(char)GET_BYTE(eipTemp+1); Instr->Size = 2; } DISPATCHCOMMON(GROUP_1WS) { int cbInstr = MOD_RM(State, &Instr->Operand1, NULL); BYTE g = GET_BYTE(eipTemp+1);
g = (g >> 3) & 0x07; Instr->Operation = MANGLENAME(Group1Map)[g]; Instr->Operand2.Type = OPND_IMM; Instr->Operand2.Immed = (UTYPE)(STYPE)(char)GET_BYTE(eipTemp + cbInstr + 1); if (g == 7) { // Cmp takes both params as byval
DEREF(Instr->Operand1); } Instr->Size = cbInstr+2; } DISPATCHCOMMON(LOCKGROUP_1WS) { int cbInstr = MOD_RM(State, &Instr->Operand1, NULL); BYTE g = GET_BYTE(eipTemp+1);
g = (g >> 3) & 0x07; Instr->Operation = MANGLENAME(Group1LockMap)[g]; Instr->Operand2.Type = OPND_IMM; Instr->Operand2.Immed = (UTYPE)(STYPE)(char)GET_BYTE(eipTemp + cbInstr + 1); if (g == 7) { // Cmp takes both params as byval
DEREF(Instr->Operand1); } Instr->Size = cbInstr+2; } DISPATCHCOMMON(mov_rw_mw) { int cbInstr = MOD_RM(State, &Instr->Operand2, &Instr->Operand1);
Instr->Operation = OPNAME(Mov); DEREF(Instr->Operand2); Instr->Size = cbInstr+1; } DISPATCHCOMMON(lea_rw_mw) { int cbInstr = MOD_RM(State, &Instr->Operand2, &Instr->Operand1);
Instr->Operation = OPNAME(Mov); Instr->Size = cbInstr+1; } DISPATCHCOMMON(pop_mw) { int cbInstr = MOD_RM(State, &Instr->Operand1, NULL);
Instr->Operation = OPNAME(Pop); Instr->Size = 1+cbInstr; } DISPATCHCOMMON(xchg_ax_cx) { Instr->Operation = OPNAME(Xchg); Instr->Operand1.Type = OPND_REGREF; Instr->Operand1.Reg = AREG; Instr->Operand2.Type = OPND_REGREF; Instr->Operand2.Reg = CREG; } DISPATCHCOMMON(xchg_ax_dx) { Instr->Operation = OPNAME(Xchg); Instr->Operand1.Type = OPND_REGREF; Instr->Operand1.Reg = AREG; Instr->Operand2.Type = OPND_REGREF; Instr->Operand2.Reg = DREG; } DISPATCHCOMMON(xchg_ax_bx) { Instr->Operation = OPNAME(Xchg); Instr->Operand1.Type = OPND_REGREF; Instr->Operand1.Reg = AREG; Instr->Operand2.Type = OPND_REGREF; Instr->Operand2.Reg = BREG; } DISPATCHCOMMON(xchg_ax_sp) { Instr->Operation = OPNAME(Xchg); Instr->Operand1.Type = OPND_REGREF; Instr->Operand1.Reg = AREG; Instr->Operand2.Type = OPND_REGREF; Instr->Operand2.Reg = SPREG; } DISPATCHCOMMON(xchg_ax_bp) { Instr->Operation = OPNAME(Xchg); Instr->Operand1.Type = OPND_REGREF; Instr->Operand1.Reg = AREG; Instr->Operand2.Type = OPND_REGREF; Instr->Operand2.Reg = BPREG; } DISPATCHCOMMON(xchg_ax_si) { Instr->Operation = OPNAME(Xchg); Instr->Operand1.Type = OPND_REGREF; Instr->Operand1.Reg = AREG; Instr->Operand2.Type = OPND_REGREF; Instr->Operand2.Reg = SIREG; } DISPATCHCOMMON(xchg_ax_di) { Instr->Operation = OPNAME(Xchg); Instr->Operand1.Type = OPND_REGREF; Instr->Operand1.Reg = AREG; Instr->Operand2.Type = OPND_REGREF; Instr->Operand2.Reg = DIREG; } DISPATCHCOMMON(cbw) { Instr->Operation = OPNAME(Cbw); } DISPATCHCOMMON(cwd) { Instr->Operation = OPNAME(Cwd); } DISPATCHCOMMON(mov_sp_iw) { Instr->Operation = OPNAME(Mov); Instr->Operand1.Type = OPND_REGREF; Instr->Operand1.Reg = SPREG; Instr->Operand2.Type = OPND_IMM; Instr->Operand2.Immed = GET_VAL(eipTemp+1); Instr->Size = 1+sizeof(UTYPE); } DISPATCHCOMMON(mov_bp_iw) { Instr->Operation = OPNAME(Mov); Instr->Operand1.Type = OPND_REGREF; Instr->Operand1.Reg = BPREG; Instr->Operand2.Type = OPND_IMM; Instr->Operand2.Immed = GET_VAL(eipTemp+1); Instr->Size = 1+sizeof(UTYPE); } DISPATCHCOMMON(mov_si_iw) { Instr->Operation = OPNAME(Mov); Instr->Operand1.Type = OPND_REGREF; Instr->Operand1.Reg = SIREG; Instr->Operand2.Type = OPND_IMM; Instr->Operand2.Immed = GET_VAL(eipTemp+1); Instr->Size = 1+sizeof(UTYPE); } DISPATCHCOMMON(mov_di_iw) { Instr->Operation = OPNAME(Mov); Instr->Operand1.Type = OPND_REGREF; Instr->Operand1.Reg = DIREG; Instr->Operand2.Type = OPND_IMM; Instr->Operand2.Immed = GET_VAL(eipTemp+1); Instr->Size = 1+sizeof(UTYPE); } DISPATCHCOMMON(loopne_b) { Instr->Operand1.Type = OPND_NOCODEGEN; Instr->Operand1.Immed = (CHAR)GET_BYTE(eipTemp+1)+2+eipTemp; if (Instr->Operand1.Immed > eipTemp) { Instr->Operation = OPNAME(CTRL_COND_Loopne_bFwd); } else { Instr->Operation = OPNAME(CTRL_COND_Loopne_b); } Instr->Size = 2; } DISPATCHCOMMON(loope_b) { Instr->Operand1.Type = OPND_NOCODEGEN; Instr->Operand1.Immed = (CHAR)GET_BYTE(eipTemp+1)+2+eipTemp; if (Instr->Operand1.Immed > eipTemp) { Instr->Operation = OPNAME(CTRL_COND_Loope_bFwd); } else { Instr->Operation = OPNAME(CTRL_COND_Loope_b); } Instr->Size = 2; } DISPATCHCOMMON(loop_b) { Instr->Operand1.Type = OPND_NOCODEGEN; Instr->Operand1.Immed = (CHAR)GET_BYTE(eipTemp+1)+2+eipTemp; if (Instr->Operand1.Immed > eipTemp) { Instr->Operation = OPNAME(CTRL_COND_Loop_bFwd); } else { Instr->Operation = OPNAME(CTRL_COND_Loop_b); } Instr->Size = 2; } DISPATCHCOMMON(jcxz_b) { Instr->Operand1.Type = OPND_NOCODEGEN; if (State->AdrPrefix) { // "ADR: jecxz" is the same as "DATA: jecxz"... which is "jcxz"
Instr->Operand1.Immed = MAKELONG((char)GET_BYTE(eipTemp+1)+2+(short)LOWORD(eipTemp), HIWORD(eipTemp)); if (Instr->Operand1.Immed > eipTemp) { Instr->Operation = OP_CTRL_COND_Jcxz_bFwd16; } else { Instr->Operation = OP_CTRL_COND_Jcxz_b16; } #if DBG
State->AdrPrefix = FALSE; #endif
} else { Instr->Operand1.Immed = (CHAR)GET_BYTE(eipTemp+1)+2+eipTemp; if (Instr->Operand1.Immed > eipTemp) { Instr->Operation = OPNAME(CTRL_COND_Jcxz_bFwd); } else { Instr->Operation = OPNAME(CTRL_COND_Jcxz_b); } } Instr->Size = 2; } DISPATCHCOMMON(GROUP_5) { int cbInstr = MOD_RM(State, &Instr->Operand1, NULL); BYTE g = GET_BYTE(eipTemp+1);
switch ((g >> 3) & 0x07) { case 0: // inc modrmW
Instr->Operation = OPNAME(Inc); break; case 1: // dec modrmW
Instr->Operation = OPNAME(Dec); break; case 2: // call indirmodrmW
DEREF(Instr->Operand1); Instr->Operand2.Type = OPND_IMM; Instr->Operand2.Immed = eipTemp + cbInstr + 1; Instr->Operation = OP_CTRL_INDIR_Call; break; case 3: // call indirFARmodrmW
Instr->Operand2.Type = OPND_IMM; Instr->Operand2.Immed = eipTemp + cbInstr + 1; Instr->Operation = OP_CTRL_INDIR_Callf; break; case 4: // jmp indirmodrmW
DEREF(Instr->Operand1); Instr->Operation = OP_CTRL_INDIR_Jmp; break; case 5: // jmp indirFARmodrmW
Instr->Operation = OP_CTRL_INDIR_Jmpf; break; case 6: // push modrmW
DEREF(Instr->Operand1); Instr->Operation = OPNAME(Push); break; case 7: // bad
BAD_INSTR; break; }
Instr->Size = cbInstr+1; } DISPATCHCOMMON(LOCKGROUP_5) { int cbInstr = MOD_RM(State, &Instr->Operand1, NULL); BYTE g = GET_BYTE(eipTemp+1);
switch ((g >> 3) & 0x07) { case 0: // inc modrmW
Instr->Operation = LOCKOPNAME(Inc); break; case 1: // dec modrmW
Instr->Operation = LOCKOPNAME(Dec); break; default: BAD_INSTR; break; }
Instr->Size = cbInstr+1; } DISPATCHCOMMON(inc_ax) { Instr->Operation = OPNAME(Inc); Instr->Operand1.Type = OPND_REGREF; Instr->Operand1.Reg = AREG; } DISPATCHCOMMON(inc_cx) { Instr->Operation = OPNAME(Inc); Instr->Operand1.Type = OPND_REGREF; Instr->Operand1.Reg = CREG; } DISPATCHCOMMON(inc_dx) { Instr->Operation = OPNAME(Inc); Instr->Operand1.Type = OPND_REGREF; Instr->Operand1.Reg = DREG; } DISPATCHCOMMON(inc_bx) { Instr->Operation = OPNAME(Inc); Instr->Operand1.Type = OPND_REGREF; Instr->Operand1.Reg = BREG; } DISPATCHCOMMON(inc_sp) { Instr->Operation = OPNAME(Inc); Instr->Operand1.Type = OPND_REGREF; Instr->Operand1.Reg = SPREG; } DISPATCHCOMMON(inc_bp) { Instr->Operation = OPNAME(Inc); Instr->Operand1.Type = OPND_REGREF; Instr->Operand1.Reg = BPREG; } DISPATCHCOMMON(inc_si) { Instr->Operation = OPNAME(Inc); Instr->Operand1.Type = OPND_REGREF; Instr->Operand1.Reg = SIREG; } DISPATCHCOMMON(inc_di) { Instr->Operation = OPNAME(Inc); Instr->Operand1.Type = OPND_REGREF; Instr->Operand1.Reg = DIREG; } DISPATCHCOMMON(dec_ax) { Instr->Operation = OPNAME(Dec); Instr->Operand1.Type = OPND_REGREF; Instr->Operand1.Reg = AREG; } DISPATCHCOMMON(dec_cx) { Instr->Operation = OPNAME(Dec); Instr->Operand1.Type = OPND_REGREF; Instr->Operand1.Reg = CREG; } DISPATCHCOMMON(dec_dx) { Instr->Operation = OPNAME(Dec); Instr->Operand1.Type = OPND_REGREF; Instr->Operand1.Reg = DREG; } DISPATCHCOMMON(dec_bx) { Instr->Operation = OPNAME(Dec); Instr->Operand1.Type = OPND_REGREF; Instr->Operand1.Reg = BREG; } DISPATCHCOMMON(dec_sp) { Instr->Operation = OPNAME(Dec); Instr->Operand1.Type = OPND_REGREF; Instr->Operand1.Reg = SPREG; } DISPATCHCOMMON(dec_bp) { Instr->Operation = OPNAME(Dec); Instr->Operand1.Type = OPND_REGREF; Instr->Operand1.Reg = BPREG; } DISPATCHCOMMON(dec_si) { Instr->Operation = OPNAME(Dec); Instr->Operand1.Type = OPND_REGREF; Instr->Operand1.Reg = SIREG; } DISPATCHCOMMON(dec_di) { Instr->Operation = OPNAME(Dec); Instr->Operand1.Type = OPND_REGREF; Instr->Operand1.Reg = DIREG; } DISPATCHCOMMON(push_ax) { Instr->Operation = OPNAME(Push); Instr->Operand1.Type = OPND_REGVALUE; Instr->Operand1.Reg = AREG; } DISPATCHCOMMON(push_cx) { Instr->Operation = OPNAME(Push); Instr->Operand1.Type = OPND_REGVALUE; Instr->Operand1.Reg = CREG; } DISPATCHCOMMON(push_dx) { Instr->Operation = OPNAME(Push); Instr->Operand1.Type = OPND_REGVALUE; Instr->Operand1.Reg = DREG; } DISPATCHCOMMON(push_bx) { Instr->Operation = OPNAME(Push); Instr->Operand1.Type = OPND_REGVALUE; Instr->Operand1.Reg = BREG; } DISPATCHCOMMON(push_sp) { Instr->Operation = OPNAME(Push); Instr->Operand1.Type = OPND_REGVALUE; Instr->Operand1.Reg = SPREG; } DISPATCHCOMMON(push_bp) { Instr->Operation = OPNAME(Push); Instr->Operand1.Type = OPND_REGVALUE; Instr->Operand1.Reg = BPREG; } DISPATCHCOMMON(push_si) { Instr->Operation = OPNAME(Push); Instr->Operand1.Type = OPND_REGVALUE; Instr->Operand1.Reg = SIREG; } DISPATCHCOMMON(push_di) { Instr->Operation = OPNAME(Push); Instr->Operand1.Type = OPND_REGVALUE; Instr->Operand1.Reg = DIREG; } DISPATCHCOMMON(pop_ax) { Instr->Operation = OPNAME(Pop); Instr->Operand1.Type = OPND_REGREF; Instr->Operand1.Reg = AREG; } DISPATCHCOMMON(pop_cx) { Instr->Operation = OPNAME(Pop); Instr->Operand1.Type = OPND_REGREF; Instr->Operand1.Reg = CREG; } DISPATCHCOMMON(pop_dx) { Instr->Operation = OPNAME(Pop); Instr->Operand1.Type = OPND_REGREF; Instr->Operand1.Reg = DREG; } DISPATCHCOMMON(pop_bx) { Instr->Operation = OPNAME(Pop); Instr->Operand1.Type = OPND_REGREF; Instr->Operand1.Reg = BREG; } DISPATCHCOMMON(pop_sp) { Instr->Operation = OPNAME(Pop); Instr->Operand1.Type = OPND_REGREF; Instr->Operand1.Reg = SPREG; } DISPATCHCOMMON(pop_bp) { Instr->Operation = OPNAME(Pop); Instr->Operand1.Type = OPND_REGREF; Instr->Operand1.Reg = BPREG; } DISPATCHCOMMON(pop_si) { Instr->Operation = OPNAME(Pop); Instr->Operand1.Type = OPND_REGREF; Instr->Operand1.Reg = SIREG; } DISPATCHCOMMON(pop_di) { Instr->Operation = OPNAME(Pop); Instr->Operand1.Type = OPND_REGREF; Instr->Operand1.Reg = DIREG; } DISPATCHCOMMON(bound) { int cbInstr = MOD_RM(State, &Instr->Operand1, &Instr->Operand2);
Instr->Operation = OPNAME(Bound); Instr->Operand2.Type = OPND_REGVALUE; Instr->Size = 1+cbInstr; } DISPATCHCOMMON(retn_i) { Instr->Operation = OPNAME(CTRL_INDIR_Retn_i); Instr->Operand1.Type = OPND_IMM; Instr->Operand1.Immed = (DWORD)GET_SHORT(eipTemp+1); Instr->Size = 3; } DISPATCHCOMMON(retn) { Instr->Operation = OPNAME(CTRL_INDIR_Retn); } DISPATCHCOMMON(retf_i) { Instr->Operation = OPNAME(CTRL_INDIR_Retf_i); Instr->Operand1.Type = OPND_IMM; Instr->Operand1.Immed = (DWORD)GET_SHORT(eipTemp+1); Instr->Size = 3; } DISPATCHCOMMON(retf) { Instr->Operation = OPNAME(CTRL_INDIR_Retf); } DISPATCHCOMMON(enter) { Instr->Operation = OPNAME(Enter); Instr->Operand1.Type = OPND_IMM; Instr->Operand1.Immed = GET_BYTE(eipTemp+3); // Nesting Level
Instr->Operand2.Type = OPND_IMM; Instr->Operand2.Immed = GET_SHORT(eipTemp+1); // Stack bytes to alloc
Instr->Size = 4; } DISPATCHCOMMON(leave) { Instr->Operation = OPNAME(Leave); }
//-------- double-byte functions -----------------------------------------------
DISPATCHCOMMON(GROUP_8) { BYTE g = GET_BYTE(eipTemp+1); int cbInstr;
switch ((g >> 3) & 0x07) { case 0: // bad
case 1: // bad
case 2: // bad
case 3: // bad
BAD_INSTR; break; case 4: // bt modrmw immb
// Note: the difference between the Reg and Mem version of the btx
// fragments is that the Reg version completely ignores any bits in the
// second operand beyond the fifth bit. In contrast, the Mem version uses
// them together with the first operand to determine the memory address.
// When the second operand is an immediate, the correct thing to do is to
// ignore them, and so we call the Reg version all the time.
cbInstr = MOD_RM(State, &Instr->Operand1, NULL);
Instr->Operation = OPNAME(BtReg); Instr->Operand2.Type = OPND_IMM; Instr->Operand2.Immed = GET_BYTE(eipTemp+cbInstr+1); Instr->Size = cbInstr+3; break; case 5: // bts modrmw immb
cbInstr = MOD_RM(State, &Instr->Operand1, NULL);
Instr->Operation = OPNAME(BtsReg); Instr->Operand2.Type = OPND_IMM; Instr->Operand2.Immed = GET_BYTE(eipTemp+cbInstr+1); Instr->Size = cbInstr+3; break; case 6: // btr modrmw immb
cbInstr = MOD_RM(State, &Instr->Operand1, NULL);
Instr->Operation = OPNAME(BtrReg); Instr->Operand2.Type = OPND_IMM; Instr->Operand2.Immed = GET_BYTE(eipTemp+cbInstr+1); Instr->Size = cbInstr+3; break; case 7: // btc modrmw immb
cbInstr = MOD_RM(State, &Instr->Operand1, NULL);
Instr->Operation = OPNAME(BtcReg); Instr->Operand2.Type = OPND_IMM; Instr->Operand2.Immed = GET_BYTE(eipTemp+cbInstr+1); Instr->Size = cbInstr+3; break; } } DISPATCHCOMMON(LOCKGROUP_8) { BYTE g = GET_BYTE(eipTemp+1); int cbInstr;
switch ((g >> 3) & 0x07) { case 0: // bad
case 1: // bad
case 2: // bad
case 3: // bad
case 4: // bt modrmw immb
BAD_INSTR; break; case 5: // bts modrmw immb
cbInstr = MOD_RM(State, &Instr->Operand1, NULL);
Instr->Operation = LOCKOPNAME(BtsReg); Instr->Operand2.Type = OPND_IMM; Instr->Operand2.Immed = GET_BYTE(eipTemp+cbInstr+1); Instr->Size = cbInstr+3; break; case 6: // btr modrmw immb
cbInstr = MOD_RM(State, &Instr->Operand1, NULL);
Instr->Operation = LOCKOPNAME(BtrReg); Instr->Operand2.Type = OPND_IMM; Instr->Operand2.Immed = GET_BYTE(eipTemp+cbInstr+1); Instr->Size = cbInstr+3; break; case 7: // btc modrmw immb
cbInstr = MOD_RM(State, &Instr->Operand1, NULL);
Instr->Operation = LOCKOPNAME(BtcReg); Instr->Operand2.Type = OPND_IMM; Instr->Operand2.Immed = GET_BYTE(eipTemp+cbInstr+1); Instr->Size = cbInstr+3; break; } } DISPATCHCOMMON(movzx_regw_modrmb) { int cbInstr = mod_rm_reg8(State, &Instr->Operand1, NULL);
Instr->Operation = OPNAME(Movzx8To); Instr->Operand2.Type = OPND_NOCODEGEN; Instr->Operand2.Reg = GET_REG(eipTemp+1); DEREF8(Instr->Operand1); Instr->Size = 2+cbInstr; } DISPATCHCOMMON(movsx_regw_modrmb) { int cbInstr = mod_rm_reg8(State, &Instr->Operand1, NULL);
Instr->Operation = OPNAME(Movsx8To); Instr->Operand2.Type = OPND_NOCODEGEN; Instr->Operand2.Reg = GET_REG(eipTemp+1); DEREF8(Instr->Operand1); Instr->Size = 2+cbInstr; } DISPATCHCOMMON(les_rw_mw) { if ((GET_BYTE(eipTemp+1) & 0xc7) == 0xc4) { //
// BOP instruction
//
PBOPINSTR Bop = (PBOPINSTR)eipTemp;
Instr->Size = sizeof(BOPINSTR);
if (Bop->BopNum == 0xfe) { //
// BOP FE - Unsimulate
//
Instr->Operation = OP_Unsimulate;
} else {
//
// Generate a BOP.
//
if (Bop->Flags & BOPFL_ENDCODE) { //
// This BOP is flagged as being the end of Intel code.
// This is typically BOP FD in x86-to-Risc callbacks.
//
Instr->Operation = OP_BOP_STOP_DECODE; } else { Instr->Operation = OP_BOP; } } } else { int cbInstr = MOD_RM(State, &Instr->Operand2, &Instr->Operand1);
Instr->Operation = OPNAME(Les); Instr->Size = 1+cbInstr; } } DISPATCHCOMMON(lds_rw_mw) { int cbInstr = MOD_RM(State, &Instr->Operand2, &Instr->Operand1);
Instr->Operation = OPNAME(Lds); Instr->Size = 1+cbInstr; } DISPATCHCOMMON(lss_rw_mw) { int cbInstr = MOD_RM(State, &Instr->Operand2, &Instr->Operand1);
Instr->Operation = OPNAME(Lss); Instr->Size = 2+cbInstr; } DISPATCHCOMMON(lfs_rw_mw) { int cbInstr = MOD_RM(State, &Instr->Operand2, &Instr->Operand1);
Instr->Operation = OPNAME(Lfs); Instr->Size = 2+cbInstr; } DISPATCHCOMMON(lgs_rw_mw) { int cbInstr = MOD_RM(State, &Instr->Operand2, &Instr->Operand1);
Instr->Operation = OPNAME(Lgs); Instr->Size = 2+cbInstr; } DISPATCHCOMMON(bts_m_r) { int cbInstr = MOD_RM(State, &Instr->Operand1, &Instr->Operand2);
DEREF(Instr->Operand2); if (Instr->Operand1.Type == OPND_REGREF){ Instr->Operation = OPNAME(BtsReg); } else { Instr->Operation = OPNAME(BtsMem); } Instr->Size = 2+cbInstr; } DISPATCHCOMMON(btr_m_r) { int cbInstr = MOD_RM(State, &Instr->Operand1, &Instr->Operand2);
DEREF(Instr->Operand2); if (Instr->Operand1.Type == OPND_REGREF){ Instr->Operation = OPNAME(BtrReg); } else { Instr->Operation = OPNAME(BtrMem); } Instr->Size = 2+cbInstr; } DISPATCHCOMMON(btc_m_r) { int cbInstr = MOD_RM(State, &Instr->Operand1, &Instr->Operand2);
DEREF(Instr->Operand2); if (Instr->Operand1.Type == OPND_REGREF){ Instr->Operation = OPNAME(BtcReg); } else { Instr->Operation = OPNAME(BtcMem); } Instr->Size = 2+cbInstr; } DISPATCHCOMMON(LOCKbts_m_r) { int cbInstr = MOD_RM(State, &Instr->Operand1, &Instr->Operand2);
DEREF(Instr->Operand2); if (Instr->Operand1.Type == OPND_REGREF){ BAD_INSTR; } else { Instr->Operation = LOCKOPNAME(BtsMem); } Instr->Size = 2+cbInstr; } DISPATCHCOMMON(LOCKbtr_m_r) { int cbInstr = MOD_RM(State, &Instr->Operand1, &Instr->Operand2);
DEREF(Instr->Operand2); if (Instr->Operand1.Type == OPND_REGREF){ BAD_INSTR; } else { Instr->Operation = LOCKOPNAME(BtrMem); } Instr->Size = 2+cbInstr; } DISPATCHCOMMON(LOCKbtc_m_r) { int cbInstr = MOD_RM(State, &Instr->Operand1, &Instr->Operand2);
DEREF(Instr->Operand2); if (Instr->Operand1.Type == OPND_REGREF){ BAD_INSTR; } else { Instr->Operation = LOCKOPNAME(BtcMem); } Instr->Size = 2+cbInstr; } DISPATCHCOMMON(bt_m_r) { int cbInstr = MOD_RM(State, &Instr->Operand1, &Instr->Operand2);
DEREF(Instr->Operand2); if (Instr->Operand1.Type == OPND_REGREF){ Instr->Operation = OPNAME(BtReg); } else { Instr->Operation = OPNAME(BtMem); } Instr->Size = 2+cbInstr; } DISPATCHCOMMON(call_rel) { Instr->Operation = OP_CTRL_UNCOND_Call; Instr->Operand1.Type = OPND_IMM; Instr->Operand1.Immed = (STYPE)GET_VAL(eipTemp+1) + sizeof(UTYPE) + 1 + eipTemp; Instr->Operand2.Type = OPND_IMM; Instr->Operand2.Immed = eipTemp + sizeof(UTYPE) + 1; Instr->Size = sizeof(UTYPE) + 1; } DISPATCHCOMMON(jmp_rel) { Instr->Operand1.Type = OPND_NOCODEGEN; if (State->AdrPrefix) { short IP;
// get the 16-bit loword from the 32-bit immediate value following
// the JMP instruction, and add that value to the loword of EIP, and
// use that value as the new IP register.
IP = (short)GET_SHORT(eipTemp+1) + sizeof(UTYPE) + 1 + (short)LOWORD(eipTemp); Instr->Operand1.Immed = MAKELONG(IP, HIWORD(eipTemp)); #if DBG
State->AdrPrefix = FALSE; #endif
} else { Instr->Operand1.Immed = (STYPE)GET_VAL(eipTemp+1) + sizeof(UTYPE) + 1 + eipTemp; } if (Instr->Operand1.Immed > eipTemp) { Instr->Operation = OP_CTRL_UNCOND_JmpFwd; } else { Instr->Operation = OP_CTRL_UNCOND_Jmp; } Instr->Size = sizeof(UTYPE) + 1; } DISPATCHCOMMON(shld_regw_modrmw_immb) { int cbInstr = MOD_RM(State, &Instr->Operand1, &Instr->Operand2);
Instr->Operation = OPNAME(Shld); DEREF(Instr->Operand2); Instr->Operand3.Type = OPND_IMM; Instr->Operand3.Immed = GET_BYTE(eipTemp+cbInstr+1); Instr->Size = 3+cbInstr; } DISPATCHCOMMON(shld_regw_modrmw_cl) { int cbInstr = MOD_RM(State, &Instr->Operand1, &Instr->Operand2);
Instr->Operation = OPNAME(Shld); DEREF(Instr->Operand2); Instr->Operand3.Type = OPND_REGVALUE; Instr->Operand3.Reg = GP_CL; Instr->Size = 2+cbInstr; } DISPATCHCOMMON(shrd_regw_modrmw_immb) { int cbInstr = MOD_RM(State, &Instr->Operand1, &Instr->Operand2);
Instr->Operation = OPNAME(Shrd); DEREF(Instr->Operand2); Instr->Operand3.Type = OPND_IMM; Instr->Operand3.Immed = GET_BYTE(eipTemp+cbInstr+1); Instr->Size = 3+cbInstr; } DISPATCHCOMMON(shrd_regw_modrmw_cl) { int cbInstr = MOD_RM(State, &Instr->Operand1, &Instr->Operand2);
Instr->Operation = OPNAME(Shrd); DEREF(Instr->Operand2); Instr->Operand3.Type = OPND_REGVALUE; Instr->Operand3.Reg = GP_CL; Instr->Size = 2+cbInstr; } DISPATCHCOMMON(bsr_modrmw_regw) { int cbInstr = MOD_RM(State, &Instr->Operand2, &Instr->Operand1);
Instr->Operation = OPNAME(Bsr); DEREF(Instr->Operand2); Instr->Size = 2+cbInstr; } DISPATCHCOMMON(bsf_modrmw_regw) { int cbInstr = MOD_RM(State, &Instr->Operand2, &Instr->Operand1);
Instr->Operation = OPNAME(Bsf); DEREF(Instr->Operand2); Instr->Size = 2+cbInstr; } DISPATCHCOMMON(lar) { int cbInstr = MOD_RM(State, &Instr->Operand2, &Instr->Operand1);
Instr->Operation = OPNAME(Lar); DEREF(Instr->Operand2); Instr->Size = 2+cbInstr; } DISPATCHCOMMON(lsl) { int cbInstr = MOD_RM(State, &Instr->Operand2, &Instr->Operand1);
Instr->Operation = OPNAME(Lsl); DEREF(Instr->Operand2); Instr->Size = 2+cbInstr; }
|