DisasmCore.cpp revision 9d4c9e0a3e2dcc3bd19303d7b4e2d96d12c11814
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
384478d3896257fbce9ceb8c01e74040b969e6d7vboxsync/*******************************************************************************
73ba84f95f918cc170be38908ad240fbb2f8f354vboxsync* Internal Functions *
73ba84f95f918cc170be38908ad240fbb2f8f354vboxsync*******************************************************************************/
73ba84f95f918cc170be38908ad240fbb2f8f354vboxsyncstatic int disInstrWorker(PDISCPUSTATE pCpu, RTUINTPTR uInstrAddr, PCDISOPCODE paOneByteMap, uint32_t *pcbInstr);
384478d3896257fbce9ceb8c01e74040b969e6d7vboxsyncstatic 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);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncstatic 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);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
4a9af9a8062589b741444d717d2dd1ed22b0f583vboxsync
4a9af9a8062589b741444d717d2dd1ed22b0f583vboxsync/** @name Parsers
4a9af9a8062589b741444d717d2dd1ed22b0f583vboxsync * @{ */
4a9af9a8062589b741444d717d2dd1ed22b0f583vboxsyncstatic FNDISPARSE ParseIllegal;
4a9af9a8062589b741444d717d2dd1ed22b0f583vboxsyncstatic FNDISPARSE ParseModRM;
4a9af9a8062589b741444d717d2dd1ed22b0f583vboxsyncstatic FNDISPARSE ParseModRM_SizeOnly;
4a9af9a8062589b741444d717d2dd1ed22b0f583vboxsyncstatic FNDISPARSE UseModRM;
4a9af9a8062589b741444d717d2dd1ed22b0f583vboxsyncstatic FNDISPARSE ParseImmByte;
4a9af9a8062589b741444d717d2dd1ed22b0f583vboxsyncstatic FNDISPARSE ParseImmByte_SizeOnly;
4a9af9a8062589b741444d717d2dd1ed22b0f583vboxsyncstatic FNDISPARSE ParseImmByteSX;
4a9af9a8062589b741444d717d2dd1ed22b0f583vboxsyncstatic FNDISPARSE ParseImmByteSX_SizeOnly;
4a9af9a8062589b741444d717d2dd1ed22b0f583vboxsyncstatic FNDISPARSE ParseImmBRel;
4a9af9a8062589b741444d717d2dd1ed22b0f583vboxsyncstatic FNDISPARSE ParseImmBRel_SizeOnly;
4a9af9a8062589b741444d717d2dd1ed22b0f583vboxsyncstatic FNDISPARSE ParseImmUshort;
4a9af9a8062589b741444d717d2dd1ed22b0f583vboxsyncstatic FNDISPARSE ParseImmUshort_SizeOnly;
4a9af9a8062589b741444d717d2dd1ed22b0f583vboxsyncstatic FNDISPARSE ParseImmV;
4a9af9a8062589b741444d717d2dd1ed22b0f583vboxsyncstatic FNDISPARSE ParseImmV_SizeOnly;
4a9af9a8062589b741444d717d2dd1ed22b0f583vboxsyncstatic FNDISPARSE ParseImmVRel;
4a9af9a8062589b741444d717d2dd1ed22b0f583vboxsyncstatic FNDISPARSE ParseImmVRel_SizeOnly;
4a9af9a8062589b741444d717d2dd1ed22b0f583vboxsyncstatic FNDISPARSE ParseImmZ;
4a9af9a8062589b741444d717d2dd1ed22b0f583vboxsyncstatic FNDISPARSE ParseImmZ_SizeOnly;
4a9af9a8062589b741444d717d2dd1ed22b0f583vboxsync
4a9af9a8062589b741444d717d2dd1ed22b0f583vboxsyncstatic FNDISPARSE ParseImmAddr;
4a9af9a8062589b741444d717d2dd1ed22b0f583vboxsyncstatic FNDISPARSE ParseImmAddr_SizeOnly;
4a9af9a8062589b741444d717d2dd1ed22b0f583vboxsyncstatic FNDISPARSE ParseImmAddrF;
4a9af9a8062589b741444d717d2dd1ed22b0f583vboxsyncstatic FNDISPARSE ParseImmAddrF_SizeOnly;
4a9af9a8062589b741444d717d2dd1ed22b0f583vboxsyncstatic FNDISPARSE ParseFixedReg;
4a9af9a8062589b741444d717d2dd1ed22b0f583vboxsyncstatic FNDISPARSE ParseImmUlong;
4a9af9a8062589b741444d717d2dd1ed22b0f583vboxsyncstatic FNDISPARSE ParseImmUlong_SizeOnly;
4a9af9a8062589b741444d717d2dd1ed22b0f583vboxsyncstatic FNDISPARSE ParseImmQword;
4a9af9a8062589b741444d717d2dd1ed22b0f583vboxsyncstatic FNDISPARSE ParseImmQword_SizeOnly;
4a9af9a8062589b741444d717d2dd1ed22b0f583vboxsync
4a9af9a8062589b741444d717d2dd1ed22b0f583vboxsyncstatic FNDISPARSE ParseTwoByteEsc;
4a9af9a8062589b741444d717d2dd1ed22b0f583vboxsyncstatic FNDISPARSE ParseThreeByteEsc4;
4a9af9a8062589b741444d717d2dd1ed22b0f583vboxsyncstatic FNDISPARSE ParseThreeByteEsc5;
4a9af9a8062589b741444d717d2dd1ed22b0f583vboxsyncstatic FNDISPARSE ParseImmGrpl;
4a9af9a8062589b741444d717d2dd1ed22b0f583vboxsyncstatic FNDISPARSE ParseShiftGrp2;
4a9af9a8062589b741444d717d2dd1ed22b0f583vboxsyncstatic FNDISPARSE ParseGrp3;
4a9af9a8062589b741444d717d2dd1ed22b0f583vboxsyncstatic FNDISPARSE ParseGrp4;
4a9af9a8062589b741444d717d2dd1ed22b0f583vboxsyncstatic FNDISPARSE ParseGrp5;
4a9af9a8062589b741444d717d2dd1ed22b0f583vboxsyncstatic FNDISPARSE Parse3DNow;
4a9af9a8062589b741444d717d2dd1ed22b0f583vboxsyncstatic FNDISPARSE ParseGrp6;
3a343ca21a267ec3c54e2317e2ed18fe99b8ebbbvboxsyncstatic FNDISPARSE ParseGrp7;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncstatic FNDISPARSE ParseGrp8;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncstatic FNDISPARSE ParseGrp9;
3a343ca21a267ec3c54e2317e2ed18fe99b8ebbbvboxsyncstatic FNDISPARSE ParseGrp10;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncstatic FNDISPARSE ParseGrp12;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncstatic FNDISPARSE ParseGrp13;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncstatic FNDISPARSE ParseGrp14;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncstatic FNDISPARSE ParseGrp15;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncstatic FNDISPARSE ParseGrp16;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncstatic FNDISPARSE ParseModFence;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncstatic FNDISPARSE ParseNopPause;
3a343ca21a267ec3c54e2317e2ed18fe99b8ebbbvboxsync
3a343ca21a267ec3c54e2317e2ed18fe99b8ebbbvboxsyncstatic 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*******************************************************************************/
73ba84f95f918cc170be38908ad240fbb2f8f354vboxsync/** 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,
73ba84f95f918cc170be38908ad240fbb2f8f354vboxsync ParseImmUlong,
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync ParseImmQword,
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync ParseTwoByteEsc,
0593640ab087e5bf747a2576b1752a2046be83aavboxsync 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
0593640ab087e5bf747a2576b1752a2046be83aavboxsync/** Parser opcode table for only calculating instruction size. */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncstatic PFNDISPARSE const g_apfnCalcSize[IDX_ParseMax] =
73ba84f95f918cc170be38908ad240fbb2f8f354vboxsync{
7b4ea63789001468ec3662bdfcd6432bf89095dfvboxsync ParseIllegal,
7b4ea63789001468ec3662bdfcd6432bf89095dfvboxsync ParseModRM_SizeOnly,
7b4ea63789001468ec3662bdfcd6432bf89095dfvboxsync UseModRM,
7b4ea63789001468ec3662bdfcd6432bf89095dfvboxsync ParseImmByte_SizeOnly,
7b4ea63789001468ec3662bdfcd6432bf89095dfvboxsync ParseImmBRel_SizeOnly,
7b4ea63789001468ec3662bdfcd6432bf89095dfvboxsync ParseImmUshort_SizeOnly,
7b4ea63789001468ec3662bdfcd6432bf89095dfvboxsync ParseImmV_SizeOnly,
7b4ea63789001468ec3662bdfcd6432bf89095dfvboxsync ParseImmVRel_SizeOnly,
7b4ea63789001468ec3662bdfcd6432bf89095dfvboxsync ParseImmAddr_SizeOnly,
7b4ea63789001468ec3662bdfcd6432bf89095dfvboxsync ParseFixedReg,
7b4ea63789001468ec3662bdfcd6432bf89095dfvboxsync ParseImmUlong_SizeOnly,
7b4ea63789001468ec3662bdfcd6432bf89095dfvboxsync ParseImmQword_SizeOnly,
7b4ea63789001468ec3662bdfcd6432bf89095dfvboxsync ParseTwoByteEsc,
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync ParseImmGrpl,
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync ParseShiftGrp2,
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync ParseGrp3,
73ba84f95f918cc170be38908ad240fbb2f8f354vboxsync ParseGrp4,
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync ParseGrp5,
73ba84f95f918cc170be38908ad240fbb2f8f354vboxsync Parse3DNow,
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync ParseGrp6,
73ba84f95f918cc170be38908ad240fbb2f8f354vboxsync ParseGrp7,
73ba84f95f918cc170be38908ad240fbb2f8f354vboxsync ParseGrp8,
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync ParseGrp9,
73ba84f95f918cc170be38908ad240fbb2f8f354vboxsync ParseGrp10,
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync ParseGrp12,
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync ParseGrp13,
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync ParseGrp14,
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync ParseGrp15,
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync ParseGrp16,
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync ParseModFence,
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync ParseYv,
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync ParseYb,
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync ParseXv,
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync ParseXb,
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync ParseEscFP,
73ba84f95f918cc170be38908ad240fbb2f8f354vboxsync 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 *
73ba84f95f918cc170be38908ad240fbb2f8f354vboxsync * @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
73ba84f95f918cc170be38908ad240fbb2f8f354vboxsync * 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.
73ba84f95f918cc170be38908ad240fbb2f8f354vboxsync * @param pfnReadBytes Callback for reading instruction bytes.
73ba84f95f918cc170be38908ad240fbb2f8f354vboxsync * @param pvUser User argument for the instruction reader. (Ends up in pvUser.)
73ba84f95f918cc170be38908ad240fbb2f8f354vboxsync * @param pCpu Pointer to cpu structure. Will be initialized.
73ba84f95f918cc170be38908ad240fbb2f8f354vboxsync * @param pcbInstr Where to store the size of the instruction.
73ba84f95f918cc170be38908ad240fbb2f8f354vboxsync * NULL is allowed. This is also stored in
73ba84f95f918cc170be38908ad240fbb2f8f354vboxsync * PDISCPUSTATE::cbInstr.
73ba84f95f918cc170be38908ad240fbb2f8f354vboxsync */
73ba84f95f918cc170be38908ad240fbb2f8f354vboxsyncDISDECL(int) DISInstr(const void *pvInstr, DISCPUMODE enmCpuMode, PDISCPUSTATE pCpu, uint32_t *pcbInstr)
73ba84f95f918cc170be38908ad240fbb2f8f354vboxsync{
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return DISInstEx((uintptr_t)pvInstr, enmCpuMode, DISOPTYPE_ALL, NULL /*pfnReadBytes*/, NULL /*pvUser*/, pCpu, pcbInstr);
73ba84f95f918cc170be38908ad240fbb2f8f354vboxsync}
73ba84f95f918cc170be38908ad240fbb2f8f354vboxsync
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)
0593640ab087e5bf747a2576b1752a2046be83aavboxsync{
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 *
73ba84f95f918cc170be38908ad240fbb2f8f354vboxsync * @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.
329df9696e709dc71611f504a4774f323545be0avboxsync * @param fFilter Instruction type filter.
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * @param pvUser User argument for the instruction reader. (Ends up in pvUser.)
329df9696e709dc71611f504a4774f323545be0avboxsync * @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.
329df9696e709dc71611f504a4774f323545be0avboxsync * @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,
329df9696e709dc71611f504a4774f323545be0avboxsync PFNDISREADBYTES pfnReadBytes, void *pvUser,
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync PDISCPUSTATE pCpu, uint32_t *pcbInstr)
329df9696e709dc71611f504a4774f323545be0avboxsync{
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync PCDISOPCODE paOneByteMap;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync /*
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * Initialize the CPU state.
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * Note! The RT_BZERO make ASSUMPTIONS about the placement of pvUser2.
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync RT_BZERO(pCpu, RT_OFFSETOF(DISCPUSTATE, pvUser2));
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pCpu->mode = enmCpuMode;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (enmCpuMode == DISCPUMODE_64BIT)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
329df9696e709dc71611f504a4774f323545be0avboxsync paOneByteMap = g_aOneByteMapX64;
329df9696e709dc71611f504a4774f323545be0avboxsync pCpu->uAddrMode = DISCPUMODE_64BIT;
329df9696e709dc71611f504a4774f323545be0avboxsync pCpu->uOpMode = DISCPUMODE_32BIT;
329df9696e709dc71611f504a4774f323545be0avboxsync }
329df9696e709dc71611f504a4774f323545be0avboxsync else
329df9696e709dc71611f504a4774f323545be0avboxsync {
329df9696e709dc71611f504a4774f323545be0avboxsync paOneByteMap = g_aOneByteMapX86;
329df9696e709dc71611f504a4774f323545be0avboxsync pCpu->uAddrMode = enmCpuMode;
329df9696e709dc71611f504a4774f323545be0avboxsync pCpu->uOpMode = enmCpuMode;
329df9696e709dc71611f504a4774f323545be0avboxsync }
329df9696e709dc71611f504a4774f323545be0avboxsync pCpu->fPrefix = DISPREFIX_NONE;
329df9696e709dc71611f504a4774f323545be0avboxsync pCpu->idxSegPrefix = DISSELREG_DS;
329df9696e709dc71611f504a4774f323545be0avboxsync pCpu->uInstrAddr = uInstrAddr;
329df9696e709dc71611f504a4774f323545be0avboxsync pCpu->pfnDisasmFnTable = g_apfnFullDisasm;
329df9696e709dc71611f504a4774f323545be0avboxsync pCpu->fFilter = fFilter;
329df9696e709dc71611f504a4774f323545be0avboxsync pCpu->rc = VINF_SUCCESS;
329df9696e709dc71611f504a4774f323545be0avboxsync pCpu->pfnReadBytes = pfnReadBytes ? pfnReadBytes : disReadBytesDefault;
329df9696e709dc71611f504a4774f323545be0avboxsync pCpu->pvUser = pvUser;
329df9696e709dc71611f504a4774f323545be0avboxsync
329df9696e709dc71611f504a4774f323545be0avboxsync return disInstrWorker(pCpu, uInstrAddr, paOneByteMap, pcbInstr);
329df9696e709dc71611f504a4774f323545be0avboxsync}
329df9696e709dc71611f504a4774f323545be0avboxsync
329df9696e709dc71611f504a4774f323545be0avboxsync
329df9696e709dc71611f504a4774f323545be0avboxsync/**
329df9696e709dc71611f504a4774f323545be0avboxsync * Internal worker for DISInstEx.
329df9696e709dc71611f504a4774f323545be0avboxsync *
329df9696e709dc71611f504a4774f323545be0avboxsync * @returns VBox status code.
329df9696e709dc71611f504a4774f323545be0avboxsync * @param pCpu Initialized cpu state.
09f4b412099acda62997fd82c8608075c453b3ebvboxsync * @param paOneByteMap The one byte opcode map to use.
09f4b412099acda62997fd82c8608075c453b3ebvboxsync * @param uInstrAddr Instruction address.
09f4b412099acda62997fd82c8608075c453b3ebvboxsync * @param pcbInstr Where to store the instruction size. Can be NULL.
09f4b412099acda62997fd82c8608075c453b3ebvboxsync */
09f4b412099acda62997fd82c8608075c453b3ebvboxsyncstatic int disInstrWorker(PDISCPUSTATE pCpu, RTUINTPTR uInstrAddr, PCDISOPCODE paOneByteMap, uint32_t *pcbInstr)
09f4b412099acda62997fd82c8608075c453b3ebvboxsync{
09f4b412099acda62997fd82c8608075c453b3ebvboxsync /*
09f4b412099acda62997fd82c8608075c453b3ebvboxsync * Parse byte by byte.
09f4b412099acda62997fd82c8608075c453b3ebvboxsync */
09f4b412099acda62997fd82c8608075c453b3ebvboxsync unsigned iByte = 0;
09f4b412099acda62997fd82c8608075c453b3ebvboxsync unsigned cbInc;
09f4b412099acda62997fd82c8608075c453b3ebvboxsync for (;;)
09f4b412099acda62997fd82c8608075c453b3ebvboxsync {
09f4b412099acda62997fd82c8608075c453b3ebvboxsync uint8_t codebyte = disReadByte(pCpu, uInstrAddr+iByte);
09f4b412099acda62997fd82c8608075c453b3ebvboxsync uint8_t opcode = paOneByteMap[codebyte].opcode;
09f4b412099acda62997fd82c8608075c453b3ebvboxsync
09f4b412099acda62997fd82c8608075c453b3ebvboxsync /* Hardcoded assumption about OP_* values!! */
09f4b412099acda62997fd82c8608075c453b3ebvboxsync if (opcode <= OP_LAST_PREFIX)
73ba84f95f918cc170be38908ad240fbb2f8f354vboxsync {
73ba84f95f918cc170be38908ad240fbb2f8f354vboxsync /* The REX prefix must precede the opcode byte(s). Any other placement is ignored. */
73ba84f95f918cc170be38908ad240fbb2f8f354vboxsync if (opcode != OP_REX)
73ba84f95f918cc170be38908ad240fbb2f8f354vboxsync {
09f4b412099acda62997fd82c8608075c453b3ebvboxsync /** Last prefix byte (for SSE2 extension tables); don't include the REX prefix */
09f4b412099acda62997fd82c8608075c453b3ebvboxsync pCpu->bLastPrefix = opcode;
09f4b412099acda62997fd82c8608075c453b3ebvboxsync pCpu->fPrefix &= ~DISPREFIX_REX;
09f4b412099acda62997fd82c8608075c453b3ebvboxsync }
73ba84f95f918cc170be38908ad240fbb2f8f354vboxsync
73ba84f95f918cc170be38908ad240fbb2f8f354vboxsync switch (opcode)
73ba84f95f918cc170be38908ad240fbb2f8f354vboxsync {
73ba84f95f918cc170be38908ad240fbb2f8f354vboxsync case OP_INVALID:
09f4b412099acda62997fd82c8608075c453b3ebvboxsync if (pcbInstr)
09f4b412099acda62997fd82c8608075c453b3ebvboxsync *pcbInstr = iByte + 1;
09f4b412099acda62997fd82c8608075c453b3ebvboxsync return pCpu->rc = VERR_DIS_INVALID_OPCODE;
73ba84f95f918cc170be38908ad240fbb2f8f354vboxsync
09f4b412099acda62997fd82c8608075c453b3ebvboxsync // segment override prefix byte
09f4b412099acda62997fd82c8608075c453b3ebvboxsync case OP_SEG:
09f4b412099acda62997fd82c8608075c453b3ebvboxsync pCpu->idxSegPrefix = (DISSELREG)(paOneByteMap[codebyte].param1 - OP_PARM_REG_SEG_START);
09f4b412099acda62997fd82c8608075c453b3ebvboxsync /* Segment prefixes for CS, DS, ES and SS are ignored in long mode. */
09f4b412099acda62997fd82c8608075c453b3ebvboxsync if ( pCpu->mode != DISCPUMODE_64BIT
09f4b412099acda62997fd82c8608075c453b3ebvboxsync || pCpu->idxSegPrefix >= DISSELREG_FS)
09f4b412099acda62997fd82c8608075c453b3ebvboxsync {
09f4b412099acda62997fd82c8608075c453b3ebvboxsync pCpu->fPrefix |= DISPREFIX_SEG;
09f4b412099acda62997fd82c8608075c453b3ebvboxsync }
09f4b412099acda62997fd82c8608075c453b3ebvboxsync iByte += sizeof(uint8_t);
09f4b412099acda62997fd82c8608075c453b3ebvboxsync continue; //fetch the next byte
09f4b412099acda62997fd82c8608075c453b3ebvboxsync
09f4b412099acda62997fd82c8608075c453b3ebvboxsync // lock prefix byte
09f4b412099acda62997fd82c8608075c453b3ebvboxsync case OP_LOCK:
09f4b412099acda62997fd82c8608075c453b3ebvboxsync pCpu->fPrefix |= DISPREFIX_LOCK;
09f4b412099acda62997fd82c8608075c453b3ebvboxsync iByte += sizeof(uint8_t);
09f4b412099acda62997fd82c8608075c453b3ebvboxsync continue; //fetch the next byte
09f4b412099acda62997fd82c8608075c453b3ebvboxsync
09f4b412099acda62997fd82c8608075c453b3ebvboxsync // address size override prefix byte
09f4b412099acda62997fd82c8608075c453b3ebvboxsync case OP_ADDRSIZE:
09f4b412099acda62997fd82c8608075c453b3ebvboxsync pCpu->fPrefix |= DISPREFIX_ADDRSIZE;
09f4b412099acda62997fd82c8608075c453b3ebvboxsync if (pCpu->mode == DISCPUMODE_16BIT)
09f4b412099acda62997fd82c8608075c453b3ebvboxsync pCpu->uAddrMode = DISCPUMODE_32BIT;
09f4b412099acda62997fd82c8608075c453b3ebvboxsync else
09f4b412099acda62997fd82c8608075c453b3ebvboxsync if (pCpu->mode == DISCPUMODE_32BIT)
09f4b412099acda62997fd82c8608075c453b3ebvboxsync pCpu->uAddrMode = DISCPUMODE_16BIT;
09f4b412099acda62997fd82c8608075c453b3ebvboxsync else
09f4b412099acda62997fd82c8608075c453b3ebvboxsync pCpu->uAddrMode = DISCPUMODE_32BIT; /* 64 bits */
09f4b412099acda62997fd82c8608075c453b3ebvboxsync
09f4b412099acda62997fd82c8608075c453b3ebvboxsync iByte += sizeof(uint8_t);
09f4b412099acda62997fd82c8608075c453b3ebvboxsync continue; //fetch the next byte
09f4b412099acda62997fd82c8608075c453b3ebvboxsync
09f4b412099acda62997fd82c8608075c453b3ebvboxsync // operand size override prefix byte
09f4b412099acda62997fd82c8608075c453b3ebvboxsync case OP_OPSIZE:
09f4b412099acda62997fd82c8608075c453b3ebvboxsync pCpu->fPrefix |= DISPREFIX_OPSIZE;
09f4b412099acda62997fd82c8608075c453b3ebvboxsync if (pCpu->mode == DISCPUMODE_16BIT)
09f4b412099acda62997fd82c8608075c453b3ebvboxsync pCpu->uOpMode = DISCPUMODE_32BIT;
09f4b412099acda62997fd82c8608075c453b3ebvboxsync else
09f4b412099acda62997fd82c8608075c453b3ebvboxsync pCpu->uOpMode = DISCPUMODE_16BIT; /* for 32 and 64 bits mode (there is no 32 bits operand size override prefix) */
09f4b412099acda62997fd82c8608075c453b3ebvboxsync
09f4b412099acda62997fd82c8608075c453b3ebvboxsync iByte += sizeof(uint8_t);
09f4b412099acda62997fd82c8608075c453b3ebvboxsync continue; //fetch the next byte
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
329df9696e709dc71611f504a4774f323545be0avboxsync // rep and repne are not really prefixes, but we'll treat them as such
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync case OP_REPE:
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pCpu->fPrefix |= DISPREFIX_REP;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync iByte += sizeof(uint8_t);
73ba84f95f918cc170be38908ad240fbb2f8f354vboxsync continue; //fetch the next byte
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync case OP_REPNE:
09f4b412099acda62997fd82c8608075c453b3ebvboxsync pCpu->fPrefix |= DISPREFIX_REPNE;
329df9696e709dc71611f504a4774f323545be0avboxsync iByte += sizeof(uint8_t);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync continue; //fetch the next byte
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync case OP_REX:
dc959f60f6d3e0cba86f7da4d39aa475913a7e10vboxsync Assert(pCpu->mode == DISCPUMODE_64BIT);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync /* REX prefix byte */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pCpu->fPrefix |= DISPREFIX_REX;
dc959f60f6d3e0cba86f7da4d39aa475913a7e10vboxsync pCpu->fRexPrefix = DISPREFIX_REX_OP_2_FLAGS(paOneByteMap[codebyte].param1);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync iByte += sizeof(uint8_t);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
dc959f60f6d3e0cba86f7da4d39aa475913a7e10vboxsync if (pCpu->fRexPrefix & DISPREFIX_REX_FLAGS_W)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pCpu->uOpMode = DISCPUMODE_64BIT; /* overrides size prefix byte */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync continue; //fetch the next byte
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync unsigned uIdx = iByte;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync iByte += sizeof(uint8_t); //first opcode byte
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pCpu->bOpCode = codebyte;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync cbInc = disParseInstruction(uInstrAddr + iByte, &paOneByteMap[pCpu->bOpCode], pCpu);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync iByte += cbInc;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync break;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync AssertMsg(pCpu->cbInstr == iByte || RT_FAILURE_NP(pCpu->rc), ("%u %u\n", pCpu->cbInstr, iByte));
dc959f60f6d3e0cba86f7da4d39aa475913a7e10vboxsync pCpu->cbInstr = iByte;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (pcbInstr)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync *pcbInstr = iByte;
dc959f60f6d3e0cba86f7da4d39aa475913a7e10vboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (pCpu->fPrefix & DISPREFIX_LOCK)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync disValidateLockSequence(pCpu);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync 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->optype & 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.param = pOp->param1;
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync pCpu->param2.param = pOp->param2;
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync pCpu->param3.param = pOp->param3;
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync /* Correct the operand size if the instruction is marked as forced or default 64 bits */
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync if (pCpu->mode == DISCPUMODE_64BIT)
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync {
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync if (pOp->optype & DISOPTYPE_FORCED_64_OP_SIZE)
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync pCpu->uOpMode = DISCPUMODE_64BIT;
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync else
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync if ( (pOp->optype & DISOPTYPE_DEFAULT_64_OP_SIZE)
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync && !(pCpu->fPrefix & DISPREFIX_OPSIZE))
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync pCpu->uOpMode = DISCPUMODE_64BIT;
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync }
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync else
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync if (pOp->optype & DISOPTYPE_FORCED_32_OP_SIZE_X86)
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync {
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync /* Forced 32 bits operand size for certain instructions (mov crx, mov drx). */
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync Assert(pCpu->mode != 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)
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync{
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync int index;
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync PCDISOPCODE fpop;
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync unsigned size = 0;
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync unsigned ModRM;
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync NOREF(pOp);
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync ModRM = disReadByte(pCpu, uCodePtr);
1ff34f218a5354068e4df9017f77fc5871e6b7c6vboxsync
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync index = pCpu->bOpCode - 0xD8;
1ff34f218a5354068e4df9017f77fc5871e6b7c6vboxsync 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.param = fpop->param1;
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync pCpu->param2.param = fpop->param2;
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync }
1ff34f218a5354068e4df9017f77fc5871e6b7c6vboxsync 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 */
1ff34f218a5354068e4df9017f77fc5871e6b7c6vboxsync if ((fpop->optype & 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->mode == DISCPUMODE_64BIT)
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync {
1ff34f218a5354068e4df9017f77fc5871e6b7c6vboxsync /* Note: redundant, but just in case this ever changes */
1ff34f218a5354068e4df9017f77fc5871e6b7c6vboxsync if (fpop->optype & DISOPTYPE_FORCED_64_OP_SIZE)
1ff34f218a5354068e4df9017f77fc5871e6b7c6vboxsync pCpu->uOpMode = DISCPUMODE_64BIT;
1ff34f218a5354068e4df9017f77fc5871e6b7c6vboxsync else
1ff34f218a5354068e4df9017f77fc5871e6b7c6vboxsync if ( (fpop->optype & DISOPTYPE_DEFAULT_64_OP_SIZE)
1ff34f218a5354068e4df9017f77fc5871e6b7c6vboxsync && !(pCpu->fPrefix & DISPREFIX_OPSIZE))
1ff34f218a5354068e4df9017f77fc5871e6b7c6vboxsync pCpu->uOpMode = DISCPUMODE_64BIT;
1ff34f218a5354068e4df9017f77fc5871e6b7c6vboxsync }
1ff34f218a5354068e4df9017f77fc5871e6b7c6vboxsync
1ff34f218a5354068e4df9017f77fc5871e6b7c6vboxsync // Little hack to make sure the ModRM byte is included in the returned size
1ff34f218a5354068e4df9017f77fc5871e6b7c6vboxsync if (fpop->idxParse1 != IDX_ParseModRM && fpop->idxParse2 != IDX_ParseModRM)
1ff34f218a5354068e4df9017f77fc5871e6b7c6vboxsync size = sizeof(uint8_t); //ModRM byte
1ff34f218a5354068e4df9017f77fc5871e6b7c6vboxsync
1ff34f218a5354068e4df9017f77fc5871e6b7c6vboxsync if (fpop->idxParse1 != IDX_ParseNop)
1ff34f218a5354068e4df9017f77fc5871e6b7c6vboxsync size += pCpu->pfnDisasmFnTable[fpop->idxParse1](uCodePtr+size, (PCDISOPCODE)fpop, pParam, pCpu);
1ff34f218a5354068e4df9017f77fc5871e6b7c6vboxsync
1ff34f218a5354068e4df9017f77fc5871e6b7c6vboxsync if (fpop->idxParse2 != IDX_ParseNop)
1ff34f218a5354068e4df9017f77fc5871e6b7c6vboxsync size += pCpu->pfnDisasmFnTable[fpop->idxParse2](uCodePtr+size, (PCDISOPCODE)fpop, pParam, pCpu);
1ff34f218a5354068e4df9017f77fc5871e6b7c6vboxsync
1ff34f218a5354068e4df9017f77fc5871e6b7c6vboxsync return size;
1ff34f218a5354068e4df9017f77fc5871e6b7c6vboxsync}
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)
1ff34f218a5354068e4df9017f77fc5871e6b7c6vboxsyncstatic const char *szSIBScale[4] = {"", "*2", "*4", "*8"};
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync#endif
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync//*****************************************************************************
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsyncvoid UseSIB(RTUINTPTR uCodePtr, PCDISOPCODE pOp, PDISOPPARAM pParam, PDISCPUSTATE pCpu)
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync{
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync unsigned scale, base, index, regtype;
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync const char **ppszSIBIndexReg;
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync const char **ppszSIBBaseReg;
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync NOREF(uCodePtr); NOREF(pOp);
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync scale = pCpu->SIB.Bits.Scale;
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync base = pCpu->SIB.Bits.Base;
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync 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 {
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync ppszSIBIndexReg = szSIBIndexReg64;
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync ppszSIBBaseReg = szSIBBaseReg64;
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync regtype = DISUSE_REG_GEN64;
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync }
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync if (ppszSIBIndexReg[index])
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync {
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync pParam->fUse |= DISUSE_INDEX | regtype;
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync pParam->index.reg_gen = index;
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync if (scale != 0)
9cdd4d805ecb43126372f7cf12e4032836cb738avboxsync {
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync pParam->fUse |= DISUSE_SCALE;
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync pParam->scale = (1<<scale);
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync }
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync }
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync if (base == 5 && pCpu->ModRM.Bits.Mod == 0)
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync {
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync // [scaled index] + disp32
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync if (pCpu->uAddrMode == DISCPUMODE_32BIT)
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync {
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync pParam->fUse |= DISUSE_DISPLACEMENT32;
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync pParam->uDisp.i32 = pCpu->i32SibDisp;
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync }
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync else
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync { /* sign-extend to 64 bits */
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync pParam->fUse |= DISUSE_DISPLACEMENT64;
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync pParam->uDisp.i64 = pCpu->i32SibDisp;
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync }
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync }
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync else
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync {
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync pParam->fUse |= DISUSE_BASE | regtype;
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync pParam->base.reg_gen = base;
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync }
1ff34f218a5354068e4df9017f77fc5871e6b7c6vboxsync return; /* Already fetched everything in ParseSIB; no size returned */
1ff34f218a5354068e4df9017f77fc5871e6b7c6vboxsync}
1ff34f218a5354068e4df9017f77fc5871e6b7c6vboxsync//*****************************************************************************
1ff34f218a5354068e4df9017f77fc5871e6b7c6vboxsync//*****************************************************************************
1ff34f218a5354068e4df9017f77fc5871e6b7c6vboxsyncunsigned ParseSIB(RTUINTPTR uCodePtr, PCDISOPCODE pOp, PDISOPPARAM pParam, PDISCPUSTATE pCpu)
1ff34f218a5354068e4df9017f77fc5871e6b7c6vboxsync{
1ff34f218a5354068e4df9017f77fc5871e6b7c6vboxsync unsigned size = sizeof(uint8_t);
1ff34f218a5354068e4df9017f77fc5871e6b7c6vboxsync unsigned SIB;
1ff34f218a5354068e4df9017f77fc5871e6b7c6vboxsync NOREF(pOp); NOREF(pParam);
1ff34f218a5354068e4df9017f77fc5871e6b7c6vboxsync
1ff34f218a5354068e4df9017f77fc5871e6b7c6vboxsync SIB = disReadByte(pCpu, uCodePtr);
1ff34f218a5354068e4df9017f77fc5871e6b7c6vboxsync uCodePtr += size;
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync pCpu->SIB.Bits.Base = SIB_BASE(SIB);
d4483a6c0c7b315e2295e61eba99ffc54d09fc0dvboxsync pCpu->SIB.Bits.Index = SIB_INDEX(SIB);
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync pCpu->SIB.Bits.Scale = SIB_SCALE(SIB);
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync
bf7ab711aa3580b3a587dcbc4653fe78c99fff37vboxsync if (pCpu->fPrefix & DISPREFIX_REX)
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync {
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync /* REX.B extends the Base field if not scaled index + disp32 */
1ff34f218a5354068e4df9017f77fc5871e6b7c6vboxsync if (!(pCpu->SIB.Bits.Base == 5 && pCpu->ModRM.Bits.Mod == 0))
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync pCpu->SIB.Bits.Base |= ((!!(pCpu->fRexPrefix & DISPREFIX_REX_FLAGS_B)) << 3);
d4483a6c0c7b315e2295e61eba99ffc54d09fc0dvboxsync
d4483a6c0c7b315e2295e61eba99ffc54d09fc0dvboxsync pCpu->SIB.Bits.Index |= ((!!(pCpu->fRexPrefix & DISPREFIX_REX_FLAGS_X)) << 3);
d4483a6c0c7b315e2295e61eba99ffc54d09fc0dvboxsync }
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync if ( pCpu->SIB.Bits.Base == 5
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync && pCpu->ModRM.Bits.Mod == 0)
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync {
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync /* Additional 32 bits displacement. No change in long mode. */
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync pCpu->i32SibDisp = disReadDWord(pCpu, uCodePtr);
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync size += sizeof(int32_t);
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync }
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync return size;
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync}
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync//*****************************************************************************
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync//*****************************************************************************
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsyncunsigned ParseSIB_SizeOnly(RTUINTPTR uCodePtr, PCDISOPCODE pOp, PDISOPPARAM pParam, PDISCPUSTATE pCpu)
c7d2f5508ab9703a7a6c5cce5c9d4bf335af660avboxsync{
c7d2f5508ab9703a7a6c5cce5c9d4bf335af660avboxsync unsigned size = sizeof(uint8_t);
c7d2f5508ab9703a7a6c5cce5c9d4bf335af660avboxsync unsigned SIB;
c7d2f5508ab9703a7a6c5cce5c9d4bf335af660avboxsync NOREF(pOp); NOREF(pParam);
c7d2f5508ab9703a7a6c5cce5c9d4bf335af660avboxsync
c7d2f5508ab9703a7a6c5cce5c9d4bf335af660avboxsync SIB = disReadByte(pCpu, uCodePtr);
c7d2f5508ab9703a7a6c5cce5c9d4bf335af660avboxsync uCodePtr += size;
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync
c7d2f5508ab9703a7a6c5cce5c9d4bf335af660avboxsync pCpu->SIB.Bits.Base = SIB_BASE(SIB);
c7d2f5508ab9703a7a6c5cce5c9d4bf335af660avboxsync pCpu->SIB.Bits.Index = SIB_INDEX(SIB);
c7d2f5508ab9703a7a6c5cce5c9d4bf335af660avboxsync pCpu->SIB.Bits.Scale = SIB_SCALE(SIB);
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync
c7d2f5508ab9703a7a6c5cce5c9d4bf335af660avboxsync if (pCpu->fPrefix & DISPREFIX_REX)
c7d2f5508ab9703a7a6c5cce5c9d4bf335af660avboxsync {
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync /* REX.B extends the Base field. */
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync pCpu->SIB.Bits.Base |= ((!!(pCpu->fRexPrefix & DISPREFIX_REX_FLAGS_B)) << 3);
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync /* REX.X extends the Index field. */
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync pCpu->SIB.Bits.Index |= ((!!(pCpu->fRexPrefix & DISPREFIX_REX_FLAGS_X)) << 3);
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync }
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync if ( pCpu->SIB.Bits.Base == 5
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync && pCpu->ModRM.Bits.Mod == 0)
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync {
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync /* Additional 32 bits displacement. No change in long mode. */
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync size += sizeof(int32_t);
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync }
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync return size;
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync}
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync//*****************************************************************************
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync// ModR/M byte:
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync// 7 - 6 5 - 3 2-0
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync// Mod Reg/Opcode R/M
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync//*****************************************************************************
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsyncunsigned UseModRM(RTUINTPTR uCodePtr, PCDISOPCODE pOp, PDISOPPARAM pParam, PDISCPUSTATE pCpu)
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync{
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync int vtype = OP_PARM_VTYPE(pParam->param);
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync unsigned reg = pCpu->ModRM.Bits.Reg;
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync unsigned mod = pCpu->ModRM.Bits.Mod;
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync unsigned rm = pCpu->ModRM.Bits.Rm;
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync switch (vtype)
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync {
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync case OP_PARM_G: //general purpose register
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync disasmModRMReg(pCpu, pOp, reg, pParam, 0);
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync return 0;
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync default:
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync if (IS_OP_PARM_RARE(vtype))
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync {
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync switch (vtype)
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync {
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync case OP_PARM_C: //control register
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync pParam->fUse |= DISUSE_REG_CR;
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync if ( pCpu->pCurInstr->opcode == OP_MOV_CR
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync && pCpu->uOpMode == DISCPUMODE_32BIT
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync && (pCpu->fPrefix & DISPREFIX_LOCK))
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync {
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync pCpu->fPrefix &= ~DISPREFIX_LOCK;
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync pParam->base.reg_ctrl = DISCREG_CR8;
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync }
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync else
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync pParam->base.reg_ctrl = reg;
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync return 0;
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync case OP_PARM_D: //debug register
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync pParam->fUse |= DISUSE_REG_DBG;
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync pParam->base.reg_dbg = reg;
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync return 0;
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync case OP_PARM_P: //MMX register
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync reg &= 7; /* REX.R has no effect here */
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync pParam->fUse |= DISUSE_REG_MMX;
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync pParam->base.reg_mmx = reg;
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync return 0;
4c98b8b05f3783351cf256cc90cd4478fb28b62bvboxsync
4c98b8b05f3783351cf256cc90cd4478fb28b62bvboxsync case OP_PARM_S: //segment register
4c98b8b05f3783351cf256cc90cd4478fb28b62bvboxsync reg &= 7; /* REX.R has no effect here */
4c98b8b05f3783351cf256cc90cd4478fb28b62bvboxsync disasmModRMSReg(pCpu, pOp, reg, pParam);
4c98b8b05f3783351cf256cc90cd4478fb28b62bvboxsync pParam->fUse |= DISUSE_REG_SEG;
4c98b8b05f3783351cf256cc90cd4478fb28b62bvboxsync return 0;
4c98b8b05f3783351cf256cc90cd4478fb28b62bvboxsync
4c98b8b05f3783351cf256cc90cd4478fb28b62bvboxsync 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;
4c98b8b05f3783351cf256cc90cd4478fb28b62bvboxsync return 0;
4c98b8b05f3783351cf256cc90cd4478fb28b62bvboxsync
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
4c98b8b05f3783351cf256cc90cd4478fb28b62bvboxsync 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 */
4c98b8b05f3783351cf256cc90cd4478fb28b62bvboxsync if (pCpu->mode != DISCPUMODE_64BIT)
4c98b8b05f3783351cf256cc90cd4478fb28b62bvboxsync {
4c98b8b05f3783351cf256cc90cd4478fb28b62bvboxsync pParam->fUse |= DISUSE_DISPLACEMENT32;
4c98b8b05f3783351cf256cc90cd4478fb28b62bvboxsync pParam->uDisp.i32 = pCpu->i32SibDisp;
4c98b8b05f3783351cf256cc90cd4478fb28b62bvboxsync }
4c98b8b05f3783351cf256cc90cd4478fb28b62bvboxsync 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
73ba84f95f918cc170be38908ad240fbb2f8f354vboxsync disasmModRMReg(pCpu, pOp, rm, pParam, 0);
73ba84f95f918cc170be38908ad240fbb2f8f354vboxsync break;
73ba84f95f918cc170be38908ad240fbb2f8f354vboxsync }
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)
105b1a31b6037dbe14acb8d09e60da540885202bvboxsync//*****************************************************************************
105b1a31b6037dbe14acb8d09e60da540885202bvboxsyncunsigned QueryModRM(RTUINTPTR uCodePtr, PCDISOPCODE pOp, PDISOPPARAM pParam, PDISCPUSTATE pCpu, unsigned *pSibInc)
105b1a31b6037dbe14acb8d09e60da540885202bvboxsync{
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)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync case 0: /* Effective address */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (rm == 5) { /* 32 bits displacement */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pCpu->i32SibDisp = disReadDWord(pCpu, uCodePtr);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync size += sizeof(int32_t);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync /* else register address */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync break;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync case 1: /* Effective address + 8 bits displacement */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pCpu->i32SibDisp = (int8_t)disReadByte(pCpu, uCodePtr);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync size += sizeof(char);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync break;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync 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
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync /* 16 bits mode */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync switch (mod)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync case 0: /* Effective address */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (rm == 6) {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pCpu->i32SibDisp = disReadWord(pCpu, uCodePtr);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync size += sizeof(uint16_t);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync /* else register address */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync break;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync case 1: /* Effective address + 8 bits displacement */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pCpu->i32SibDisp = (int8_t)disReadByte(pCpu, uCodePtr);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync size += sizeof(char);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync break;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync case 2: /* Effective address + 32 bits displacement */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pCpu->i32SibDisp = (int16_t)disReadWord(pCpu, uCodePtr);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync size += sizeof(uint16_t);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync break;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync case 3: /* registers */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync break;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return size;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync}
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync//*****************************************************************************
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync// Query the size of the ModRM parameters and fetch the immediate data (if any)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync//*****************************************************************************
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);
105b1a31b6037dbe14acb8d09e60da540885202bvboxsync uCodePtr += *pSibInc;
105b1a31b6037dbe14acb8d09e60da540885202bvboxsync size += *pSibInc;
105b1a31b6037dbe14acb8d09e60da540885202bvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync switch (mod)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync case 0: //effective address
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (rm == 5) { /* 32 bits displacement */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync size += sizeof(int32_t);
2721dfb0e330d57ba888311520f5a343c64e7cefvboxsync }
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
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (rm == 6) {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync size += sizeof(uint16_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(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->optype & DISOPTYPE_MOD_FIXED_11)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pCpu->ModRM.Bits.Mod = 3;
4c98b8b05f3783351cf256cc90cd4478fb28b62bvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (pCpu->fPrefix & DISPREFIX_REX)
4c98b8b05f3783351cf256cc90cd4478fb28b62bvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync Assert(pCpu->mode == DISCPUMODE_64BIT);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
4c98b8b05f3783351cf256cc90cd4478fb28b62bvboxsync /* 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
4c98b8b05f3783351cf256cc90cd4478fb28b62bvboxsync && pCpu->ModRM.Bits.Rm == 4)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync &&
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync !( pCpu->ModRM.Bits.Mod == 0
4c98b8b05f3783351cf256cc90cd4478fb28b62bvboxsync && pCpu->ModRM.Bits.Rm == 5))
4c98b8b05f3783351cf256cc90cd4478fb28b62bvboxsync {
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
4c98b8b05f3783351cf256cc90cd4478fb28b62bvboxsync UseModRM(uCodePtr, pOp, pParam, pCpu);
4c98b8b05f3783351cf256cc90cd4478fb28b62bvboxsync return size;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync}
4c98b8b05f3783351cf256cc90cd4478fb28b62bvboxsync//*****************************************************************************
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync//*****************************************************************************
4c98b8b05f3783351cf256cc90cd4478fb28b62bvboxsyncunsigned ParseModRM_SizeOnly(RTUINTPTR uCodePtr, PCDISOPCODE pOp, PDISOPPARAM pParam, PDISCPUSTATE pCpu)
4c98b8b05f3783351cf256cc90cd4478fb28b62bvboxsync{
4c98b8b05f3783351cf256cc90cd4478fb28b62bvboxsync unsigned size = sizeof(uint8_t); //ModRM byte
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync unsigned sibinc, ModRM;
4c98b8b05f3783351cf256cc90cd4478fb28b62bvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync ModRM = disReadByte(pCpu, uCodePtr);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync uCodePtr += sizeof(uint8_t);
4c98b8b05f3783351cf256cc90cd4478fb28b62bvboxsync
4c98b8b05f3783351cf256cc90cd4478fb28b62bvboxsync pCpu->ModRM.Bits.Rm = MODRM_RM(ModRM);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pCpu->ModRM.Bits.Mod = MODRM_MOD(ModRM);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pCpu->ModRM.Bits.Reg = MODRM_REG(ModRM);
4c98b8b05f3783351cf256cc90cd4478fb28b62bvboxsync
4c98b8b05f3783351cf256cc90cd4478fb28b62bvboxsync /* Disregard the mod bits for certain instructions (mov crx, mov drx).
4c98b8b05f3783351cf256cc90cd4478fb28b62bvboxsync *
4c98b8b05f3783351cf256cc90cd4478fb28b62bvboxsync * From the AMD manual:
09f4b412099acda62997fd82c8608075c453b3ebvboxsync * This instruction is always treated as a register-to-register (MOD = 11) instruction, regardless of the
09f4b412099acda62997fd82c8608075c453b3ebvboxsync * encoding of the MOD field in the MODR/M byte.
67b8a5a52c43a79ea7e159dbbeec99687fb9cd3bvboxsync */
4c98b8b05f3783351cf256cc90cd4478fb28b62bvboxsync if (pOp->optype & DISOPTYPE_MOD_FIXED_11)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pCpu->ModRM.Bits.Mod = 3;
4c98b8b05f3783351cf256cc90cd4478fb28b62bvboxsync
c7d2f5508ab9703a7a6c5cce5c9d4bf335af660avboxsync if (pCpu->fPrefix & DISPREFIX_REX)
c7d2f5508ab9703a7a6c5cce5c9d4bf335af660avboxsync {
c7d2f5508ab9703a7a6c5cce5c9d4bf335af660avboxsync Assert(pCpu->mode == DISCPUMODE_64BIT);
3a343ca21a267ec3c54e2317e2ed18fe99b8ebbbvboxsync
4c98b8b05f3783351cf256cc90cd4478fb28b62bvboxsync /* REX.R extends the Reg field. */
3a343ca21a267ec3c54e2317e2ed18fe99b8ebbbvboxsync 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 */
4c98b8b05f3783351cf256cc90cd4478fb28b62bvboxsync if (!( pCpu->ModRM.Bits.Mod != 3
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync && pCpu->ModRM.Bits.Rm == 4)
105b1a31b6037dbe14acb8d09e60da540885202bvboxsync &&
105b1a31b6037dbe14acb8d09e60da540885202bvboxsync !( pCpu->ModRM.Bits.Mod == 0
67b8a5a52c43a79ea7e159dbbeec99687fb9cd3bvboxsync && pCpu->ModRM.Bits.Rm == 5))
67b8a5a52c43a79ea7e159dbbeec99687fb9cd3bvboxsync {
67b8a5a52c43a79ea7e159dbbeec99687fb9cd3bvboxsync pCpu->ModRM.Bits.Rm |= ((!!(pCpu->fRexPrefix & DISPREFIX_REX_FLAGS_B)) << 3);
67b8a5a52c43a79ea7e159dbbeec99687fb9cd3bvboxsync }
105b1a31b6037dbe14acb8d09e60da540885202bvboxsync }
105b1a31b6037dbe14acb8d09e60da540885202bvboxsync
105b1a31b6037dbe14acb8d09e60da540885202bvboxsync size += QueryModRM_SizeOnly(uCodePtr, pOp, pParam, pCpu, &sibinc);
105b1a31b6037dbe14acb8d09e60da540885202bvboxsync uCodePtr += sibinc;
105b1a31b6037dbe14acb8d09e60da540885202bvboxsync
6b2a50fc09aa4f7ce2082284f082d97a2c738321vboxsync /* UseModRM is not necessary here; we're only interested in the opcode size */
6b2a50fc09aa4f7ce2082284f082d97a2c738321vboxsync return size;
6b2a50fc09aa4f7ce2082284f082d97a2c738321vboxsync}
6b2a50fc09aa4f7ce2082284f082d97a2c738321vboxsync//*****************************************************************************
6b2a50fc09aa4f7ce2082284f082d97a2c738321vboxsync//*****************************************************************************
73ba84f95f918cc170be38908ad240fbb2f8f354vboxsyncunsigned ParseModFence(RTUINTPTR uCodePtr, PCDISOPCODE pOp, PDISOPPARAM pParam, PDISCPUSTATE pCpu)
73ba84f95f918cc170be38908ad240fbb2f8f354vboxsync{
73ba84f95f918cc170be38908ad240fbb2f8f354vboxsync ////AssertMsgFailed(("??\n"));
5159c4c6485473c77871b515c15b59c3caa60b46vboxsync //nothing to do apparently
5159c4c6485473c77871b515c15b59c3caa60b46vboxsync NOREF(uCodePtr); NOREF(pOp); NOREF(pParam); NOREF(pCpu);
5159c4c6485473c77871b515c15b59c3caa60b46vboxsync return 0;
5159c4c6485473c77871b515c15b59c3caa60b46vboxsync}
5159c4c6485473c77871b515c15b59c3caa60b46vboxsync//*****************************************************************************
5159c4c6485473c77871b515c15b59c3caa60b46vboxsync//*****************************************************************************
5159c4c6485473c77871b515c15b59c3caa60b46vboxsyncunsigned ParseImmByte(RTUINTPTR uCodePtr, PCDISOPCODE pOp, PDISOPPARAM pParam, PDISCPUSTATE pCpu)
5159c4c6485473c77871b515c15b59c3caa60b46vboxsync{
5159c4c6485473c77871b515c15b59c3caa60b46vboxsync NOREF(pOp);
5159c4c6485473c77871b515c15b59c3caa60b46vboxsync pParam->parval = disReadByte(pCpu, uCodePtr);
5159c4c6485473c77871b515c15b59c3caa60b46vboxsync pParam->fUse |= DISUSE_IMMEDIATE8;
5159c4c6485473c77871b515c15b59c3caa60b46vboxsync pParam->cb = sizeof(uint8_t);
5159c4c6485473c77871b515c15b59c3caa60b46vboxsync return sizeof(uint8_t);
5159c4c6485473c77871b515c15b59c3caa60b46vboxsync}
5159c4c6485473c77871b515c15b59c3caa60b46vboxsync//*****************************************************************************
5159c4c6485473c77871b515c15b59c3caa60b46vboxsync//*****************************************************************************
5159c4c6485473c77871b515c15b59c3caa60b46vboxsyncunsigned ParseImmByte_SizeOnly(RTUINTPTR uCodePtr, PCDISOPCODE pOp, PDISOPPARAM pParam, PDISCPUSTATE pCpu)
5159c4c6485473c77871b515c15b59c3caa60b46vboxsync{
5159c4c6485473c77871b515c15b59c3caa60b46vboxsync NOREF(uCodePtr); NOREF(pOp); NOREF(pParam); NOREF(pCpu);
5159c4c6485473c77871b515c15b59c3caa60b46vboxsync return sizeof(uint8_t);
5159c4c6485473c77871b515c15b59c3caa60b46vboxsync}
5159c4c6485473c77871b515c15b59c3caa60b46vboxsync//*****************************************************************************
5159c4c6485473c77871b515c15b59c3caa60b46vboxsync//*****************************************************************************
5159c4c6485473c77871b515c15b59c3caa60b46vboxsyncunsigned ParseImmByteSX(RTUINTPTR uCodePtr, PCDISOPCODE pOp, PDISOPPARAM pParam, PDISCPUSTATE pCpu)
5159c4c6485473c77871b515c15b59c3caa60b46vboxsync{
73ba84f95f918cc170be38908ad240fbb2f8f354vboxsync NOREF(pOp);
73ba84f95f918cc170be38908ad240fbb2f8f354vboxsync if (pCpu->uOpMode == DISCPUMODE_32BIT)
6b2a50fc09aa4f7ce2082284f082d97a2c738321vboxsync {
6b2a50fc09aa4f7ce2082284f082d97a2c738321vboxsync pParam->parval = (uint32_t)(int8_t)disReadByte(pCpu, uCodePtr);
6b2a50fc09aa4f7ce2082284f082d97a2c738321vboxsync pParam->fUse |= DISUSE_IMMEDIATE32_SX8;
6b2a50fc09aa4f7ce2082284f082d97a2c738321vboxsync pParam->cb = sizeof(uint32_t);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync else
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (pCpu->uOpMode == DISCPUMODE_64BIT)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pParam->parval = (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->parval = (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)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync{
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->parval = 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);
67b8a5a52c43a79ea7e159dbbeec99687fb9cd3bvboxsync pParam->parval = disReadDWord(pCpu, uCodePtr);
67b8a5a52c43a79ea7e159dbbeec99687fb9cd3bvboxsync pParam->fUse |= DISUSE_IMMEDIATE32;
67b8a5a52c43a79ea7e159dbbeec99687fb9cd3bvboxsync pParam->cb = sizeof(uint32_t);
67b8a5a52c43a79ea7e159dbbeec99687fb9cd3bvboxsync return sizeof(uint32_t);
105b1a31b6037dbe14acb8d09e60da540885202bvboxsync}
105b1a31b6037dbe14acb8d09e60da540885202bvboxsync//*****************************************************************************
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}
3a343ca21a267ec3c54e2317e2ed18fe99b8ebbbvboxsync//*****************************************************************************
3a343ca21a267ec3c54e2317e2ed18fe99b8ebbbvboxsync//*****************************************************************************
3a343ca21a267ec3c54e2317e2ed18fe99b8ebbbvboxsyncunsigned ParseImmQword(RTUINTPTR uCodePtr, PCDISOPCODE pOp, PDISOPPARAM pParam, PDISCPUSTATE pCpu)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync{
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync NOREF(pOp);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pParam->parval = disReadQWord(pCpu, uCodePtr);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pParam->fUse |= DISUSE_IMMEDIATE64;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pParam->cb = sizeof(uint64_t);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return sizeof(uint64_t);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync}
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync//*****************************************************************************
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync//*****************************************************************************
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncunsigned ParseImmQword_SizeOnly(RTUINTPTR uCodePtr, PCDISOPCODE pOp, PDISOPPARAM pParam, PDISCPUSTATE pCpu)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync{
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync NOREF(uCodePtr); NOREF(pOp); NOREF(pParam); NOREF(pCpu);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return sizeof(uint64_t);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync}
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync//*****************************************************************************
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync//*****************************************************************************
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncunsigned ParseImmV(RTUINTPTR uCodePtr, PCDISOPCODE pOp, PDISOPPARAM pParam, PDISCPUSTATE pCpu)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync{
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync NOREF(pOp);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (pCpu->uOpMode == DISCPUMODE_32BIT)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pParam->parval = 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->parval = disReadQWord(pCpu, uCodePtr);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pParam->fUse |= DISUSE_IMMEDIATE64;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pParam->cb = sizeof(uint64_t);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return sizeof(uint64_t);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pParam->parval = disReadWord(pCpu, uCodePtr);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pParam->fUse |= DISUSE_IMMEDIATE16;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pParam->cb = sizeof(uint16_t);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return sizeof(uint16_t);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync}
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync//*****************************************************************************
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync//*****************************************************************************
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//*****************************************************************************
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncunsigned ParseImmZ(RTUINTPTR uCodePtr, PCDISOPCODE pOp, PDISOPPARAM pParam, PDISCPUSTATE pCpu)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync{
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync NOREF(pOp);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync /* Word for 16-bit operand-size or doubleword for 32 or 64-bit operand-size. */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (pCpu->uOpMode == DISCPUMODE_16BIT)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pParam->parval = 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->parval = (uint64_t)(int32_t)disReadDWord(pCpu, uCodePtr);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pParam->fUse |= DISUSE_IMMEDIATE64;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pParam->cb = sizeof(uint64_t);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync else
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pParam->parval = disReadDWord(pCpu, uCodePtr);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pParam->fUse |= DISUSE_IMMEDIATE32;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pParam->cb = sizeof(uint32_t);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return sizeof(uint32_t);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync}
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync//*****************************************************************************
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync//*****************************************************************************
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->parval = 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{
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync NOREF(pOp);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (pCpu->uOpMode == DISCPUMODE_32BIT)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pParam->parval = disReadDWord(pCpu, uCodePtr);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pParam->fUse |= DISUSE_IMMEDIATE32_REL;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pParam->cb = sizeof(int32_t);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return sizeof(int32_t);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
e6ad2e18e663b076aeabfec994947514566a7accvboxsync if (pCpu->uOpMode == DISCPUMODE_64BIT)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
e6ad2e18e663b076aeabfec994947514566a7accvboxsync /* 32 bits relative immediate sign extended to 64 bits. */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pParam->parval = (uint64_t)(int32_t)disReadDWord(pCpu, uCodePtr);
e6ad2e18e663b076aeabfec994947514566a7accvboxsync pParam->fUse |= DISUSE_IMMEDIATE64_REL;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pParam->cb = sizeof(int64_t);
e6ad2e18e663b076aeabfec994947514566a7accvboxsync return sizeof(int32_t);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pParam->parval = disReadWord(pCpu, uCodePtr);
e6ad2e18e663b076aeabfec994947514566a7accvboxsync pParam->fUse |= DISUSE_IMMEDIATE16_REL;
e6ad2e18e663b076aeabfec994947514566a7accvboxsync 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//*****************************************************************************
e6ad2e18e663b076aeabfec994947514566a7accvboxsync//*****************************************************************************
dc959f60f6d3e0cba86f7da4d39aa475913a7e10vboxsyncunsigned ParseImmAddr(RTUINTPTR uCodePtr, PCDISOPCODE pOp, PDISOPPARAM pParam, PDISCPUSTATE pCpu)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync{
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (pCpu->uAddrMode == DISCPUMODE_32BIT)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (OP_PARM_VSUBTYPE(pParam->param) == OP_PARM_p)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync /* far 16:32 pointer */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pParam->parval = disReadDWord(pCpu, uCodePtr);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync *((uint32_t*)&pParam->parval+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 /*
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 */
dc959f60f6d3e0cba86f7da4d39aa475913a7e10vboxsync 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->param) != 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->param) == OP_PARM_p)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync /* far 16:16 pointer */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pParam->parval = 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}
e6ad2e18e663b076aeabfec994947514566a7accvboxsync//*****************************************************************************
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync//*****************************************************************************
e6ad2e18e663b076aeabfec994947514566a7accvboxsyncunsigned ParseImmAddr_SizeOnly(RTUINTPTR uCodePtr, PCDISOPCODE pOp, PDISOPPARAM pParam, PDISCPUSTATE pCpu)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync{
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync NOREF(uCodePtr); NOREF(pOp);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (pCpu->uAddrMode == DISCPUMODE_32BIT)
e6ad2e18e663b076aeabfec994947514566a7accvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (OP_PARM_VSUBTYPE(pParam->param) == OP_PARM_p)
e6ad2e18e663b076aeabfec994947514566a7accvboxsync {// far 16:32 pointer
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return sizeof(uint32_t) + sizeof(uint16_t);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync else
e6ad2e18e663b076aeabfec994947514566a7accvboxsync {// near 32 bits pointer
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return sizeof(uint32_t);
e6ad2e18e663b076aeabfec994947514566a7accvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (pCpu->uAddrMode == DISCPUMODE_64BIT)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9cdd4d805ecb43126372f7cf12e4032836cb738avboxsync Assert(OP_PARM_VSUBTYPE(pParam->param) != OP_PARM_p);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return sizeof(uint64_t);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync else
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (OP_PARM_VSUBTYPE(pParam->param) == OP_PARM_p)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {// far 16:16 pointer
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return sizeof(uint32_t);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
105b1a31b6037dbe14acb8d09e60da540885202bvboxsync else
105b1a31b6037dbe14acb8d09e60da540885202bvboxsync {// near 16 bits pointer
105b1a31b6037dbe14acb8d09e60da540885202bvboxsync return sizeof(uint16_t);
105b1a31b6037dbe14acb8d09e60da540885202bvboxsync }
105b1a31b6037dbe14acb8d09e60da540885202bvboxsync }
105b1a31b6037dbe14acb8d09e60da540885202bvboxsync}
105b1a31b6037dbe14acb8d09e60da540885202bvboxsync//*****************************************************************************
105b1a31b6037dbe14acb8d09e60da540885202bvboxsync//*****************************************************************************
105b1a31b6037dbe14acb8d09e60da540885202bvboxsyncunsigned ParseImmAddrF(RTUINTPTR uCodePtr, PCDISOPCODE pOp, PDISOPPARAM pParam, PDISCPUSTATE pCpu)
105b1a31b6037dbe14acb8d09e60da540885202bvboxsync{
105b1a31b6037dbe14acb8d09e60da540885202bvboxsync // immediate far pointers - only 16:16 or 16:32; determined by operand, *not* address size!
105b1a31b6037dbe14acb8d09e60da540885202bvboxsync Assert(pCpu->uOpMode == DISCPUMODE_16BIT || pCpu->uOpMode == DISCPUMODE_32BIT);
105b1a31b6037dbe14acb8d09e60da540885202bvboxsync Assert(OP_PARM_VSUBTYPE(pParam->param) == OP_PARM_p);
105b1a31b6037dbe14acb8d09e60da540885202bvboxsync if (pCpu->uOpMode == DISCPUMODE_32BIT)
73ba84f95f918cc170be38908ad240fbb2f8f354vboxsync {
105b1a31b6037dbe14acb8d09e60da540885202bvboxsync // far 16:32 pointer
105b1a31b6037dbe14acb8d09e60da540885202bvboxsync pParam->parval = disReadDWord(pCpu, uCodePtr);
105b1a31b6037dbe14acb8d09e60da540885202bvboxsync *((uint32_t*)&pParam->parval+1) = disReadWord(pCpu, uCodePtr+sizeof(uint32_t));
105b1a31b6037dbe14acb8d09e60da540885202bvboxsync pParam->fUse |= DISUSE_IMMEDIATE_ADDR_16_32;
105b1a31b6037dbe14acb8d09e60da540885202bvboxsync pParam->cb = sizeof(uint16_t) + sizeof(uint32_t);
73ba84f95f918cc170be38908ad240fbb2f8f354vboxsync return sizeof(uint32_t) + sizeof(uint16_t);
105b1a31b6037dbe14acb8d09e60da540885202bvboxsync }
105b1a31b6037dbe14acb8d09e60da540885202bvboxsync
105b1a31b6037dbe14acb8d09e60da540885202bvboxsync // far 16:16 pointer
105b1a31b6037dbe14acb8d09e60da540885202bvboxsync pParam->parval = disReadDWord(pCpu, uCodePtr);
105b1a31b6037dbe14acb8d09e60da540885202bvboxsync pParam->fUse |= DISUSE_IMMEDIATE_ADDR_16_16;
105b1a31b6037dbe14acb8d09e60da540885202bvboxsync pParam->cb = 2*sizeof(uint16_t);
105b1a31b6037dbe14acb8d09e60da540885202bvboxsync return sizeof(uint32_t);
105b1a31b6037dbe14acb8d09e60da540885202bvboxsync}
105b1a31b6037dbe14acb8d09e60da540885202bvboxsync//*****************************************************************************
105b1a31b6037dbe14acb8d09e60da540885202bvboxsync//*****************************************************************************
105b1a31b6037dbe14acb8d09e60da540885202bvboxsyncunsigned ParseImmAddrF_SizeOnly(RTUINTPTR uCodePtr, PCDISOPCODE pOp, PDISOPPARAM pParam, PDISCPUSTATE pCpu)
105b1a31b6037dbe14acb8d09e60da540885202bvboxsync{
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync NOREF(uCodePtr); NOREF(pOp);
c58dc77ef4af214d7ae06910fa5ab18587d2ae08vboxsync // 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->param) == OP_PARM_p);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (pCpu->uOpMode == DISCPUMODE_32BIT)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync // far 16:32 pointer
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return sizeof(uint32_t) + sizeof(uint16_t);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync else
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync // far 16:16 pointer
c58dc77ef4af214d7ae06910fa5ab18587d2ae08vboxsync return sizeof(uint32_t);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync}
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync//*****************************************************************************
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync//*****************************************************************************
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncunsigned ParseFixedReg(RTUINTPTR uCodePtr, PCDISOPCODE pOp, PDISOPPARAM pParam, PDISCPUSTATE pCpu)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync{
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync NOREF(uCodePtr);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync /*
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * Sets up flags for stored in OPC fixed registers.
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync */
e6ad2e18e663b076aeabfec994947514566a7accvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (pParam->param == OP_PARM_NONE)
e6ad2e18e663b076aeabfec994947514566a7accvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync /* No parameter at all. */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return 0;
e6ad2e18e663b076aeabfec994947514566a7accvboxsync }
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->param <= 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->param - OP_PARM_REG_GEN32_START;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pParam->fUse |= DISUSE_REG_GEN32;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pParam->cb = 4;
e6ad2e18e663b076aeabfec994947514566a7accvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync else
e6ad2e18e663b076aeabfec994947514566a7accvboxsync if (pCpu->uOpMode == DISCPUMODE_64BIT)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync /* Use 64-bit registers. */
e6ad2e18e663b076aeabfec994947514566a7accvboxsync pParam->base.reg_gen = pParam->param - OP_PARM_REG_GEN32_START;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if ( (pOp->optype & DISOPTYPE_REXB_EXTENDS_OPREG)
9cdd4d805ecb43126372f7cf12e4032836cb738avboxsync && 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->param - OP_PARM_REG_GEN32_START;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pParam->fUse |= DISUSE_REG_GEN16;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pParam->cb = 2;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pParam->param = pParam->param - OP_PARM_REG_GEN32_START + OP_PARM_REG_GEN16_START;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync else
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (pParam->param <= OP_PARM_REG_SEG_END)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync /* Segment ES..GS registers. */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pParam->base.reg_seg = (DISSELREG)(pParam->param - OP_PARM_REG_SEG_START);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pParam->fUse |= DISUSE_REG_SEG;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pParam->cb = 2;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync else
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (pParam->param <= OP_PARM_REG_GEN16_END)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync /* 16-bit AX..DI registers. */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pParam->base.reg_gen = pParam->param - OP_PARM_REG_GEN16_START;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pParam->fUse |= DISUSE_REG_GEN16;
105b1a31b6037dbe14acb8d09e60da540885202bvboxsync pParam->cb = 2;
105b1a31b6037dbe14acb8d09e60da540885202bvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync else
e6ad2e18e663b076aeabfec994947514566a7accvboxsync if (pParam->param <= OP_PARM_REG_GEN8_END)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync /* 8-bit AL..DL, AH..DH registers. */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pParam->base.reg_gen = pParam->param - OP_PARM_REG_GEN8_START;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pParam->fUse |= DISUSE_REG_GEN8;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pParam->cb = 1;
e6ad2e18e663b076aeabfec994947514566a7accvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (pCpu->uOpMode == DISCPUMODE_64BIT)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if ( (pOp->optype & 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))
e6ad2e18e663b076aeabfec994947514566a7accvboxsync pParam->base.reg_gen += 8; /* least significant byte of R8-R15 */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync else
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (pParam->param <= OP_PARM_REG_FP_END)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9cdd4d805ecb43126372f7cf12e4032836cb738avboxsync /* FPU registers. */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pParam->base.reg_fp = pParam->param - OP_PARM_REG_FP_START;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pParam->fUse |= DISUSE_REG_FP;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pParam->cb = 10;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync Assert(!(pParam->param >= OP_PARM_REG_GEN64_START && pParam->param <= 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 {
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync pParam->base.reg_gen = DISGREG_RSI;
5793d23a719d4902824a3649b6fef3822ddd5fc7vboxsync 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 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 }
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 {
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;
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 }
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 {
eb2d4958f7faf812c3bdb2d7587d815022f0bd55vboxsync 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 ParseTwoByteEsc(RTUINTPTR uCodePtr, PCDISOPCODE pOp, PDISOPPARAM pParam, PDISCPUSTATE pCpu)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync{
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync PCDISOPCODE pOpcode;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync int size = sizeof(uint8_t);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync NOREF(pOp); NOREF(pParam);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
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 {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync switch (pCpu->bLastPrefix)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync case OP_OPSIZE: /* 0x66 */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (g_aTwoByteMapX86_PF66[pCpu->bOpCode].opcode != OP_INVALID)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync /* Table entry is valid, so use the extension table. */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pOpcode = &g_aTwoByteMapX86_PF66[pCpu->bOpCode];
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync /* Cancel prefix changes. */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pCpu->fPrefix &= ~DISPREFIX_OPSIZE;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pCpu->uOpMode = pCpu->mode;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync break;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync case OP_REPNE: /* 0xF2 */
441b60f8b0601cc1718368c9c3ef082223ad12a2vboxsync if (g_aTwoByteMapX86_PFF2[pCpu->bOpCode].opcode != OP_INVALID)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync /* Table entry is valid, so use the extension table. */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pOpcode = &g_aTwoByteMapX86_PFF2[pCpu->bOpCode];
2721dfb0e330d57ba888311520f5a343c64e7cefvboxsync
2721dfb0e330d57ba888311520f5a343c64e7cefvboxsync /* Cancel prefix changes. */
e6ad2e18e663b076aeabfec994947514566a7accvboxsync pCpu->fPrefix &= ~DISPREFIX_REPNE;
e6ad2e18e663b076aeabfec994947514566a7accvboxsync }
441b60f8b0601cc1718368c9c3ef082223ad12a2vboxsync break;
441b60f8b0601cc1718368c9c3ef082223ad12a2vboxsync
441b60f8b0601cc1718368c9c3ef082223ad12a2vboxsync case OP_REPE: /* 0xF3 */
441b60f8b0601cc1718368c9c3ef082223ad12a2vboxsync if (g_aTwoByteMapX86_PFF3[pCpu->bOpCode].opcode != OP_INVALID)
441b60f8b0601cc1718368c9c3ef082223ad12a2vboxsync {
441b60f8b0601cc1718368c9c3ef082223ad12a2vboxsync /* Table entry is valid, so use the extension table. */
441b60f8b0601cc1718368c9c3ef082223ad12a2vboxsync pOpcode = &g_aTwoByteMapX86_PFF3[pCpu->bOpCode];
441b60f8b0601cc1718368c9c3ef082223ad12a2vboxsync
441b60f8b0601cc1718368c9c3ef082223ad12a2vboxsync /* Cancel prefix changes. */
441b60f8b0601cc1718368c9c3ef082223ad12a2vboxsync pCpu->fPrefix &= ~DISPREFIX_REP;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync break;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
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;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync 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])
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
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 */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (g_apThreeByteMapX86_660F38[pCpu->bOpCode >> 4])
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pOpcode = g_apThreeByteMapX86_660F38[pCpu->bOpCode >> 4];
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pOpcode = &pOpcode[pCpu->bOpCode & 0xf];
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (pOpcode->opcode != OP_INVALID)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync /* Table entry is valid, so use the extension table. */
4c98b8b05f3783351cf256cc90cd4478fb28b62bvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync /* Cancel prefix changes. */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pCpu->fPrefix &= ~DISPREFIX_OPSIZE;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pCpu->uOpMode = pCpu->mode;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync break;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync case OP_REPNE: /* 0xF2 */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (g_apThreeByteMapX86_F20F38[pCpu->bOpCode >> 4])
73ba84f95f918cc170be38908ad240fbb2f8f354vboxsync {
6b2a50fc09aa4f7ce2082284f082d97a2c738321vboxsync pOpcode = g_apThreeByteMapX86_F20F38[pCpu->bOpCode >> 4];
73ba84f95f918cc170be38908ad240fbb2f8f354vboxsync pOpcode = &pOpcode[pCpu->bOpCode & 0xf];
6b2a50fc09aa4f7ce2082284f082d97a2c738321vboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (pOpcode->opcode != OP_INVALID)
71c0735a959eefb3e0b7a3bd8c8640a5660584cavboxsync {
71c0735a959eefb3e0b7a3bd8c8640a5660584cavboxsync /* Table entry is valid, so use the extension table. */
71c0735a959eefb3e0b7a3bd8c8640a5660584cavboxsync
73ba84f95f918cc170be38908ad240fbb2f8f354vboxsync /* Cancel prefix changes. */
73ba84f95f918cc170be38908ad240fbb2f8f354vboxsync pCpu->fPrefix &= ~DISPREFIX_REPNE;
73ba84f95f918cc170be38908ad240fbb2f8f354vboxsync }
73ba84f95f918cc170be38908ad240fbb2f8f354vboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync break;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync size += disParseInstruction(uCodePtr+size, pOpcode, pCpu);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return size;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync}
4c98b8b05f3783351cf256cc90cd4478fb28b62bvboxsync//*****************************************************************************
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync//*****************************************************************************
4c98b8b05f3783351cf256cc90cd4478fb28b62bvboxsyncunsigned ParseThreeByteEsc5(RTUINTPTR uCodePtr, PCDISOPCODE pOp, PDISOPPARAM pParam, PDISCPUSTATE pCpu)
4c98b8b05f3783351cf256cc90cd4478fb28b62bvboxsync{
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync PCDISOPCODE pOpcode;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync int size = sizeof(uint8_t);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync NOREF(pOp); NOREF(pParam);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync /* 3rd byte */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pCpu->bOpCode = disReadByte(pCpu, uCodePtr);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync /** @todo Should we take the first or last prefix byte in case of multiple prefix bytes??? */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync Assert(pCpu->bLastPrefix == OP_OPSIZE);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync /* default to the non-prefixed table. */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (g_apThreeByteMapX86_660F3A[pCpu->bOpCode >> 4])
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pOpcode = g_apThreeByteMapX86_660F3A[pCpu->bOpCode >> 4];
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pOpcode = &pOpcode[pCpu->bOpCode & 0xf];
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (pOpcode->opcode != OP_INVALID)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync /* Table entry is valid, so use the extension table. */
9cdd4d805ecb43126372f7cf12e4032836cb738avboxsync
73ba84f95f918cc170be38908ad240fbb2f8f354vboxsync /* Cancel prefix changes. */
73ba84f95f918cc170be38908ad240fbb2f8f354vboxsync pCpu->fPrefix &= ~DISPREFIX_OPSIZE;
73ba84f95f918cc170be38908ad240fbb2f8f354vboxsync pCpu->uOpMode = pCpu->mode;
73ba84f95f918cc170be38908ad240fbb2f8f354vboxsync }
73ba84f95f918cc170be38908ad240fbb2f8f354vboxsync }
73ba84f95f918cc170be38908ad240fbb2f8f354vboxsync else
73ba84f95f918cc170be38908ad240fbb2f8f354vboxsync pOpcode = &g_InvalidOpcode[0];
73ba84f95f918cc170be38908ad240fbb2f8f354vboxsync
73ba84f95f918cc170be38908ad240fbb2f8f354vboxsync size += disParseInstruction(uCodePtr+size, pOpcode, pCpu);
6b2a50fc09aa4f7ce2082284f082d97a2c738321vboxsync return size;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync}
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync//*****************************************************************************
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync//*****************************************************************************
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncunsigned ParseNopPause(RTUINTPTR uCodePtr, PCDISOPCODE pOp, PDISOPPARAM pParam, PDISCPUSTATE pCpu)
73ba84f95f918cc170be38908ad240fbb2f8f354vboxsync{
73ba84f95f918cc170be38908ad240fbb2f8f354vboxsync unsigned size = 0;
73ba84f95f918cc170be38908ad240fbb2f8f354vboxsync NOREF(pParam);
73ba84f95f918cc170be38908ad240fbb2f8f354vboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (pCpu->fPrefix & DISPREFIX_REP)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pOp = &g_aMapX86_NopPause[1]; /* PAUSE */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pCpu->fPrefix &= ~DISPREFIX_REP;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync else
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pOp = &g_aMapX86_NopPause[0]; /* NOP */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
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];
4c98b8b05f3783351cf256cc90cd4478fb28b62bvboxsync //little hack to make sure the ModRM byte is included in the returned size
4c98b8b05f3783351cf256cc90cd4478fb28b62bvboxsync if (pOp->idxParse1 != IDX_ParseModRM && pOp->idxParse2 != IDX_ParseModRM)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync size = sizeof(uint8_t); //ModRM byte
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
4c98b8b05f3783351cf256cc90cd4478fb28b62bvboxsync 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);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync switch (pCpu->bOpCode)
4c98b8b05f3783351cf256cc90cd4478fb28b62bvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync 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;
73ba84f95f918cc170be38908ad240fbb2f8f354vboxsync break;
73ba84f95f918cc170be38908ad240fbb2f8f354vboxsync
73ba84f95f918cc170be38908ad240fbb2f8f354vboxsync default:
73ba84f95f918cc170be38908ad240fbb2f8f354vboxsync AssertMsgFailed(("Oops\n"));
73ba84f95f918cc170be38908ad240fbb2f8f354vboxsync return sizeof(uint8_t);
73ba84f95f918cc170be38908ad240fbb2f8f354vboxsync }
73ba84f95f918cc170be38908ad240fbb2f8f354vboxsync
73ba84f95f918cc170be38908ad240fbb2f8f354vboxsync modrm = disReadByte(pCpu, uCodePtr);
73ba84f95f918cc170be38908ad240fbb2f8f354vboxsync reg = MODRM_REG(modrm);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pOp = (PCDISOPCODE)&g_aMapX86_Group2[idx+reg];
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
73ba84f95f918cc170be38908ad240fbb2f8f354vboxsync //little hack to make sure the ModRM byte is included in the returned size
73ba84f95f918cc170be38908ad240fbb2f8f354vboxsync if (pOp->idxParse1 != IDX_ParseModRM && pOp->idxParse2 != IDX_ParseModRM)
73ba84f95f918cc170be38908ad240fbb2f8f354vboxsync size = sizeof(uint8_t); //ModRM byte
73ba84f95f918cc170be38908ad240fbb2f8f354vboxsync
b6b29a7e040f2b46480aa596fe0861bb16ce3da5vboxsync size += disParseInstruction(uCodePtr, pOp, pCpu);
b6b29a7e040f2b46480aa596fe0861bb16ce3da5vboxsync
b6b29a7e040f2b46480aa596fe0861bb16ce3da5vboxsync return size;
b6b29a7e040f2b46480aa596fe0861bb16ce3da5vboxsync}
b6b29a7e040f2b46480aa596fe0861bb16ce3da5vboxsync//*****************************************************************************
b6b29a7e040f2b46480aa596fe0861bb16ce3da5vboxsync//*****************************************************************************
b6b29a7e040f2b46480aa596fe0861bb16ce3da5vboxsyncunsigned ParseGrp3(RTUINTPTR uCodePtr, PCDISOPCODE pOp, PDISOPPARAM pParam, PDISCPUSTATE pCpu)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync{
b6b29a7e040f2b46480aa596fe0861bb16ce3da5vboxsync int idx = (pCpu->bOpCode - 0xF6) * 8;
b6b29a7e040f2b46480aa596fe0861bb16ce3da5vboxsync unsigned size = 0, modrm, reg;
b6b29a7e040f2b46480aa596fe0861bb16ce3da5vboxsync NOREF(pParam);
b6b29a7e040f2b46480aa596fe0861bb16ce3da5vboxsync
b6b29a7e040f2b46480aa596fe0861bb16ce3da5vboxsync modrm = disReadByte(pCpu, uCodePtr);
b6b29a7e040f2b46480aa596fe0861bb16ce3da5vboxsync reg = MODRM_REG(modrm);
b6b29a7e040f2b46480aa596fe0861bb16ce3da5vboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pOp = (PCDISOPCODE)&g_aMapX86_Group3[idx+reg];
b6b29a7e040f2b46480aa596fe0861bb16ce3da5vboxsync
b6b29a7e040f2b46480aa596fe0861bb16ce3da5vboxsync //little hack to make sure the ModRM byte is included in the returned size
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (pOp->idxParse1 != IDX_ParseModRM && pOp->idxParse2 != IDX_ParseModRM)
73ba84f95f918cc170be38908ad240fbb2f8f354vboxsync size = sizeof(uint8_t); //ModRM byte
73ba84f95f918cc170be38908ad240fbb2f8f354vboxsync
73ba84f95f918cc170be38908ad240fbb2f8f354vboxsync size += disParseInstruction(uCodePtr, pOp, pCpu);
73ba84f95f918cc170be38908ad240fbb2f8f354vboxsync
73ba84f95f918cc170be38908ad240fbb2f8f354vboxsync return size;
73ba84f95f918cc170be38908ad240fbb2f8f354vboxsync}
73ba84f95f918cc170be38908ad240fbb2f8f354vboxsync//*****************************************************************************
73ba84f95f918cc170be38908ad240fbb2f8f354vboxsync//*****************************************************************************
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncunsigned ParseGrp4(RTUINTPTR uCodePtr, PCDISOPCODE pOp, PDISOPPARAM pParam, PDISCPUSTATE pCpu)
b6b29a7e040f2b46480aa596fe0861bb16ce3da5vboxsync{
b6b29a7e040f2b46480aa596fe0861bb16ce3da5vboxsync unsigned size = 0, modrm, reg;
b6b29a7e040f2b46480aa596fe0861bb16ce3da5vboxsync NOREF(pParam);
b6b29a7e040f2b46480aa596fe0861bb16ce3da5vboxsync
b6b29a7e040f2b46480aa596fe0861bb16ce3da5vboxsync modrm = disReadByte(pCpu, uCodePtr);
b6b29a7e040f2b46480aa596fe0861bb16ce3da5vboxsync reg = MODRM_REG(modrm);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
6b2a50fc09aa4f7ce2082284f082d97a2c738321vboxsync pOp = (PCDISOPCODE)&g_aMapX86_Group4[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 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
4c98b8b05f3783351cf256cc90cd4478fb28b62bvboxsync 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;
4c98b8b05f3783351cf256cc90cd4478fb28b62bvboxsync}
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
9cdd4d805ecb43126372f7cf12e4032836cb738avboxsync#ifdef DEBUG_Sander
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync //needs testing
9cdd4d805ecb43126372f7cf12e4032836cb738avboxsync AssertMsgFailed(("Test me\n"));
9cdd4d805ecb43126372f7cf12e4032836cb738avboxsync#endif
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9cdd4d805ecb43126372f7cf12e4032836cb738avboxsync unsigned ModRM = disReadByte(pCpu, uCodePtr);
9cdd4d805ecb43126372f7cf12e4032836cb738avboxsync pCpu->ModRM.Bits.Rm = MODRM_RM(ModRM);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pCpu->ModRM.Bits.Mod = MODRM_MOD(ModRM);
9cdd4d805ecb43126372f7cf12e4032836cb738avboxsync pCpu->ModRM.Bits.Reg = MODRM_REG(ModRM);
9cdd4d805ecb43126372f7cf12e4032836cb738avboxsync
9cdd4d805ecb43126372f7cf12e4032836cb738avboxsync modrmsize = QueryModRM(uCodePtr+sizeof(uint8_t), pOp, pParam, pCpu);
9cdd4d805ecb43126372f7cf12e4032836cb738avboxsync
9cdd4d805ecb43126372f7cf12e4032836cb738avboxsync uint8_t opcode = disReadByte(pCpu, uCodePtr+sizeof(uint8_t)+modrmsize);
9cdd4d805ecb43126372f7cf12e4032836cb738avboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pOp = (PCDISOPCODE)&g_aTwoByteMapX86_3DNow[opcode];
9cdd4d805ecb43126372f7cf12e4032836cb738avboxsync
9cdd4d805ecb43126372f7cf12e4032836cb738avboxsync //little hack to make sure the ModRM byte is included in the returned size
9cdd4d805ecb43126372f7cf12e4032836cb738avboxsync if (pOp->idxParse1 != IDX_ParseModRM && pOp->idxParse2 != IDX_ParseModRM)
9cdd4d805ecb43126372f7cf12e4032836cb738avboxsync {
9cdd4d805ecb43126372f7cf12e4032836cb738avboxsync#ifdef DEBUG_Sander /* bird, 2005-06-28: Alex is getting this during full installation of win2ksp4. */
9cdd4d805ecb43126372f7cf12e4032836cb738avboxsync AssertMsgFailed(("Oops!\n")); //shouldn't happen!
9cdd4d805ecb43126372f7cf12e4032836cb738avboxsync#endif
9cdd4d805ecb43126372f7cf12e4032836cb738avboxsync size = sizeof(uint8_t); //ModRM byte
9cdd4d805ecb43126372f7cf12e4032836cb738avboxsync }
9cdd4d805ecb43126372f7cf12e4032836cb738avboxsync
9cdd4d805ecb43126372f7cf12e4032836cb738avboxsync size += disParseInstruction(uCodePtr, pOp, pCpu);
9cdd4d805ecb43126372f7cf12e4032836cb738avboxsync size += sizeof(uint8_t); //imm8_opcode uint8_t
9cdd4d805ecb43126372f7cf12e4032836cb738avboxsync
9cdd4d805ecb43126372f7cf12e4032836cb738avboxsync return size;
9cdd4d805ecb43126372f7cf12e4032836cb738avboxsync}
9cdd4d805ecb43126372f7cf12e4032836cb738avboxsync//*****************************************************************************
9cdd4d805ecb43126372f7cf12e4032836cb738avboxsync//*****************************************************************************
9cdd4d805ecb43126372f7cf12e4032836cb738avboxsyncunsigned ParseGrp6(RTUINTPTR uCodePtr, PCDISOPCODE pOp, PDISOPPARAM pParam, PDISCPUSTATE pCpu)
9cdd4d805ecb43126372f7cf12e4032836cb738avboxsync{
9cdd4d805ecb43126372f7cf12e4032836cb738avboxsync unsigned size = 0, modrm, reg;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync NOREF(pParam);
9cdd4d805ecb43126372f7cf12e4032836cb738avboxsync
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
9cdd4d805ecb43126372f7cf12e4032836cb738avboxsync size += disParseInstruction(uCodePtr, pOp, pCpu);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return size;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync}
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync//*****************************************************************************
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync//*****************************************************************************
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncunsigned ParseGrp7(RTUINTPTR uCodePtr, PCDISOPCODE pOp, PDISOPPARAM pParam, PDISCPUSTATE pCpu)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync{
105b1a31b6037dbe14acb8d09e60da540885202bvboxsync 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];
73ba84f95f918cc170be38908ad240fbb2f8f354vboxsync 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
73ba84f95f918cc170be38908ad240fbb2f8f354vboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync size += disParseInstruction(uCodePtr, pOp, pCpu);
73ba84f95f918cc170be38908ad240fbb2f8f354vboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return size;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync}
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync//*****************************************************************************
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync//*****************************************************************************
105b1a31b6037dbe14acb8d09e60da540885202bvboxsyncunsigned ParseGrp8(RTUINTPTR uCodePtr, PCDISOPCODE pOp, PDISOPPARAM pParam, PDISCPUSTATE pCpu)
105b1a31b6037dbe14acb8d09e60da540885202bvboxsync{
105b1a31b6037dbe14acb8d09e60da540885202bvboxsync unsigned size = 0, modrm, reg;
105b1a31b6037dbe14acb8d09e60da540885202bvboxsync NOREF(pParam);
105b1a31b6037dbe14acb8d09e60da540885202bvboxsync
105b1a31b6037dbe14acb8d09e60da540885202bvboxsync modrm = disReadByte(pCpu, uCodePtr);
105b1a31b6037dbe14acb8d09e60da540885202bvboxsync reg = MODRM_REG(modrm);
105b1a31b6037dbe14acb8d09e60da540885202bvboxsync
105b1a31b6037dbe14acb8d09e60da540885202bvboxsync pOp = (PCDISOPCODE)&g_aMapX86_Group8[reg];
105b1a31b6037dbe14acb8d09e60da540885202bvboxsync
105b1a31b6037dbe14acb8d09e60da540885202bvboxsync //little hack to make sure the ModRM byte is included in the returned size
105b1a31b6037dbe14acb8d09e60da540885202bvboxsync if (pOp->idxParse1 != IDX_ParseModRM && pOp->idxParse2 != IDX_ParseModRM)
105b1a31b6037dbe14acb8d09e60da540885202bvboxsync size = sizeof(uint8_t); //ModRM byte
105b1a31b6037dbe14acb8d09e60da540885202bvboxsync
105b1a31b6037dbe14acb8d09e60da540885202bvboxsync size += disParseInstruction(uCodePtr, pOp, pCpu);
105b1a31b6037dbe14acb8d09e60da540885202bvboxsync
105b1a31b6037dbe14acb8d09e60da540885202bvboxsync return size;
105b1a31b6037dbe14acb8d09e60da540885202bvboxsync}
105b1a31b6037dbe14acb8d09e60da540885202bvboxsync//*****************************************************************************
105b1a31b6037dbe14acb8d09e60da540885202bvboxsync//*****************************************************************************
105b1a31b6037dbe14acb8d09e60da540885202bvboxsyncunsigned ParseGrp9(RTUINTPTR uCodePtr, PCDISOPCODE pOp, PDISOPPARAM pParam, PDISCPUSTATE pCpu)
105b1a31b6037dbe14acb8d09e60da540885202bvboxsync{
105b1a31b6037dbe14acb8d09e60da540885202bvboxsync 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_Group9[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//*****************************************************************************
9cdd4d805ecb43126372f7cf12e4032836cb738avboxsync//*****************************************************************************
9cdd4d805ecb43126372f7cf12e4032836cb738avboxsyncunsigned ParseGrp10(RTUINTPTR uCodePtr, PCDISOPCODE pOp, PDISOPPARAM pParam, PDISCPUSTATE pCpu)
9cdd4d805ecb43126372f7cf12e4032836cb738avboxsync{
9cdd4d805ecb43126372f7cf12e4032836cb738avboxsync unsigned size = 0, modrm, reg;
9cdd4d805ecb43126372f7cf12e4032836cb738avboxsync NOREF(pParam);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync modrm = disReadByte(pCpu, uCodePtr);
9cdd4d805ecb43126372f7cf12e4032836cb738avboxsync reg = MODRM_REG(modrm);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9cdd4d805ecb43126372f7cf12e4032836cb738avboxsync pOp = (PCDISOPCODE)&g_aMapX86_Group10[reg];
9cdd4d805ecb43126372f7cf12e4032836cb738avboxsync
9cdd4d805ecb43126372f7cf12e4032836cb738avboxsync //little hack to make sure the ModRM byte is included in the returned size
9cdd4d805ecb43126372f7cf12e4032836cb738avboxsync if (pOp->idxParse1 != IDX_ParseModRM && pOp->idxParse2 != IDX_ParseModRM)
9cdd4d805ecb43126372f7cf12e4032836cb738avboxsync size = sizeof(uint8_t); //ModRM byte
9cdd4d805ecb43126372f7cf12e4032836cb738avboxsync
9cdd4d805ecb43126372f7cf12e4032836cb738avboxsync size += disParseInstruction(uCodePtr, pOp, pCpu);
9cdd4d805ecb43126372f7cf12e4032836cb738avboxsync
9cdd4d805ecb43126372f7cf12e4032836cb738avboxsync return size;
9cdd4d805ecb43126372f7cf12e4032836cb738avboxsync}
9cdd4d805ecb43126372f7cf12e4032836cb738avboxsync//*****************************************************************************
9cdd4d805ecb43126372f7cf12e4032836cb738avboxsync//*****************************************************************************
9cdd4d805ecb43126372f7cf12e4032836cb738avboxsyncunsigned ParseGrp12(RTUINTPTR uCodePtr, PCDISOPCODE pOp, PDISOPPARAM pParam, PDISCPUSTATE pCpu)
9cdd4d805ecb43126372f7cf12e4032836cb738avboxsync{
9cdd4d805ecb43126372f7cf12e4032836cb738avboxsync unsigned size = 0, modrm, reg;
9cdd4d805ecb43126372f7cf12e4032836cb738avboxsync NOREF(pParam);
9cdd4d805ecb43126372f7cf12e4032836cb738avboxsync
9cdd4d805ecb43126372f7cf12e4032836cb738avboxsync modrm = disReadByte(pCpu, uCodePtr);
9cdd4d805ecb43126372f7cf12e4032836cb738avboxsync reg = MODRM_REG(modrm);
9cdd4d805ecb43126372f7cf12e4032836cb738avboxsync
9cdd4d805ecb43126372f7cf12e4032836cb738avboxsync if (pCpu->fPrefix & DISPREFIX_OPSIZE)
9cdd4d805ecb43126372f7cf12e4032836cb738avboxsync reg += 8; //2nd table
9cdd4d805ecb43126372f7cf12e4032836cb738avboxsync
9cdd4d805ecb43126372f7cf12e4032836cb738avboxsync pOp = (PCDISOPCODE)&g_aMapX86_Group12[reg];
9cdd4d805ecb43126372f7cf12e4032836cb738avboxsync
9cdd4d805ecb43126372f7cf12e4032836cb738avboxsync //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
9cdd4d805ecb43126372f7cf12e4032836cb738avboxsync
9cdd4d805ecb43126372f7cf12e4032836cb738avboxsync size += disParseInstruction(uCodePtr, pOp, pCpu);
9cdd4d805ecb43126372f7cf12e4032836cb738avboxsync 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
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_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)
73ba84f95f918cc170be38908ad240fbb2f8f354vboxsync reg += 8; //2nd table
73ba84f95f918cc170be38908ad240fbb2f8f354vboxsync
9cdd4d805ecb43126372f7cf12e4032836cb738avboxsync pOp = (PCDISOPCODE)&g_aMapX86_Group14[reg];
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync //little hack to make sure the ModRM byte is included in the returned size
4a9af9a8062589b741444d717d2dd1ed22b0f583vboxsync 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 ParseGrp15(RTUINTPTR uCodePtr, PCDISOPCODE pOp, PDISOPPARAM pParam, PDISCPUSTATE pCpu)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync{
73ba84f95f918cc170be38908ad240fbb2f8f354vboxsync 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);
73ba84f95f918cc170be38908ad240fbb2f8f354vboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync 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}
73ba84f95f918cc170be38908ad240fbb2f8f354vboxsync//*****************************************************************************
73ba84f95f918cc170be38908ad240fbb2f8f354vboxsync#if !defined(DIS_CORE_ONLY) && defined(LOG_ENABLED)
73ba84f95f918cc170be38908ad240fbb2f8f354vboxsyncstatic 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"};
3a343ca21a267ec3c54e2317e2ed18fe99b8ebbbvboxsync#endif
3a343ca21a267ec3c54e2317e2ed18fe99b8ebbbvboxsyncstatic const char *szModRMSegReg[6] = {"ES", "CS", "SS", "DS", "FS", "GS"};
3a343ca21a267ec3c54e2317e2ed18fe99b8ebbbvboxsyncstatic const int BaseModRMReg16[8] = { DISGREG_BX, DISGREG_BX, DISGREG_BP, DISGREG_BP, DISGREG_SI, DISGREG_DI, DISGREG_BP, DISGREG_BX};
3a343ca21a267ec3c54e2317e2ed18fe99b8ebbbvboxsyncstatic const int IndexModRMReg16[4] = { DISGREG_SI, DISGREG_DI, DISGREG_SI, DISGREG_DI};
3a343ca21a267ec3c54e2317e2ed18fe99b8ebbbvboxsync//*****************************************************************************
3a343ca21a267ec3c54e2317e2ed18fe99b8ebbbvboxsyncstatic void disasmModRMReg(PDISCPUSTATE pCpu, PCDISOPCODE pOp, unsigned idx, PDISOPPARAM pParam, int fRegAddr)
3a343ca21a267ec3c54e2317e2ed18fe99b8ebbbvboxsync{
3a343ca21a267ec3c54e2317e2ed18fe99b8ebbbvboxsync int subtype, type, mod;
3a343ca21a267ec3c54e2317e2ed18fe99b8ebbbvboxsync NOREF(pOp); NOREF(pCpu);
3a343ca21a267ec3c54e2317e2ed18fe99b8ebbbvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync mod = pCpu->ModRM.Bits.Mod;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync type = OP_PARM_VTYPE(pParam->param);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync subtype = OP_PARM_VSUBTYPE(pParam->param);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (fRegAddr)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync subtype = (pCpu->uAddrMode == DISCPUMODE_64BIT) ? OP_PARM_q : OP_PARM_d;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync else
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync 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:
73ba84f95f918cc170be38908ad240fbb2f8f354vboxsync subtype = OP_PARM_q;
73ba84f95f918cc170be38908ad240fbb2f8f354vboxsync break;
73ba84f95f918cc170be38908ad240fbb2f8f354vboxsync 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));
521d8df5a1a304406b911c2e2c7bf9214d6d9200vboxsync
73ba84f95f918cc170be38908ad240fbb2f8f354vboxsync /* 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
521d8df5a1a304406b911c2e2c7bf9214d6d9200vboxsync && idx <= DISGREG_BH)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
521d8df5a1a304406b911c2e2c7bf9214d6d9200vboxsync idx += (DISGREG_SPL - DISGREG_AH);
521d8df5a1a304406b911c2e2c7bf9214d6d9200vboxsync }
521d8df5a1a304406b911c2e2c7bf9214d6d9200vboxsync
521d8df5a1a304406b911c2e2c7bf9214d6d9200vboxsync 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.reg_gen = 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;
6d9d4a12f6f9f341c968f711765c2c17c9a5a28cvboxsync return;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
6d9d4a12f6f9f341c968f711765c2c17c9a5a28cvboxsync
6d9d4a12f6f9f341c968f711765c2c17c9a5a28cvboxsync pParam->fUse |= DISUSE_REG_SEG;
6d9d4a12f6f9f341c968f711765c2c17c9a5a28cvboxsync pParam->base.reg_seg = (DISSELREG)idx;
6d9d4a12f6f9f341c968f711765c2c17c9a5a28cvboxsync}
6d9d4a12f6f9f341c968f711765c2c17c9a5a28cvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
6d9d4a12f6f9f341c968f711765c2c17c9a5a28cvboxsync/**
6d9d4a12f6f9f341c968f711765c2c17c9a5a28cvboxsync * Slow path for storing instruction bytes.
6d9d4a12f6f9f341c968f711765c2c17c9a5a28cvboxsync *
6d9d4a12f6f9f341c968f711765c2c17c9a5a28cvboxsync * @param pCpu The disassembler state.
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * @param uAddress The address.
6d9d4a12f6f9f341c968f711765c2c17c9a5a28cvboxsync * @param pbSrc The bytes.
0cb5af53de7aed97b1b35311f93de8175756e4afvboxsync * @param cbSrc The number of bytes.
0cb5af53de7aed97b1b35311f93de8175756e4afvboxsync */
0cb5af53de7aed97b1b35311f93de8175756e4afvboxsyncDECL_NO_INLINE(static, void)
0cb5af53de7aed97b1b35311f93de8175756e4afvboxsyncdisStoreInstrBytesSlow(PDISCPUSTATE pCpu, RTUINTPTR uAddress, const uint8_t *pbSrc, size_t cbSrc)
0cb5af53de7aed97b1b35311f93de8175756e4afvboxsync{
0cb5af53de7aed97b1b35311f93de8175756e4afvboxsync /*
0cb5af53de7aed97b1b35311f93de8175756e4afvboxsync * Figure out which case it is.
6d9d4a12f6f9f341c968f711765c2c17c9a5a28cvboxsync */
6d9d4a12f6f9f341c968f711765c2c17c9a5a28cvboxsync uint32_t cbInstr = pCpu->cbInstr;
6d9d4a12f6f9f341c968f711765c2c17c9a5a28cvboxsync RTUINTPTR off = uAddress - pCpu->uInstrAddr;
6d9d4a12f6f9f341c968f711765c2c17c9a5a28cvboxsync if (off < cbInstr)
6d9d4a12f6f9f341c968f711765c2c17c9a5a28cvboxsync {
6d9d4a12f6f9f341c968f711765c2c17c9a5a28cvboxsync if (off + cbSrc <= cbInstr)
6d9d4a12f6f9f341c968f711765c2c17c9a5a28cvboxsync {
6d9d4a12f6f9f341c968f711765c2c17c9a5a28cvboxsync AssertMsg(memcmp(&pCpu->abInstr[off], pbSrc, cbSrc) == 0,
6d9d4a12f6f9f341c968f711765c2c17c9a5a28cvboxsync ("%RTptr LB %zx off=%RTptr (%.*Rhxs)", uAddress, cbSrc, off, cbInstr, pCpu->abInstr));
6d9d4a12f6f9f341c968f711765c2c17c9a5a28cvboxsync return; /* fully re-reading old stuff. */
6d9d4a12f6f9f341c968f711765c2c17c9a5a28cvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync /* Only partially re-reading stuff, skip ahead and add the rest. */
6d9d4a12f6f9f341c968f711765c2c17c9a5a28cvboxsync uint32_t cbAlreadyRead = cbInstr - (uint32_t)off;
6d9d4a12f6f9f341c968f711765c2c17c9a5a28cvboxsync Assert(memcmp(&pCpu->abInstr[off], pbSrc, cbAlreadyRead) == 0);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync uAddress += cbAlreadyRead;
6d9d4a12f6f9f341c968f711765c2c17c9a5a28cvboxsync pbSrc += cbAlreadyRead;
6d9d4a12f6f9f341c968f711765c2c17c9a5a28cvboxsync cbSrc -= cbAlreadyRead;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
6d9d4a12f6f9f341c968f711765c2c17c9a5a28cvboxsync
6d9d4a12f6f9f341c968f711765c2c17c9a5a28cvboxsync if (off >= sizeof(cbInstr))
6d9d4a12f6f9f341c968f711765c2c17c9a5a28cvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync /* The instruction is too long! This shouldn't happen. */
6d9d4a12f6f9f341c968f711765c2c17c9a5a28cvboxsync AssertMsgFailed(("%RTptr LB %zx off=%RTptr (%.*Rhxs)", uAddress, cbSrc, off, cbInstr, pCpu->abInstr));
6d9d4a12f6f9f341c968f711765c2c17c9a5a28cvboxsync return;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync else if (off > cbInstr)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
6d9d4a12f6f9f341c968f711765c2c17c9a5a28cvboxsync /* Mind the gap - this shouldn't happen, but read the gap bytes if it does. */
6d9d4a12f6f9f341c968f711765c2c17c9a5a28cvboxsync AssertMsgFailed(("%RTptr LB %zx off=%RTptr (%.16Rhxs)", uAddress, cbSrc, off, cbInstr, pCpu->abInstr));
6d9d4a12f6f9f341c968f711765c2c17c9a5a28cvboxsync uint32_t cbGap = off - cbInstr;
6d9d4a12f6f9f341c968f711765c2c17c9a5a28cvboxsync int rc = pCpu->pfnReadBytes(pCpu, &pCpu->abInstr[cbInstr], uAddress - cbGap, cbGap);
6d9d4a12f6f9f341c968f711765c2c17c9a5a28cvboxsync 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));
9cdd4d805ecb43126372f7cf12e4032836cb738avboxsync }
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);
105b1a31b6037dbe14acb8d09e60da540885202bvboxsync return VINF_SUCCESS;
9cdd4d805ecb43126372f7cf12e4032836cb738avboxsync#endif
9cdd4d805ecb43126372f7cf12e4032836cb738avboxsync}
9cdd4d805ecb43126372f7cf12e4032836cb738avboxsync
9cdd4d805ecb43126372f7cf12e4032836cb738avboxsync//*****************************************************************************
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync/* Read functions for getting the opcode bytes */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync//*****************************************************************************
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncuint8_t disReadByte(PDISCPUSTATE pCpu, RTUINTPTR uAddress)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync{
9cdd4d805ecb43126372f7cf12e4032836cb738avboxsync uint8_t bTemp = 0;
9cdd4d805ecb43126372f7cf12e4032836cb738avboxsync int rc = pCpu->pfnReadBytes(pCpu, &bTemp, uAddress, sizeof(bTemp));
9cdd4d805ecb43126372f7cf12e4032836cb738avboxsync 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;
73ba84f95f918cc170be38908ad240fbb2f8f354vboxsync int rc = pCpu->pfnReadBytes(pCpu, uTemp.au8, uAddress, sizeof(uTemp));
73ba84f95f918cc170be38908ad240fbb2f8f354vboxsync if (RT_FAILURE(rc))
73ba84f95f918cc170be38908ad240fbb2f8f354vboxsync {
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 {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync Log(("disReadDWord 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->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}
d64aa881df34a86dd70ab0e1b7b94ffa41be9731vboxsync//*****************************************************************************
d64aa881df34a86dd70ab0e1b7b94ffa41be9731vboxsync//*****************************************************************************
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];
d64aa881df34a86dd70ab0e1b7b94ffa41be9731vboxsync 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
d64aa881df34a86dd70ab0e1b7b94ffa41be9731vboxsync
d64aa881df34a86dd70ab0e1b7b94ffa41be9731vboxsync/**
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * Validates the lock sequence.
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync *
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * The AMD manual lists the following instructions:
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * ADC
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * ADD
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * AND
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * BTC
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * BTR
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * BTS
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * CMPXCHG
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * CMPXCHG8B
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * CMPXCHG16B
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * DEC
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * INC
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * NEG
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * NOT
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * OR
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * SBB
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * SUB
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * XADD
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * XCHG
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * XOR
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync *
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * @param pCpu Fully disassembled instruction.
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncstatic void disValidateLockSequence(PDISCPUSTATE pCpu)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync{
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync Assert(pCpu->fPrefix & DISPREFIX_LOCK);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync /*
d64aa881df34a86dd70ab0e1b7b94ffa41be9731vboxsync * Filter out the valid lock sequences.
d64aa881df34a86dd70ab0e1b7b94ffa41be9731vboxsync */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync switch (pCpu->pCurInstr->opcode)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
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->opcode == OP_ILLUD2);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync}
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync