DisasmCore.cpp revision a483cdaf39353be16051341f24a8f32baa77c72d
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*******************************************************************************/
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync/*******************************************************************************
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync* Internal Functions *
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync*******************************************************************************/
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncstatic int disInstrWorker(PDISCPUSTATE pCpu, RTUINTPTR uInstrAddr, PCDISOPCODE paOneByteMap, uint32_t *pcbInstr);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncstatic unsigned disParseInstruction(RTUINTPTR uCodePtr, PCDISOPCODE pOp, PDISCPUSTATE pCpu);
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);
3a343ca21a267ec3c54e2317e2ed18fe99b8ebbbvboxsyncstatic uint32_t disReadDWord(PDISCPUSTATE pCpu, RTUINTPTR pAddress);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncstatic uint64_t disReadQWord(PDISCPUSTATE pCpu, RTUINTPTR pAddress);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncstatic DECLCALLBACK(int) disReadBytesDefault(PDISCPUSTATE pCpu, uint8_t *pbDst, RTUINTPTR uSrcAddr, uint32_t cbToRead);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync/** @name Parsers
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync/** Floating point parsing */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync/*******************************************************************************
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync* Global Variables *
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync*******************************************************************************/
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync/** Parser opcode table for full disassembly. */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncstatic PFNDISPARSE const g_apfnFullDisasm[IDX_ParseMax] =
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync/** 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.
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * @returns VBox status code.
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * @param pvInstr Address of the instruction to decode. This is a
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * real address in the current context that can be
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * accessed without faulting. (Consider
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * DISInstrWithReader if this isn't the case.)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * @param enmCpuMode The CPU mode. DISCPUMODE_32BIT, DISCPUMODE_16BIT, or DISCPUMODE_64BIT.
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * @param pfnReadBytes Callback for reading instruction bytes.
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * @param pvUser User argument for the instruction reader. (Ends up in pvUser.)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * @param pCpu Pointer to cpu structure. Will be initialized.
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * @param pcbInstr Where to store the size of the instruction.
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * NULL is allowed. This is also stored in
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * PDISCPUSTATE::cbInstr.
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncDISDECL(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.
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * @returns VBox status code.
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * @param uInstrAddr Address of the instruction to decode. What this means
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * is left to the pfnReadBytes function.
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * @param enmCpuMode The CPU mode. DISCPUMODE_32BIT, DISCPUMODE_16BIT, or DISCPUMODE_64BIT.
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * @param pfnReadBytes Callback for reading instruction bytes.
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * @param fFilter Instruction type filter.
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * @param pvUser User argument for the instruction reader. (Ends up in pvUser.)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * @param pCpu Pointer to CPU structure. With the exception of
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * DISCPUSTATE::pvUser2, the structure will be
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * completely initialized by this API, i.e. no input is
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * taken from it.
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * @param pcbInstr Where to store the size of the instruction. (This
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * is also stored in PDISCPUSTATE::cbInstr.) Optional.
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.
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pCpu->pfnReadBytes = pfnReadBytes ? pfnReadBytes : disReadBytesDefault;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return disInstrWorker(pCpu, uInstrAddr, paOneByteMap, pcbInstr);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * Internal worker for DISInstEx.
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync * @returns VBox status code.
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync * @param pCpu Initialized cpu state.
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync * @param paOneByteMap The one byte opcode map to use.
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync * @param uInstrAddr Instruction address.
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync * @param pcbInstr Where to store the instruction size. Can be NULL.
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsyncstatic int disInstrWorker(PDISCPUSTATE pCpu, RTUINTPTR uInstrAddr, PCDISOPCODE paOneByteMap, uint32_t *pcbInstr)
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync * Parse byte by byte.
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync unsigned iByte = 0;
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync uint8_t codebyte = disReadByte(pCpu, uInstrAddr+iByte);
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync /* Hardcoded assumption about OP_* values!! */
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync /* The REX prefix must precede the opcode byte(s). Any other placement is ignored. */
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync /** Last prefix byte (for SSE2 extension tables); don't include the REX prefix */
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync // segment override prefix byte
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync pCpu->idxSegPrefix = (DISSELREG)(paOneByteMap[codebyte].fParam1 - OP_PARM_REG_SEG_START);
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync /* Segment prefixes for CS, DS, ES and SS are ignored in long mode. */
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync continue; //fetch the next byte
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync // lock prefix byte
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync continue; //fetch the next byte
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync // address size override prefix byte
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync continue; //fetch the next byte
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync // operand size override prefix byte
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync pCpu->uOpMode = DISCPUMODE_16BIT; /* for 32 and 64 bits mode (there is no 32 bits operand size override prefix) */
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync continue; //fetch the next byte
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync // rep and repne are not really prefixes, but we'll treat them as such
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync continue; //fetch the next byte
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync continue; //fetch the next byte
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync /* REX prefix byte */
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync pCpu->fRexPrefix = DISPREFIX_REX_OP_2_FLAGS(paOneByteMap[codebyte].fParam1);
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync pCpu->uOpMode = DISCPUMODE_64BIT; /* overrides size prefix byte */
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync continue; //fetch the next byte
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync cbInc = disParseInstruction(uInstrAddr + iByte, &paOneByteMap[pCpu->bOpCode], pCpu);
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync 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 if (pOp->fOpType & DISOPTYPE_FORCED_32_OP_SIZE_X86)
9cdd4d805ecb43126372f7cf12e4032836cb738avboxsync /* 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 */
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync /* Note: redundant, but just in case this ever changes */
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync if ( (fpop->fOpType & DISOPTYPE_DEFAULT_64_OP_SIZE)
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync // Little hack to make sure the ModRM byte is included in the returned size
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync if (fpop->idxParse1 != IDX_ParseModRM && fpop->idxParse2 != IDX_ParseModRM)
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync size += pCpu->pfnDisasmFnTable[fpop->idxParse1](uCodePtr+size, (PCDISOPCODE)fpop, pParam, pCpu);
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync 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)
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsyncstatic const char *szSIBScale[4] = {"", "*2", "*4", "*8"};
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync//*****************************************************************************
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsyncvoid UseSIB(RTUINTPTR uCodePtr, PCDISOPCODE pOp, PDISOPPARAM pParam, PDISCPUSTATE pCpu)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync // [scaled index] + disp32
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync { /* sign-extend to 64 bits */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return; /* Already fetched everything in ParseSIB; no size returned */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync//*****************************************************************************
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync//*****************************************************************************
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncunsigned ParseSIB(RTUINTPTR uCodePtr, PCDISOPCODE pOp, PDISOPPARAM pParam, PDISCPUSTATE pCpu)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync /* REX.B extends the Base field if not scaled index + disp32 */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (!(pCpu->SIB.Bits.Base == 5 && pCpu->ModRM.Bits.Mod == 0))
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pCpu->SIB.Bits.Base |= ((!!(pCpu->fRexPrefix & DISPREFIX_REX_FLAGS_B)) << 3);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pCpu->SIB.Bits.Index |= ((!!(pCpu->fRexPrefix & DISPREFIX_REX_FLAGS_X)) << 3);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync /* Additional 32 bits displacement. No change in long mode. */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync//*****************************************************************************
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync//*****************************************************************************
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncunsigned ParseSIB_SizeOnly(RTUINTPTR uCodePtr, PCDISOPCODE pOp, PDISOPPARAM pParam, PDISCPUSTATE pCpu)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync /* REX.B extends the Base field. */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pCpu->SIB.Bits.Base |= ((!!(pCpu->fRexPrefix & DISPREFIX_REX_FLAGS_B)) << 3);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync /* REX.X extends the Index field. */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pCpu->SIB.Bits.Index |= ((!!(pCpu->fRexPrefix & DISPREFIX_REX_FLAGS_X)) << 3);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync /* Additional 32 bits displacement. No change in long mode. */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync//*****************************************************************************
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync// ModR/M byte:
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync// 7 - 6 5 - 3 2-0
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync//*****************************************************************************
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncunsigned 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)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync//*****************************************************************************
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncunsigned 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 */
4c98b8b05f3783351cf256cc90cd4478fb28b62bvboxsync pCpu->i32SibDisp = (int8_t)disReadByte(pCpu, uCodePtr);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync size += sizeof(char);
4c98b8b05f3783351cf256cc90cd4478fb28b62bvboxsync case 2: /* Effective address + 32 bits displacement */
4c98b8b05f3783351cf256cc90cd4478fb28b62bvboxsync /* 16 bits mode */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync case 0: /* Effective address */
4c98b8b05f3783351cf256cc90cd4478fb28b62bvboxsync /* else register address */
4c98b8b05f3783351cf256cc90cd4478fb28b62bvboxsync case 1: /* Effective address + 8 bits displacement */
4c98b8b05f3783351cf256cc90cd4478fb28b62bvboxsync pCpu->i32SibDisp = (int8_t)disReadByte(pCpu, uCodePtr);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync size += sizeof(char);
4c98b8b05f3783351cf256cc90cd4478fb28b62bvboxsync case 2: /* Effective address + 32 bits displacement */
4c98b8b05f3783351cf256cc90cd4478fb28b62bvboxsync pCpu->i32SibDisp = (int16_t)disReadWord(pCpu, uCodePtr);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync//*****************************************************************************
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync// Query the size of the ModRM parameters and fetch the immediate data (if any)
4c98b8b05f3783351cf256cc90cd4478fb28b62bvboxsync//*****************************************************************************
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncunsigned QueryModRM_SizeOnly(RTUINTPTR uCodePtr, PCDISOPCODE pOp, PDISOPPARAM pParam, PDISCPUSTATE pCpu, unsigned *pSibInc)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync 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.
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync /* 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);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync//*****************************************************************************
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync//*****************************************************************************
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncunsigned ParseModRM_SizeOnly(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.
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync /* 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_SizeOnly(uCodePtr, pOp, pParam, pCpu, &sibinc);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync /* UseModRM is not necessary here; we're only interested in the opcode size */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync//*****************************************************************************
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync//*****************************************************************************
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncunsigned ParseModFence(RTUINTPTR uCodePtr, PCDISOPCODE pOp, PDISOPPARAM pParam, PDISCPUSTATE pCpu)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync ////AssertMsgFailed(("??\n"));
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync //nothing to do apparently
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync NOREF(uCodePtr); NOREF(pOp); NOREF(pParam); NOREF(pCpu);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync//*****************************************************************************
e6ad2e18e663b076aeabfec994947514566a7accvboxsync//*****************************************************************************
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncunsigned ParseImmByte(RTUINTPTR uCodePtr, PCDISOPCODE pOp, PDISOPPARAM pParam, PDISCPUSTATE pCpu)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return sizeof(uint8_t);
e6ad2e18e663b076aeabfec994947514566a7accvboxsync//*****************************************************************************
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync//*****************************************************************************
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncunsigned ParseImmByte_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 ParseImmByteSX(RTUINTPTR uCodePtr, PCDISOPCODE pOp, PDISOPPARAM pParam, PDISCPUSTATE pCpu)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pParam->uValue = (uint32_t)(int8_t)disReadByte(pCpu, uCodePtr);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pParam->uValue = (uint64_t)(int8_t)disReadByte(pCpu, uCodePtr);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pParam->uValue = (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)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return sizeof(uint32_t);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync//*****************************************************************************
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);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync//*****************************************************************************
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync//*****************************************************************************
e6ad2e18e663b076aeabfec994947514566a7accvboxsyncunsigned ParseImmQword(RTUINTPTR uCodePtr, PCDISOPCODE pOp, PDISOPPARAM pParam, PDISCPUSTATE pCpu)
e6ad2e18e663b076aeabfec994947514566a7accvboxsync return sizeof(uint64_t);
e6ad2e18e663b076aeabfec994947514566a7accvboxsync//*****************************************************************************
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync//*****************************************************************************
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncunsigned ParseImmQword_SizeOnly(RTUINTPTR uCodePtr, PCDISOPCODE pOp, PDISOPPARAM pParam, PDISCPUSTATE pCpu)
e6ad2e18e663b076aeabfec994947514566a7accvboxsync 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//*****************************************************************************
c58dc77ef4af214d7ae06910fa5ab18587d2ae08vboxsync//*****************************************************************************
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//*****************************************************************************
e6ad2e18e663b076aeabfec994947514566a7accvboxsyncunsigned 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->uValue = (uint64_t)(int32_t)disReadDWord(pCpu, uCodePtr);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return sizeof(uint32_t);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync//*****************************************************************************
9cdd4d805ecb43126372f7cf12e4032836cb738avboxsync//*****************************************************************************
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)
e6ad2e18e663b076aeabfec994947514566a7accvboxsync return sizeof(int32_t);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync /* 32 bits relative immediate sign extended to 64 bits. */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pParam->uValue = (uint64_t)(int32_t)disReadDWord(pCpu, uCodePtr);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync 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//*****************************************************************************
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync//*****************************************************************************
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncunsigned ParseImmAddr(RTUINTPTR uCodePtr, PCDISOPCODE pOp, PDISOPPARAM pParam, PDISCPUSTATE pCpu)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync /* far 16:32 pointer */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync *((uint32_t*)&pParam->uValue+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->fParam) != 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);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync//*****************************************************************************
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync//*****************************************************************************
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncunsigned ParseImmAddr_SizeOnly(RTUINTPTR uCodePtr, PCDISOPCODE pOp, PDISOPPARAM pParam, PDISCPUSTATE pCpu)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {// far 16:32 pointer
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {// near 32 bits pointer
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return sizeof(uint32_t);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync Assert(OP_PARM_VSUBTYPE(pParam->fParam) != OP_PARM_p);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return sizeof(uint64_t);
eb2d4958f7faf812c3bdb2d7587d815022f0bd55vboxsync {// far 16:16 pointer
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return sizeof(uint32_t);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {// near 16 bits pointer
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return sizeof(uint16_t);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync//*****************************************************************************
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync//*****************************************************************************
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncunsigned ParseImmAddrF(RTUINTPTR uCodePtr, PCDISOPCODE pOp, PDISOPPARAM pParam, PDISCPUSTATE pCpu)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync // immediate far pointers - only 16:16 or 16:32; determined by operand, *not* address size!
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync Assert(pCpu->uOpMode == DISCPUMODE_16BIT || pCpu->uOpMode == DISCPUMODE_32BIT);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync Assert(OP_PARM_VSUBTYPE(pParam->fParam) == OP_PARM_p);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync // far 16:32 pointer
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync *((uint32_t*)&pParam->uValue+1) = disReadWord(pCpu, uCodePtr+sizeof(uint32_t));
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync // far 16:16 pointer
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return sizeof(uint32_t);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync//*****************************************************************************
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync//*****************************************************************************
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncunsigned ParseImmAddrF_SizeOnly(RTUINTPTR uCodePtr, PCDISOPCODE pOp, PDISOPPARAM pParam, PDISCPUSTATE pCpu)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync // immediate far pointers - only 16:16 or 16:32
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync Assert(pCpu->uOpMode == DISCPUMODE_16BIT || pCpu->uOpMode == DISCPUMODE_32BIT);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync Assert(OP_PARM_VSUBTYPE(pParam->fParam) == OP_PARM_p);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync // far 16:32 pointer
e6ad2e18e663b076aeabfec994947514566a7accvboxsync // far 16:16 pointer
e6ad2e18e663b076aeabfec994947514566a7accvboxsync return sizeof(uint32_t);
441b60f8b0601cc1718368c9c3ef082223ad12a2vboxsync//*****************************************************************************
441b60f8b0601cc1718368c9c3ef082223ad12a2vboxsync//*****************************************************************************
441b60f8b0601cc1718368c9c3ef082223ad12a2vboxsyncunsigned ParseFixedReg(RTUINTPTR uCodePtr, PCDISOPCODE pOp, PDISOPPARAM pParam, PDISCPUSTATE pCpu)
441b60f8b0601cc1718368c9c3ef082223ad12a2vboxsync * 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->fParam - OP_PARM_REG_GEN32_START;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync /* Use 64-bit registers. */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pParam->base.reg_gen = pParam->fParam - OP_PARM_REG_GEN32_START;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync && pParam == &pCpu->Param1 /* ugly assumption that it only applies to the first parameter */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync /* Use 16-bit registers. */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pParam->base.reg_gen = pParam->fParam - OP_PARM_REG_GEN32_START;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pParam->fParam = pParam->fParam - OP_PARM_REG_GEN32_START + OP_PARM_REG_GEN16_START;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync /* Segment ES..GS registers. */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pParam->base.reg_seg = (DISSELREG)(pParam->fParam - OP_PARM_REG_SEG_START);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync /* 16-bit AX..DI registers. */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pParam->base.reg_gen = pParam->fParam - OP_PARM_REG_GEN16_START;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync /* 8-bit AL..DL, AH..DH registers. */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pParam->base.reg_gen = pParam->fParam - OP_PARM_REG_GEN8_START;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync && pParam == &pCpu->Param1 /* ugly assumption that it only applies to the first parameter */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pParam->base.reg_gen += 8; /* least significant byte of R8-R15 */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync /* FPU registers. */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pParam->base.reg_fp = pParam->fParam - OP_PARM_REG_FP_START;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync Assert(!(pParam->fParam >= OP_PARM_REG_GEN64_START && pParam->fParam <= 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??? */
9cdd4d805ecb43126372f7cf12e4032836cb738avboxsync if (g_aTwoByteMapX86_PF66[pCpu->bOpCode].uOpcode != OP_INVALID)
9cdd4d805ecb43126372f7cf12e4032836cb738avboxsync /* Table entry is valid, so use the extension table. */
9cdd4d805ecb43126372f7cf12e4032836cb738avboxsync /* Cancel prefix changes. */
9cdd4d805ecb43126372f7cf12e4032836cb738avboxsync if (g_aTwoByteMapX86_PFF2[pCpu->bOpCode].uOpcode != OP_INVALID)
9cdd4d805ecb43126372f7cf12e4032836cb738avboxsync /* Table entry is valid, so use the extension table. */
9cdd4d805ecb43126372f7cf12e4032836cb738avboxsync /* Cancel prefix changes. */
9cdd4d805ecb43126372f7cf12e4032836cb738avboxsync if (g_aTwoByteMapX86_PFF3[pCpu->bOpCode].uOpcode != OP_INVALID)
9cdd4d805ecb43126372f7cf12e4032836cb738avboxsync /* Table entry is valid, so use the extension table. */
9cdd4d805ecb43126372f7cf12e4032836cb738avboxsync /* 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??? */
3a343ca21a267ec3c54e2317e2ed18fe99b8ebbbvboxsync if (g_apThreeByteMapX86_660F38[pCpu->bOpCode >> 4])
3a343ca21a267ec3c54e2317e2ed18fe99b8ebbbvboxsync pOpcode = g_apThreeByteMapX86_660F38[pCpu->bOpCode >> 4];
3a343ca21a267ec3c54e2317e2ed18fe99b8ebbbvboxsync /* Table entry is valid, so use the extension table. */
3a343ca21a267ec3c54e2317e2ed18fe99b8ebbbvboxsync /* Cancel prefix changes. */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (g_apThreeByteMapX86_F20F38[pCpu->bOpCode >> 4])
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pOpcode = g_apThreeByteMapX86_F20F38[pCpu->bOpCode >> 4];
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync /* Table entry is valid, so use the extension table. */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync /* Cancel prefix changes. */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync size += disParseInstruction(uCodePtr+size, pOpcode, pCpu);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync//*****************************************************************************
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync//*****************************************************************************
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncunsigned ParseThreeByteEsc5(RTUINTPTR uCodePtr, PCDISOPCODE pOp, PDISOPPARAM pParam, PDISCPUSTATE pCpu)
9cdd4d805ecb43126372f7cf12e4032836cb738avboxsync /* 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. */
9cdd4d805ecb43126372f7cf12e4032836cb738avboxsync if (g_apThreeByteMapX86_660F3A[pCpu->bOpCode >> 4])
9cdd4d805ecb43126372f7cf12e4032836cb738avboxsync pOpcode = g_apThreeByteMapX86_660F3A[pCpu->bOpCode >> 4];
9cdd4d805ecb43126372f7cf12e4032836cb738avboxsync /* Table entry is valid, so use the extension table. */
9cdd4d805ecb43126372f7cf12e4032836cb738avboxsync /* Cancel prefix changes. */
9cdd4d805ecb43126372f7cf12e4032836cb738avboxsync size += disParseInstruction(uCodePtr+size, pOpcode, pCpu);
9cdd4d805ecb43126372f7cf12e4032836cb738avboxsync//*****************************************************************************
9cdd4d805ecb43126372f7cf12e4032836cb738avboxsync//*****************************************************************************
9cdd4d805ecb43126372f7cf12e4032836cb738avboxsyncunsigned ParseNopPause(RTUINTPTR uCodePtr, PCDISOPCODE pOp, PDISOPPARAM pParam, PDISCPUSTATE pCpu)
9cdd4d805ecb43126372f7cf12e4032836cb738avboxsync unsigned size = 0;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync//*****************************************************************************
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync//*****************************************************************************
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncunsigned ParseImmGrpl(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 ParseShiftGrp2(RTUINTPTR uCodePtr, PCDISOPCODE pOp, PDISOPPARAM pParam, PDISCPUSTATE pCpu)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return sizeof(uint8_t);
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 ParseGrp3(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 ParseGrp4(RTUINTPTR uCodePtr, PCDISOPCODE pOp, PDISOPPARAM pParam, PDISCPUSTATE pCpu)
3a343ca21a267ec3c54e2317e2ed18fe99b8ebbbvboxsync //little hack to make sure the ModRM byte is included in the returned size
3a343ca21a267ec3c54e2317e2ed18fe99b8ebbbvboxsync if (pOp->idxParse1 != IDX_ParseModRM && pOp->idxParse2 != IDX_ParseModRM)
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
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync modrmsize = QueryModRM(uCodePtr+sizeof(uint8_t), pOp, pParam, pCpu);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync uint8_t opcode = disReadByte(pCpu, uCodePtr+sizeof(uint8_t)+modrmsize);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pOp = (PCDISOPCODE)&g_aTwoByteMapX86_3DNow[opcode];
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#ifdef DEBUG_Sander /* bird, 2005-06-28: Alex is getting this during full installation of win2ksp4. */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync//*****************************************************************************
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync//*****************************************************************************
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncunsigned 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)
6d9d4a12f6f9f341c968f711765c2c17c9a5a28cvboxsync//*****************************************************************************
6d9d4a12f6f9f341c968f711765c2c17c9a5a28cvboxsync//*****************************************************************************
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncunsigned ParseGrp8(RTUINTPTR uCodePtr, PCDISOPCODE pOp, PDISOPPARAM pParam, PDISCPUSTATE pCpu)
0cb5af53de7aed97b1b35311f93de8175756e4afvboxsync //little hack to make sure the ModRM byte is included in the returned size
0cb5af53de7aed97b1b35311f93de8175756e4afvboxsync if (pOp->idxParse1 != IDX_ParseModRM && pOp->idxParse2 != IDX_ParseModRM)
6d9d4a12f6f9f341c968f711765c2c17c9a5a28cvboxsync//*****************************************************************************
6d9d4a12f6f9f341c968f711765c2c17c9a5a28cvboxsync//*****************************************************************************
6d9d4a12f6f9f341c968f711765c2c17c9a5a28cvboxsyncunsigned ParseGrp9(RTUINTPTR uCodePtr, PCDISOPCODE pOp, PDISOPPARAM pParam, PDISCPUSTATE pCpu)
6d9d4a12f6f9f341c968f711765c2c17c9a5a28cvboxsync //little hack to make sure the ModRM byte is included in the returned size
6d9d4a12f6f9f341c968f711765c2c17c9a5a28cvboxsync if (pOp->idxParse1 != IDX_ParseModRM && pOp->idxParse2 != IDX_ParseModRM)
6d9d4a12f6f9f341c968f711765c2c17c9a5a28cvboxsync//*****************************************************************************
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync//*****************************************************************************
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncunsigned ParseGrp10(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 ParseGrp12(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)
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
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync 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)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync//*****************************************************************************
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncstatic const char *szModRMReg8[] = {"AL", "CL", "DL", "BL", "AH", "CH", "DH", "BH", "R8B", "R9B", "R10B", "R11B", "R12B", "R13B", "R14B", "R15B", "SPL", "BPL", "SIL", "DIL"};
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncstatic const char *szModRMReg16[] = {"AX", "CX", "DX", "BX", "SP", "BP", "SI", "DI", "R8W", "R9W", "R10W", "R11W", "R12W", "R13W", "R14W", "R15W"};
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncstatic const char *szModRMReg32[] = {"EAX", "ECX", "EDX", "EBX", "ESP", "EBP", "ESI", "EDI", "R8D", "R9D", "R10D", "R11D", "R12D", "R13D", "R14D", "R15D"};
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncstatic const char *szModRMReg64[] = {"RAX", "RCX", "RDX", "RBX", "RSP", "RBP", "RSI", "RDI", "R8", "R9", "R10", "R11", "R12", "R13", "R14", "R15"};
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncstatic const char *szModRMReg1616[8] = {"BX+SI", "BX+DI", "BP+SI", "BP+DI", "SI", "DI", "BP", "BX"};
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncstatic const char *szModRMSegReg[6] = {"ES", "CS", "SS", "DS", "FS", "GS"};
d64aa881df34a86dd70ab0e1b7b94ffa41be9731vboxsyncstatic const int BaseModRMReg16[8] = { DISGREG_BX, DISGREG_BX, DISGREG_BP, DISGREG_BP, DISGREG_SI, DISGREG_DI, DISGREG_BP, DISGREG_BX};
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncstatic const int IndexModRMReg16[4] = { DISGREG_SI, DISGREG_DI, DISGREG_SI, DISGREG_DI};
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync//*****************************************************************************
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncstatic void disasmModRMReg(PDISCPUSTATE pCpu, PCDISOPCODE pOp, unsigned idx, PDISOPPARAM pParam, int fRegAddr)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync unsigned subtype = OP_PARM_VSUBTYPE(pParam->fParam);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync subtype = (pCpu->uAddrMode == DISCPUMODE_64BIT) ? OP_PARM_q : OP_PARM_d;
d64aa881df34a86dd70ab0e1b7b94ffa41be9731vboxsync if (subtype == OP_PARM_v || subtype == OP_PARM_NONE)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync /* make gcc happy */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync Assert(idx < (pCpu->fPrefix & DISPREFIX_REX ? 16U : 8U));
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync /* AH, BH, CH & DH map to DIL, SIL, EBL & SPL when a rex prefix is present. */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync /* Intel� 64 and IA-32 Architectures Software Developer�s Manual: 3.4.1.1 */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync 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)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * Slow path for storing instruction bytes.
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * @param pCpu The disassembler state.
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * @param uAddress The address.
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * @param pbSrc The bytes.
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * @param cbSrc The number of bytes.
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncdisStoreInstrBytesSlow(PDISCPUSTATE pCpu, RTUINTPTR uAddress, const uint8_t *pbSrc, size_t cbSrc)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * Figure out which case it is.
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync AssertMsg(memcmp(&pCpu->abInstr[off], pbSrc, cbSrc) == 0,
a21a14c99f2698c3a8b6dc0a3086e087701fe719vboxsync ("%RTptr LB %zx off=%RTptr (%.*Rhxs)", uAddress, cbSrc, off, cbInstr, pCpu->abInstr));
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return; /* fully re-reading old stuff. */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync /* Only partially re-reading stuff, skip ahead and add the rest. */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync Assert(memcmp(&pCpu->abInstr[off], pbSrc, cbAlreadyRead) == 0);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync /* The instruction is too long! This shouldn't happen. */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync AssertMsgFailed(("%RTptr LB %zx off=%RTptr (%.*Rhxs)", uAddress, cbSrc, off, cbInstr, pCpu->abInstr));
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync /* Mind the gap - this shouldn't happen, but read the gap bytes if it does. */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync AssertMsgFailed(("%RTptr LB %zx off=%RTptr (%.16Rhxs)", uAddress, cbSrc, off, cbInstr, pCpu->abInstr));
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync 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);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync//*****************************************************************************
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync/* Read functions for getting the opcode bytes */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync//*****************************************************************************
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncuint8_t disReadByte(PDISCPUSTATE pCpu, RTUINTPTR uAddress)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync 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)
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//*****************************************************************************
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync//*****************************************************************************
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncuint32_t disReadDWord(PDISCPUSTATE pCpu, RTUINTPTR uAddress)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync int rc = pCpu->pfnReadBytes(pCpu, uTemp.au8, uAddress, sizeof(uTemp));
a21a14c99f2698c3a8b6dc0a3086e087701fe719vboxsync if (RT_LIKELY( pCpu->uInstrAddr + pCpu->cbInstr == uAddress
a21a14c99f2698c3a8b6dc0a3086e087701fe719vboxsync && pCpu->cbInstr + sizeof(uTemp) < sizeof(pCpu->abInstr)))
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync disStoreInstrBytesSlow(pCpu, uAddress, uTemp.au8, sizeof(uTemp));
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync//*****************************************************************************
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync//*****************************************************************************
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.
9cdd4d805ecb43126372f7cf12e4032836cb738avboxsync * The AMD manual lists the following instructions:
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * CMPXCHG8B
9cdd4d805ecb43126372f7cf12e4032836cb738avboxsync * CMPXCHG16B
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * @param pCpu Fully disassembled instruction.
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncstatic void disValidateLockSequence(PDISCPUSTATE pCpu)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * 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.