DisasmCore.cpp revision 9d4c9e0a3e2dcc3bd19303d7b4e2d96d12c11814
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * VBox Disassembler - Core Components.
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * Copyright (C) 2006-2012 Oracle Corporation
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* Header Files *
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);
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);
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);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncstatic void disValidateLockSequence(PDISCPUSTATE pCpu);
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);
4a9af9a8062589b741444d717d2dd1ed22b0f583vboxsync/** @name Parsers
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync/** Floating point parsing */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync/*******************************************************************************
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync* Global Variables *
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync*******************************************************************************/
73ba84f95f918cc170be38908ad240fbb2f8f354vboxsync/** Parser opcode table for full disassembly. */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncstatic PFNDISPARSE const g_apfnFullDisasm[IDX_ParseMax] =
0593640ab087e5bf747a2576b1752a2046be83aavboxsync/** Parser opcode table for only calculating instruction size. */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncstatic PFNDISPARSE const g_apfnCalcSize[IDX_ParseMax] =
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * Parses one guest instruction.
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * The result is found in pCpu and pcbInstr.
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.
73ba84f95f918cc170be38908ad240fbb2f8f354vboxsyncDISDECL(int) DISInstr(const void *pvInstr, DISCPUMODE enmCpuMode, PDISCPUSTATE pCpu, uint32_t *pcbInstr)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return DISInstEx((uintptr_t)pvInstr, enmCpuMode, DISOPTYPE_ALL, NULL /*pfnReadBytes*/, NULL /*pvUser*/, pCpu, pcbInstr);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * Parses one guest instruction.
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * The result is found in pCpu and pcbInstr.
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.
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncDISDECL(int) DISInstrWithReader(RTUINTPTR uInstrAddr, DISCPUMODE enmCpuMode, PFNDISREADBYTES pfnReadBytes, void *pvUser,
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return DISInstEx(uInstrAddr, enmCpuMode, DISOPTYPE_ALL, pfnReadBytes, pvUser, pCpu, pcbInstr);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * Disassembles on instruction, details in @a pCpu and length in @a pcbInstr.
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.
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncDISDECL(int) DISInstEx(RTUINTPTR uInstrAddr, DISCPUMODE enmCpuMode, uint32_t fFilter,
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * Initialize the CPU state.
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * Note! The RT_BZERO make ASSUMPTIONS about the placement of pvUser2.
329df9696e709dc71611f504a4774f323545be0avboxsync pCpu->pfnReadBytes = pfnReadBytes ? pfnReadBytes : disReadBytesDefault;
329df9696e709dc71611f504a4774f323545be0avboxsync return disInstrWorker(pCpu, uInstrAddr, paOneByteMap, pcbInstr);
329df9696e709dc71611f504a4774f323545be0avboxsync * Internal worker for DISInstEx.
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.
09f4b412099acda62997fd82c8608075c453b3ebvboxsyncstatic int disInstrWorker(PDISCPUSTATE pCpu, RTUINTPTR uInstrAddr, PCDISOPCODE paOneByteMap, uint32_t *pcbInstr)
09f4b412099acda62997fd82c8608075c453b3ebvboxsync * Parse byte by byte.
09f4b412099acda62997fd82c8608075c453b3ebvboxsync unsigned iByte = 0;
09f4b412099acda62997fd82c8608075c453b3ebvboxsync uint8_t codebyte = disReadByte(pCpu, uInstrAddr+iByte);
09f4b412099acda62997fd82c8608075c453b3ebvboxsync /* Hardcoded assumption about OP_* values!! */
73ba84f95f918cc170be38908ad240fbb2f8f354vboxsync /* The REX prefix must precede the opcode byte(s). Any other placement is ignored. */
09f4b412099acda62997fd82c8608075c453b3ebvboxsync /** Last prefix byte (for SSE2 extension tables); don't include the REX prefix */
09f4b412099acda62997fd82c8608075c453b3ebvboxsync // segment override prefix byte
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 continue; //fetch the next byte
09f4b412099acda62997fd82c8608075c453b3ebvboxsync // lock prefix byte
09f4b412099acda62997fd82c8608075c453b3ebvboxsync continue; //fetch the next byte
09f4b412099acda62997fd82c8608075c453b3ebvboxsync // address size override prefix byte
09f4b412099acda62997fd82c8608075c453b3ebvboxsync continue; //fetch the next byte
09f4b412099acda62997fd82c8608075c453b3ebvboxsync // operand size override prefix byte
09f4b412099acda62997fd82c8608075c453b3ebvboxsync pCpu->uOpMode = DISCPUMODE_16BIT; /* for 32 and 64 bits mode (there is no 32 bits operand size override prefix) */
09f4b412099acda62997fd82c8608075c453b3ebvboxsync continue; //fetch the next byte
329df9696e709dc71611f504a4774f323545be0avboxsync // rep and repne are not really prefixes, but we'll treat them as such
73ba84f95f918cc170be38908ad240fbb2f8f354vboxsync continue; //fetch the next byte
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync continue; //fetch the next byte
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync /* REX prefix byte */
dc959f60f6d3e0cba86f7da4d39aa475913a7e10vboxsync pCpu->fRexPrefix = DISPREFIX_REX_OP_2_FLAGS(paOneByteMap[codebyte].param1);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pCpu->uOpMode = DISCPUMODE_64BIT; /* overrides size prefix byte */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync continue; //fetch the next byte
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync cbInc = disParseInstruction(uInstrAddr + iByte, &paOneByteMap[pCpu->bOpCode], pCpu);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync AssertMsg(pCpu->cbInstr == iByte || RT_FAILURE_NP(pCpu->rc), ("%u %u\n", pCpu->cbInstr, iByte));
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync//*****************************************************************************
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync//*****************************************************************************
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsyncstatic unsigned disParseInstruction(RTUINTPTR uCodePtr, PCDISOPCODE pOp, PDISCPUSTATE pCpu)
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync bool fFiltered = false;
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync // Store the opcode format string for disasmPrintf
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 /* Not filtered out -> full disassembly */
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync // Should contain the parameter type on input
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync /* Correct the operand size if the instruction is marked as forced or default 64 bits */
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync /* Forced 32 bits operand size for certain instructions (mov crx, mov drx). */
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync size += pCpu->pfnDisasmFnTable[pOp->idxParse1](uCodePtr, pOp, &pCpu->param1, pCpu);
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync if (fFiltered == false) pCpu->param1.cb = DISGetParamSize(pCpu, &pCpu->param1);
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync size += pCpu->pfnDisasmFnTable[pOp->idxParse2](uCodePtr+size, pOp, &pCpu->param2, pCpu);
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync if (fFiltered == false) pCpu->param2.cb = DISGetParamSize(pCpu, &pCpu->param2);
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync size += pCpu->pfnDisasmFnTable[pOp->idxParse3](uCodePtr+size, pOp, &pCpu->param3, pCpu);
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync if (fFiltered == false) pCpu->param3.cb = DISGetParamSize(pCpu, &pCpu->param3);
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync // else simple one byte instruction
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync//*****************************************************************************
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync/* Floating point opcode parsing */
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync//*****************************************************************************
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsyncunsigned ParseEscFP(RTUINTPTR uCodePtr, PCDISOPCODE pOp, PDISOPPARAM pParam, PDISCPUSTATE pCpu)
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync unsigned size = 0;
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync fpop = &(g_apMapX86_FP_Low[index])[MODRM_REG(ModRM)];
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync // Should contain the parameter type on input
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 /* Not filtered out -> full disassembly */
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync /* Correct the operand size if the instruction is marked as forced or default 64 bits */
1ff34f218a5354068e4df9017f77fc5871e6b7c6vboxsync /* Note: redundant, but just in case this ever changes */
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 += pCpu->pfnDisasmFnTable[fpop->idxParse1](uCodePtr+size, (PCDISOPCODE)fpop, pParam, pCpu);
1ff34f218a5354068e4df9017f77fc5871e6b7c6vboxsync size += pCpu->pfnDisasmFnTable[fpop->idxParse2](uCodePtr+size, (PCDISOPCODE)fpop, pParam, pCpu);
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//*****************************************************************************
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsyncvoid UseSIB(RTUINTPTR uCodePtr, PCDISOPCODE pOp, PDISOPPARAM pParam, PDISCPUSTATE pCpu)
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync // [scaled index] + disp32
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync { /* sign-extend to 64 bits */
1ff34f218a5354068e4df9017f77fc5871e6b7c6vboxsync return; /* Already fetched everything in ParseSIB; no size returned */
1ff34f218a5354068e4df9017f77fc5871e6b7c6vboxsync//*****************************************************************************
1ff34f218a5354068e4df9017f77fc5871e6b7c6vboxsync//*****************************************************************************
1ff34f218a5354068e4df9017f77fc5871e6b7c6vboxsyncunsigned ParseSIB(RTUINTPTR uCodePtr, PCDISOPCODE pOp, PDISOPPARAM pParam, PDISCPUSTATE pCpu)
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 pCpu->SIB.Bits.Index |= ((!!(pCpu->fRexPrefix & DISPREFIX_REX_FLAGS_X)) << 3);
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync /* Additional 32 bits displacement. No change in long mode. */
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync//*****************************************************************************
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync//*****************************************************************************
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsyncunsigned ParseSIB_SizeOnly(RTUINTPTR uCodePtr, PCDISOPCODE pOp, PDISOPPARAM pParam, PDISCPUSTATE pCpu)
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 /* Additional 32 bits displacement. No change in long mode. */
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync//*****************************************************************************
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync// ModR/M byte:
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync// 7 - 6 5 - 3 2-0
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync//*****************************************************************************
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsyncunsigned UseModRM(RTUINTPTR uCodePtr, PCDISOPCODE pOp, PDISOPPARAM pParam, PDISCPUSTATE pCpu)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync break; /* memory operand */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync reg = rm; /* the RM field specifies the xmm register */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync /* else no break */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync /* @todo bound */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync Assert(pCpu->uAddrMode == DISCPUMODE_32BIT || pCpu->uAddrMode == DISCPUMODE_64BIT);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * Note: displacements in long mode are 8 or 32 bits and sign-extended to 64 bits
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync case 0: //effective address
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync { /* SIB byte follows ModRM */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync /* 32 bits displacement */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync { //register address
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {//16 bits addressing mode
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync case 0: //effective address
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {//16 bits displacement
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pParam->fUse |= DISUSE_BASE | DISUSE_DISPLACEMENT8;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pParam->fUse |= DISUSE_BASE | DISUSE_DISPLACEMENT16;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return 0; //everything was already fetched in ParseModRM
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)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync unsigned size = 0;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync // unsigned reg = pCpu->ModRM.Bits.Reg;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync Assert(pCpu->uAddrMode == DISCPUMODE_32BIT || pCpu->uAddrMode == DISCPUMODE_64BIT);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * Note: displacements in long mode are 8 or 32 bits and sign-extended to 64 bits
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync { /* SIB byte follows ModRM */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync case 0: /* Effective address */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync /* else register address */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync case 1: /* Effective address + 8 bits displacement */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pCpu->i32SibDisp = (int8_t)disReadByte(pCpu, uCodePtr);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync size += sizeof(char);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync case 2: /* Effective address + 32 bits displacement */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync /* 16 bits mode */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync case 0: /* Effective address */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync /* else register address */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync case 1: /* Effective address + 8 bits displacement */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pCpu->i32SibDisp = (int8_t)disReadByte(pCpu, uCodePtr);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync size += sizeof(char);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync case 2: /* Effective address + 32 bits displacement */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pCpu->i32SibDisp = (int16_t)disReadWord(pCpu, uCodePtr);
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 unsigned size = 0;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync // unsigned reg = pCpu->ModRM.Bits.Reg;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync Assert(pCpu->uAddrMode == DISCPUMODE_32BIT || pCpu->uAddrMode == DISCPUMODE_64BIT);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * Note: displacements in long mode are 8 or 32 bits and sign-extended to 64 bits
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync { /* SIB byte follows ModRM */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync *pSibInc = ParseSIB_SizeOnly(uCodePtr, pOp, pParam, pCpu);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync case 0: //effective address
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync /* else register address */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync case 1: /* Effective address + 8 bits displacement */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync size += sizeof(char);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync case 2: /* Effective address + 32 bits displacement */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync /* 16 bits mode */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync case 0: //effective address
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync /* else register address */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync case 1: /* Effective address + 8 bits displacement */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync size += sizeof(char);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync case 2: /* Effective address + 32 bits displacement */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync//*****************************************************************************
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync//*****************************************************************************
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncunsigned ParseIllegal(RTUINTPTR uCodePtr, PCDISOPCODE pOp, PDISOPPARAM pParam, PDISCPUSTATE pCpu)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync NOREF(uCodePtr); NOREF(pOp); NOREF(pParam); NOREF(pCpu);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync//*****************************************************************************
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync//*****************************************************************************
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncunsigned ParseModRM(RTUINTPTR uCodePtr, PCDISOPCODE pOp, PDISOPPARAM pParam, PDISCPUSTATE pCpu)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync /* Disregard the mod bits for certain instructions (mov crx, mov drx).
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.
4c98b8b05f3783351cf256cc90cd4478fb28b62bvboxsync /* REX.R extends the Reg field. */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pCpu->ModRM.Bits.Reg |= ((!!(pCpu->fRexPrefix & DISPREFIX_REX_FLAGS_R)) << 3);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync /* REX.B extends the Rm field if there is no SIB byte nor a 32 bits displacement */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pCpu->ModRM.Bits.Rm |= ((!!(pCpu->fRexPrefix & DISPREFIX_REX_FLAGS_B)) << 3);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync size += QueryModRM(uCodePtr, pOp, pParam, pCpu, &sibinc);
4c98b8b05f3783351cf256cc90cd4478fb28b62bvboxsync//*****************************************************************************
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync//*****************************************************************************
4c98b8b05f3783351cf256cc90cd4478fb28b62bvboxsyncunsigned ParseModRM_SizeOnly(RTUINTPTR uCodePtr, PCDISOPCODE pOp, PDISOPPARAM pParam, PDISCPUSTATE pCpu)
4c98b8b05f3783351cf256cc90cd4478fb28b62bvboxsync /* Disregard the mod bits for certain instructions (mov crx, mov drx).
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.
4c98b8b05f3783351cf256cc90cd4478fb28b62bvboxsync /* REX.R extends the Reg field. */
3a343ca21a267ec3c54e2317e2ed18fe99b8ebbbvboxsync pCpu->ModRM.Bits.Reg |= ((!!(pCpu->fRexPrefix & DISPREFIX_REX_FLAGS_R)) << 3);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync /* REX.B extends the Rm field if there is no SIB byte nor a 32 bits displacement */
67b8a5a52c43a79ea7e159dbbeec99687fb9cd3bvboxsync pCpu->ModRM.Bits.Rm |= ((!!(pCpu->fRexPrefix & DISPREFIX_REX_FLAGS_B)) << 3);
105b1a31b6037dbe14acb8d09e60da540885202bvboxsync size += QueryModRM_SizeOnly(uCodePtr, pOp, pParam, pCpu, &sibinc);
6b2a50fc09aa4f7ce2082284f082d97a2c738321vboxsync /* UseModRM is not necessary here; we're only interested in the opcode size */
6b2a50fc09aa4f7ce2082284f082d97a2c738321vboxsync//*****************************************************************************
6b2a50fc09aa4f7ce2082284f082d97a2c738321vboxsync//*****************************************************************************
73ba84f95f918cc170be38908ad240fbb2f8f354vboxsyncunsigned ParseModFence(RTUINTPTR uCodePtr, PCDISOPCODE pOp, PDISOPPARAM pParam, PDISCPUSTATE pCpu)
73ba84f95f918cc170be38908ad240fbb2f8f354vboxsync ////AssertMsgFailed(("??\n"));
5159c4c6485473c77871b515c15b59c3caa60b46vboxsync //nothing to do apparently
5159c4c6485473c77871b515c15b59c3caa60b46vboxsync NOREF(uCodePtr); NOREF(pOp); NOREF(pParam); NOREF(pCpu);
5159c4c6485473c77871b515c15b59c3caa60b46vboxsync//*****************************************************************************
5159c4c6485473c77871b515c15b59c3caa60b46vboxsync//*****************************************************************************
5159c4c6485473c77871b515c15b59c3caa60b46vboxsyncunsigned ParseImmByte(RTUINTPTR uCodePtr, PCDISOPCODE pOp, PDISOPPARAM pParam, PDISCPUSTATE pCpu)
5159c4c6485473c77871b515c15b59c3caa60b46vboxsync return sizeof(uint8_t);
5159c4c6485473c77871b515c15b59c3caa60b46vboxsync//*****************************************************************************
5159c4c6485473c77871b515c15b59c3caa60b46vboxsync//*****************************************************************************
5159c4c6485473c77871b515c15b59c3caa60b46vboxsyncunsigned ParseImmByte_SizeOnly(RTUINTPTR uCodePtr, PCDISOPCODE pOp, PDISOPPARAM pParam, PDISCPUSTATE pCpu)
5159c4c6485473c77871b515c15b59c3caa60b46vboxsync NOREF(uCodePtr); NOREF(pOp); NOREF(pParam); NOREF(pCpu);
5159c4c6485473c77871b515c15b59c3caa60b46vboxsync return sizeof(uint8_t);
5159c4c6485473c77871b515c15b59c3caa60b46vboxsync//*****************************************************************************
5159c4c6485473c77871b515c15b59c3caa60b46vboxsync//*****************************************************************************
5159c4c6485473c77871b515c15b59c3caa60b46vboxsyncunsigned ParseImmByteSX(RTUINTPTR uCodePtr, PCDISOPCODE pOp, PDISOPPARAM pParam, PDISCPUSTATE pCpu)
6b2a50fc09aa4f7ce2082284f082d97a2c738321vboxsync pParam->parval = (uint32_t)(int8_t)disReadByte(pCpu, uCodePtr);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pParam->parval = (uint64_t)(int8_t)disReadByte(pCpu, uCodePtr);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pParam->parval = (uint16_t)(int8_t)disReadByte(pCpu, uCodePtr);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return sizeof(uint8_t);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync//*****************************************************************************
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync//*****************************************************************************
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncunsigned ParseImmByteSX_SizeOnly(RTUINTPTR uCodePtr, PCDISOPCODE pOp, PDISOPPARAM pParam, PDISCPUSTATE pCpu)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync NOREF(uCodePtr); NOREF(pOp); NOREF(pParam); NOREF(pCpu);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return sizeof(uint8_t);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync//*****************************************************************************
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync//*****************************************************************************
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncunsigned ParseImmUshort(RTUINTPTR uCodePtr, PCDISOPCODE pOp, PDISOPPARAM pParam, PDISCPUSTATE pCpu)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return sizeof(uint16_t);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync//*****************************************************************************
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync//*****************************************************************************
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncunsigned ParseImmUshort_SizeOnly(RTUINTPTR uCodePtr, PCDISOPCODE pOp, PDISOPPARAM pParam, PDISCPUSTATE pCpu)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync NOREF(uCodePtr); NOREF(pOp); NOREF(pParam); NOREF(pCpu);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return sizeof(uint16_t);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync//*****************************************************************************
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync//*****************************************************************************
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncunsigned ParseImmUlong(RTUINTPTR uCodePtr, PCDISOPCODE pOp, PDISOPPARAM pParam, PDISCPUSTATE pCpu)
67b8a5a52c43a79ea7e159dbbeec99687fb9cd3bvboxsync return sizeof(uint32_t);
105b1a31b6037dbe14acb8d09e60da540885202bvboxsync//*****************************************************************************
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync//*****************************************************************************
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncunsigned ParseImmUlong_SizeOnly(RTUINTPTR uCodePtr, PCDISOPCODE pOp, PDISOPPARAM pParam, PDISCPUSTATE pCpu)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync NOREF(uCodePtr); NOREF(pOp); NOREF(pParam); NOREF(pCpu);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return sizeof(uint32_t);
3a343ca21a267ec3c54e2317e2ed18fe99b8ebbbvboxsync//*****************************************************************************
3a343ca21a267ec3c54e2317e2ed18fe99b8ebbbvboxsync//*****************************************************************************
3a343ca21a267ec3c54e2317e2ed18fe99b8ebbbvboxsyncunsigned ParseImmQword(RTUINTPTR uCodePtr, PCDISOPCODE pOp, PDISOPPARAM pParam, PDISCPUSTATE pCpu)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return sizeof(uint64_t);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync//*****************************************************************************
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync//*****************************************************************************
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncunsigned ParseImmQword_SizeOnly(RTUINTPTR uCodePtr, PCDISOPCODE pOp, PDISOPPARAM pParam, PDISCPUSTATE pCpu)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync NOREF(uCodePtr); NOREF(pOp); NOREF(pParam); NOREF(pCpu);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return sizeof(uint64_t);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync//*****************************************************************************
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync//*****************************************************************************
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncunsigned ParseImmV(RTUINTPTR uCodePtr, PCDISOPCODE pOp, PDISOPPARAM pParam, PDISCPUSTATE pCpu)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return sizeof(uint32_t);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return sizeof(uint64_t);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return sizeof(uint16_t);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync//*****************************************************************************
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync//*****************************************************************************
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncunsigned ParseImmV_SizeOnly(RTUINTPTR uCodePtr, PCDISOPCODE pOp, PDISOPPARAM pParam, PDISCPUSTATE pCpu)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return sizeof(uint32_t);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return sizeof(uint64_t);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return sizeof(uint16_t);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync//*****************************************************************************
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync//*****************************************************************************
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncunsigned ParseImmZ(RTUINTPTR uCodePtr, PCDISOPCODE pOp, PDISOPPARAM pParam, PDISCPUSTATE pCpu)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync /* Word for 16-bit operand-size or doubleword for 32 or 64-bit operand-size. */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return sizeof(uint16_t);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync /* 64 bits op mode means *sign* extend to 64 bits. */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pParam->parval = (uint64_t)(int32_t)disReadDWord(pCpu, uCodePtr);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return sizeof(uint32_t);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync//*****************************************************************************
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync//*****************************************************************************
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncunsigned ParseImmZ_SizeOnly(RTUINTPTR uCodePtr, PCDISOPCODE pOp, PDISOPPARAM pParam, PDISCPUSTATE pCpu)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync /* Word for 16-bit operand-size or doubleword for 32 or 64-bit operand-size. */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return sizeof(uint16_t);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return sizeof(uint32_t);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync//*****************************************************************************
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync// Relative displacement for branches (rel. to next instruction)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync//*****************************************************************************
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncunsigned ParseImmBRel(RTUINTPTR uCodePtr, PCDISOPCODE pOp, PDISOPPARAM pParam, PDISCPUSTATE pCpu)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return sizeof(char);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync//*****************************************************************************
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync// Relative displacement for branches (rel. to next instruction)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync//*****************************************************************************
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncunsigned ParseImmBRel_SizeOnly(RTUINTPTR uCodePtr, PCDISOPCODE pOp, PDISOPPARAM pParam, PDISCPUSTATE pCpu)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync NOREF(uCodePtr); NOREF(pOp); NOREF(pParam); NOREF(pCpu);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return sizeof(char);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync//*****************************************************************************
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync// Relative displacement for branches (rel. to next instruction)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync//*****************************************************************************
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncunsigned ParseImmVRel(RTUINTPTR uCodePtr, PCDISOPCODE pOp, PDISOPPARAM pParam, PDISCPUSTATE pCpu)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return sizeof(int32_t);
e6ad2e18e663b076aeabfec994947514566a7accvboxsync /* 32 bits relative immediate sign extended to 64 bits. */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pParam->parval = (uint64_t)(int32_t)disReadDWord(pCpu, uCodePtr);
e6ad2e18e663b076aeabfec994947514566a7accvboxsync return sizeof(int32_t);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return sizeof(int16_t);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync//*****************************************************************************
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync// Relative displacement for branches (rel. to next instruction)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync//*****************************************************************************
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncunsigned ParseImmVRel_SizeOnly(RTUINTPTR uCodePtr, PCDISOPCODE pOp, PDISOPPARAM pParam, PDISCPUSTATE pCpu)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return sizeof(int16_t);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync /* Both 32 & 64 bits mode use 32 bits relative immediates. */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return sizeof(int32_t);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync//*****************************************************************************
e6ad2e18e663b076aeabfec994947514566a7accvboxsync//*****************************************************************************
dc959f60f6d3e0cba86f7da4d39aa475913a7e10vboxsyncunsigned ParseImmAddr(RTUINTPTR uCodePtr, PCDISOPCODE pOp, PDISOPPARAM pParam, PDISCPUSTATE pCpu)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync /* far 16:32 pointer */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync *((uint32_t*)&pParam->parval+1) = disReadWord(pCpu, uCodePtr+sizeof(uint32_t));
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * near 32 bits pointer
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * Note: used only in "mov al|ax|eax, [Addr]" and "mov [Addr], al|ax|eax"
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * so we treat it like displacement.
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return sizeof(uint32_t);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync Assert(OP_PARM_VSUBTYPE(pParam->param) != OP_PARM_p);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * near 64 bits pointer
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * Note: used only in "mov al|ax|eax, [Addr]" and "mov [Addr], al|ax|eax"
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * so we treat it like displacement.
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return sizeof(uint64_t);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync /* far 16:16 pointer */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return sizeof(uint32_t);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * near 16 bits pointer
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * Note: used only in "mov al|ax|eax, [Addr]" and "mov [Addr], al|ax|eax"
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * so we treat it like displacement.
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return sizeof(uint16_t);
e6ad2e18e663b076aeabfec994947514566a7accvboxsync//*****************************************************************************
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync//*****************************************************************************
e6ad2e18e663b076aeabfec994947514566a7accvboxsyncunsigned ParseImmAddr_SizeOnly(RTUINTPTR uCodePtr, PCDISOPCODE pOp, PDISOPPARAM pParam, PDISCPUSTATE pCpu)
e6ad2e18e663b076aeabfec994947514566a7accvboxsync {// far 16:32 pointer
e6ad2e18e663b076aeabfec994947514566a7accvboxsync {// near 32 bits pointer
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return sizeof(uint32_t);
9cdd4d805ecb43126372f7cf12e4032836cb738avboxsync Assert(OP_PARM_VSUBTYPE(pParam->param) != OP_PARM_p);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return sizeof(uint64_t);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {// far 16:16 pointer
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return sizeof(uint32_t);
105b1a31b6037dbe14acb8d09e60da540885202bvboxsync {// near 16 bits pointer
105b1a31b6037dbe14acb8d09e60da540885202bvboxsync return sizeof(uint16_t);
105b1a31b6037dbe14acb8d09e60da540885202bvboxsync//*****************************************************************************
105b1a31b6037dbe14acb8d09e60da540885202bvboxsync//*****************************************************************************
105b1a31b6037dbe14acb8d09e60da540885202bvboxsyncunsigned ParseImmAddrF(RTUINTPTR uCodePtr, PCDISOPCODE pOp, PDISOPPARAM pParam, PDISCPUSTATE pCpu)
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 // far 16:32 pointer
105b1a31b6037dbe14acb8d09e60da540885202bvboxsync *((uint32_t*)&pParam->parval+1) = disReadWord(pCpu, uCodePtr+sizeof(uint32_t));
105b1a31b6037dbe14acb8d09e60da540885202bvboxsync // far 16:16 pointer
105b1a31b6037dbe14acb8d09e60da540885202bvboxsync return sizeof(uint32_t);
105b1a31b6037dbe14acb8d09e60da540885202bvboxsync//*****************************************************************************
105b1a31b6037dbe14acb8d09e60da540885202bvboxsync//*****************************************************************************
105b1a31b6037dbe14acb8d09e60da540885202bvboxsyncunsigned ParseImmAddrF_SizeOnly(RTUINTPTR uCodePtr, PCDISOPCODE pOp, PDISOPPARAM pParam, PDISCPUSTATE pCpu)
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 // far 16:32 pointer
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync // far 16:16 pointer
c58dc77ef4af214d7ae06910fa5ab18587d2ae08vboxsync return sizeof(uint32_t);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync//*****************************************************************************
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync//*****************************************************************************
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncunsigned ParseFixedReg(RTUINTPTR uCodePtr, PCDISOPCODE pOp, PDISOPPARAM pParam, PDISCPUSTATE pCpu)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * Sets up flags for stored in OPC fixed registers.
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync /* No parameter at all. */
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 /* 32-bit EAX..EDI registers. */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync /* Use 32-bit registers. */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pParam->base.reg_gen = pParam->param - OP_PARM_REG_GEN32_START;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync /* Use 64-bit registers. */
e6ad2e18e663b076aeabfec994947514566a7accvboxsync pParam->base.reg_gen = pParam->param - OP_PARM_REG_GEN32_START;
9cdd4d805ecb43126372f7cf12e4032836cb738avboxsync && pParam == &pCpu->param1 /* ugly assumption that it only applies to the first parameter */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync /* Use 16-bit registers. */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pParam->base.reg_gen = pParam->param - OP_PARM_REG_GEN32_START;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pParam->param = pParam->param - OP_PARM_REG_GEN32_START + OP_PARM_REG_GEN16_START;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync /* Segment ES..GS registers. */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pParam->base.reg_seg = (DISSELREG)(pParam->param - OP_PARM_REG_SEG_START);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync /* 16-bit AX..DI registers. */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pParam->base.reg_gen = pParam->param - OP_PARM_REG_GEN16_START;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync /* 8-bit AL..DL, AH..DH registers. */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pParam->base.reg_gen = pParam->param - OP_PARM_REG_GEN8_START;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync && pParam == &pCpu->param1 /* ugly assumption that it only applies to the first parameter */
e6ad2e18e663b076aeabfec994947514566a7accvboxsync pParam->base.reg_gen += 8; /* least significant byte of R8-R15 */
9cdd4d805ecb43126372f7cf12e4032836cb738avboxsync /* FPU registers. */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pParam->base.reg_fp = pParam->param - OP_PARM_REG_FP_START;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync Assert(!(pParam->param >= OP_PARM_REG_GEN64_START && pParam->param <= OP_PARM_REG_GEN64_END));
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync /* else - not supported for now registers. */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync//*****************************************************************************
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync//*****************************************************************************
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncunsigned ParseXv(RTUINTPTR uCodePtr, PCDISOPCODE pOp, PDISOPPARAM pParam, PDISCPUSTATE pCpu)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return 0; //no additional opcode bytes
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync//*****************************************************************************
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync//*****************************************************************************
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncunsigned ParseXb(RTUINTPTR uCodePtr, PCDISOPCODE pOp, PDISOPPARAM pParam, PDISCPUSTATE pCpu)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return 0; //no additional opcode bytes
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync//*****************************************************************************
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync//*****************************************************************************
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncunsigned ParseYv(RTUINTPTR uCodePtr, PCDISOPCODE pOp, PDISOPPARAM pParam, PDISCPUSTATE pCpu)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return 0; //no additional opcode bytes
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync//*****************************************************************************
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync//*****************************************************************************
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncunsigned ParseYb(RTUINTPTR uCodePtr, PCDISOPCODE pOp, PDISOPPARAM pParam, PDISCPUSTATE pCpu)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return 0; //no additional opcode bytes
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync//*****************************************************************************
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync//*****************************************************************************
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncunsigned ParseTwoByteEsc(RTUINTPTR uCodePtr, PCDISOPCODE pOp, PDISOPPARAM pParam, PDISCPUSTATE pCpu)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync /* 2nd byte */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync /* default to the non-prefixed table. */
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 (g_aTwoByteMapX86_PF66[pCpu->bOpCode].opcode != OP_INVALID)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync /* Table entry is valid, so use the extension table. */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync /* Cancel prefix changes. */
441b60f8b0601cc1718368c9c3ef082223ad12a2vboxsync if (g_aTwoByteMapX86_PFF2[pCpu->bOpCode].opcode != OP_INVALID)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync /* Table entry is valid, so use the extension table. */
2721dfb0e330d57ba888311520f5a343c64e7cefvboxsync /* Cancel prefix changes. */
441b60f8b0601cc1718368c9c3ef082223ad12a2vboxsync if (g_aTwoByteMapX86_PFF3[pCpu->bOpCode].opcode != OP_INVALID)
441b60f8b0601cc1718368c9c3ef082223ad12a2vboxsync /* Table entry is valid, so use the extension table. */
441b60f8b0601cc1718368c9c3ef082223ad12a2vboxsync /* Cancel prefix changes. */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync size += disParseInstruction(uCodePtr+size, pOpcode, pCpu);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync//*****************************************************************************
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync//*****************************************************************************
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncunsigned ParseThreeByteEsc4(RTUINTPTR uCodePtr, PCDISOPCODE pOp, PDISOPPARAM pParam, PDISCPUSTATE pCpu)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync /* 3rd byte */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync /* default to the non-prefixed table. */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pOpcode = g_apThreeByteMapX86_0F38[pCpu->bOpCode >> 4];
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 if (g_apThreeByteMapX86_660F38[pCpu->bOpCode >> 4])
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pOpcode = g_apThreeByteMapX86_660F38[pCpu->bOpCode >> 4];
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync /* Table entry is valid, so use the extension table. */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync /* Cancel prefix changes. */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (g_apThreeByteMapX86_F20F38[pCpu->bOpCode >> 4])
6b2a50fc09aa4f7ce2082284f082d97a2c738321vboxsync pOpcode = g_apThreeByteMapX86_F20F38[pCpu->bOpCode >> 4];
71c0735a959eefb3e0b7a3bd8c8640a5660584cavboxsync /* Table entry is valid, so use the extension table. */
73ba84f95f918cc170be38908ad240fbb2f8f354vboxsync /* Cancel prefix changes. */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync size += disParseInstruction(uCodePtr+size, pOpcode, pCpu);
4c98b8b05f3783351cf256cc90cd4478fb28b62bvboxsync//*****************************************************************************
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync//*****************************************************************************
4c98b8b05f3783351cf256cc90cd4478fb28b62bvboxsyncunsigned ParseThreeByteEsc5(RTUINTPTR uCodePtr, PCDISOPCODE pOp, PDISOPPARAM pParam, PDISCPUSTATE pCpu)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync /* 3rd byte */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync /** @todo Should we take the first or last prefix byte in case of multiple prefix bytes??? */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync /* default to the non-prefixed table. */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (g_apThreeByteMapX86_660F3A[pCpu->bOpCode >> 4])
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pOpcode = g_apThreeByteMapX86_660F3A[pCpu->bOpCode >> 4];
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync /* Table entry is valid, so use the extension table. */
73ba84f95f918cc170be38908ad240fbb2f8f354vboxsync /* Cancel prefix changes. */
73ba84f95f918cc170be38908ad240fbb2f8f354vboxsync size += disParseInstruction(uCodePtr+size, pOpcode, pCpu);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync//*****************************************************************************
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync//*****************************************************************************
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncunsigned ParseNopPause(RTUINTPTR uCodePtr, PCDISOPCODE pOp, PDISOPPARAM pParam, PDISCPUSTATE pCpu)
73ba84f95f918cc170be38908ad240fbb2f8f354vboxsync unsigned size = 0;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync//*****************************************************************************
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync//*****************************************************************************
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncunsigned ParseImmGrpl(RTUINTPTR uCodePtr, PCDISOPCODE pOp, PDISOPPARAM pParam, PDISCPUSTATE pCpu)
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//*****************************************************************************
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync//*****************************************************************************
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncunsigned ParseShiftGrp2(RTUINTPTR uCodePtr, PCDISOPCODE pOp, PDISOPPARAM pParam, PDISCPUSTATE pCpu)
73ba84f95f918cc170be38908ad240fbb2f8f354vboxsync return sizeof(uint8_t);
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)
b6b29a7e040f2b46480aa596fe0861bb16ce3da5vboxsync//*****************************************************************************
b6b29a7e040f2b46480aa596fe0861bb16ce3da5vboxsync//*****************************************************************************
b6b29a7e040f2b46480aa596fe0861bb16ce3da5vboxsyncunsigned ParseGrp3(RTUINTPTR uCodePtr, PCDISOPCODE pOp, PDISOPPARAM pParam, PDISCPUSTATE pCpu)
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//*****************************************************************************
73ba84f95f918cc170be38908ad240fbb2f8f354vboxsync//*****************************************************************************
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncunsigned ParseGrp4(RTUINTPTR uCodePtr, PCDISOPCODE pOp, PDISOPPARAM pParam, PDISCPUSTATE pCpu)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync //little hack to make sure the ModRM byte is included in the returned size
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (pOp->idxParse1 != IDX_ParseModRM && pOp->idxParse2 != IDX_ParseModRM)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync//*****************************************************************************
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync//*****************************************************************************
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncunsigned ParseGrp5(RTUINTPTR uCodePtr, PCDISOPCODE pOp, PDISOPPARAM pParam, PDISCPUSTATE pCpu)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync //little hack to make sure the ModRM byte is included in the returned size
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (pOp->idxParse1 != IDX_ParseModRM && pOp->idxParse2 != IDX_ParseModRM)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync//*****************************************************************************
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync// 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//*****************************************************************************
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncunsigned Parse3DNow(RTUINTPTR uCodePtr, PCDISOPCODE pOp, PDISOPPARAM pParam, PDISCPUSTATE pCpu)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync //needs testing
9cdd4d805ecb43126372f7cf12e4032836cb738avboxsync modrmsize = QueryModRM(uCodePtr+sizeof(uint8_t), pOp, pParam, pCpu);
9cdd4d805ecb43126372f7cf12e4032836cb738avboxsync uint8_t opcode = disReadByte(pCpu, uCodePtr+sizeof(uint8_t)+modrmsize);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pOp = (PCDISOPCODE)&g_aTwoByteMapX86_3DNow[opcode];
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#ifdef DEBUG_Sander /* bird, 2005-06-28: Alex is getting this during full installation of win2ksp4. */
9cdd4d805ecb43126372f7cf12e4032836cb738avboxsync//*****************************************************************************
9cdd4d805ecb43126372f7cf12e4032836cb738avboxsync//*****************************************************************************
9cdd4d805ecb43126372f7cf12e4032836cb738avboxsyncunsigned ParseGrp6(RTUINTPTR uCodePtr, PCDISOPCODE pOp, PDISOPPARAM pParam, PDISCPUSTATE pCpu)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync //little hack to make sure the ModRM byte is included in the returned size
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (pOp->idxParse1 != IDX_ParseModRM && pOp->idxParse2 != IDX_ParseModRM)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync//*****************************************************************************
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync//*****************************************************************************
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncunsigned ParseGrp7(RTUINTPTR uCodePtr, PCDISOPCODE pOp, PDISOPPARAM pParam, PDISCPUSTATE pCpu)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pOp = (PCDISOPCODE)&g_aMapX86_Group7_mod11_rm000[reg];
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pOp = (PCDISOPCODE)&g_aMapX86_Group7_mod11_rm001[reg];
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync //little hack to make sure the ModRM byte is included in the returned size
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (pOp->idxParse1 != IDX_ParseModRM && pOp->idxParse2 != IDX_ParseModRM)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync//*****************************************************************************
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync//*****************************************************************************
105b1a31b6037dbe14acb8d09e60da540885202bvboxsyncunsigned ParseGrp8(RTUINTPTR uCodePtr, PCDISOPCODE pOp, PDISOPPARAM pParam, PDISCPUSTATE pCpu)
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//*****************************************************************************
105b1a31b6037dbe14acb8d09e60da540885202bvboxsync//*****************************************************************************
105b1a31b6037dbe14acb8d09e60da540885202bvboxsyncunsigned ParseGrp9(RTUINTPTR uCodePtr, PCDISOPCODE pOp, PDISOPPARAM pParam, PDISCPUSTATE pCpu)
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//*****************************************************************************
9cdd4d805ecb43126372f7cf12e4032836cb738avboxsync//*****************************************************************************
9cdd4d805ecb43126372f7cf12e4032836cb738avboxsyncunsigned ParseGrp10(RTUINTPTR uCodePtr, PCDISOPCODE pOp, PDISOPPARAM pParam, PDISCPUSTATE pCpu)
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//*****************************************************************************
9cdd4d805ecb43126372f7cf12e4032836cb738avboxsyncunsigned ParseGrp12(RTUINTPTR uCodePtr, PCDISOPCODE pOp, PDISOPPARAM pParam, PDISCPUSTATE pCpu)
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)
9cdd4d805ecb43126372f7cf12e4032836cb738avboxsync//*****************************************************************************
9cdd4d805ecb43126372f7cf12e4032836cb738avboxsync//*****************************************************************************
9cdd4d805ecb43126372f7cf12e4032836cb738avboxsyncunsigned ParseGrp13(RTUINTPTR uCodePtr, PCDISOPCODE pOp, PDISOPPARAM pParam, PDISCPUSTATE pCpu)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync //little hack to make sure the ModRM byte is included in the returned size
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (pOp->idxParse1 != IDX_ParseModRM && pOp->idxParse2 != IDX_ParseModRM)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync//*****************************************************************************
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync//*****************************************************************************
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncunsigned ParseGrp14(RTUINTPTR uCodePtr, PCDISOPCODE pOp, PDISOPPARAM pParam, PDISCPUSTATE pCpu)
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)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync//*****************************************************************************
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync//*****************************************************************************
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncunsigned ParseGrp15(RTUINTPTR uCodePtr, PCDISOPCODE pOp, PDISOPPARAM pParam, PDISCPUSTATE pCpu)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pOp = (PCDISOPCODE)&g_aMapX86_Group15_mod11_rm000[reg];
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync //little hack to make sure the ModRM byte is included in the returned size
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (pOp->idxParse1 != IDX_ParseModRM && pOp->idxParse2 != IDX_ParseModRM)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync//*****************************************************************************
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync//*****************************************************************************
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncunsigned ParseGrp16(RTUINTPTR uCodePtr, PCDISOPCODE pOp, PDISOPPARAM pParam, PDISCPUSTATE pCpu)
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)
73ba84f95f918cc170be38908ad240fbb2f8f354vboxsync//*****************************************************************************
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"};
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)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync subtype = (pCpu->uAddrMode == DISCPUMODE_64BIT) ? OP_PARM_q : OP_PARM_d;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (subtype == OP_PARM_v || subtype == OP_PARM_NONE)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync /* make gcc happy */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync Assert(idx < (pCpu->fPrefix & DISPREFIX_REX ? 16U : 8U));
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 Assert(idx < (pCpu->fPrefix & DISPREFIX_REX ? 16U : 8U));
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync Assert(idx < (pCpu->fPrefix & DISPREFIX_REX ? 16U : 8U));
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync Log(("disasmModRMReg %x:%x failed!!\n", type, subtype));
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync//*****************************************************************************
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync//*****************************************************************************
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncstatic void disasmModRMReg16(PDISCPUSTATE pCpu, PCDISOPCODE pOp, unsigned idx, PDISOPPARAM pParam)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync//*****************************************************************************
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync//*****************************************************************************
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncstatic void disasmModRMSReg(PDISCPUSTATE pCpu, PCDISOPCODE pOp, unsigned idx, PDISOPPARAM pParam)
6d9d4a12f6f9f341c968f711765c2c17c9a5a28cvboxsync * Slow path for storing instruction bytes.
6d9d4a12f6f9f341c968f711765c2c17c9a5a28cvboxsync * @param pCpu The disassembler state.
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * @param uAddress The address.
6d9d4a12f6f9f341c968f711765c2c17c9a5a28cvboxsync * @param pbSrc The bytes.
0cb5af53de7aed97b1b35311f93de8175756e4afvboxsync * @param cbSrc The number of bytes.
0cb5af53de7aed97b1b35311f93de8175756e4afvboxsyncdisStoreInstrBytesSlow(PDISCPUSTATE pCpu, RTUINTPTR uAddress, const uint8_t *pbSrc, size_t cbSrc)
0cb5af53de7aed97b1b35311f93de8175756e4afvboxsync * Figure out which case it is.
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. */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync /* Only partially re-reading stuff, skip ahead and add the rest. */
6d9d4a12f6f9f341c968f711765c2c17c9a5a28cvboxsync Assert(memcmp(&pCpu->abInstr[off], pbSrc, cbAlreadyRead) == 0);
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 /* 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 int rc = pCpu->pfnReadBytes(pCpu, &pCpu->abInstr[cbInstr], uAddress - cbGap, cbGap);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * Copy the bytes.
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync AssertMsgFailed(("%RTptr LB %zx off=%RTptr (%.*Rhxs)", uAddress, cbSrc, off, sizeof(pCpu->abInstr), pCpu->abInstr));
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncDECLCALLBACK(int) disReadBytesDefault(PDISCPUSTATE pCpu, uint8_t *pbDst, RTUINTPTR uSrcAddr, uint32_t cbToRead)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync AssertMsgFailed(("disReadWord with no read callback in ring 0!!\n"));
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync memcpy(pbDst, (void const *)(uintptr_t)uSrcAddr, cbToRead);
9cdd4d805ecb43126372f7cf12e4032836cb738avboxsync//*****************************************************************************
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync/* Read functions for getting the opcode bytes */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync//*****************************************************************************
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncuint8_t disReadByte(PDISCPUSTATE pCpu, RTUINTPTR uAddress)
9cdd4d805ecb43126372f7cf12e4032836cb738avboxsync int rc = pCpu->pfnReadBytes(pCpu, &bTemp, uAddress, sizeof(bTemp));
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 disStoreInstrBytesSlow(pCpu, uAddress, &bTemp, sizeof(bTemp));
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync//*****************************************************************************
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync//*****************************************************************************
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncuint16_t disReadWord(PDISCPUSTATE pCpu, RTUINTPTR uAddress)
73ba84f95f918cc170be38908ad240fbb2f8f354vboxsync int rc = pCpu->pfnReadBytes(pCpu, uTemp.au8, uAddress, sizeof(uTemp));
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (RT_LIKELY( pCpu->uInstrAddr + pCpu->cbInstr == uAddress
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync && pCpu->cbInstr + sizeof(uTemp) < sizeof(pCpu->abInstr)))
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync disStoreInstrBytesSlow(pCpu, uAddress, uTemp.au8, sizeof(uTemp));
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync//*****************************************************************************
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync//*****************************************************************************
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncuint32_t disReadDWord(PDISCPUSTATE pCpu, RTUINTPTR uAddress)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync int rc = pCpu->pfnReadBytes(pCpu, uTemp.au8, uAddress, sizeof(uTemp));
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (RT_LIKELY( pCpu->uInstrAddr + pCpu->cbInstr == uAddress
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync && pCpu->cbInstr + sizeof(uTemp) < sizeof(pCpu->abInstr)))
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync disStoreInstrBytesSlow(pCpu, uAddress, uTemp.au8, sizeof(uTemp));
d64aa881df34a86dd70ab0e1b7b94ffa41be9731vboxsync//*****************************************************************************
d64aa881df34a86dd70ab0e1b7b94ffa41be9731vboxsync//*****************************************************************************
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncuint64_t disReadQWord(PDISCPUSTATE pCpu, RTUINTPTR uAddress)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync int rc = pCpu->pfnReadBytes(pCpu, uTemp.au8, uAddress, sizeof(uTemp));
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (RT_LIKELY( pCpu->uInstrAddr + pCpu->cbInstr == uAddress
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync && pCpu->cbInstr + sizeof(uTemp) < sizeof(pCpu->abInstr)))
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync disStoreInstrBytesSlow(pCpu, uAddress, uTemp.au8, sizeof(uTemp));
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * Validates the lock sequence.
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * The AMD manual lists the following instructions:
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * CMPXCHG8B
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * CMPXCHG16B
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * @param pCpu Fully disassembled instruction.
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncstatic void disValidateLockSequence(PDISCPUSTATE pCpu)
d64aa881df34a86dd70ab0e1b7b94ffa41be9731vboxsync * Filter out the valid lock sequences.
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync /* simple: no variations */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync /* simple: /r - reject register destination. */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * Lots of variants but its sufficient to check that param 1
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * is a memory operand.
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (pCpu->param1.fUse & (DISUSE_BASE | DISUSE_INDEX | DISUSE_DISPLACEMENT64 | DISUSE_DISPLACEMENT32
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync | DISUSE_DISPLACEMENT16 | DISUSE_DISPLACEMENT8 | DISUSE_RIPDISPLACEMENT32))
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * Invalid lock sequence, make it a OP_ILLUD2.