DisasmCore.cpp revision a483cdaf39353be16051341f24a8f32baa77c72d
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync/* $Id$ */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync/** @file
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * VBox Disassembler - Core Components.
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync/*
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * Copyright (C) 2006-2012 Oracle Corporation
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync *
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * available from http://www.virtualbox.org. This file is free software;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * you can redistribute it and/or modify it under the terms of the GNU
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * General Public License (GPL) as published by the Free Software
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * Foundation, in version 2 as it comes in the "COPYING" file of the
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync/*******************************************************************************
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync* Header Files *
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync*******************************************************************************/
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync#define LOG_GROUP LOG_GROUP_DIS
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync#include <VBox/dis.h>
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync#include <VBox/disopcode.h>
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync#include <VBox/err.h>
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync#include <VBox/log.h>
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync#include <iprt/assert.h>
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync#include <iprt/string.h>
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync#include <iprt/stdarg.h>
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync#include "DisasmInternal.h"
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync/*******************************************************************************
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync* Internal Functions *
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync*******************************************************************************/
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncstatic int disInstrWorker(PDISCPUSTATE pCpu, RTUINTPTR uInstrAddr, PCDISOPCODE paOneByteMap, uint32_t *pcbInstr);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncstatic unsigned disParseInstruction(RTUINTPTR uCodePtr, PCDISOPCODE pOp, PDISCPUSTATE pCpu);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncstatic unsigned QueryModRM(RTUINTPTR uCodePtr, PCDISOPCODE pOp, PDISOPPARAM pParam, PDISCPUSTATE pCpu, unsigned *pSibInc = NULL);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncstatic unsigned QueryModRM_SizeOnly(RTUINTPTR uCodePtr, PCDISOPCODE pOp, PDISOPPARAM pParam, PDISCPUSTATE pCpu, unsigned *pSibInc = NULL);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncstatic void UseSIB(RTUINTPTR uCodePtr, PCDISOPCODE pOp, PDISOPPARAM pParam, PDISCPUSTATE pCpu);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncstatic unsigned ParseSIB_SizeOnly(RTUINTPTR uCodePtr, PCDISOPCODE pOp, PDISOPPARAM pParam, PDISCPUSTATE pCpu);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncstatic void disasmModRMReg(PDISCPUSTATE pCpu, PCDISOPCODE pOp, unsigned idx, PDISOPPARAM pParam, int fRegAddr);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncstatic void disasmModRMReg16(PDISCPUSTATE pCpu, PCDISOPCODE pOp, unsigned idx, PDISOPPARAM pParam);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncstatic void disasmModRMSReg(PDISCPUSTATE pCpu, PCDISOPCODE pOp, unsigned idx, PDISOPPARAM pParam);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncstatic void disValidateLockSequence(PDISCPUSTATE pCpu);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync/* Read functions */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncstatic uint8_t disReadByte(PDISCPUSTATE pCpu, RTUINTPTR pAddress);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncstatic uint16_t disReadWord(PDISCPUSTATE pCpu, RTUINTPTR pAddress);
3a343ca21a267ec3c54e2317e2ed18fe99b8ebbbvboxsyncstatic uint32_t disReadDWord(PDISCPUSTATE pCpu, RTUINTPTR pAddress);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncstatic uint64_t disReadQWord(PDISCPUSTATE pCpu, RTUINTPTR pAddress);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncstatic DECLCALLBACK(int) disReadBytesDefault(PDISCPUSTATE pCpu, uint8_t *pbDst, RTUINTPTR uSrcAddr, uint32_t cbToRead);
3a343ca21a267ec3c54e2317e2ed18fe99b8ebbbvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync/** @name Parsers
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * @{ */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncstatic FNDISPARSE ParseIllegal;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncstatic FNDISPARSE ParseModRM;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncstatic FNDISPARSE ParseModRM_SizeOnly;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncstatic FNDISPARSE UseModRM;
3a343ca21a267ec3c54e2317e2ed18fe99b8ebbbvboxsyncstatic FNDISPARSE ParseImmByte;
3a343ca21a267ec3c54e2317e2ed18fe99b8ebbbvboxsyncstatic FNDISPARSE ParseImmByte_SizeOnly;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncstatic FNDISPARSE ParseImmByteSX;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncstatic FNDISPARSE ParseImmByteSX_SizeOnly;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncstatic FNDISPARSE ParseImmBRel;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncstatic FNDISPARSE ParseImmBRel_SizeOnly;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncstatic FNDISPARSE ParseImmUshort;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncstatic FNDISPARSE ParseImmUshort_SizeOnly;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncstatic FNDISPARSE ParseImmV;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncstatic FNDISPARSE ParseImmV_SizeOnly;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncstatic FNDISPARSE ParseImmVRel;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncstatic FNDISPARSE ParseImmVRel_SizeOnly;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncstatic FNDISPARSE ParseImmZ;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncstatic FNDISPARSE ParseImmZ_SizeOnly;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncstatic FNDISPARSE ParseImmAddr;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncstatic FNDISPARSE ParseImmAddr_SizeOnly;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncstatic FNDISPARSE ParseImmAddrF;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncstatic FNDISPARSE ParseImmAddrF_SizeOnly;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncstatic FNDISPARSE ParseFixedReg;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncstatic FNDISPARSE ParseImmUlong;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncstatic FNDISPARSE ParseImmUlong_SizeOnly;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncstatic FNDISPARSE ParseImmQword;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncstatic FNDISPARSE ParseImmQword_SizeOnly;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncstatic FNDISPARSE ParseTwoByteEsc;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncstatic FNDISPARSE ParseThreeByteEsc4;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncstatic FNDISPARSE ParseThreeByteEsc5;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncstatic FNDISPARSE ParseImmGrpl;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncstatic FNDISPARSE ParseShiftGrp2;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncstatic FNDISPARSE ParseGrp3;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncstatic FNDISPARSE ParseGrp4;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncstatic FNDISPARSE ParseGrp5;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncstatic FNDISPARSE Parse3DNow;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncstatic FNDISPARSE ParseGrp6;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncstatic FNDISPARSE ParseGrp7;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncstatic FNDISPARSE ParseGrp8;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncstatic FNDISPARSE ParseGrp9;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncstatic FNDISPARSE ParseGrp10;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncstatic FNDISPARSE ParseGrp12;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncstatic FNDISPARSE ParseGrp13;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncstatic FNDISPARSE ParseGrp14;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncstatic FNDISPARSE ParseGrp15;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncstatic FNDISPARSE ParseGrp16;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncstatic FNDISPARSE ParseModFence;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncstatic FNDISPARSE ParseNopPause;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncstatic FNDISPARSE ParseYv;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncstatic FNDISPARSE ParseYb;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncstatic FNDISPARSE ParseXv;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncstatic FNDISPARSE ParseXb;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync/** Floating point parsing */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncstatic FNDISPARSE ParseEscFP;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync/** @} */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync/*******************************************************************************
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync* Global Variables *
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync*******************************************************************************/
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync/** Parser opcode table for full disassembly. */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncstatic PFNDISPARSE const g_apfnFullDisasm[IDX_ParseMax] =
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync{
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync ParseIllegal,
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync ParseModRM,
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync UseModRM,
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync ParseImmByte,
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync ParseImmBRel,
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync ParseImmUshort,
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync ParseImmV,
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync ParseImmVRel,
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync ParseImmAddr,
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync ParseFixedReg,
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync ParseImmUlong,
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync ParseImmQword,
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync ParseTwoByteEsc,
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync ParseImmGrpl,
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync ParseShiftGrp2,
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync ParseGrp3,
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync ParseGrp4,
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync ParseGrp5,
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync Parse3DNow,
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync ParseGrp6,
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync ParseGrp7,
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync ParseGrp8,
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync ParseGrp9,
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync ParseGrp10,
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync ParseGrp12,
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync ParseGrp13,
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync ParseGrp14,
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync ParseGrp15,
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync ParseGrp16,
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync ParseModFence,
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync ParseYv,
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync ParseYb,
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync ParseXv,
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync ParseXb,
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync ParseEscFP,
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync ParseNopPause,
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync ParseImmByteSX,
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync ParseImmZ,
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync ParseThreeByteEsc4,
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync ParseThreeByteEsc5,
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync ParseImmAddrF
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync};
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync/** Parser opcode table for only calculating instruction size. */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncstatic PFNDISPARSE const g_apfnCalcSize[IDX_ParseMax] =
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync{
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync ParseIllegal,
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync ParseModRM_SizeOnly,
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync UseModRM,
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync ParseImmByte_SizeOnly,
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync ParseImmBRel_SizeOnly,
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync ParseImmUshort_SizeOnly,
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync ParseImmV_SizeOnly,
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync ParseImmVRel_SizeOnly,
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync ParseImmAddr_SizeOnly,
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync ParseFixedReg,
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync ParseImmUlong_SizeOnly,
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync ParseImmQword_SizeOnly,
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync ParseTwoByteEsc,
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync ParseImmGrpl,
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync ParseShiftGrp2,
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync ParseGrp3,
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync ParseGrp4,
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync ParseGrp5,
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync Parse3DNow,
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync ParseGrp6,
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync ParseGrp7,
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync ParseGrp8,
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync ParseGrp9,
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync ParseGrp10,
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync ParseGrp12,
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync ParseGrp13,
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync ParseGrp14,
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync ParseGrp15,
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync ParseGrp16,
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync ParseModFence,
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync ParseYv,
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync ParseYb,
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync ParseXv,
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync ParseXb,
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync ParseEscFP,
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync ParseNopPause,
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync ParseImmByteSX_SizeOnly,
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync ParseImmZ_SizeOnly,
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync ParseThreeByteEsc4,
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync ParseThreeByteEsc5,
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync ParseImmAddrF_SizeOnly
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync};
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync/**
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * Parses one guest instruction.
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync *
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * The result is found in pCpu and pcbInstr.
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync *
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * @returns VBox status code.
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * @param pvInstr Address of the instruction to decode. This is a
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * real address in the current context that can be
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * accessed without faulting. (Consider
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * DISInstrWithReader if this isn't the case.)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * @param enmCpuMode The CPU mode. DISCPUMODE_32BIT, DISCPUMODE_16BIT, or DISCPUMODE_64BIT.
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * @param pfnReadBytes Callback for reading instruction bytes.
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * @param pvUser User argument for the instruction reader. (Ends up in pvUser.)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * @param pCpu Pointer to cpu structure. Will be initialized.
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * @param pcbInstr Where to store the size of the instruction.
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * NULL is allowed. This is also stored in
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * PDISCPUSTATE::cbInstr.
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncDISDECL(int) DISInstr(const void *pvInstr, DISCPUMODE enmCpuMode, PDISCPUSTATE pCpu, uint32_t *pcbInstr)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync{
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return DISInstEx((uintptr_t)pvInstr, enmCpuMode, DISOPTYPE_ALL, NULL /*pfnReadBytes*/, NULL /*pvUser*/, pCpu, pcbInstr);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync}
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync/**
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * Parses one guest instruction.
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync *
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * The result is found in pCpu and pcbInstr.
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync *
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * @returns VBox status code.
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * @param uInstrAddr Address of the instruction to decode. What this means
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * is left to the pfnReadBytes function.
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * @param enmCpuMode The CPU mode. DISCPUMODE_32BIT, DISCPUMODE_16BIT, or DISCPUMODE_64BIT.
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * @param pfnReadBytes Callback for reading instruction bytes.
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * @param pvUser User argument for the instruction reader. (Ends up in pvUser.)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * @param pCpu Pointer to cpu structure. Will be initialized.
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * @param pcbInstr Where to store the size of the instruction.
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * NULL is allowed. This is also stored in
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * PDISCPUSTATE::cbInstr.
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncDISDECL(int) DISInstrWithReader(RTUINTPTR uInstrAddr, DISCPUMODE enmCpuMode, PFNDISREADBYTES pfnReadBytes, void *pvUser,
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync PDISCPUSTATE pCpu, uint32_t *pcbInstr)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync{
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return DISInstEx(uInstrAddr, enmCpuMode, DISOPTYPE_ALL, pfnReadBytes, pvUser, pCpu, pcbInstr);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync}
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync/**
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * Disassembles on instruction, details in @a pCpu and length in @a pcbInstr.
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync *
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * @returns VBox status code.
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * @param uInstrAddr Address of the instruction to decode. What this means
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * is left to the pfnReadBytes function.
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * @param enmCpuMode The CPU mode. DISCPUMODE_32BIT, DISCPUMODE_16BIT, or DISCPUMODE_64BIT.
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * @param pfnReadBytes Callback for reading instruction bytes.
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * @param fFilter Instruction type filter.
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * @param pvUser User argument for the instruction reader. (Ends up in pvUser.)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * @param pCpu Pointer to CPU structure. With the exception of
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * DISCPUSTATE::pvUser2, the structure will be
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * completely initialized by this API, i.e. no input is
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * taken from it.
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * @param pcbInstr Where to store the size of the instruction. (This
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * is also stored in PDISCPUSTATE::cbInstr.) Optional.
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncDISDECL(int) DISInstEx(RTUINTPTR uInstrAddr, DISCPUMODE enmCpuMode, uint32_t fFilter,
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync PFNDISREADBYTES pfnReadBytes, void *pvUser,
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync PDISCPUSTATE pCpu, uint32_t *pcbInstr)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync{
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync PCDISOPCODE paOneByteMap;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync /*
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * Initialize the CPU state.
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * Note! The RT_BZERO make ASSUMPTIONS about the placement of pvUser2.
dc959f60f6d3e0cba86f7da4d39aa475913a7e10vboxsync */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync RT_BZERO(pCpu, RT_OFFSETOF(DISCPUSTATE, pvUser2));
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
dc959f60f6d3e0cba86f7da4d39aa475913a7e10vboxsync pCpu->uCpuMode = enmCpuMode;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (enmCpuMode == DISCPUMODE_64BIT)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
dc959f60f6d3e0cba86f7da4d39aa475913a7e10vboxsync paOneByteMap = g_aOneByteMapX64;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pCpu->uAddrMode = DISCPUMODE_64BIT;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pCpu->uOpMode = DISCPUMODE_32BIT;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync else
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync paOneByteMap = g_aOneByteMapX86;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pCpu->uAddrMode = enmCpuMode;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pCpu->uOpMode = enmCpuMode;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pCpu->fPrefix = DISPREFIX_NONE;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pCpu->idxSegPrefix = DISSELREG_DS;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pCpu->uInstrAddr = uInstrAddr;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pCpu->pfnDisasmFnTable = g_apfnFullDisasm;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pCpu->fFilter = fFilter;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pCpu->rc = VINF_SUCCESS;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pCpu->pfnReadBytes = pfnReadBytes ? pfnReadBytes : disReadBytesDefault;
dc959f60f6d3e0cba86f7da4d39aa475913a7e10vboxsync pCpu->pvUser = pvUser;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return disInstrWorker(pCpu, uInstrAddr, paOneByteMap, pcbInstr);
dc959f60f6d3e0cba86f7da4d39aa475913a7e10vboxsync}
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync/**
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * Internal worker for DISInstEx.
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync *
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync * @returns VBox status code.
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync * @param pCpu Initialized cpu state.
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync * @param paOneByteMap The one byte opcode map to use.
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync * @param uInstrAddr Instruction address.
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync * @param pcbInstr Where to store the instruction size. Can be NULL.
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync */
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsyncstatic int disInstrWorker(PDISCPUSTATE pCpu, RTUINTPTR uInstrAddr, PCDISOPCODE paOneByteMap, uint32_t *pcbInstr)
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync{
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync /*
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync * Parse byte by byte.
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync */
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync unsigned iByte = 0;
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync unsigned cbInc;
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync for (;;)
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync {
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync uint8_t codebyte = disReadByte(pCpu, uInstrAddr+iByte);
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync uint8_t opcode = paOneByteMap[codebyte].uOpcode;
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync /* Hardcoded assumption about OP_* values!! */
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync if (opcode <= OP_LAST_PREFIX)
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync {
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync /* The REX prefix must precede the opcode byte(s). Any other placement is ignored. */
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync if (opcode != OP_REX)
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync {
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync /** Last prefix byte (for SSE2 extension tables); don't include the REX prefix */
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync pCpu->bLastPrefix = opcode;
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync pCpu->fPrefix &= ~DISPREFIX_REX;
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync }
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync switch (opcode)
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync {
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync case OP_INVALID:
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync if (pcbInstr)
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync *pcbInstr = iByte + 1;
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync return pCpu->rc = VERR_DIS_INVALID_OPCODE;
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync // segment override prefix byte
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync case OP_SEG:
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync pCpu->idxSegPrefix = (DISSELREG)(paOneByteMap[codebyte].fParam1 - OP_PARM_REG_SEG_START);
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync /* Segment prefixes for CS, DS, ES and SS are ignored in long mode. */
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync if ( pCpu->uCpuMode != DISCPUMODE_64BIT
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync || pCpu->idxSegPrefix >= DISSELREG_FS)
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync {
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync pCpu->fPrefix |= DISPREFIX_SEG;
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync }
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync iByte += sizeof(uint8_t);
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync continue; //fetch the next byte
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync // lock prefix byte
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync case OP_LOCK:
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync pCpu->fPrefix |= DISPREFIX_LOCK;
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync iByte += sizeof(uint8_t);
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync continue; //fetch the next byte
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync // address size override prefix byte
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync case OP_ADDRSIZE:
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync pCpu->fPrefix |= DISPREFIX_ADDRSIZE;
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync if (pCpu->uCpuMode == DISCPUMODE_16BIT)
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync pCpu->uAddrMode = DISCPUMODE_32BIT;
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync else
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync if (pCpu->uCpuMode == DISCPUMODE_32BIT)
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync pCpu->uAddrMode = DISCPUMODE_16BIT;
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync else
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync pCpu->uAddrMode = DISCPUMODE_32BIT; /* 64 bits */
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync iByte += sizeof(uint8_t);
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync continue; //fetch the next byte
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync // operand size override prefix byte
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync case OP_OPSIZE:
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync pCpu->fPrefix |= DISPREFIX_OPSIZE;
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync if (pCpu->uCpuMode == DISCPUMODE_16BIT)
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync pCpu->uOpMode = DISCPUMODE_32BIT;
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync else
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync pCpu->uOpMode = DISCPUMODE_16BIT; /* for 32 and 64 bits mode (there is no 32 bits operand size override prefix) */
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync iByte += sizeof(uint8_t);
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync continue; //fetch the next byte
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync // rep and repne are not really prefixes, but we'll treat them as such
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync case OP_REPE:
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync pCpu->fPrefix |= DISPREFIX_REP;
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync iByte += sizeof(uint8_t);
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync continue; //fetch the next byte
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync case OP_REPNE:
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync pCpu->fPrefix |= DISPREFIX_REPNE;
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync iByte += sizeof(uint8_t);
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync continue; //fetch the next byte
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync case OP_REX:
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync Assert(pCpu->uCpuMode == DISCPUMODE_64BIT);
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync /* REX prefix byte */
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync pCpu->fPrefix |= DISPREFIX_REX;
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync pCpu->fRexPrefix = DISPREFIX_REX_OP_2_FLAGS(paOneByteMap[codebyte].fParam1);
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync iByte += sizeof(uint8_t);
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync if (pCpu->fRexPrefix & DISPREFIX_REX_FLAGS_W)
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync pCpu->uOpMode = DISCPUMODE_64BIT; /* overrides size prefix byte */
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync continue; //fetch the next byte
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync }
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync }
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync unsigned uIdx = iByte;
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync iByte += sizeof(uint8_t); //first opcode byte
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync pCpu->bOpCode = codebyte;
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync cbInc = disParseInstruction(uInstrAddr + iByte, &paOneByteMap[pCpu->bOpCode], pCpu);
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync iByte += cbInc;
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync break;
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync }
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync AssertMsg(pCpu->cbInstr == iByte || RT_FAILURE_NP(pCpu->rc), ("%u %u\n", pCpu->cbInstr, iByte));
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync pCpu->cbInstr = iByte;
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync if (pcbInstr)
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync *pcbInstr = iByte;
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync if (pCpu->fPrefix & DISPREFIX_LOCK)
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync disValidateLockSequence(pCpu);
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync return pCpu->rc;
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync}
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync//*****************************************************************************
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync//*****************************************************************************
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsyncstatic unsigned disParseInstruction(RTUINTPTR uCodePtr, PCDISOPCODE pOp, PDISCPUSTATE pCpu)
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync{
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync int size = 0;
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync bool fFiltered = false;
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync Assert(uCodePtr && pOp && pCpu);
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync // Store the opcode format string for disasmPrintf
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync pCpu->pCurInstr = pOp;
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync /*
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync * Apply filter to instruction type to determine if a full disassembly is required.
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync * Note! Multibyte opcodes are always marked harmless until the final byte.
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync */
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync if ((pOp->fOpType & pCpu->fFilter) == 0)
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync {
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync fFiltered = true;
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync pCpu->pfnDisasmFnTable = g_apfnCalcSize;
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync }
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync else
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync {
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync /* Not filtered out -> full disassembly */
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync pCpu->pfnDisasmFnTable = g_apfnFullDisasm;
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync }
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync // Should contain the parameter type on input
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync pCpu->Param1.fParam = pOp->fParam1;
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync pCpu->Param2.fParam = pOp->fParam2;
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync pCpu->Param3.fParam = pOp->fParam3;
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync /* Correct the operand size if the instruction is marked as forced or default 64 bits */
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync if (pCpu->uCpuMode == DISCPUMODE_64BIT)
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync {
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync if (pOp->fOpType & DISOPTYPE_FORCED_64_OP_SIZE)
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync pCpu->uOpMode = DISCPUMODE_64BIT;
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync else
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync if ( (pOp->fOpType & DISOPTYPE_DEFAULT_64_OP_SIZE)
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync && !(pCpu->fPrefix & DISPREFIX_OPSIZE))
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync pCpu->uOpMode = DISCPUMODE_64BIT;
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync }
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync else
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync if (pOp->fOpType & DISOPTYPE_FORCED_32_OP_SIZE_X86)
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync {
9cdd4d805ecb43126372f7cf12e4032836cb738avboxsync /* Forced 32 bits operand size for certain instructions (mov crx, mov drx). */
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync Assert(pCpu->uCpuMode != DISCPUMODE_64BIT);
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync pCpu->uOpMode = DISCPUMODE_32BIT;
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync }
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync if (pOp->idxParse1 != IDX_ParseNop)
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync {
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync size += pCpu->pfnDisasmFnTable[pOp->idxParse1](uCodePtr, pOp, &pCpu->Param1, pCpu);
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync if (fFiltered == false) pCpu->Param1.cb = DISGetParamSize(pCpu, &pCpu->Param1);
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync }
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync if (pOp->idxParse2 != IDX_ParseNop)
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync {
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync size += pCpu->pfnDisasmFnTable[pOp->idxParse2](uCodePtr+size, pOp, &pCpu->Param2, pCpu);
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync if (fFiltered == false) pCpu->Param2.cb = DISGetParamSize(pCpu, &pCpu->Param2);
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync }
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync if (pOp->idxParse3 != IDX_ParseNop)
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync {
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync size += pCpu->pfnDisasmFnTable[pOp->idxParse3](uCodePtr+size, pOp, &pCpu->Param3, pCpu);
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync if (fFiltered == false) pCpu->Param3.cb = DISGetParamSize(pCpu, &pCpu->Param3);
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync }
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync // else simple one byte instruction
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync return size;
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync}
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync//*****************************************************************************
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync/* Floating point opcode parsing */
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync//*****************************************************************************
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsyncunsigned ParseEscFP(RTUINTPTR uCodePtr, PCDISOPCODE pOp, PDISOPPARAM pParam, PDISCPUSTATE pCpu)
bf7ab711aa3580b3a587dcbc4653fe78c99fff37vboxsync{
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync int index;
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync PCDISOPCODE fpop;
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync unsigned size = 0;
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync unsigned ModRM;
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync NOREF(pOp);
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync ModRM = disReadByte(pCpu, uCodePtr);
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync index = pCpu->bOpCode - 0xD8;
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync if (ModRM <= 0xBF)
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync {
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync fpop = &(g_apMapX86_FP_Low[index])[MODRM_REG(ModRM)];
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync pCpu->pCurInstr = (PCDISOPCODE)fpop;
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync // Should contain the parameter type on input
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync pCpu->Param1.fParam = fpop->fParam1;
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync pCpu->Param2.fParam = fpop->fParam2;
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync }
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync else
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync {
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync fpop = &(g_apMapX86_FP_High[index])[ModRM - 0xC0];
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync pCpu->pCurInstr = (PCDISOPCODE)fpop;
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync }
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync /*
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync * Apply filter to instruction type to determine if a full disassembly is required.
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync * @note Multibyte opcodes are always marked harmless until the final byte.
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync */
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync if ((fpop->fOpType & pCpu->fFilter) == 0)
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync pCpu->pfnDisasmFnTable = g_apfnCalcSize;
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync else
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync /* Not filtered out -> full disassembly */
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync pCpu->pfnDisasmFnTable = g_apfnFullDisasm;
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync /* Correct the operand size if the instruction is marked as forced or default 64 bits */
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync if (pCpu->uCpuMode == DISCPUMODE_64BIT)
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync {
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync /* Note: redundant, but just in case this ever changes */
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync if (fpop->fOpType & DISOPTYPE_FORCED_64_OP_SIZE)
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync pCpu->uOpMode = DISCPUMODE_64BIT;
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync else
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync if ( (fpop->fOpType & DISOPTYPE_DEFAULT_64_OP_SIZE)
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync && !(pCpu->fPrefix & DISPREFIX_OPSIZE))
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync pCpu->uOpMode = DISCPUMODE_64BIT;
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync }
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync // Little hack to make sure the ModRM byte is included in the returned size
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync if (fpop->idxParse1 != IDX_ParseModRM && fpop->idxParse2 != IDX_ParseModRM)
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync size = sizeof(uint8_t); //ModRM byte
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync if (fpop->idxParse1 != IDX_ParseNop)
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync size += pCpu->pfnDisasmFnTable[fpop->idxParse1](uCodePtr+size, (PCDISOPCODE)fpop, pParam, pCpu);
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync if (fpop->idxParse2 != IDX_ParseNop)
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync size += pCpu->pfnDisasmFnTable[fpop->idxParse2](uCodePtr+size, (PCDISOPCODE)fpop, pParam, pCpu);
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync return size;
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync}
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync//*****************************************************************************
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync// SIB byte: (32 bits mode only)
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync// 7 - 6 5 - 3 2-0
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync// Scale Index Base
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync//*****************************************************************************
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsyncstatic const char *szSIBBaseReg[8] = {"EAX", "ECX", "EDX", "EBX", "ESP", "EBP", "ESI", "EDI"};
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsyncstatic const char *szSIBIndexReg[8] = {"EAX", "ECX", "EDX", "EBX", NULL, "EBP", "ESI", "EDI"};
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsyncstatic const char *szSIBBaseReg64[16] = {"RAX", "RCX", "RDX", "RBX", "RSP", "RBP", "RSI", "RDI", "R8", "R9", "R10", "R11", "R12", "R13", "R14", "R15"};
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsyncstatic const char *szSIBIndexReg64[16]= {"RAX", "RCX", "RDX", "RBX", NULL, "RBP", "RSI", "RDI", "R8", "R9", "R10", "R11", "R12", "R13", "R14", "R15"};
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync#if !defined(DIS_CORE_ONLY) && defined(LOG_ENABLED) || defined(_MSC_VER)
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsyncstatic const char *szSIBScale[4] = {"", "*2", "*4", "*8"};
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync#endif
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync//*****************************************************************************
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsyncvoid UseSIB(RTUINTPTR uCodePtr, PCDISOPCODE pOp, PDISOPPARAM pParam, PDISCPUSTATE pCpu)
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync{
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync unsigned regtype;
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync const char **ppszSIBIndexReg;
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync const char **ppszSIBBaseReg;
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync NOREF(uCodePtr); NOREF(pOp);
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync unsigned scale = pCpu->SIB.Bits.Scale;
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync unsigned base = pCpu->SIB.Bits.Base;
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync unsigned index = pCpu->SIB.Bits.Index;
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync if (pCpu->uAddrMode == DISCPUMODE_32BIT)
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync {
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync ppszSIBIndexReg = szSIBIndexReg;
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync ppszSIBBaseReg = szSIBBaseReg;
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync regtype = DISUSE_REG_GEN32;
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync }
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync else
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync {
4c98b8b05f3783351cf256cc90cd4478fb28b62bvboxsync ppszSIBIndexReg = szSIBIndexReg64;
4c98b8b05f3783351cf256cc90cd4478fb28b62bvboxsync ppszSIBBaseReg = szSIBBaseReg64;
4c98b8b05f3783351cf256cc90cd4478fb28b62bvboxsync regtype = DISUSE_REG_GEN64;
4c98b8b05f3783351cf256cc90cd4478fb28b62bvboxsync }
4c98b8b05f3783351cf256cc90cd4478fb28b62bvboxsync
4c98b8b05f3783351cf256cc90cd4478fb28b62bvboxsync if (ppszSIBIndexReg[index])
4c98b8b05f3783351cf256cc90cd4478fb28b62bvboxsync {
4c98b8b05f3783351cf256cc90cd4478fb28b62bvboxsync pParam->fUse |= DISUSE_INDEX | regtype;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pParam->Index.idxGenReg = index;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (scale != 0)
4c98b8b05f3783351cf256cc90cd4478fb28b62bvboxsync {
4c98b8b05f3783351cf256cc90cd4478fb28b62bvboxsync pParam->fUse |= DISUSE_SCALE;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pParam->uScale = (1<<scale);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (base == 5 && pCpu->ModRM.Bits.Mod == 0)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync // [scaled index] + disp32
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (pCpu->uAddrMode == DISCPUMODE_32BIT)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pParam->fUse |= DISUSE_DISPLACEMENT32;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pParam->uDisp.i32 = pCpu->i32SibDisp;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync else
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync { /* sign-extend to 64 bits */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pParam->fUse |= DISUSE_DISPLACEMENT64;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pParam->uDisp.i64 = pCpu->i32SibDisp;
4c98b8b05f3783351cf256cc90cd4478fb28b62bvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync else
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pParam->fUse |= DISUSE_BASE | regtype;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pParam->base.reg_gen = base;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return; /* Already fetched everything in ParseSIB; no size returned */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync}
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync//*****************************************************************************
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync//*****************************************************************************
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncunsigned ParseSIB(RTUINTPTR uCodePtr, PCDISOPCODE pOp, PDISOPPARAM pParam, PDISCPUSTATE pCpu)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync{
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync unsigned size = sizeof(uint8_t);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync unsigned SIB;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync NOREF(pOp); NOREF(pParam);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync SIB = disReadByte(pCpu, uCodePtr);
4c98b8b05f3783351cf256cc90cd4478fb28b62bvboxsync uCodePtr += size;
4c98b8b05f3783351cf256cc90cd4478fb28b62bvboxsync
4c98b8b05f3783351cf256cc90cd4478fb28b62bvboxsync pCpu->SIB.Bits.Base = SIB_BASE(SIB);
4c98b8b05f3783351cf256cc90cd4478fb28b62bvboxsync pCpu->SIB.Bits.Index = SIB_INDEX(SIB);
4c98b8b05f3783351cf256cc90cd4478fb28b62bvboxsync pCpu->SIB.Bits.Scale = SIB_SCALE(SIB);
4c98b8b05f3783351cf256cc90cd4478fb28b62bvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (pCpu->fPrefix & DISPREFIX_REX)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync /* REX.B extends the Base field if not scaled index + disp32 */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (!(pCpu->SIB.Bits.Base == 5 && pCpu->ModRM.Bits.Mod == 0))
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pCpu->SIB.Bits.Base |= ((!!(pCpu->fRexPrefix & DISPREFIX_REX_FLAGS_B)) << 3);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pCpu->SIB.Bits.Index |= ((!!(pCpu->fRexPrefix & DISPREFIX_REX_FLAGS_X)) << 3);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if ( pCpu->SIB.Bits.Base == 5
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync && pCpu->ModRM.Bits.Mod == 0)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync /* Additional 32 bits displacement. No change in long mode. */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pCpu->i32SibDisp = disReadDWord(pCpu, uCodePtr);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync size += sizeof(int32_t);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return size;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync}
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync//*****************************************************************************
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync//*****************************************************************************
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncunsigned ParseSIB_SizeOnly(RTUINTPTR uCodePtr, PCDISOPCODE pOp, PDISOPPARAM pParam, PDISCPUSTATE pCpu)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync{
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync unsigned size = sizeof(uint8_t);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync unsigned SIB;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync NOREF(pOp); NOREF(pParam);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync SIB = disReadByte(pCpu, uCodePtr);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync uCodePtr += size;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pCpu->SIB.Bits.Base = SIB_BASE(SIB);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pCpu->SIB.Bits.Index = SIB_INDEX(SIB);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pCpu->SIB.Bits.Scale = SIB_SCALE(SIB);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (pCpu->fPrefix & DISPREFIX_REX)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync /* REX.B extends the Base field. */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pCpu->SIB.Bits.Base |= ((!!(pCpu->fRexPrefix & DISPREFIX_REX_FLAGS_B)) << 3);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync /* REX.X extends the Index field. */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pCpu->SIB.Bits.Index |= ((!!(pCpu->fRexPrefix & DISPREFIX_REX_FLAGS_X)) << 3);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if ( pCpu->SIB.Bits.Base == 5
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync && pCpu->ModRM.Bits.Mod == 0)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync /* Additional 32 bits displacement. No change in long mode. */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync size += sizeof(int32_t);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return size;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync}
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync//*****************************************************************************
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync// ModR/M byte:
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync// 7 - 6 5 - 3 2-0
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync// Mod Reg/Opcode R/M
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync//*****************************************************************************
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncunsigned UseModRM(RTUINTPTR uCodePtr, PCDISOPCODE pOp, PDISOPPARAM pParam, PDISCPUSTATE pCpu)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync{
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync unsigned vtype = OP_PARM_VTYPE(pParam->fParam);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync unsigned reg = pCpu->ModRM.Bits.Reg;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync unsigned mod = pCpu->ModRM.Bits.Mod;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync unsigned rm = pCpu->ModRM.Bits.Rm;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync switch (vtype)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync case OP_PARM_G: //general purpose register
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync disasmModRMReg(pCpu, pOp, reg, pParam, 0);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return 0;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync default:
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (IS_OP_PARM_RARE(vtype))
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync switch (vtype)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync case OP_PARM_C: //control register
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pParam->fUse |= DISUSE_REG_CR;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if ( pCpu->pCurInstr->uOpcode == OP_MOV_CR
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync && pCpu->uOpMode == DISCPUMODE_32BIT
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync && (pCpu->fPrefix & DISPREFIX_LOCK))
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pCpu->fPrefix &= ~DISPREFIX_LOCK;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pParam->base.reg_ctrl = DISCREG_CR8;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync else
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pParam->base.reg_ctrl = reg;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return 0;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync case OP_PARM_D: //debug register
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pParam->fUse |= DISUSE_REG_DBG;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pParam->base.reg_dbg = reg;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return 0;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync case OP_PARM_P: //MMX register
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync reg &= 7; /* REX.R has no effect here */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pParam->fUse |= DISUSE_REG_MMX;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pParam->base.reg_mmx = reg;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return 0;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync case OP_PARM_S: //segment register
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync reg &= 7; /* REX.R has no effect here */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync disasmModRMSReg(pCpu, pOp, reg, pParam);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pParam->fUse |= DISUSE_REG_SEG;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return 0;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync case OP_PARM_T: //test register
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync reg &= 7; /* REX.R has no effect here */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pParam->fUse |= DISUSE_REG_TEST;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pParam->base.reg_test = reg;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return 0;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync case OP_PARM_W: //XMM register or memory operand
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (mod != 3)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync break; /* memory operand */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync reg = rm; /* the RM field specifies the xmm register */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync /* else no break */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync case OP_PARM_V: //XMM register
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pParam->fUse |= DISUSE_REG_XMM;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pParam->base.reg_xmm = reg;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return 0;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync /* @todo bound */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (pCpu->uAddrMode != DISCPUMODE_16BIT)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync Assert(pCpu->uAddrMode == DISCPUMODE_32BIT || pCpu->uAddrMode == DISCPUMODE_64BIT);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync /*
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * Note: displacements in long mode are 8 or 32 bits and sign-extended to 64 bits
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync switch (mod)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync case 0: //effective address
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (rm == 4)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync { /* SIB byte follows ModRM */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync UseSIB(uCodePtr, pOp, pParam, pCpu);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync else
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (rm == 5)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync /* 32 bits displacement */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (pCpu->uCpuMode != DISCPUMODE_64BIT)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pParam->fUse |= DISUSE_DISPLACEMENT32;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pParam->uDisp.i32 = pCpu->i32SibDisp;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync else
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pParam->fUse |= DISUSE_RIPDISPLACEMENT32;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pParam->uDisp.i32 = pCpu->i32SibDisp;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync else
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync { //register address
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pParam->fUse |= DISUSE_BASE;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync disasmModRMReg(pCpu, pOp, rm, pParam, 1);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync break;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync case 1: //effective address + 8 bits displacement
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (rm == 4) {//SIB byte follows ModRM
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync UseSIB(uCodePtr, pOp, pParam, pCpu);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync else
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pParam->fUse |= DISUSE_BASE;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync disasmModRMReg(pCpu, pOp, rm, pParam, 1);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pParam->uDisp.i8 = pCpu->i32SibDisp;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pParam->fUse |= DISUSE_DISPLACEMENT8;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync break;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync case 2: //effective address + 32 bits displacement
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (rm == 4) {//SIB byte follows ModRM
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync UseSIB(uCodePtr, pOp, pParam, pCpu);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync else
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pParam->fUse |= DISUSE_BASE;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync disasmModRMReg(pCpu, pOp, rm, pParam, 1);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pParam->uDisp.i32 = pCpu->i32SibDisp;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pParam->fUse |= DISUSE_DISPLACEMENT32;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync break;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync case 3: //registers
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync disasmModRMReg(pCpu, pOp, rm, pParam, 0);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync break;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync else
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {//16 bits addressing mode
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync switch (mod)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync case 0: //effective address
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (rm == 6)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {//16 bits displacement
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pParam->uDisp.i16 = pCpu->i32SibDisp;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pParam->fUse |= DISUSE_DISPLACEMENT16;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync else
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pParam->fUse |= DISUSE_BASE;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync disasmModRMReg16(pCpu, pOp, rm, pParam);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync break;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync case 1: //effective address + 8 bits displacement
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync disasmModRMReg16(pCpu, pOp, rm, pParam);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pParam->uDisp.i8 = pCpu->i32SibDisp;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pParam->fUse |= DISUSE_BASE | DISUSE_DISPLACEMENT8;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync break;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync case 2: //effective address + 16 bits displacement
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync disasmModRMReg16(pCpu, pOp, rm, pParam);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pParam->uDisp.i16 = pCpu->i32SibDisp;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pParam->fUse |= DISUSE_BASE | DISUSE_DISPLACEMENT16;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync break;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync case 3: //registers
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync disasmModRMReg(pCpu, pOp, rm, pParam, 0);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync break;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return 0; //everything was already fetched in ParseModRM
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync}
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync//*****************************************************************************
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync// Query the size of the ModRM parameters and fetch the immediate data (if any)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync//*****************************************************************************
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncunsigned QueryModRM(RTUINTPTR uCodePtr, PCDISOPCODE pOp, PDISOPPARAM pParam, PDISCPUSTATE pCpu, unsigned *pSibInc)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync{
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync unsigned sibinc;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync unsigned size = 0;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync // unsigned reg = pCpu->ModRM.Bits.Reg;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync unsigned mod = pCpu->ModRM.Bits.Mod;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync unsigned rm = pCpu->ModRM.Bits.Rm;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (!pSibInc)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pSibInc = &sibinc;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync *pSibInc = 0;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (pCpu->uAddrMode != DISCPUMODE_16BIT)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync Assert(pCpu->uAddrMode == DISCPUMODE_32BIT || pCpu->uAddrMode == DISCPUMODE_64BIT);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync /*
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * Note: displacements in long mode are 8 or 32 bits and sign-extended to 64 bits
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (mod != 3 && rm == 4)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync { /* SIB byte follows ModRM */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync *pSibInc = ParseSIB(uCodePtr, pOp, pParam, pCpu);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync uCodePtr += *pSibInc;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync size += *pSibInc;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync switch (mod)
4c98b8b05f3783351cf256cc90cd4478fb28b62bvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync case 0: /* Effective address */
4c98b8b05f3783351cf256cc90cd4478fb28b62bvboxsync if (rm == 5) { /* 32 bits displacement */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pCpu->i32SibDisp = disReadDWord(pCpu, uCodePtr);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync size += sizeof(int32_t);
4c98b8b05f3783351cf256cc90cd4478fb28b62bvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync /* else register address */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync break;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync case 1: /* Effective address + 8 bits displacement */
4c98b8b05f3783351cf256cc90cd4478fb28b62bvboxsync pCpu->i32SibDisp = (int8_t)disReadByte(pCpu, uCodePtr);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync size += sizeof(char);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync break;
4c98b8b05f3783351cf256cc90cd4478fb28b62bvboxsync
4c98b8b05f3783351cf256cc90cd4478fb28b62bvboxsync case 2: /* Effective address + 32 bits displacement */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pCpu->i32SibDisp = disReadDWord(pCpu, uCodePtr);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync size += sizeof(int32_t);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync break;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync case 3: /* registers */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync break;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync else
4c98b8b05f3783351cf256cc90cd4478fb28b62bvboxsync {
4c98b8b05f3783351cf256cc90cd4478fb28b62bvboxsync /* 16 bits mode */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync switch (mod)
4c98b8b05f3783351cf256cc90cd4478fb28b62bvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync case 0: /* Effective address */
4c98b8b05f3783351cf256cc90cd4478fb28b62bvboxsync if (rm == 6) {
4c98b8b05f3783351cf256cc90cd4478fb28b62bvboxsync pCpu->i32SibDisp = disReadWord(pCpu, uCodePtr);
4c98b8b05f3783351cf256cc90cd4478fb28b62bvboxsync size += sizeof(uint16_t);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
4c98b8b05f3783351cf256cc90cd4478fb28b62bvboxsync /* else register address */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync break;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
4c98b8b05f3783351cf256cc90cd4478fb28b62bvboxsync case 1: /* Effective address + 8 bits displacement */
4c98b8b05f3783351cf256cc90cd4478fb28b62bvboxsync pCpu->i32SibDisp = (int8_t)disReadByte(pCpu, uCodePtr);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync size += sizeof(char);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync break;
4c98b8b05f3783351cf256cc90cd4478fb28b62bvboxsync
4c98b8b05f3783351cf256cc90cd4478fb28b62bvboxsync case 2: /* Effective address + 32 bits displacement */
4c98b8b05f3783351cf256cc90cd4478fb28b62bvboxsync pCpu->i32SibDisp = (int16_t)disReadWord(pCpu, uCodePtr);
4c98b8b05f3783351cf256cc90cd4478fb28b62bvboxsync size += sizeof(uint16_t);
4c98b8b05f3783351cf256cc90cd4478fb28b62bvboxsync break;
4c98b8b05f3783351cf256cc90cd4478fb28b62bvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync case 3: /* registers */
4c98b8b05f3783351cf256cc90cd4478fb28b62bvboxsync break;
4c98b8b05f3783351cf256cc90cd4478fb28b62bvboxsync }
3a343ca21a267ec3c54e2317e2ed18fe99b8ebbbvboxsync }
4c98b8b05f3783351cf256cc90cd4478fb28b62bvboxsync return size;
3a343ca21a267ec3c54e2317e2ed18fe99b8ebbbvboxsync}
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync//*****************************************************************************
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync// Query the size of the ModRM parameters and fetch the immediate data (if any)
4c98b8b05f3783351cf256cc90cd4478fb28b62bvboxsync//*****************************************************************************
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncunsigned QueryModRM_SizeOnly(RTUINTPTR uCodePtr, PCDISOPCODE pOp, PDISOPPARAM pParam, PDISCPUSTATE pCpu, unsigned *pSibInc)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync{
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync unsigned sibinc;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync unsigned size = 0;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync // unsigned reg = pCpu->ModRM.Bits.Reg;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync unsigned mod = pCpu->ModRM.Bits.Mod;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync unsigned rm = pCpu->ModRM.Bits.Rm;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (!pSibInc)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pSibInc = &sibinc;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync *pSibInc = 0;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (pCpu->uAddrMode != DISCPUMODE_16BIT)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync Assert(pCpu->uAddrMode == DISCPUMODE_32BIT || pCpu->uAddrMode == DISCPUMODE_64BIT);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync /*
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * Note: displacements in long mode are 8 or 32 bits and sign-extended to 64 bits
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (mod != 3 && rm == 4)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync { /* SIB byte follows ModRM */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync *pSibInc = ParseSIB_SizeOnly(uCodePtr, pOp, pParam, pCpu);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync uCodePtr += *pSibInc;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync size += *pSibInc;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync switch (mod)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync case 0: //effective address
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (rm == 5) { /* 32 bits displacement */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync size += sizeof(int32_t);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync /* else register address */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync break;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync case 1: /* Effective address + 8 bits displacement */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync size += sizeof(char);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync break;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync case 2: /* Effective address + 32 bits displacement */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync size += sizeof(int32_t);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync break;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync case 3: /* registers */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync break;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync else
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync /* 16 bits mode */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync switch (mod)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync case 0: //effective address
3a343ca21a267ec3c54e2317e2ed18fe99b8ebbbvboxsync if (rm == 6) {
3a343ca21a267ec3c54e2317e2ed18fe99b8ebbbvboxsync size += sizeof(uint16_t);
3a343ca21a267ec3c54e2317e2ed18fe99b8ebbbvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync /* else register address */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync break;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync case 1: /* Effective address + 8 bits displacement */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync size += sizeof(char);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync break;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync case 2: /* Effective address + 32 bits displacement */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync size += sizeof(uint16_t);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync break;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync case 3: /* registers */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync break;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return size;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync}
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync//*****************************************************************************
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync//*****************************************************************************
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncunsigned ParseIllegal(RTUINTPTR uCodePtr, PCDISOPCODE pOp, PDISOPPARAM pParam, PDISCPUSTATE pCpu)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync{
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync NOREF(uCodePtr); NOREF(pOp); NOREF(pParam); NOREF(pCpu);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync AssertFailed();
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return 0;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync}
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync//*****************************************************************************
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync//*****************************************************************************
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncunsigned ParseModRM(RTUINTPTR uCodePtr, PCDISOPCODE pOp, PDISOPPARAM pParam, PDISCPUSTATE pCpu)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync{
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync unsigned size = sizeof(uint8_t); //ModRM byte
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync unsigned sibinc, ModRM;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync ModRM = disReadByte(pCpu, uCodePtr);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync uCodePtr += sizeof(uint8_t);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pCpu->ModRM.Bits.Rm = MODRM_RM(ModRM);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pCpu->ModRM.Bits.Mod = MODRM_MOD(ModRM);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pCpu->ModRM.Bits.Reg = MODRM_REG(ModRM);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync /* Disregard the mod bits for certain instructions (mov crx, mov drx).
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync *
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * From the AMD manual:
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * This instruction is always treated as a register-to-register (MOD = 11) instruction, regardless of the
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * encoding of the MOD field in the MODR/M byte.
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (pOp->fOpType & DISOPTYPE_MOD_FIXED_11)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pCpu->ModRM.Bits.Mod = 3;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (pCpu->fPrefix & DISPREFIX_REX)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync Assert(pCpu->uCpuMode == DISCPUMODE_64BIT);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync /* REX.R extends the Reg field. */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pCpu->ModRM.Bits.Reg |= ((!!(pCpu->fRexPrefix & DISPREFIX_REX_FLAGS_R)) << 3);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync /* REX.B extends the Rm field if there is no SIB byte nor a 32 bits displacement */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (!( pCpu->ModRM.Bits.Mod != 3
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync && pCpu->ModRM.Bits.Rm == 4)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync &&
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync !( pCpu->ModRM.Bits.Mod == 0
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync && pCpu->ModRM.Bits.Rm == 5))
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pCpu->ModRM.Bits.Rm |= ((!!(pCpu->fRexPrefix & DISPREFIX_REX_FLAGS_B)) << 3);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync size += QueryModRM(uCodePtr, pOp, pParam, pCpu, &sibinc);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync uCodePtr += sibinc;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync UseModRM(uCodePtr, pOp, pParam, pCpu);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return size;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync}
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync//*****************************************************************************
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync//*****************************************************************************
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncunsigned ParseModRM_SizeOnly(RTUINTPTR uCodePtr, PCDISOPCODE pOp, PDISOPPARAM pParam, PDISCPUSTATE pCpu)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync{
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync unsigned size = sizeof(uint8_t); //ModRM byte
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync unsigned sibinc, ModRM;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync ModRM = disReadByte(pCpu, uCodePtr);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync uCodePtr += sizeof(uint8_t);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pCpu->ModRM.Bits.Rm = MODRM_RM(ModRM);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pCpu->ModRM.Bits.Mod = MODRM_MOD(ModRM);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pCpu->ModRM.Bits.Reg = MODRM_REG(ModRM);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync /* Disregard the mod bits for certain instructions (mov crx, mov drx).
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync *
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * From the AMD manual:
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * This instruction is always treated as a register-to-register (MOD = 11) instruction, regardless of the
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * encoding of the MOD field in the MODR/M byte.
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (pOp->fOpType & DISOPTYPE_MOD_FIXED_11)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pCpu->ModRM.Bits.Mod = 3;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (pCpu->fPrefix & DISPREFIX_REX)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync Assert(pCpu->uCpuMode == DISCPUMODE_64BIT);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync /* REX.R extends the Reg field. */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pCpu->ModRM.Bits.Reg |= ((!!(pCpu->fRexPrefix & DISPREFIX_REX_FLAGS_R)) << 3);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync /* REX.B extends the Rm field if there is no SIB byte nor a 32 bits displacement */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (!( pCpu->ModRM.Bits.Mod != 3
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync && pCpu->ModRM.Bits.Rm == 4)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync &&
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync !( pCpu->ModRM.Bits.Mod == 0
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync && pCpu->ModRM.Bits.Rm == 5))
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pCpu->ModRM.Bits.Rm |= ((!!(pCpu->fRexPrefix & DISPREFIX_REX_FLAGS_B)) << 3);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync size += QueryModRM_SizeOnly(uCodePtr, pOp, pParam, pCpu, &sibinc);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync uCodePtr += sibinc;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync /* UseModRM is not necessary here; we're only interested in the opcode size */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return size;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync}
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync//*****************************************************************************
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync//*****************************************************************************
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncunsigned ParseModFence(RTUINTPTR uCodePtr, PCDISOPCODE pOp, PDISOPPARAM pParam, PDISCPUSTATE pCpu)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync{
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync ////AssertMsgFailed(("??\n"));
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync //nothing to do apparently
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync NOREF(uCodePtr); NOREF(pOp); NOREF(pParam); NOREF(pCpu);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return 0;
e6ad2e18e663b076aeabfec994947514566a7accvboxsync}
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync//*****************************************************************************
e6ad2e18e663b076aeabfec994947514566a7accvboxsync//*****************************************************************************
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncunsigned ParseImmByte(RTUINTPTR uCodePtr, PCDISOPCODE pOp, PDISOPPARAM pParam, PDISCPUSTATE pCpu)
e6ad2e18e663b076aeabfec994947514566a7accvboxsync{
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync NOREF(pOp);
e6ad2e18e663b076aeabfec994947514566a7accvboxsync pParam->uValue = disReadByte(pCpu, uCodePtr);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pParam->fUse |= DISUSE_IMMEDIATE8;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pParam->cb = sizeof(uint8_t);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return sizeof(uint8_t);
e6ad2e18e663b076aeabfec994947514566a7accvboxsync}
e6ad2e18e663b076aeabfec994947514566a7accvboxsync//*****************************************************************************
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync//*****************************************************************************
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncunsigned ParseImmByte_SizeOnly(RTUINTPTR uCodePtr, PCDISOPCODE pOp, PDISOPPARAM pParam, PDISCPUSTATE pCpu)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync{
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync NOREF(uCodePtr); NOREF(pOp); NOREF(pParam); NOREF(pCpu);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return sizeof(uint8_t);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync}
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync//*****************************************************************************
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync//*****************************************************************************
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncunsigned ParseImmByteSX(RTUINTPTR uCodePtr, PCDISOPCODE pOp, PDISOPPARAM pParam, PDISCPUSTATE pCpu)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync{
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync NOREF(pOp);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (pCpu->uOpMode == DISCPUMODE_32BIT)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pParam->uValue = (uint32_t)(int8_t)disReadByte(pCpu, uCodePtr);
e6ad2e18e663b076aeabfec994947514566a7accvboxsync pParam->fUse |= DISUSE_IMMEDIATE32_SX8;
dc959f60f6d3e0cba86f7da4d39aa475913a7e10vboxsync pParam->cb = sizeof(uint32_t);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync else
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (pCpu->uOpMode == DISCPUMODE_64BIT)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pParam->uValue = (uint64_t)(int8_t)disReadByte(pCpu, uCodePtr);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pParam->fUse |= DISUSE_IMMEDIATE64_SX8;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pParam->cb = sizeof(uint64_t);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync else
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pParam->uValue = (uint16_t)(int8_t)disReadByte(pCpu, uCodePtr);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pParam->fUse |= DISUSE_IMMEDIATE16_SX8;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pParam->cb = sizeof(uint16_t);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return sizeof(uint8_t);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync}
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync//*****************************************************************************
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync//*****************************************************************************
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncunsigned ParseImmByteSX_SizeOnly(RTUINTPTR uCodePtr, PCDISOPCODE pOp, PDISOPPARAM pParam, PDISCPUSTATE pCpu)
dc959f60f6d3e0cba86f7da4d39aa475913a7e10vboxsync{
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync NOREF(uCodePtr); NOREF(pOp); NOREF(pParam); NOREF(pCpu);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return sizeof(uint8_t);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync}
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync//*****************************************************************************
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync//*****************************************************************************
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncunsigned ParseImmUshort(RTUINTPTR uCodePtr, PCDISOPCODE pOp, PDISOPPARAM pParam, PDISCPUSTATE pCpu)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync{
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync NOREF(pOp);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pParam->uValue = disReadWord(pCpu, uCodePtr);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pParam->fUse |= DISUSE_IMMEDIATE16;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pParam->cb = sizeof(uint16_t);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return sizeof(uint16_t);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync}
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync//*****************************************************************************
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync//*****************************************************************************
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncunsigned ParseImmUshort_SizeOnly(RTUINTPTR uCodePtr, PCDISOPCODE pOp, PDISOPPARAM pParam, PDISCPUSTATE pCpu)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync{
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync NOREF(uCodePtr); NOREF(pOp); NOREF(pParam); NOREF(pCpu);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return sizeof(uint16_t);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync}
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync//*****************************************************************************
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync//*****************************************************************************
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncunsigned ParseImmUlong(RTUINTPTR uCodePtr, PCDISOPCODE pOp, PDISOPPARAM pParam, PDISCPUSTATE pCpu)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync{
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync NOREF(pOp);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pParam->uValue = disReadDWord(pCpu, uCodePtr);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pParam->fUse |= DISUSE_IMMEDIATE32;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pParam->cb = sizeof(uint32_t);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return sizeof(uint32_t);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync}
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync//*****************************************************************************
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync//*****************************************************************************
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncunsigned ParseImmUlong_SizeOnly(RTUINTPTR uCodePtr, PCDISOPCODE pOp, PDISOPPARAM pParam, PDISCPUSTATE pCpu)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync{
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync NOREF(uCodePtr); NOREF(pOp); NOREF(pParam); NOREF(pCpu);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return sizeof(uint32_t);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync}
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync//*****************************************************************************
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync//*****************************************************************************
e6ad2e18e663b076aeabfec994947514566a7accvboxsyncunsigned ParseImmQword(RTUINTPTR uCodePtr, PCDISOPCODE pOp, PDISOPPARAM pParam, PDISCPUSTATE pCpu)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync{
e6ad2e18e663b076aeabfec994947514566a7accvboxsync NOREF(pOp);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pParam->uValue = disReadQWord(pCpu, uCodePtr);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pParam->fUse |= DISUSE_IMMEDIATE64;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pParam->cb = sizeof(uint64_t);
e6ad2e18e663b076aeabfec994947514566a7accvboxsync return sizeof(uint64_t);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync}
e6ad2e18e663b076aeabfec994947514566a7accvboxsync//*****************************************************************************
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync//*****************************************************************************
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncunsigned ParseImmQword_SizeOnly(RTUINTPTR uCodePtr, PCDISOPCODE pOp, PDISOPPARAM pParam, PDISCPUSTATE pCpu)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync{
e6ad2e18e663b076aeabfec994947514566a7accvboxsync NOREF(uCodePtr); NOREF(pOp); NOREF(pParam); NOREF(pCpu);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return sizeof(uint64_t);
e6ad2e18e663b076aeabfec994947514566a7accvboxsync}
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync//*****************************************************************************
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync//*****************************************************************************
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncunsigned ParseImmV(RTUINTPTR uCodePtr, PCDISOPCODE pOp, PDISOPPARAM pParam, PDISCPUSTATE pCpu)
9cdd4d805ecb43126372f7cf12e4032836cb738avboxsync{
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync NOREF(pOp);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (pCpu->uOpMode == DISCPUMODE_32BIT)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pParam->uValue = disReadDWord(pCpu, uCodePtr);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pParam->fUse |= DISUSE_IMMEDIATE32;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pParam->cb = sizeof(uint32_t);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return sizeof(uint32_t);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (pCpu->uOpMode == DISCPUMODE_64BIT)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pParam->uValue = disReadQWord(pCpu, uCodePtr);
c58dc77ef4af214d7ae06910fa5ab18587d2ae08vboxsync pParam->fUse |= DISUSE_IMMEDIATE64;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pParam->cb = sizeof(uint64_t);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return sizeof(uint64_t);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pParam->uValue = disReadWord(pCpu, uCodePtr);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pParam->fUse |= DISUSE_IMMEDIATE16;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pParam->cb = sizeof(uint16_t);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return sizeof(uint16_t);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync}
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync//*****************************************************************************
c58dc77ef4af214d7ae06910fa5ab18587d2ae08vboxsync//*****************************************************************************
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncunsigned ParseImmV_SizeOnly(RTUINTPTR uCodePtr, PCDISOPCODE pOp, PDISOPPARAM pParam, PDISCPUSTATE pCpu)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync{
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync NOREF(uCodePtr); NOREF(pOp); NOREF(pParam);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (pCpu->uOpMode == DISCPUMODE_32BIT)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return sizeof(uint32_t);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (pCpu->uOpMode == DISCPUMODE_64BIT)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return sizeof(uint64_t);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return sizeof(uint16_t);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync}
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync//*****************************************************************************
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync//*****************************************************************************
e6ad2e18e663b076aeabfec994947514566a7accvboxsyncunsigned ParseImmZ(RTUINTPTR uCodePtr, PCDISOPCODE pOp, PDISOPPARAM pParam, PDISCPUSTATE pCpu)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync{
e6ad2e18e663b076aeabfec994947514566a7accvboxsync NOREF(pOp);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync /* Word for 16-bit operand-size or doubleword for 32 or 64-bit operand-size. */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (pCpu->uOpMode == DISCPUMODE_16BIT)
e6ad2e18e663b076aeabfec994947514566a7accvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pParam->uValue = disReadWord(pCpu, uCodePtr);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pParam->fUse |= DISUSE_IMMEDIATE16;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pParam->cb = sizeof(uint16_t);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return sizeof(uint16_t);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync /* 64 bits op mode means *sign* extend to 64 bits. */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (pCpu->uOpMode == DISCPUMODE_64BIT)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pParam->uValue = (uint64_t)(int32_t)disReadDWord(pCpu, uCodePtr);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pParam->fUse |= DISUSE_IMMEDIATE64;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pParam->cb = sizeof(uint64_t);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync else
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
e6ad2e18e663b076aeabfec994947514566a7accvboxsync pParam->uValue = disReadDWord(pCpu, uCodePtr);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pParam->fUse |= DISUSE_IMMEDIATE32;
e6ad2e18e663b076aeabfec994947514566a7accvboxsync pParam->cb = sizeof(uint32_t);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return sizeof(uint32_t);
e6ad2e18e663b076aeabfec994947514566a7accvboxsync}
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync//*****************************************************************************
9cdd4d805ecb43126372f7cf12e4032836cb738avboxsync//*****************************************************************************
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncunsigned ParseImmZ_SizeOnly(RTUINTPTR uCodePtr, PCDISOPCODE pOp, PDISOPPARAM pParam, PDISCPUSTATE pCpu)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync{
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync NOREF(uCodePtr); NOREF(pOp); NOREF(pParam);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync /* Word for 16-bit operand-size or doubleword for 32 or 64-bit operand-size. */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (pCpu->uOpMode == DISCPUMODE_16BIT)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return sizeof(uint16_t);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return sizeof(uint32_t);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync}
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync//*****************************************************************************
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync// Relative displacement for branches (rel. to next instruction)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync//*****************************************************************************
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncunsigned ParseImmBRel(RTUINTPTR uCodePtr, PCDISOPCODE pOp, PDISOPPARAM pParam, PDISCPUSTATE pCpu)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync{
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync NOREF(pOp);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pParam->uValue = disReadByte(pCpu, uCodePtr);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pParam->fUse |= DISUSE_IMMEDIATE8_REL;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pParam->cb = sizeof(uint8_t);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return sizeof(char);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync}
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync//*****************************************************************************
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync// Relative displacement for branches (rel. to next instruction)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync//*****************************************************************************
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncunsigned ParseImmBRel_SizeOnly(RTUINTPTR uCodePtr, PCDISOPCODE pOp, PDISOPPARAM pParam, PDISCPUSTATE pCpu)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync{
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync NOREF(uCodePtr); NOREF(pOp); NOREF(pParam); NOREF(pCpu);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return sizeof(char);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync}
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync//*****************************************************************************
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync// Relative displacement for branches (rel. to next instruction)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync//*****************************************************************************
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncunsigned ParseImmVRel(RTUINTPTR uCodePtr, PCDISOPCODE pOp, PDISOPPARAM pParam, PDISCPUSTATE pCpu)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync{
e6ad2e18e663b076aeabfec994947514566a7accvboxsync NOREF(pOp);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (pCpu->uOpMode == DISCPUMODE_32BIT)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pParam->uValue = disReadDWord(pCpu, uCodePtr);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pParam->fUse |= DISUSE_IMMEDIATE32_REL;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pParam->cb = sizeof(int32_t);
e6ad2e18e663b076aeabfec994947514566a7accvboxsync return sizeof(int32_t);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (pCpu->uOpMode == DISCPUMODE_64BIT)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync /* 32 bits relative immediate sign extended to 64 bits. */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pParam->uValue = (uint64_t)(int32_t)disReadDWord(pCpu, uCodePtr);
e6ad2e18e663b076aeabfec994947514566a7accvboxsync pParam->fUse |= DISUSE_IMMEDIATE64_REL;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pParam->cb = sizeof(int64_t);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return sizeof(int32_t);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pParam->uValue = disReadWord(pCpu, uCodePtr);
9cdd4d805ecb43126372f7cf12e4032836cb738avboxsync pParam->fUse |= DISUSE_IMMEDIATE16_REL;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pParam->cb = sizeof(int16_t);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return sizeof(int16_t);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync}
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync//*****************************************************************************
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync// Relative displacement for branches (rel. to next instruction)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync//*****************************************************************************
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncunsigned ParseImmVRel_SizeOnly(RTUINTPTR uCodePtr, PCDISOPCODE pOp, PDISOPPARAM pParam, PDISCPUSTATE pCpu)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync{
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync NOREF(uCodePtr); NOREF(pOp); NOREF(pParam);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (pCpu->uOpMode == DISCPUMODE_16BIT)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return sizeof(int16_t);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync /* Both 32 & 64 bits mode use 32 bits relative immediates. */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return sizeof(int32_t);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync}
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync//*****************************************************************************
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync//*****************************************************************************
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncunsigned ParseImmAddr(RTUINTPTR uCodePtr, PCDISOPCODE pOp, PDISOPPARAM pParam, PDISCPUSTATE pCpu)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync{
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (pCpu->uAddrMode == DISCPUMODE_32BIT)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (OP_PARM_VSUBTYPE(pParam->fParam) == OP_PARM_p)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync /* far 16:32 pointer */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pParam->uValue = disReadDWord(pCpu, uCodePtr);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync *((uint32_t*)&pParam->uValue+1) = disReadWord(pCpu, uCodePtr+sizeof(uint32_t));
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync pParam->fUse |= DISUSE_IMMEDIATE_ADDR_16_32;
5793d23a719d4902824a3649b6fef3822ddd5fc7vboxsync pParam->cb = sizeof(uint16_t) + sizeof(uint32_t);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return sizeof(uint32_t) + sizeof(uint16_t);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync /*
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * near 32 bits pointer
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync *
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * Note: used only in "mov al|ax|eax, [Addr]" and "mov [Addr], al|ax|eax"
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * so we treat it like displacement.
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pParam->uDisp.i32 = disReadDWord(pCpu, uCodePtr);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pParam->fUse |= DISUSE_DISPLACEMENT32;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pParam->cb = sizeof(uint32_t);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return sizeof(uint32_t);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (pCpu->uAddrMode == DISCPUMODE_64BIT)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync Assert(OP_PARM_VSUBTYPE(pParam->fParam) != OP_PARM_p);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync /*
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * near 64 bits pointer
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync *
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * Note: used only in "mov al|ax|eax, [Addr]" and "mov [Addr], al|ax|eax"
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * so we treat it like displacement.
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pParam->uDisp.i64 = disReadQWord(pCpu, uCodePtr);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pParam->fUse |= DISUSE_DISPLACEMENT64;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pParam->cb = sizeof(uint64_t);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return sizeof(uint64_t);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (OP_PARM_VSUBTYPE(pParam->fParam) == OP_PARM_p)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync /* far 16:16 pointer */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pParam->uValue = disReadDWord(pCpu, uCodePtr);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pParam->fUse |= DISUSE_IMMEDIATE_ADDR_16_16;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pParam->cb = 2*sizeof(uint16_t);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return sizeof(uint32_t);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync /*
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * near 16 bits pointer
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync *
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * Note: used only in "mov al|ax|eax, [Addr]" and "mov [Addr], al|ax|eax"
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * so we treat it like displacement.
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pParam->uDisp.i16 = disReadWord(pCpu, uCodePtr);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pParam->fUse |= DISUSE_DISPLACEMENT16;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pParam->cb = sizeof(uint16_t);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return sizeof(uint16_t);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync}
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync//*****************************************************************************
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync//*****************************************************************************
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncunsigned ParseImmAddr_SizeOnly(RTUINTPTR uCodePtr, PCDISOPCODE pOp, PDISOPPARAM pParam, PDISCPUSTATE pCpu)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync{
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync NOREF(uCodePtr); NOREF(pOp);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (pCpu->uAddrMode == DISCPUMODE_32BIT)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (OP_PARM_VSUBTYPE(pParam->fParam) == OP_PARM_p)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {// far 16:32 pointer
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return sizeof(uint32_t) + sizeof(uint16_t);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync else
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {// near 32 bits pointer
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return sizeof(uint32_t);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (pCpu->uAddrMode == DISCPUMODE_64BIT)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync Assert(OP_PARM_VSUBTYPE(pParam->fParam) != OP_PARM_p);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return sizeof(uint64_t);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync else
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (OP_PARM_VSUBTYPE(pParam->fParam) == OP_PARM_p)
eb2d4958f7faf812c3bdb2d7587d815022f0bd55vboxsync {// far 16:16 pointer
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return sizeof(uint32_t);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync else
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {// near 16 bits pointer
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return sizeof(uint16_t);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync}
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync//*****************************************************************************
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync//*****************************************************************************
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncunsigned ParseImmAddrF(RTUINTPTR uCodePtr, PCDISOPCODE pOp, PDISOPPARAM pParam, PDISCPUSTATE pCpu)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync{
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync // immediate far pointers - only 16:16 or 16:32; determined by operand, *not* address size!
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync Assert(pCpu->uOpMode == DISCPUMODE_16BIT || pCpu->uOpMode == DISCPUMODE_32BIT);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync Assert(OP_PARM_VSUBTYPE(pParam->fParam) == OP_PARM_p);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (pCpu->uOpMode == DISCPUMODE_32BIT)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync // far 16:32 pointer
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pParam->uValue = disReadDWord(pCpu, uCodePtr);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync *((uint32_t*)&pParam->uValue+1) = disReadWord(pCpu, uCodePtr+sizeof(uint32_t));
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pParam->fUse |= DISUSE_IMMEDIATE_ADDR_16_32;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pParam->cb = sizeof(uint16_t) + sizeof(uint32_t);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return sizeof(uint32_t) + sizeof(uint16_t);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync // far 16:16 pointer
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pParam->uValue = disReadDWord(pCpu, uCodePtr);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pParam->fUse |= DISUSE_IMMEDIATE_ADDR_16_16;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pParam->cb = 2*sizeof(uint16_t);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return sizeof(uint32_t);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync}
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync//*****************************************************************************
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync//*****************************************************************************
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncunsigned ParseImmAddrF_SizeOnly(RTUINTPTR uCodePtr, PCDISOPCODE pOp, PDISOPPARAM pParam, PDISCPUSTATE pCpu)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync{
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync NOREF(uCodePtr); NOREF(pOp);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync // immediate far pointers - only 16:16 or 16:32
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync Assert(pCpu->uOpMode == DISCPUMODE_16BIT || pCpu->uOpMode == DISCPUMODE_32BIT);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync Assert(OP_PARM_VSUBTYPE(pParam->fParam) == OP_PARM_p);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (pCpu->uOpMode == DISCPUMODE_32BIT)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync // far 16:32 pointer
441b60f8b0601cc1718368c9c3ef082223ad12a2vboxsync return sizeof(uint32_t) + sizeof(uint16_t);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync else
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
e6ad2e18e663b076aeabfec994947514566a7accvboxsync // far 16:16 pointer
e6ad2e18e663b076aeabfec994947514566a7accvboxsync return sizeof(uint32_t);
441b60f8b0601cc1718368c9c3ef082223ad12a2vboxsync }
441b60f8b0601cc1718368c9c3ef082223ad12a2vboxsync}
441b60f8b0601cc1718368c9c3ef082223ad12a2vboxsync//*****************************************************************************
441b60f8b0601cc1718368c9c3ef082223ad12a2vboxsync//*****************************************************************************
441b60f8b0601cc1718368c9c3ef082223ad12a2vboxsyncunsigned ParseFixedReg(RTUINTPTR uCodePtr, PCDISOPCODE pOp, PDISOPPARAM pParam, PDISCPUSTATE pCpu)
441b60f8b0601cc1718368c9c3ef082223ad12a2vboxsync{
441b60f8b0601cc1718368c9c3ef082223ad12a2vboxsync NOREF(uCodePtr);
441b60f8b0601cc1718368c9c3ef082223ad12a2vboxsync
441b60f8b0601cc1718368c9c3ef082223ad12a2vboxsync /*
441b60f8b0601cc1718368c9c3ef082223ad12a2vboxsync * Sets up flags for stored in OPC fixed registers.
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (pParam->fParam == OP_PARM_NONE)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync /* No parameter at all. */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return 0;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync AssertCompile(OP_PARM_REG_GEN32_END < OP_PARM_REG_SEG_END);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync AssertCompile(OP_PARM_REG_SEG_END < OP_PARM_REG_GEN16_END);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync AssertCompile(OP_PARM_REG_GEN16_END < OP_PARM_REG_GEN8_END);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync AssertCompile(OP_PARM_REG_GEN8_END < OP_PARM_REG_FP_END);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (pParam->fParam <= OP_PARM_REG_GEN32_END)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync /* 32-bit EAX..EDI registers. */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (pCpu->uOpMode == DISCPUMODE_32BIT)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync /* Use 32-bit registers. */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pParam->base.reg_gen = pParam->fParam - OP_PARM_REG_GEN32_START;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pParam->fUse |= DISUSE_REG_GEN32;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pParam->cb = 4;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync else
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (pCpu->uOpMode == DISCPUMODE_64BIT)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync /* Use 64-bit registers. */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pParam->base.reg_gen = pParam->fParam - OP_PARM_REG_GEN32_START;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if ( (pOp->fOpType & DISOPTYPE_REXB_EXTENDS_OPREG)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync && pParam == &pCpu->Param1 /* ugly assumption that it only applies to the first parameter */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync && (pCpu->fPrefix & DISPREFIX_REX)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync && (pCpu->fRexPrefix & DISPREFIX_REX_FLAGS))
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pParam->base.reg_gen += 8;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pParam->fUse |= DISUSE_REG_GEN64;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pParam->cb = 8;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync else
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync /* Use 16-bit registers. */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pParam->base.reg_gen = pParam->fParam - OP_PARM_REG_GEN32_START;
4c98b8b05f3783351cf256cc90cd4478fb28b62bvboxsync pParam->fUse |= DISUSE_REG_GEN16;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pParam->cb = 2;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pParam->fParam = pParam->fParam - OP_PARM_REG_GEN32_START + OP_PARM_REG_GEN16_START;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync else
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (pParam->fParam <= OP_PARM_REG_SEG_END)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync /* Segment ES..GS registers. */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pParam->base.reg_seg = (DISSELREG)(pParam->fParam - OP_PARM_REG_SEG_START);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pParam->fUse |= DISUSE_REG_SEG;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pParam->cb = 2;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync else
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (pParam->fParam <= OP_PARM_REG_GEN16_END)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync /* 16-bit AX..DI registers. */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pParam->base.reg_gen = pParam->fParam - OP_PARM_REG_GEN16_START;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pParam->fUse |= DISUSE_REG_GEN16;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pParam->cb = 2;
4c98b8b05f3783351cf256cc90cd4478fb28b62bvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync else
4c98b8b05f3783351cf256cc90cd4478fb28b62bvboxsync if (pParam->fParam <= OP_PARM_REG_GEN8_END)
4c98b8b05f3783351cf256cc90cd4478fb28b62bvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync /* 8-bit AL..DL, AH..DH registers. */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pParam->base.reg_gen = pParam->fParam - OP_PARM_REG_GEN8_START;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pParam->fUse |= DISUSE_REG_GEN8;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pParam->cb = 1;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (pCpu->uOpMode == DISCPUMODE_64BIT)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if ( (pOp->fOpType & DISOPTYPE_REXB_EXTENDS_OPREG)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync && pParam == &pCpu->Param1 /* ugly assumption that it only applies to the first parameter */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync && (pCpu->fPrefix & DISPREFIX_REX)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync && (pCpu->fRexPrefix & DISPREFIX_REX_FLAGS))
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pParam->base.reg_gen += 8; /* least significant byte of R8-R15 */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync else
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (pParam->fParam <= OP_PARM_REG_FP_END)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync /* FPU registers. */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pParam->base.reg_fp = pParam->fParam - OP_PARM_REG_FP_START;
9cdd4d805ecb43126372f7cf12e4032836cb738avboxsync pParam->fUse |= DISUSE_REG_FP;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pParam->cb = 10;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync Assert(!(pParam->fParam >= OP_PARM_REG_GEN64_START && pParam->fParam <= OP_PARM_REG_GEN64_END));
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync /* else - not supported for now registers. */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return 0;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync}
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync//*****************************************************************************
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync//*****************************************************************************
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncunsigned ParseXv(RTUINTPTR uCodePtr, PCDISOPCODE pOp, PDISOPPARAM pParam, PDISCPUSTATE pCpu)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync{
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync NOREF(uCodePtr);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pParam->fUse |= DISUSE_POINTER_DS_BASED;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (pCpu->uAddrMode == DISCPUMODE_32BIT)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pParam->base.reg_gen = DISGREG_ESI;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pParam->fUse |= DISUSE_REG_GEN32;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync else
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (pCpu->uAddrMode == DISCPUMODE_64BIT)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pParam->base.reg_gen = DISGREG_RSI;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pParam->fUse |= DISUSE_REG_GEN64;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync else
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
4c98b8b05f3783351cf256cc90cd4478fb28b62bvboxsync pParam->base.reg_gen = DISGREG_SI;
4c98b8b05f3783351cf256cc90cd4478fb28b62bvboxsync pParam->fUse |= DISUSE_REG_GEN16;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return 0; //no additional opcode bytes
4c98b8b05f3783351cf256cc90cd4478fb28b62bvboxsync}
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync//*****************************************************************************
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync//*****************************************************************************
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncunsigned ParseXb(RTUINTPTR uCodePtr, PCDISOPCODE pOp, PDISOPPARAM pParam, PDISCPUSTATE pCpu)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync{
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync NOREF(uCodePtr); NOREF(pOp);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pParam->fUse |= DISUSE_POINTER_DS_BASED;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (pCpu->uAddrMode == DISCPUMODE_32BIT)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pParam->base.reg_gen = DISGREG_ESI;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pParam->fUse |= DISUSE_REG_GEN32;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
4c98b8b05f3783351cf256cc90cd4478fb28b62bvboxsync else
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (pCpu->uAddrMode == DISCPUMODE_64BIT)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pParam->base.reg_gen = DISGREG_RSI;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pParam->fUse |= DISUSE_REG_GEN64;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync else
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pParam->base.reg_gen = DISGREG_SI;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pParam->fUse |= DISUSE_REG_GEN16;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return 0; //no additional opcode bytes
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync}
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync//*****************************************************************************
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync//*****************************************************************************
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncunsigned ParseYv(RTUINTPTR uCodePtr, PCDISOPCODE pOp, PDISOPPARAM pParam, PDISCPUSTATE pCpu)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync{
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync NOREF(uCodePtr);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pParam->fUse |= DISUSE_POINTER_ES_BASED;
4c98b8b05f3783351cf256cc90cd4478fb28b62bvboxsync if (pCpu->uAddrMode == DISCPUMODE_32BIT)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
4c98b8b05f3783351cf256cc90cd4478fb28b62bvboxsync pParam->base.reg_gen = DISGREG_EDI;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pParam->fUse |= DISUSE_REG_GEN32;
4c98b8b05f3783351cf256cc90cd4478fb28b62bvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync else
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (pCpu->uAddrMode == DISCPUMODE_64BIT)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pParam->base.reg_gen = DISGREG_RDI;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pParam->fUse |= DISUSE_REG_GEN64;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync else
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pParam->base.reg_gen = DISGREG_DI;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pParam->fUse |= DISUSE_REG_GEN16;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return 0; //no additional opcode bytes
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync}
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync//*****************************************************************************
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync//*****************************************************************************
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncunsigned ParseYb(RTUINTPTR uCodePtr, PCDISOPCODE pOp, PDISOPPARAM pParam, PDISCPUSTATE pCpu)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync{
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync NOREF(uCodePtr); NOREF(pOp);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pParam->fUse |= DISUSE_POINTER_ES_BASED;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (pCpu->uAddrMode == DISCPUMODE_32BIT)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pParam->base.reg_gen = DISGREG_EDI;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pParam->fUse |= DISUSE_REG_GEN32;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync else
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (pCpu->uAddrMode == DISCPUMODE_64BIT)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pParam->base.reg_gen = DISGREG_RDI;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pParam->fUse |= DISUSE_REG_GEN64;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
4c98b8b05f3783351cf256cc90cd4478fb28b62bvboxsync else
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pParam->base.reg_gen = DISGREG_DI;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pParam->fUse |= DISUSE_REG_GEN16;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return 0; //no additional opcode bytes
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync}
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync//*****************************************************************************
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync//*****************************************************************************
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncunsigned ParseTwoByteEsc(RTUINTPTR uCodePtr, PCDISOPCODE pOp, PDISOPPARAM pParam, PDISCPUSTATE pCpu)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync{
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync PCDISOPCODE pOpcode;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync int size = sizeof(uint8_t);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync NOREF(pOp); NOREF(pParam);
4c98b8b05f3783351cf256cc90cd4478fb28b62bvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync /* 2nd byte */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pCpu->bOpCode = disReadByte(pCpu, uCodePtr);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync /* default to the non-prefixed table. */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pOpcode = &g_aTwoByteMapX86[pCpu->bOpCode];
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync /* Handle opcode table extensions that rely on the address, repe or repne prefix byte. */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync /** @todo Should we take the first or last prefix byte in case of multiple prefix bytes??? */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (pCpu->bLastPrefix)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9cdd4d805ecb43126372f7cf12e4032836cb738avboxsync switch (pCpu->bLastPrefix)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9cdd4d805ecb43126372f7cf12e4032836cb738avboxsync case OP_OPSIZE: /* 0x66 */
9cdd4d805ecb43126372f7cf12e4032836cb738avboxsync if (g_aTwoByteMapX86_PF66[pCpu->bOpCode].uOpcode != OP_INVALID)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9cdd4d805ecb43126372f7cf12e4032836cb738avboxsync /* Table entry is valid, so use the extension table. */
9cdd4d805ecb43126372f7cf12e4032836cb738avboxsync pOpcode = &g_aTwoByteMapX86_PF66[pCpu->bOpCode];
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9cdd4d805ecb43126372f7cf12e4032836cb738avboxsync /* Cancel prefix changes. */
9cdd4d805ecb43126372f7cf12e4032836cb738avboxsync pCpu->fPrefix &= ~DISPREFIX_OPSIZE;
9cdd4d805ecb43126372f7cf12e4032836cb738avboxsync pCpu->uOpMode = pCpu->uCpuMode;
9cdd4d805ecb43126372f7cf12e4032836cb738avboxsync }
9cdd4d805ecb43126372f7cf12e4032836cb738avboxsync break;
9cdd4d805ecb43126372f7cf12e4032836cb738avboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync case OP_REPNE: /* 0xF2 */
9cdd4d805ecb43126372f7cf12e4032836cb738avboxsync if (g_aTwoByteMapX86_PFF2[pCpu->bOpCode].uOpcode != OP_INVALID)
9cdd4d805ecb43126372f7cf12e4032836cb738avboxsync {
9cdd4d805ecb43126372f7cf12e4032836cb738avboxsync /* Table entry is valid, so use the extension table. */
9cdd4d805ecb43126372f7cf12e4032836cb738avboxsync pOpcode = &g_aTwoByteMapX86_PFF2[pCpu->bOpCode];
9cdd4d805ecb43126372f7cf12e4032836cb738avboxsync
9cdd4d805ecb43126372f7cf12e4032836cb738avboxsync /* Cancel prefix changes. */
9cdd4d805ecb43126372f7cf12e4032836cb738avboxsync pCpu->fPrefix &= ~DISPREFIX_REPNE;
9cdd4d805ecb43126372f7cf12e4032836cb738avboxsync }
9cdd4d805ecb43126372f7cf12e4032836cb738avboxsync break;
9cdd4d805ecb43126372f7cf12e4032836cb738avboxsync
9cdd4d805ecb43126372f7cf12e4032836cb738avboxsync case OP_REPE: /* 0xF3 */
9cdd4d805ecb43126372f7cf12e4032836cb738avboxsync if (g_aTwoByteMapX86_PFF3[pCpu->bOpCode].uOpcode != OP_INVALID)
9cdd4d805ecb43126372f7cf12e4032836cb738avboxsync {
9cdd4d805ecb43126372f7cf12e4032836cb738avboxsync /* Table entry is valid, so use the extension table. */
9cdd4d805ecb43126372f7cf12e4032836cb738avboxsync pOpcode = &g_aTwoByteMapX86_PFF3[pCpu->bOpCode];
9cdd4d805ecb43126372f7cf12e4032836cb738avboxsync
9cdd4d805ecb43126372f7cf12e4032836cb738avboxsync /* Cancel prefix changes. */
9cdd4d805ecb43126372f7cf12e4032836cb738avboxsync pCpu->fPrefix &= ~DISPREFIX_REP;
9cdd4d805ecb43126372f7cf12e4032836cb738avboxsync }
9cdd4d805ecb43126372f7cf12e4032836cb738avboxsync break;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9cdd4d805ecb43126372f7cf12e4032836cb738avboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync size += disParseInstruction(uCodePtr+size, pOpcode, pCpu);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return size;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync}
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync//*****************************************************************************
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync//*****************************************************************************
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncunsigned ParseThreeByteEsc4(RTUINTPTR uCodePtr, PCDISOPCODE pOp, PDISOPPARAM pParam, PDISCPUSTATE pCpu)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync{
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync PCDISOPCODE pOpcode;
9cdd4d805ecb43126372f7cf12e4032836cb738avboxsync int size = sizeof(uint8_t);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync NOREF(pOp); NOREF(pParam);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync /* 3rd byte */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pCpu->bOpCode = disReadByte(pCpu, uCodePtr);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync /* default to the non-prefixed table. */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (g_apThreeByteMapX86_0F38[pCpu->bOpCode >> 4])
9cdd4d805ecb43126372f7cf12e4032836cb738avboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pOpcode = g_apThreeByteMapX86_0F38[pCpu->bOpCode >> 4];
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pOpcode = &pOpcode[pCpu->bOpCode & 0xf];
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync else
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pOpcode = &g_InvalidOpcode[0];
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync /* Handle opcode table extensions that rely on the address, repne prefix byte. */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync /** @todo Should we take the first or last prefix byte in case of multiple prefix bytes??? */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync switch (pCpu->bLastPrefix)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync case OP_OPSIZE: /* 0x66 */
3a343ca21a267ec3c54e2317e2ed18fe99b8ebbbvboxsync if (g_apThreeByteMapX86_660F38[pCpu->bOpCode >> 4])
3a343ca21a267ec3c54e2317e2ed18fe99b8ebbbvboxsync {
3a343ca21a267ec3c54e2317e2ed18fe99b8ebbbvboxsync pOpcode = g_apThreeByteMapX86_660F38[pCpu->bOpCode >> 4];
3a343ca21a267ec3c54e2317e2ed18fe99b8ebbbvboxsync pOpcode = &pOpcode[pCpu->bOpCode & 0xf];
3a343ca21a267ec3c54e2317e2ed18fe99b8ebbbvboxsync
3a343ca21a267ec3c54e2317e2ed18fe99b8ebbbvboxsync if (pOpcode->uOpcode != OP_INVALID)
3a343ca21a267ec3c54e2317e2ed18fe99b8ebbbvboxsync {
3a343ca21a267ec3c54e2317e2ed18fe99b8ebbbvboxsync /* Table entry is valid, so use the extension table. */
3a343ca21a267ec3c54e2317e2ed18fe99b8ebbbvboxsync
3a343ca21a267ec3c54e2317e2ed18fe99b8ebbbvboxsync /* Cancel prefix changes. */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pCpu->fPrefix &= ~DISPREFIX_OPSIZE;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pCpu->uOpMode = pCpu->uCpuMode;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync break;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync case OP_REPNE: /* 0xF2 */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (g_apThreeByteMapX86_F20F38[pCpu->bOpCode >> 4])
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pOpcode = g_apThreeByteMapX86_F20F38[pCpu->bOpCode >> 4];
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pOpcode = &pOpcode[pCpu->bOpCode & 0xf];
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (pOpcode->uOpcode != OP_INVALID)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync /* Table entry is valid, so use the extension table. */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync /* Cancel prefix changes. */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pCpu->fPrefix &= ~DISPREFIX_REPNE;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync break;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync size += disParseInstruction(uCodePtr+size, pOpcode, pCpu);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return size;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync}
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync//*****************************************************************************
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync//*****************************************************************************
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncunsigned ParseThreeByteEsc5(RTUINTPTR uCodePtr, PCDISOPCODE pOp, PDISOPPARAM pParam, PDISCPUSTATE pCpu)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync{
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync PCDISOPCODE pOpcode;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync int size = sizeof(uint8_t);
9cdd4d805ecb43126372f7cf12e4032836cb738avboxsync NOREF(pOp); NOREF(pParam);
9cdd4d805ecb43126372f7cf12e4032836cb738avboxsync
9cdd4d805ecb43126372f7cf12e4032836cb738avboxsync /* 3rd byte */
9cdd4d805ecb43126372f7cf12e4032836cb738avboxsync pCpu->bOpCode = disReadByte(pCpu, uCodePtr);
9cdd4d805ecb43126372f7cf12e4032836cb738avboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync /** @todo Should we take the first or last prefix byte in case of multiple prefix bytes??? */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync Assert(pCpu->bLastPrefix == OP_OPSIZE);
9cdd4d805ecb43126372f7cf12e4032836cb738avboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync /* default to the non-prefixed table. */
9cdd4d805ecb43126372f7cf12e4032836cb738avboxsync if (g_apThreeByteMapX86_660F3A[pCpu->bOpCode >> 4])
9cdd4d805ecb43126372f7cf12e4032836cb738avboxsync {
9cdd4d805ecb43126372f7cf12e4032836cb738avboxsync pOpcode = g_apThreeByteMapX86_660F3A[pCpu->bOpCode >> 4];
9cdd4d805ecb43126372f7cf12e4032836cb738avboxsync pOpcode = &pOpcode[pCpu->bOpCode & 0xf];
9cdd4d805ecb43126372f7cf12e4032836cb738avboxsync
9cdd4d805ecb43126372f7cf12e4032836cb738avboxsync if (pOpcode->uOpcode != OP_INVALID)
9cdd4d805ecb43126372f7cf12e4032836cb738avboxsync {
9cdd4d805ecb43126372f7cf12e4032836cb738avboxsync /* Table entry is valid, so use the extension table. */
9cdd4d805ecb43126372f7cf12e4032836cb738avboxsync
9cdd4d805ecb43126372f7cf12e4032836cb738avboxsync /* Cancel prefix changes. */
9cdd4d805ecb43126372f7cf12e4032836cb738avboxsync pCpu->fPrefix &= ~DISPREFIX_OPSIZE;
9cdd4d805ecb43126372f7cf12e4032836cb738avboxsync pCpu->uOpMode = pCpu->uCpuMode;
9cdd4d805ecb43126372f7cf12e4032836cb738avboxsync }
9cdd4d805ecb43126372f7cf12e4032836cb738avboxsync }
9cdd4d805ecb43126372f7cf12e4032836cb738avboxsync else
9cdd4d805ecb43126372f7cf12e4032836cb738avboxsync pOpcode = &g_InvalidOpcode[0];
9cdd4d805ecb43126372f7cf12e4032836cb738avboxsync
9cdd4d805ecb43126372f7cf12e4032836cb738avboxsync size += disParseInstruction(uCodePtr+size, pOpcode, pCpu);
9cdd4d805ecb43126372f7cf12e4032836cb738avboxsync return size;
9cdd4d805ecb43126372f7cf12e4032836cb738avboxsync}
9cdd4d805ecb43126372f7cf12e4032836cb738avboxsync//*****************************************************************************
9cdd4d805ecb43126372f7cf12e4032836cb738avboxsync//*****************************************************************************
9cdd4d805ecb43126372f7cf12e4032836cb738avboxsyncunsigned ParseNopPause(RTUINTPTR uCodePtr, PCDISOPCODE pOp, PDISOPPARAM pParam, PDISCPUSTATE pCpu)
9cdd4d805ecb43126372f7cf12e4032836cb738avboxsync{
9cdd4d805ecb43126372f7cf12e4032836cb738avboxsync unsigned size = 0;
9cdd4d805ecb43126372f7cf12e4032836cb738avboxsync NOREF(pParam);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (pCpu->fPrefix & DISPREFIX_REP)
9cdd4d805ecb43126372f7cf12e4032836cb738avboxsync {
9cdd4d805ecb43126372f7cf12e4032836cb738avboxsync pOp = &g_aMapX86_NopPause[1]; /* PAUSE */
9cdd4d805ecb43126372f7cf12e4032836cb738avboxsync pCpu->fPrefix &= ~DISPREFIX_REP;
9cdd4d805ecb43126372f7cf12e4032836cb738avboxsync }
9cdd4d805ecb43126372f7cf12e4032836cb738avboxsync else
9cdd4d805ecb43126372f7cf12e4032836cb738avboxsync pOp = &g_aMapX86_NopPause[0]; /* NOP */
9cdd4d805ecb43126372f7cf12e4032836cb738avboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync size += disParseInstruction(uCodePtr, pOp, pCpu);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return size;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync}
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync//*****************************************************************************
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync//*****************************************************************************
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncunsigned ParseImmGrpl(RTUINTPTR uCodePtr, PCDISOPCODE pOp, PDISOPPARAM pParam, PDISCPUSTATE pCpu)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync{
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync int idx = (pCpu->bOpCode - 0x80) * 8;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync unsigned size = 0, modrm, reg;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync NOREF(pParam);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync modrm = disReadByte(pCpu, uCodePtr);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync reg = MODRM_REG(modrm);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pOp = (PCDISOPCODE)&g_aMapX86_Group1[idx+reg];
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync //little hack to make sure the ModRM byte is included in the returned size
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (pOp->idxParse1 != IDX_ParseModRM && pOp->idxParse2 != IDX_ParseModRM)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync size = sizeof(uint8_t); //ModRM byte
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync size += disParseInstruction(uCodePtr, pOp, pCpu);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return size;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync}
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync//*****************************************************************************
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync//*****************************************************************************
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncunsigned ParseShiftGrp2(RTUINTPTR uCodePtr, PCDISOPCODE pOp, PDISOPPARAM pParam, PDISCPUSTATE pCpu)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync{
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync int idx;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync unsigned size = 0, modrm, reg;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync NOREF(pParam);
9cdd4d805ecb43126372f7cf12e4032836cb738avboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync switch (pCpu->bOpCode)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
3a343ca21a267ec3c54e2317e2ed18fe99b8ebbbvboxsync case 0xC0:
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync case 0xC1:
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync idx = (pCpu->bOpCode - 0xC0)*8;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync break;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync case 0xD0:
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync case 0xD1:
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync case 0xD2:
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync case 0xD3:
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync idx = (pCpu->bOpCode - 0xD0 + 2)*8;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync break;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync default:
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync AssertMsgFailed(("Oops\n"));
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return sizeof(uint8_t);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync modrm = disReadByte(pCpu, uCodePtr);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync reg = MODRM_REG(modrm);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pOp = (PCDISOPCODE)&g_aMapX86_Group2[idx+reg];
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync //little hack to make sure the ModRM byte is included in the returned size
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (pOp->idxParse1 != IDX_ParseModRM && pOp->idxParse2 != IDX_ParseModRM)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync size = sizeof(uint8_t); //ModRM byte
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync size += disParseInstruction(uCodePtr, pOp, pCpu);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return size;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync}
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync//*****************************************************************************
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync//*****************************************************************************
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncunsigned ParseGrp3(RTUINTPTR uCodePtr, PCDISOPCODE pOp, PDISOPPARAM pParam, PDISCPUSTATE pCpu)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync{
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync int idx = (pCpu->bOpCode - 0xF6) * 8;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync unsigned size = 0, modrm, reg;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync NOREF(pParam);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync modrm = disReadByte(pCpu, uCodePtr);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync reg = MODRM_REG(modrm);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pOp = (PCDISOPCODE)&g_aMapX86_Group3[idx+reg];
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync //little hack to make sure the ModRM byte is included in the returned size
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (pOp->idxParse1 != IDX_ParseModRM && pOp->idxParse2 != IDX_ParseModRM)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync size = sizeof(uint8_t); //ModRM byte
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync size += disParseInstruction(uCodePtr, pOp, pCpu);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return size;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync}
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync//*****************************************************************************
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync//*****************************************************************************
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncunsigned ParseGrp4(RTUINTPTR uCodePtr, PCDISOPCODE pOp, PDISOPPARAM pParam, PDISCPUSTATE pCpu)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync{
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync unsigned size = 0, modrm, reg;
3a343ca21a267ec3c54e2317e2ed18fe99b8ebbbvboxsync NOREF(pParam);
3a343ca21a267ec3c54e2317e2ed18fe99b8ebbbvboxsync
3a343ca21a267ec3c54e2317e2ed18fe99b8ebbbvboxsync modrm = disReadByte(pCpu, uCodePtr);
3a343ca21a267ec3c54e2317e2ed18fe99b8ebbbvboxsync reg = MODRM_REG(modrm);
3a343ca21a267ec3c54e2317e2ed18fe99b8ebbbvboxsync
3a343ca21a267ec3c54e2317e2ed18fe99b8ebbbvboxsync pOp = (PCDISOPCODE)&g_aMapX86_Group4[reg];
3a343ca21a267ec3c54e2317e2ed18fe99b8ebbbvboxsync
3a343ca21a267ec3c54e2317e2ed18fe99b8ebbbvboxsync //little hack to make sure the ModRM byte is included in the returned size
3a343ca21a267ec3c54e2317e2ed18fe99b8ebbbvboxsync if (pOp->idxParse1 != IDX_ParseModRM && pOp->idxParse2 != IDX_ParseModRM)
3a343ca21a267ec3c54e2317e2ed18fe99b8ebbbvboxsync size = sizeof(uint8_t); //ModRM byte
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync size += disParseInstruction(uCodePtr, pOp, pCpu);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return size;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync}
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync//*****************************************************************************
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync//*****************************************************************************
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncunsigned ParseGrp5(RTUINTPTR uCodePtr, PCDISOPCODE pOp, PDISOPPARAM pParam, PDISCPUSTATE pCpu)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync{
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync unsigned size = 0, modrm, reg;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync NOREF(pParam);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync modrm = disReadByte(pCpu, uCodePtr);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync reg = MODRM_REG(modrm);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pOp = (PCDISOPCODE)&g_aMapX86_Group5[reg];
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync //little hack to make sure the ModRM byte is included in the returned size
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (pOp->idxParse1 != IDX_ParseModRM && pOp->idxParse2 != IDX_ParseModRM)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync size = sizeof(uint8_t); //ModRM byte
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync size += disParseInstruction(uCodePtr, pOp, pCpu);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return size;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync}
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync//*****************************************************************************
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync// 0xF 0xF [ModRM] [SIB] [displacement] imm8_opcode
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync// It would appear the ModRM byte must always be present. How else can you
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync// determine the offset of the imm8_opcode byte otherwise?
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync//
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync//*****************************************************************************
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncunsigned Parse3DNow(RTUINTPTR uCodePtr, PCDISOPCODE pOp, PDISOPPARAM pParam, PDISCPUSTATE pCpu)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync{
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync unsigned size = 0, modrmsize;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync#ifdef DEBUG_Sander
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync //needs testing
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync AssertMsgFailed(("Test me\n"));
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync#endif
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync unsigned ModRM = disReadByte(pCpu, uCodePtr);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pCpu->ModRM.Bits.Rm = MODRM_RM(ModRM);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pCpu->ModRM.Bits.Mod = MODRM_MOD(ModRM);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pCpu->ModRM.Bits.Reg = MODRM_REG(ModRM);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync modrmsize = QueryModRM(uCodePtr+sizeof(uint8_t), pOp, pParam, pCpu);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync uint8_t opcode = disReadByte(pCpu, uCodePtr+sizeof(uint8_t)+modrmsize);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pOp = (PCDISOPCODE)&g_aTwoByteMapX86_3DNow[opcode];
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync //little hack to make sure the ModRM byte is included in the returned size
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (pOp->idxParse1 != IDX_ParseModRM && pOp->idxParse2 != IDX_ParseModRM)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync#ifdef DEBUG_Sander /* bird, 2005-06-28: Alex is getting this during full installation of win2ksp4. */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync AssertMsgFailed(("Oops!\n")); //shouldn't happen!
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync#endif
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync size = sizeof(uint8_t); //ModRM byte
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync size += disParseInstruction(uCodePtr, pOp, pCpu);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync size += sizeof(uint8_t); //imm8_opcode uint8_t
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return size;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync}
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync//*****************************************************************************
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync//*****************************************************************************
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncunsigned ParseGrp6(RTUINTPTR uCodePtr, PCDISOPCODE pOp, PDISOPPARAM pParam, PDISCPUSTATE pCpu)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync{
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync unsigned size = 0, modrm, reg;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync NOREF(pParam);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync modrm = disReadByte(pCpu, uCodePtr);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync reg = MODRM_REG(modrm);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pOp = (PCDISOPCODE)&g_aMapX86_Group6[reg];
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync //little hack to make sure the ModRM byte is included in the returned size
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (pOp->idxParse1 != IDX_ParseModRM && pOp->idxParse2 != IDX_ParseModRM)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync size = sizeof(uint8_t); //ModRM byte
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync size += disParseInstruction(uCodePtr, pOp, pCpu);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return size;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync}
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync//*****************************************************************************
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync//*****************************************************************************
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncunsigned ParseGrp7(RTUINTPTR uCodePtr, PCDISOPCODE pOp, PDISOPPARAM pParam, PDISCPUSTATE pCpu)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync{
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync unsigned size = 0, modrm, reg, rm, mod;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync NOREF(pParam);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync modrm = disReadByte(pCpu, uCodePtr);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync mod = MODRM_MOD(modrm);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync reg = MODRM_REG(modrm);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync rm = MODRM_RM(modrm);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (mod == 3 && rm == 0)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pOp = (PCDISOPCODE)&g_aMapX86_Group7_mod11_rm000[reg];
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync else
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (mod == 3 && rm == 1)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pOp = (PCDISOPCODE)&g_aMapX86_Group7_mod11_rm001[reg];
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync else
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pOp = (PCDISOPCODE)&g_aMapX86_Group7_mem[reg];
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync //little hack to make sure the ModRM byte is included in the returned size
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (pOp->idxParse1 != IDX_ParseModRM && pOp->idxParse2 != IDX_ParseModRM)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync size = sizeof(uint8_t); //ModRM byte
6d9d4a12f6f9f341c968f711765c2c17c9a5a28cvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync size += disParseInstruction(uCodePtr, pOp, pCpu);
6d9d4a12f6f9f341c968f711765c2c17c9a5a28cvboxsync
6d9d4a12f6f9f341c968f711765c2c17c9a5a28cvboxsync return size;
6d9d4a12f6f9f341c968f711765c2c17c9a5a28cvboxsync}
6d9d4a12f6f9f341c968f711765c2c17c9a5a28cvboxsync//*****************************************************************************
6d9d4a12f6f9f341c968f711765c2c17c9a5a28cvboxsync//*****************************************************************************
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncunsigned ParseGrp8(RTUINTPTR uCodePtr, PCDISOPCODE pOp, PDISOPPARAM pParam, PDISCPUSTATE pCpu)
6d9d4a12f6f9f341c968f711765c2c17c9a5a28cvboxsync{
6d9d4a12f6f9f341c968f711765c2c17c9a5a28cvboxsync unsigned size = 0, modrm, reg;
6d9d4a12f6f9f341c968f711765c2c17c9a5a28cvboxsync NOREF(pParam);
6d9d4a12f6f9f341c968f711765c2c17c9a5a28cvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync modrm = disReadByte(pCpu, uCodePtr);
6d9d4a12f6f9f341c968f711765c2c17c9a5a28cvboxsync reg = MODRM_REG(modrm);
0cb5af53de7aed97b1b35311f93de8175756e4afvboxsync
0cb5af53de7aed97b1b35311f93de8175756e4afvboxsync pOp = (PCDISOPCODE)&g_aMapX86_Group8[reg];
0cb5af53de7aed97b1b35311f93de8175756e4afvboxsync
0cb5af53de7aed97b1b35311f93de8175756e4afvboxsync //little hack to make sure the ModRM byte is included in the returned size
0cb5af53de7aed97b1b35311f93de8175756e4afvboxsync if (pOp->idxParse1 != IDX_ParseModRM && pOp->idxParse2 != IDX_ParseModRM)
0cb5af53de7aed97b1b35311f93de8175756e4afvboxsync size = sizeof(uint8_t); //ModRM byte
0cb5af53de7aed97b1b35311f93de8175756e4afvboxsync
6d9d4a12f6f9f341c968f711765c2c17c9a5a28cvboxsync size += disParseInstruction(uCodePtr, pOp, pCpu);
6d9d4a12f6f9f341c968f711765c2c17c9a5a28cvboxsync
6d9d4a12f6f9f341c968f711765c2c17c9a5a28cvboxsync return size;
6d9d4a12f6f9f341c968f711765c2c17c9a5a28cvboxsync}
6d9d4a12f6f9f341c968f711765c2c17c9a5a28cvboxsync//*****************************************************************************
6d9d4a12f6f9f341c968f711765c2c17c9a5a28cvboxsync//*****************************************************************************
6d9d4a12f6f9f341c968f711765c2c17c9a5a28cvboxsyncunsigned ParseGrp9(RTUINTPTR uCodePtr, PCDISOPCODE pOp, PDISOPPARAM pParam, PDISCPUSTATE pCpu)
6d9d4a12f6f9f341c968f711765c2c17c9a5a28cvboxsync{
6d9d4a12f6f9f341c968f711765c2c17c9a5a28cvboxsync unsigned size = 0, modrm, reg;
6d9d4a12f6f9f341c968f711765c2c17c9a5a28cvboxsync NOREF(pParam);
6d9d4a12f6f9f341c968f711765c2c17c9a5a28cvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync modrm = disReadByte(pCpu, uCodePtr);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync reg = MODRM_REG(modrm);
6d9d4a12f6f9f341c968f711765c2c17c9a5a28cvboxsync
6d9d4a12f6f9f341c968f711765c2c17c9a5a28cvboxsync pOp = (PCDISOPCODE)&g_aMapX86_Group9[reg];
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
6d9d4a12f6f9f341c968f711765c2c17c9a5a28cvboxsync //little hack to make sure the ModRM byte is included in the returned size
6d9d4a12f6f9f341c968f711765c2c17c9a5a28cvboxsync if (pOp->idxParse1 != IDX_ParseModRM && pOp->idxParse2 != IDX_ParseModRM)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync size = sizeof(uint8_t); //ModRM byte
6d9d4a12f6f9f341c968f711765c2c17c9a5a28cvboxsync
6d9d4a12f6f9f341c968f711765c2c17c9a5a28cvboxsync size += disParseInstruction(uCodePtr, pOp, pCpu);
6d9d4a12f6f9f341c968f711765c2c17c9a5a28cvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return size;
6d9d4a12f6f9f341c968f711765c2c17c9a5a28cvboxsync}
6d9d4a12f6f9f341c968f711765c2c17c9a5a28cvboxsync//*****************************************************************************
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync//*****************************************************************************
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncunsigned ParseGrp10(RTUINTPTR uCodePtr, PCDISOPCODE pOp, PDISOPPARAM pParam, PDISCPUSTATE pCpu)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync{
6d9d4a12f6f9f341c968f711765c2c17c9a5a28cvboxsync unsigned size = 0, modrm, reg;
6d9d4a12f6f9f341c968f711765c2c17c9a5a28cvboxsync NOREF(pParam);
6d9d4a12f6f9f341c968f711765c2c17c9a5a28cvboxsync
6d9d4a12f6f9f341c968f711765c2c17c9a5a28cvboxsync modrm = disReadByte(pCpu, uCodePtr);
6d9d4a12f6f9f341c968f711765c2c17c9a5a28cvboxsync reg = MODRM_REG(modrm);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pOp = (PCDISOPCODE)&g_aMapX86_Group10[reg];
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync //little hack to make sure the ModRM byte is included in the returned size
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (pOp->idxParse1 != IDX_ParseModRM && pOp->idxParse2 != IDX_ParseModRM)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync size = sizeof(uint8_t); //ModRM byte
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync size += disParseInstruction(uCodePtr, pOp, pCpu);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return size;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync}
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync//*****************************************************************************
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync//*****************************************************************************
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncunsigned ParseGrp12(RTUINTPTR uCodePtr, PCDISOPCODE pOp, PDISOPPARAM pParam, PDISCPUSTATE pCpu)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync{
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync unsigned size = 0, modrm, reg;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync NOREF(pParam);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync modrm = disReadByte(pCpu, uCodePtr);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync reg = MODRM_REG(modrm);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9cdd4d805ecb43126372f7cf12e4032836cb738avboxsync if (pCpu->fPrefix & DISPREFIX_OPSIZE)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync reg += 8; //2nd table
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pOp = (PCDISOPCODE)&g_aMapX86_Group12[reg];
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync //little hack to make sure the ModRM byte is included in the returned size
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (pOp->idxParse1 != IDX_ParseModRM && pOp->idxParse2 != IDX_ParseModRM)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync size = sizeof(uint8_t); //ModRM byte
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync size += disParseInstruction(uCodePtr, pOp, pCpu);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return size;
9cdd4d805ecb43126372f7cf12e4032836cb738avboxsync}
9cdd4d805ecb43126372f7cf12e4032836cb738avboxsync//*****************************************************************************
9cdd4d805ecb43126372f7cf12e4032836cb738avboxsync//*****************************************************************************
9cdd4d805ecb43126372f7cf12e4032836cb738avboxsyncunsigned ParseGrp13(RTUINTPTR uCodePtr, PCDISOPCODE pOp, PDISOPPARAM pParam, PDISCPUSTATE pCpu)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync{
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync unsigned size = 0, modrm, reg;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync NOREF(pParam);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9cdd4d805ecb43126372f7cf12e4032836cb738avboxsync modrm = disReadByte(pCpu, uCodePtr);
9cdd4d805ecb43126372f7cf12e4032836cb738avboxsync reg = MODRM_REG(modrm);
9cdd4d805ecb43126372f7cf12e4032836cb738avboxsync if (pCpu->fPrefix & DISPREFIX_OPSIZE)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync reg += 8; //2nd table
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pOp = (PCDISOPCODE)&g_aMapX86_Group13[reg];
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync //little hack to make sure the ModRM byte is included in the returned size
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (pOp->idxParse1 != IDX_ParseModRM && pOp->idxParse2 != IDX_ParseModRM)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync size = sizeof(uint8_t); //ModRM byte
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync size += disParseInstruction(uCodePtr, pOp, pCpu);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return size;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync}
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync//*****************************************************************************
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync//*****************************************************************************
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncunsigned ParseGrp14(RTUINTPTR uCodePtr, PCDISOPCODE pOp, PDISOPPARAM pParam, PDISCPUSTATE pCpu)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync{
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync unsigned size = 0, modrm, reg;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync NOREF(pParam);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync modrm = disReadByte(pCpu, uCodePtr);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync reg = MODRM_REG(modrm);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (pCpu->fPrefix & DISPREFIX_OPSIZE)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync reg += 8; //2nd table
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pOp = (PCDISOPCODE)&g_aMapX86_Group14[reg];
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync //little hack to make sure the ModRM byte is included in the returned size
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (pOp->idxParse1 != IDX_ParseModRM && pOp->idxParse2 != IDX_ParseModRM)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync size = sizeof(uint8_t); //ModRM byte
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync size += disParseInstruction(uCodePtr, pOp, pCpu);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return size;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync}
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync//*****************************************************************************
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync//*****************************************************************************
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncunsigned ParseGrp15(RTUINTPTR uCodePtr, PCDISOPCODE pOp, PDISOPPARAM pParam, PDISCPUSTATE pCpu)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync{
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync unsigned size = 0, modrm, reg, mod, rm;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync NOREF(pParam);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync modrm = disReadByte(pCpu, uCodePtr);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync mod = MODRM_MOD(modrm);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync reg = MODRM_REG(modrm);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync rm = MODRM_RM(modrm);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (mod == 3 && rm == 0)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pOp = (PCDISOPCODE)&g_aMapX86_Group15_mod11_rm000[reg];
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync else
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pOp = (PCDISOPCODE)&g_aMapX86_Group15_mem[reg];
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync //little hack to make sure the ModRM byte is included in the returned size
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (pOp->idxParse1 != IDX_ParseModRM && pOp->idxParse2 != IDX_ParseModRM)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync size = sizeof(uint8_t); //ModRM byte
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync size += disParseInstruction(uCodePtr, pOp, pCpu);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return size;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync}
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync//*****************************************************************************
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync//*****************************************************************************
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncunsigned ParseGrp16(RTUINTPTR uCodePtr, PCDISOPCODE pOp, PDISOPPARAM pParam, PDISCPUSTATE pCpu)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync{
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync unsigned size = 0, modrm, reg;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync NOREF(pParam);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync modrm = disReadByte(pCpu, uCodePtr);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync reg = MODRM_REG(modrm);
d64aa881df34a86dd70ab0e1b7b94ffa41be9731vboxsync
d64aa881df34a86dd70ab0e1b7b94ffa41be9731vboxsync pOp = (PCDISOPCODE)&g_aMapX86_Group16[reg];
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync //little hack to make sure the ModRM byte is included in the returned size
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (pOp->idxParse1 != IDX_ParseModRM && pOp->idxParse2 != IDX_ParseModRM)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync size = sizeof(uint8_t); //ModRM byte
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync size += disParseInstruction(uCodePtr, pOp, pCpu);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return size;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync}
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync//*****************************************************************************
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync#if !defined(DIS_CORE_ONLY) && defined(LOG_ENABLED)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncstatic const char *szModRMReg8[] = {"AL", "CL", "DL", "BL", "AH", "CH", "DH", "BH", "R8B", "R9B", "R10B", "R11B", "R12B", "R13B", "R14B", "R15B", "SPL", "BPL", "SIL", "DIL"};
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncstatic const char *szModRMReg16[] = {"AX", "CX", "DX", "BX", "SP", "BP", "SI", "DI", "R8W", "R9W", "R10W", "R11W", "R12W", "R13W", "R14W", "R15W"};
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncstatic const char *szModRMReg32[] = {"EAX", "ECX", "EDX", "EBX", "ESP", "EBP", "ESI", "EDI", "R8D", "R9D", "R10D", "R11D", "R12D", "R13D", "R14D", "R15D"};
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncstatic const char *szModRMReg64[] = {"RAX", "RCX", "RDX", "RBX", "RSP", "RBP", "RSI", "RDI", "R8", "R9", "R10", "R11", "R12", "R13", "R14", "R15"};
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncstatic const char *szModRMReg1616[8] = {"BX+SI", "BX+DI", "BP+SI", "BP+DI", "SI", "DI", "BP", "BX"};
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync#endif
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncstatic const char *szModRMSegReg[6] = {"ES", "CS", "SS", "DS", "FS", "GS"};
d64aa881df34a86dd70ab0e1b7b94ffa41be9731vboxsyncstatic const int BaseModRMReg16[8] = { DISGREG_BX, DISGREG_BX, DISGREG_BP, DISGREG_BP, DISGREG_SI, DISGREG_DI, DISGREG_BP, DISGREG_BX};
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncstatic const int IndexModRMReg16[4] = { DISGREG_SI, DISGREG_DI, DISGREG_SI, DISGREG_DI};
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync//*****************************************************************************
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncstatic void disasmModRMReg(PDISCPUSTATE pCpu, PCDISOPCODE pOp, unsigned idx, PDISOPPARAM pParam, int fRegAddr)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync{
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync NOREF(pOp); NOREF(pCpu);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync unsigned mod = pCpu->ModRM.Bits.Mod;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync unsigned type = OP_PARM_VTYPE(pParam->fParam);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync unsigned subtype = OP_PARM_VSUBTYPE(pParam->fParam);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (fRegAddr)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync subtype = (pCpu->uAddrMode == DISCPUMODE_64BIT) ? OP_PARM_q : OP_PARM_d;
d64aa881df34a86dd70ab0e1b7b94ffa41be9731vboxsync else
d64aa881df34a86dd70ab0e1b7b94ffa41be9731vboxsync if (subtype == OP_PARM_v || subtype == OP_PARM_NONE)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync switch (pCpu->uOpMode)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync case DISCPUMODE_32BIT:
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync subtype = OP_PARM_d;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync break;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync case DISCPUMODE_64BIT:
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync subtype = OP_PARM_q;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync break;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync case DISCPUMODE_16BIT:
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync subtype = OP_PARM_w;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync break;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync default:
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync /* make gcc happy */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync break;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync switch (subtype)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync case OP_PARM_b:
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync Assert(idx < (pCpu->fPrefix & DISPREFIX_REX ? 16U : 8U));
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync /* AH, BH, CH & DH map to DIL, SIL, EBL & SPL when a rex prefix is present. */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync /* Intel� 64 and IA-32 Architectures Software Developer�s Manual: 3.4.1.1 */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if ( (pCpu->fPrefix & DISPREFIX_REX)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync && idx >= DISGREG_AH
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync && idx <= DISGREG_BH)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync idx += (DISGREG_SPL - DISGREG_AH);
d64aa881df34a86dd70ab0e1b7b94ffa41be9731vboxsync }
d64aa881df34a86dd70ab0e1b7b94ffa41be9731vboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pParam->fUse |= DISUSE_REG_GEN8;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pParam->base.reg_gen = idx;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync break;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync case OP_PARM_w:
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync Assert(idx < (pCpu->fPrefix & DISPREFIX_REX ? 16U : 8U));
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pParam->fUse |= DISUSE_REG_GEN16;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pParam->base.reg_gen = idx;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync break;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync case OP_PARM_d:
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync Assert(idx < (pCpu->fPrefix & DISPREFIX_REX ? 16U : 8U));
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pParam->fUse |= DISUSE_REG_GEN32;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pParam->base.reg_gen = idx;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync break;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync case OP_PARM_q:
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pParam->fUse |= DISUSE_REG_GEN64;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pParam->base.reg_gen = idx;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync break;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync default:
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync Log(("disasmModRMReg %x:%x failed!!\n", type, subtype));
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pCpu->rc = VERR_DIS_INVALID_MODRM;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync break;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync}
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync//*****************************************************************************
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync//*****************************************************************************
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncstatic void disasmModRMReg16(PDISCPUSTATE pCpu, PCDISOPCODE pOp, unsigned idx, PDISOPPARAM pParam)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync{
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync NOREF(pCpu); NOREF(pOp);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pParam->fUse |= DISUSE_REG_GEN16;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pParam->base.reg_gen = BaseModRMReg16[idx];
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (idx < 4)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pParam->fUse |= DISUSE_INDEX;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pParam->Index.idxGenReg = IndexModRMReg16[idx];
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync}
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync//*****************************************************************************
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync//*****************************************************************************
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncstatic void disasmModRMSReg(PDISCPUSTATE pCpu, PCDISOPCODE pOp, unsigned idx, PDISOPPARAM pParam)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync{
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync NOREF(pOp);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (idx >= RT_ELEMENTS(szModRMSegReg))
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync Log(("disasmModRMSReg %d failed!!\n", idx));
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pCpu->rc = VERR_DIS_INVALID_PARAMETER;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pParam->fUse |= DISUSE_REG_SEG;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pParam->base.reg_seg = (DISSELREG)idx;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync}
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync/**
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * Slow path for storing instruction bytes.
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync *
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * @param pCpu The disassembler state.
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * @param uAddress The address.
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * @param pbSrc The bytes.
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * @param cbSrc The number of bytes.
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncDECL_NO_INLINE(static, void)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncdisStoreInstrBytesSlow(PDISCPUSTATE pCpu, RTUINTPTR uAddress, const uint8_t *pbSrc, size_t cbSrc)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync{
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync /*
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * Figure out which case it is.
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync uint32_t cbInstr = pCpu->cbInstr;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync RTUINTPTR off = uAddress - pCpu->uInstrAddr;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (off < cbInstr)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (off + cbSrc <= cbInstr)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync AssertMsg(memcmp(&pCpu->abInstr[off], pbSrc, cbSrc) == 0,
a21a14c99f2698c3a8b6dc0a3086e087701fe719vboxsync ("%RTptr LB %zx off=%RTptr (%.*Rhxs)", uAddress, cbSrc, off, cbInstr, pCpu->abInstr));
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return; /* fully re-reading old stuff. */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync /* Only partially re-reading stuff, skip ahead and add the rest. */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync uint32_t cbAlreadyRead = cbInstr - (uint32_t)off;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync Assert(memcmp(&pCpu->abInstr[off], pbSrc, cbAlreadyRead) == 0);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync uAddress += cbAlreadyRead;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pbSrc += cbAlreadyRead;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync cbSrc -= cbAlreadyRead;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (off >= sizeof(cbInstr))
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync /* The instruction is too long! This shouldn't happen. */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync AssertMsgFailed(("%RTptr LB %zx off=%RTptr (%.*Rhxs)", uAddress, cbSrc, off, cbInstr, pCpu->abInstr));
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync else if (off > cbInstr)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync /* Mind the gap - this shouldn't happen, but read the gap bytes if it does. */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync AssertMsgFailed(("%RTptr LB %zx off=%RTptr (%.16Rhxs)", uAddress, cbSrc, off, cbInstr, pCpu->abInstr));
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync uint32_t cbGap = off - cbInstr;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync int rc = pCpu->pfnReadBytes(pCpu, &pCpu->abInstr[cbInstr], uAddress - cbGap, cbGap);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (RT_FAILURE(rc))
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pCpu->rc = VERR_DIS_MEM_READ;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync RT_BZERO(&pCpu->abInstr[cbInstr], cbGap);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pCpu->cbInstr = cbInstr = off;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync /*
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * Copy the bytes.
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (off + cbSrc <= sizeof(pCpu->abInstr))
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync memcpy(&pCpu->abInstr[cbInstr], pbSrc, cbSrc);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pCpu->cbInstr = cbInstr + (uint32_t)cbSrc;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync else
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync size_t cbToCopy = sizeof(pCpu->abInstr) - off;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync memcpy(&pCpu->abInstr[cbInstr], pbSrc, cbToCopy);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pCpu->cbInstr = sizeof(pCpu->abInstr);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync AssertMsgFailed(("%RTptr LB %zx off=%RTptr (%.*Rhxs)", uAddress, cbSrc, off, sizeof(pCpu->abInstr), pCpu->abInstr));
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync}
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncDECLCALLBACK(int) disReadBytesDefault(PDISCPUSTATE pCpu, uint8_t *pbDst, RTUINTPTR uSrcAddr, uint32_t cbToRead)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync{
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync#ifdef IN_RING0
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync AssertMsgFailed(("disReadWord with no read callback in ring 0!!\n"));
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync RT_BZERO(pbDst, cbToRead);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return VERR_DIS_NO_READ_CALLBACK;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync#else
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync memcpy(pbDst, (void const *)(uintptr_t)uSrcAddr, cbToRead);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return VINF_SUCCESS;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync#endif
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync}
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync//*****************************************************************************
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync/* Read functions for getting the opcode bytes */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync//*****************************************************************************
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncuint8_t disReadByte(PDISCPUSTATE pCpu, RTUINTPTR uAddress)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync{
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync uint8_t bTemp = 0;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync int rc = pCpu->pfnReadBytes(pCpu, &bTemp, uAddress, sizeof(bTemp));
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (RT_FAILURE(rc))
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync Log(("disReadByte failed!!\n"));
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pCpu->rc = VERR_DIS_MEM_READ;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync/** @todo change this into reading directly into abInstr and use it as a
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * cache. */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (RT_LIKELY( pCpu->uInstrAddr + pCpu->cbInstr == uAddress
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync && pCpu->cbInstr + sizeof(bTemp) < sizeof(pCpu->abInstr)))
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pCpu->abInstr[pCpu->cbInstr++] = bTemp;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync else
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync disStoreInstrBytesSlow(pCpu, uAddress, &bTemp, sizeof(bTemp));
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return bTemp;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync}
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync//*****************************************************************************
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync//*****************************************************************************
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncuint16_t disReadWord(PDISCPUSTATE pCpu, RTUINTPTR uAddress)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync{
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync RTUINT16U uTemp;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync uTemp.u = 0;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync int rc = pCpu->pfnReadBytes(pCpu, uTemp.au8, uAddress, sizeof(uTemp));
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (RT_FAILURE(rc))
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync Log(("disReadWord failed!!\n"));
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pCpu->rc = VERR_DIS_MEM_READ;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (RT_LIKELY( pCpu->uInstrAddr + pCpu->cbInstr == uAddress
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync && pCpu->cbInstr + sizeof(uTemp) < sizeof(pCpu->abInstr)))
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pCpu->abInstr[pCpu->cbInstr ] = uTemp.au8[0];
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pCpu->abInstr[pCpu->cbInstr + 1] = uTemp.au8[1];
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pCpu->cbInstr += 2;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync else
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync disStoreInstrBytesSlow(pCpu, uAddress, uTemp.au8, sizeof(uTemp));
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return uTemp.u;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync}
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync//*****************************************************************************
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync//*****************************************************************************
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncuint32_t disReadDWord(PDISCPUSTATE pCpu, RTUINTPTR uAddress)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync{
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync RTUINT32U uTemp;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync uTemp.u = 0;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync int rc = pCpu->pfnReadBytes(pCpu, uTemp.au8, uAddress, sizeof(uTemp));
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (RT_FAILURE(rc))
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
a21a14c99f2698c3a8b6dc0a3086e087701fe719vboxsync Log(("disReadDWord failed!!\n"));
a21a14c99f2698c3a8b6dc0a3086e087701fe719vboxsync pCpu->rc = VERR_DIS_MEM_READ;
a21a14c99f2698c3a8b6dc0a3086e087701fe719vboxsync }
a21a14c99f2698c3a8b6dc0a3086e087701fe719vboxsync
a21a14c99f2698c3a8b6dc0a3086e087701fe719vboxsync if (RT_LIKELY( pCpu->uInstrAddr + pCpu->cbInstr == uAddress
a21a14c99f2698c3a8b6dc0a3086e087701fe719vboxsync && pCpu->cbInstr + sizeof(uTemp) < sizeof(pCpu->abInstr)))
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pCpu->abInstr[pCpu->cbInstr ] = uTemp.au8[0];
a21a14c99f2698c3a8b6dc0a3086e087701fe719vboxsync pCpu->abInstr[pCpu->cbInstr + 1] = uTemp.au8[1];
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pCpu->abInstr[pCpu->cbInstr + 2] = uTemp.au8[2];
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pCpu->abInstr[pCpu->cbInstr + 3] = uTemp.au8[3];
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pCpu->cbInstr += 4;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync else
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync disStoreInstrBytesSlow(pCpu, uAddress, uTemp.au8, sizeof(uTemp));
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return uTemp.u;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync}
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync//*****************************************************************************
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync//*****************************************************************************
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncuint64_t disReadQWord(PDISCPUSTATE pCpu, RTUINTPTR uAddress)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync{
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync RTUINT64U uTemp;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync uTemp.u = 0;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync int rc = pCpu->pfnReadBytes(pCpu, uTemp.au8, uAddress, sizeof(uTemp));
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (RT_FAILURE(rc))
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync Log(("disReadQWord %x failed!!\n", uAddress));
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pCpu->rc = VERR_DIS_MEM_READ;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (RT_LIKELY( pCpu->uInstrAddr + pCpu->cbInstr == uAddress
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync && pCpu->cbInstr + sizeof(uTemp) < sizeof(pCpu->abInstr)))
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pCpu->abInstr[pCpu->cbInstr ] = uTemp.au8[0];
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pCpu->abInstr[pCpu->cbInstr + 1] = uTemp.au8[1];
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pCpu->abInstr[pCpu->cbInstr + 2] = uTemp.au8[2];
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pCpu->abInstr[pCpu->cbInstr + 3] = uTemp.au8[3];
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pCpu->abInstr[pCpu->cbInstr + 4] = uTemp.au8[4];
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pCpu->abInstr[pCpu->cbInstr + 5] = uTemp.au8[5];
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pCpu->abInstr[pCpu->cbInstr + 6] = uTemp.au8[6];
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pCpu->abInstr[pCpu->cbInstr + 7] = uTemp.au8[7];
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pCpu->cbInstr += 8;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync else
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync disStoreInstrBytesSlow(pCpu, uAddress, uTemp.au8, sizeof(uTemp));
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return uTemp.u;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync}
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9cdd4d805ecb43126372f7cf12e4032836cb738avboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync/**
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * Validates the lock sequence.
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync *
9cdd4d805ecb43126372f7cf12e4032836cb738avboxsync * The AMD manual lists the following instructions:
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * ADC
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * ADD
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * AND
9cdd4d805ecb43126372f7cf12e4032836cb738avboxsync * BTC
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * BTR
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * BTS
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * CMPXCHG
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * CMPXCHG8B
9cdd4d805ecb43126372f7cf12e4032836cb738avboxsync * CMPXCHG16B
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * DEC
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * INC
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * NEG
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * NOT
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * OR
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * SBB
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * SUB
9cdd4d805ecb43126372f7cf12e4032836cb738avboxsync * XADD
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * XCHG
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * XOR
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync *
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * @param pCpu Fully disassembled instruction.
9cdd4d805ecb43126372f7cf12e4032836cb738avboxsync */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncstatic void disValidateLockSequence(PDISCPUSTATE pCpu)
9cdd4d805ecb43126372f7cf12e4032836cb738avboxsync{
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync Assert(pCpu->fPrefix & DISPREFIX_LOCK);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync /*
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * Filter out the valid lock sequences.
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync switch (pCpu->pCurInstr->uOpcode)
9cdd4d805ecb43126372f7cf12e4032836cb738avboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync /* simple: no variations */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync case OP_CMPXCHG8B: /* == OP_CMPXCHG16B? */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync /* simple: /r - reject register destination. */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync case OP_BTC:
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync case OP_BTR:
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync case OP_BTS:
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync case OP_CMPXCHG:
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync case OP_XADD:
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (pCpu->ModRM.Bits.Mod == 3)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync break;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync /*
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * Lots of variants but its sufficient to check that param 1
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * is a memory operand.
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync case OP_ADC:
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync case OP_ADD:
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync case OP_AND:
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync case OP_DEC:
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync case OP_INC:
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync case OP_NEG:
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync case OP_NOT:
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync case OP_OR:
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync case OP_SBB:
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync case OP_SUB:
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync case OP_XCHG:
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync case OP_XOR:
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (pCpu->Param1.fUse & (DISUSE_BASE | DISUSE_INDEX | DISUSE_DISPLACEMENT64 | DISUSE_DISPLACEMENT32
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync | DISUSE_DISPLACEMENT16 | DISUSE_DISPLACEMENT8 | DISUSE_RIPDISPLACEMENT32))
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync break;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync default:
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync break;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync /*
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * Invalid lock sequence, make it a OP_ILLUD2.
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pCpu->pCurInstr = &g_aTwoByteMapX86[11];
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync Assert(pCpu->pCurInstr->uOpcode == OP_ILLUD2);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync}
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync