cidet-core.cpp revision fdf66bdf7b03d58ec33dbc065f2d28e1f7d4986a
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync/* $Id$ */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync/** @file
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * CPU Instruction Decoding & Execution Tests - Simple Instructions.
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync/*
c7814cf6e1240a519cbec0441e033d0e2470ed00vboxsync * Copyright (C) 2014 Oracle Corporation
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync *
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * available from http://www.virtualbox.org. This file is free software;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * you can redistribute it and/or modify it under the terms of the GNU
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * General Public License (GPL) as published by the Free Software
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * Foundation, in version 2 as it comes in the "COPYING" file of the
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync *
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * The contents of this file may alternatively be used under the terms
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * of the Common Development and Distribution License Version 1.0
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * VirtualBox OSE distribution, in which case the provisions of the
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * CDDL are applicable instead of those of the GPL.
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync *
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * You may elect to license modified versions of this file under the
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * terms and conditions of either the GPL or the CDDL or both.
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync/*******************************************************************************
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync* Defined Constants And Macros *
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync*******************************************************************************/
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync#define CIDET_INSTR_TEST_OP_FLAG(a_pInstr, a_fFlag) \
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync ( ((a_pInstr)->afOperands[0] & (a_fFlag)) \
3fa7a7e633f46a212052b510cdb8cee41f279a67vboxsync || ((a_pInstr)->afOperands[1] & (a_fFlag)) \
3fa7a7e633f46a212052b510cdb8cee41f279a67vboxsync || ( (a_pInstr)->cOperands > 2 \
11f8b3da5f2ead2461e7998b3b091bb0f7bd14d9vboxsync && ( ((a_pInstr)->afOperands[2] & (a_fFlag)) \
cb0578a5309e1fc264e5a4acc30543bea075be43vboxsync || ((a_pInstr)->afOperands[3] & (a_fFlag)) ) ) )
384478d3896257fbce9ceb8c01e74040b969e6d7vboxsync
73ba84f95f918cc170be38908ad240fbb2f8f354vboxsync#define CIDET_INSTR_TEST_OP_MASK_VALUE(a_pInstr, a_fMask, a_fValue) \
73ba84f95f918cc170be38908ad240fbb2f8f354vboxsync ( ((a_pInstr)->afOperands[0] & (a_fMask)) == (a_fValue) \
73ba84f95f918cc170be38908ad240fbb2f8f354vboxsync || ((a_pInstr)->afOperands[1] & (a_fMask)) == (a_fValue) \
384478d3896257fbce9ceb8c01e74040b969e6d7vboxsync || ( (a_pInstr)->cOperands > 2 \
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync && ( ((a_pInstr)->afOperands[2] & (a_fMask)) == (a_fValue) \
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync || ((a_pInstr)->afOperands[3] & (a_fMask)) == (a_fValue) ) ) )
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync/** @def CIDET_DPRINTF
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * Debug printf. */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync#if 1 //def DEBUG_bird
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync# define CIDET_DPRINTF(a) do { RTPrintf a; } while (0)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync# define CIDET_DPRINTF_ENABLED
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync#else
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync# define CIDET_DPRINTF(a) do { } while (0)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync#endif
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync/** @def CIDET_DEBUG_DISAS
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * Enables instruction disassembly. */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync#if defined(DOXYGEN_RUNNING)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync# define CIDET_DEBUG_DISAS 1
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync#endif
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
1c0d3d017f9a45748b4839bf6622b53e83a4f1f8vboxsync/*******************************************************************************
1c0d3d017f9a45748b4839bf6622b53e83a4f1f8vboxsync* Header Files *
1c0d3d017f9a45748b4839bf6622b53e83a4f1f8vboxsync*******************************************************************************/
1c0d3d017f9a45748b4839bf6622b53e83a4f1f8vboxsync#include "cidet.h"
1c0d3d017f9a45748b4839bf6622b53e83a4f1f8vboxsync
1c0d3d017f9a45748b4839bf6622b53e83a4f1f8vboxsync#include <iprt/assert.h>
1c0d3d017f9a45748b4839bf6622b53e83a4f1f8vboxsync#include <iprt/rand.h>
1c0d3d017f9a45748b4839bf6622b53e83a4f1f8vboxsync#include <iprt/param.h>
1c0d3d017f9a45748b4839bf6622b53e83a4f1f8vboxsync#include <iprt/string.h>
1c0d3d017f9a45748b4839bf6622b53e83a4f1f8vboxsync#include <VBox/err.h>
1c0d3d017f9a45748b4839bf6622b53e83a4f1f8vboxsync#if defined(CIDET_DPRINTF_ENABLED) || defined(CIDET_DEBUG_DISAS)
1c0d3d017f9a45748b4839bf6622b53e83a4f1f8vboxsync# include <VBox/dis.h>
1c0d3d017f9a45748b4839bf6622b53e83a4f1f8vboxsync# include <iprt/stream.h>
1c0d3d017f9a45748b4839bf6622b53e83a4f1f8vboxsync#endif
1c0d3d017f9a45748b4839bf6622b53e83a4f1f8vboxsync
1c0d3d017f9a45748b4839bf6622b53e83a4f1f8vboxsync
1c0d3d017f9a45748b4839bf6622b53e83a4f1f8vboxsync/*******************************************************************************
1c0d3d017f9a45748b4839bf6622b53e83a4f1f8vboxsync* Global Variables *
4a9af9a8062589b741444d717d2dd1ed22b0f583vboxsync*******************************************************************************/
4a9af9a8062589b741444d717d2dd1ed22b0f583vboxsync/** For translating CIDET_OF_Z_XXX values (after shifting). */
4a9af9a8062589b741444d717d2dd1ed22b0f583vboxsyncuint16_t const g_acbCidetOfSizes[] =
4a9af9a8062589b741444d717d2dd1ed22b0f583vboxsync{
4a9af9a8062589b741444d717d2dd1ed22b0f583vboxsync /* [CIDET_OF_Z_NONE] = */ 0,
4a9af9a8062589b741444d717d2dd1ed22b0f583vboxsync /* [CIDET_OF_Z_BYTE] = */ 1,
1c0d3d017f9a45748b4839bf6622b53e83a4f1f8vboxsync /* [CIDET_OF_Z_WORD] = */ 2,
4a9af9a8062589b741444d717d2dd1ed22b0f583vboxsync /* [CIDET_OF_Z_DWORD] = */ 4,
4a9af9a8062589b741444d717d2dd1ed22b0f583vboxsync /* [CIDET_OF_Z_QWORD] = */ 8,
4a9af9a8062589b741444d717d2dd1ed22b0f583vboxsync /* [CIDET_OF_Z_TBYTE] = */ 10,
4a9af9a8062589b741444d717d2dd1ed22b0f583vboxsync /* [CIDET_OF_Z_OWORD] = */ 16,
4a9af9a8062589b741444d717d2dd1ed22b0f583vboxsync /* [CIDET_OF_Z_YWORD] = */ 32,
4a9af9a8062589b741444d717d2dd1ed22b0f583vboxsync /* [CIDET_OF_Z_ZWORD] = */ 64,
4a9af9a8062589b741444d717d2dd1ed22b0f583vboxsync /* [CIDET_OF_Z_VAR_WDQ] = */ UINT16_MAX,
4a9af9a8062589b741444d717d2dd1ed22b0f583vboxsync /* [0xa] = */ 0,
4a9af9a8062589b741444d717d2dd1ed22b0f583vboxsync /* [0xb] = */ 0,
4a9af9a8062589b741444d717d2dd1ed22b0f583vboxsync /* [0xc] = */ 0,
4a9af9a8062589b741444d717d2dd1ed22b0f583vboxsync /* [0xd] = */ 0,
4a9af9a8062589b741444d717d2dd1ed22b0f583vboxsync /* [0xe] = */ 0,
4a9af9a8062589b741444d717d2dd1ed22b0f583vboxsync /* [CIDET_OF_Z_SPECIAL] = */ UINT16_MAX - 1,
4a9af9a8062589b741444d717d2dd1ed22b0f583vboxsync};
4a9af9a8062589b741444d717d2dd1ed22b0f583vboxsync
4a9af9a8062589b741444d717d2dd1ed22b0f583vboxsync
4a9af9a8062589b741444d717d2dd1ed22b0f583vboxsync/** Converts operand sizes in bytes to 64-bit masks. */
4a9af9a8062589b741444d717d2dd1ed22b0f583vboxsyncstatic const uint64_t g_au64ByteSizeToMask[] =
4a9af9a8062589b741444d717d2dd1ed22b0f583vboxsync{
4a9af9a8062589b741444d717d2dd1ed22b0f583vboxsync UINT64_C(0x0000000000000000),
4a9af9a8062589b741444d717d2dd1ed22b0f583vboxsync UINT64_C(0x00000000000000ff),
4a9af9a8062589b741444d717d2dd1ed22b0f583vboxsync UINT64_C(0x000000000000ffff),
4a9af9a8062589b741444d717d2dd1ed22b0f583vboxsync UINT64_C(0x0000000000ffffff),
4a9af9a8062589b741444d717d2dd1ed22b0f583vboxsync UINT64_C(0x00000000ffffffff),
4a9af9a8062589b741444d717d2dd1ed22b0f583vboxsync UINT64_C(0x000000ffffffffff),
4a9af9a8062589b741444d717d2dd1ed22b0f583vboxsync UINT64_C(0x0000ffffffffffff),
4a9af9a8062589b741444d717d2dd1ed22b0f583vboxsync UINT64_C(0x00ffffffffffffff),
4a9af9a8062589b741444d717d2dd1ed22b0f583vboxsync UINT64_C(0xffffffffffffffff),
4a9af9a8062589b741444d717d2dd1ed22b0f583vboxsync};
4a9af9a8062589b741444d717d2dd1ed22b0f583vboxsync
4a9af9a8062589b741444d717d2dd1ed22b0f583vboxsync/** Converts operand sizes in bytes to 64-bit signed max values. */
4a9af9a8062589b741444d717d2dd1ed22b0f583vboxsyncstatic const int64_t g_ai64ByteSizeToMax[] =
4a9af9a8062589b741444d717d2dd1ed22b0f583vboxsync{
4a9af9a8062589b741444d717d2dd1ed22b0f583vboxsync INT64_C(0x0000000000000000),
4a9af9a8062589b741444d717d2dd1ed22b0f583vboxsync INT64_C(0x000000000000007f),
4a9af9a8062589b741444d717d2dd1ed22b0f583vboxsync INT64_C(0x0000000000007fff),
1c0d3d017f9a45748b4839bf6622b53e83a4f1f8vboxsync INT64_C(0x00000000007fffff),
1c0d3d017f9a45748b4839bf6622b53e83a4f1f8vboxsync INT64_C(0x000000007fffffff),
1c0d3d017f9a45748b4839bf6622b53e83a4f1f8vboxsync INT64_C(0x0000007fffffffff),
1c0d3d017f9a45748b4839bf6622b53e83a4f1f8vboxsync INT64_C(0x00007fffffffffff),
1c0d3d017f9a45748b4839bf6622b53e83a4f1f8vboxsync INT64_C(0x007fffffffffffff),
1c0d3d017f9a45748b4839bf6622b53e83a4f1f8vboxsync INT64_C(0x7fffffffffffffff),
1c0d3d017f9a45748b4839bf6622b53e83a4f1f8vboxsync};
1c0d3d017f9a45748b4839bf6622b53e83a4f1f8vboxsync
1c0d3d017f9a45748b4839bf6622b53e83a4f1f8vboxsync
1c0d3d017f9a45748b4839bf6622b53e83a4f1f8vboxsyncbool CidetInstrHasMrmMemOperand(PCCIDETINSTR pInstr)
1c0d3d017f9a45748b4839bf6622b53e83a4f1f8vboxsync{
1c0d3d017f9a45748b4839bf6622b53e83a4f1f8vboxsync return CIDET_INSTR_TEST_OP_FLAG(pInstr, CIDET_OF_M_RM_ONLY_M);
1c0d3d017f9a45748b4839bf6622b53e83a4f1f8vboxsync}
1c0d3d017f9a45748b4839bf6622b53e83a4f1f8vboxsync
1c0d3d017f9a45748b4839bf6622b53e83a4f1f8vboxsync
1c0d3d017f9a45748b4839bf6622b53e83a4f1f8vboxsyncbool CidetInstrHasMrmRegOperand(PCCIDETINSTR pInstr)
1c0d3d017f9a45748b4839bf6622b53e83a4f1f8vboxsync{
1c0d3d017f9a45748b4839bf6622b53e83a4f1f8vboxsync return CIDET_INSTR_TEST_OP_FLAG(pInstr, CIDET_OF_M_RM_ONLY_R);
1c0d3d017f9a45748b4839bf6622b53e83a4f1f8vboxsync}
1c0d3d017f9a45748b4839bf6622b53e83a4f1f8vboxsync
1c0d3d017f9a45748b4839bf6622b53e83a4f1f8vboxsync
1c0d3d017f9a45748b4839bf6622b53e83a4f1f8vboxsyncbool CidetInstrRespondsToOperandSizePrefixes(PCCIDETINSTR pInstr)
1c0d3d017f9a45748b4839bf6622b53e83a4f1f8vboxsync{
1c0d3d017f9a45748b4839bf6622b53e83a4f1f8vboxsync return CIDET_INSTR_TEST_OP_MASK_VALUE(pInstr, CIDET_OF_Z_MASK, CIDET_OF_Z_VAR_WDQ);
1c0d3d017f9a45748b4839bf6622b53e83a4f1f8vboxsync}
1c0d3d017f9a45748b4839bf6622b53e83a4f1f8vboxsync
1c0d3d017f9a45748b4839bf6622b53e83a4f1f8vboxsync
1c0d3d017f9a45748b4839bf6622b53e83a4f1f8vboxsync
1c0d3d017f9a45748b4839bf6622b53e83a4f1f8vboxsync
1c0d3d017f9a45748b4839bf6622b53e83a4f1f8vboxsyncint CidetCoreInit(PCIDETCORE pThis, RTRAND hRand)
1c0d3d017f9a45748b4839bf6622b53e83a4f1f8vboxsync{
1c0d3d017f9a45748b4839bf6622b53e83a4f1f8vboxsync AssertPtr(pThis);
1c0d3d017f9a45748b4839bf6622b53e83a4f1f8vboxsync AssertPtr(hRand);
1c0d3d017f9a45748b4839bf6622b53e83a4f1f8vboxsync
1c0d3d017f9a45748b4839bf6622b53e83a4f1f8vboxsync RT_ZERO(*pThis);
1c0d3d017f9a45748b4839bf6622b53e83a4f1f8vboxsync pThis->u32Magic = CIDETCORE_MAGIC;
1c0d3d017f9a45748b4839bf6622b53e83a4f1f8vboxsync pThis->hRand = hRand;
1c0d3d017f9a45748b4839bf6622b53e83a4f1f8vboxsync return VINF_SUCCESS;
1c0d3d017f9a45748b4839bf6622b53e83a4f1f8vboxsync}
1c0d3d017f9a45748b4839bf6622b53e83a4f1f8vboxsync
1c0d3d017f9a45748b4839bf6622b53e83a4f1f8vboxsync
3a343ca21a267ec3c54e2317e2ed18fe99b8ebbbvboxsyncvoid CidetCoreDelete(PCIDETCORE pThis)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync{
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync AssertPtr(pThis); Assert(pThis->u32Magic == CIDETCORE_MAGIC);
3a343ca21a267ec3c54e2317e2ed18fe99b8ebbbvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync RTRandAdvDestroy(pThis->hRand);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync RT_ZERO(*pThis);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync}
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync/**
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * Report a test failure via CIDET::pfnFailure
3a343ca21a267ec3c54e2317e2ed18fe99b8ebbbvboxsync *
3a343ca21a267ec3c54e2317e2ed18fe99b8ebbbvboxsync * @returns false
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * @param pThis Pointer to the core structure.
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * @param pszFormat Format string containing failure details.
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * @param va Arguments referenced in @a pszFormat.
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncint CidetCoreSetErrorV(PCIDETCORE pThis, const char *pszFormat, va_list va)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync{
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pThis->pfnFailure(pThis, pszFormat, va);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return false;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync}
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync/**
73ba84f95f918cc170be38908ad240fbb2f8f354vboxsync * Report a test failure via CIDET::pfnFailure
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync *
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * @returns false
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * @param pThis Pointer to the core structure.
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * @param pszFormat Format string containing failure details.
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * @param ... Arguments referenced in @a pszFormat.
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncbool CidetCoreSetError(PCIDETCORE pThis, const char *pszFormat, ...)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync{
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync va_list va;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync va_start(va, pszFormat);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync CidetCoreSetErrorV(pThis, pszFormat, va);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync va_end(va);
73ba84f95f918cc170be38908ad240fbb2f8f354vboxsync return false;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync}
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
bdbed0b8e7fb553d01417fdc976a76f3b287dbe2vboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync/**
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * Get a signed random number, with a given number of significant bytes.
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync *
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * @returns Random number.
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * @param pThis Pointer to the core structure.
bdbed0b8e7fb553d01417fdc976a76f3b287dbe2vboxsync * @param cbSignificant The number of significant bytes.
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync */
bdbed0b8e7fb553d01417fdc976a76f3b287dbe2vboxsyncint64_t CidetCoreGetRandS64(PCIDETCORE pThis, uint8_t cbSignificant)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync{
bdbed0b8e7fb553d01417fdc976a76f3b287dbe2vboxsync int64_t iVal = RTRandAdvS64(pThis->hRand);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync switch (cbSignificant)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
bdbed0b8e7fb553d01417fdc976a76f3b287dbe2vboxsync case 1: return (int8_t)iVal;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync case 2: return (int16_t)iVal;
bdbed0b8e7fb553d01417fdc976a76f3b287dbe2vboxsync case 4: return (int32_t)iVal;
bdbed0b8e7fb553d01417fdc976a76f3b287dbe2vboxsync case 8: return iVal;
bdbed0b8e7fb553d01417fdc976a76f3b287dbe2vboxsync default:
bdbed0b8e7fb553d01417fdc976a76f3b287dbe2vboxsync AssertReleaseFailed();
7b4ea63789001468ec3662bdfcd6432bf89095dfvboxsync return iVal;
bdbed0b8e7fb553d01417fdc976a76f3b287dbe2vboxsync }
bdbed0b8e7fb553d01417fdc976a76f3b287dbe2vboxsync}
bdbed0b8e7fb553d01417fdc976a76f3b287dbe2vboxsync
bdbed0b8e7fb553d01417fdc976a76f3b287dbe2vboxsync
bdbed0b8e7fb553d01417fdc976a76f3b287dbe2vboxsync/**
bdbed0b8e7fb553d01417fdc976a76f3b287dbe2vboxsync * Get an unsigned random number, with a given number of significant bytes.
46737b2c6b2da473108a7670c3682d88474bd8b9vboxsync *
bdbed0b8e7fb553d01417fdc976a76f3b287dbe2vboxsync * @returns Random number.
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * @param pThis Pointer to the core structure.
bdbed0b8e7fb553d01417fdc976a76f3b287dbe2vboxsync * @param cbSignificant The number of significant bytes.
3fa7a7e633f46a212052b510cdb8cee41f279a67vboxsync */
3fa7a7e633f46a212052b510cdb8cee41f279a67vboxsyncuint64_t CidetCoreGetRandU64(PCIDETCORE pThis, uint8_t cbSignificant)
bdbed0b8e7fb553d01417fdc976a76f3b287dbe2vboxsync{
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync Assert(cbSignificant == 1 || cbSignificant == 2 || cbSignificant == 4 || cbSignificant == 8);
1389294d44ac76b0a25f5655756c9d39855a73efvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync uint64_t uVal = RTRandAdvU64(pThis->hRand);
73ba84f95f918cc170be38908ad240fbb2f8f354vboxsync uVal &= g_au64ByteSizeToMask[cbSignificant];
73ba84f95f918cc170be38908ad240fbb2f8f354vboxsync
bdbed0b8e7fb553d01417fdc976a76f3b287dbe2vboxsync return uVal;
73ba84f95f918cc170be38908ad240fbb2f8f354vboxsync}
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncvoid CidetCoreInitializeCtxTemplate(PCIDETCORE pThis)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync{
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pThis->InTemplateCtx.rip = UINT64_MAX;
bdbed0b8e7fb553d01417fdc976a76f3b287dbe2vboxsync pThis->InTemplateCtx.rfl = X86_EFL_1 | X86_EFL_ID | X86_EFL_IF;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
bdbed0b8e7fb553d01417fdc976a76f3b287dbe2vboxsync unsigned i = RT_ELEMENTS(pThis->InTemplateCtx.aGRegs);
bdbed0b8e7fb553d01417fdc976a76f3b287dbe2vboxsync if (CIDETMODE_IS_LM(pThis->bMode))
bdbed0b8e7fb553d01417fdc976a76f3b287dbe2vboxsync while (i-- > 0)
bdbed0b8e7fb553d01417fdc976a76f3b287dbe2vboxsync pThis->InTemplateCtx.aGRegs[i] = UINT64_C(0x3fefcc00daba005d)
bdbed0b8e7fb553d01417fdc976a76f3b287dbe2vboxsync | ((uint64_t)i << 32)
bdbed0b8e7fb553d01417fdc976a76f3b287dbe2vboxsync | ((uint32_t)i << 8);
bdbed0b8e7fb553d01417fdc976a76f3b287dbe2vboxsync else
bdbed0b8e7fb553d01417fdc976a76f3b287dbe2vboxsync while (i-- > 0)
bdbed0b8e7fb553d01417fdc976a76f3b287dbe2vboxsync pThis->InTemplateCtx.aGRegs[i] = UINT64_C(0xfada009b)
bdbed0b8e7fb553d01417fdc976a76f3b287dbe2vboxsync | ((uint32_t)i << 12)
bdbed0b8e7fb553d01417fdc976a76f3b287dbe2vboxsync | ((uint32_t)i << 8);
bdbed0b8e7fb553d01417fdc976a76f3b287dbe2vboxsync i = RT_ELEMENTS(pThis->InTemplateCtx.aSRegs);
bdbed0b8e7fb553d01417fdc976a76f3b287dbe2vboxsync while (i-- > 0)
bdbed0b8e7fb553d01417fdc976a76f3b287dbe2vboxsync pThis->InTemplateCtx.aSRegs[i] = 0; /* Front end sets these afterwards. */
bdbed0b8e7fb553d01417fdc976a76f3b287dbe2vboxsync pThis->InTemplateCtx.cr2 = 0;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync#ifndef CIDET_REDUCED_CTX
bdbed0b8e7fb553d01417fdc976a76f3b287dbe2vboxsync pThis->InTemplateCtx.tr = 0;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pThis->InTemplateCtx.ldtr = 0;
bdbed0b8e7fb553d01417fdc976a76f3b287dbe2vboxsync pThis->InTemplateCtx.cr0 = 0;
bdbed0b8e7fb553d01417fdc976a76f3b287dbe2vboxsync pThis->InTemplateCtx.cr3 = 0;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pThis->InTemplateCtx.cr4 = 0;
359416647a711739d1b14addbf399178949a1a60vboxsync pThis->InTemplateCtx.cr8 = 0;
bdbed0b8e7fb553d01417fdc976a76f3b287dbe2vboxsync#endif
bdbed0b8e7fb553d01417fdc976a76f3b287dbe2vboxsync pThis->InTemplateCtx.fIgnoredRFlags = 0;
bdbed0b8e7fb553d01417fdc976a76f3b287dbe2vboxsync pThis->InTemplateCtx.uXcpt = UINT32_MAX;
bdbed0b8e7fb553d01417fdc976a76f3b287dbe2vboxsync pThis->InTemplateCtx.uErr = UINT64_MAX;
bdbed0b8e7fb553d01417fdc976a76f3b287dbe2vboxsync pThis->InTemplateCtx.fTrickyStack = false;
bdbed0b8e7fb553d01417fdc976a76f3b287dbe2vboxsync}
bdbed0b8e7fb553d01417fdc976a76f3b287dbe2vboxsync
bdbed0b8e7fb553d01417fdc976a76f3b287dbe2vboxsync
bdbed0b8e7fb553d01417fdc976a76f3b287dbe2vboxsync/**
bdbed0b8e7fb553d01417fdc976a76f3b287dbe2vboxsync * Sets the target mode.
bdbed0b8e7fb553d01417fdc976a76f3b287dbe2vboxsync *
bdbed0b8e7fb553d01417fdc976a76f3b287dbe2vboxsync * Caller must set up default selector values after calling this function.
bdbed0b8e7fb553d01417fdc976a76f3b287dbe2vboxsync *
bdbed0b8e7fb553d01417fdc976a76f3b287dbe2vboxsync * @returns VBox status code.
bdbed0b8e7fb553d01417fdc976a76f3b287dbe2vboxsync * @param pThis Pointer to the core structure.
bdbed0b8e7fb553d01417fdc976a76f3b287dbe2vboxsync * @param bMode The new mode.
bdbed0b8e7fb553d01417fdc976a76f3b287dbe2vboxsync */
bdbed0b8e7fb553d01417fdc976a76f3b287dbe2vboxsyncint CidetCoreSetTargetMode(PCIDETCORE pThis, uint8_t bMode)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync{
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync AssertPtrReturn(pThis, VERR_INVALID_HANDLE); AssertReturn(pThis->u32Magic == CIDETCORE_MAGIC, VERR_INVALID_HANDLE);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync switch (bMode)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync //case CIDETMODE_RM:
359416647a711739d1b14addbf399178949a1a60vboxsync //case CIDETMODE_PE_16:
bdbed0b8e7fb553d01417fdc976a76f3b287dbe2vboxsync //case CIDETMODE_PE_32:
359416647a711739d1b14addbf399178949a1a60vboxsync //case CIDETMODE_PE_V86:
359416647a711739d1b14addbf399178949a1a60vboxsync //case CIDETMODE_PP_16:
359416647a711739d1b14addbf399178949a1a60vboxsync case CIDETMODE_PP_32:
bdbed0b8e7fb553d01417fdc976a76f3b287dbe2vboxsync //case CIDETMODE_PP_V86:
359416647a711739d1b14addbf399178949a1a60vboxsync //case CIDETMODE_PAE_16:
359416647a711739d1b14addbf399178949a1a60vboxsync case CIDETMODE_PAE_32:
bdbed0b8e7fb553d01417fdc976a76f3b287dbe2vboxsync //case CIDETMODE_PAE_V86:
bdbed0b8e7fb553d01417fdc976a76f3b287dbe2vboxsync //case CIDETMODE_LM_S16:
6902a98267d5180fb081cb5273751d0a628bf04dvboxsync //case CIDETMODE_LM_32:
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync case CIDETMODE_LM_64:
1389294d44ac76b0a25f5655756c9d39855a73efvboxsync break;
1389294d44ac76b0a25f5655756c9d39855a73efvboxsync default:
73ba84f95f918cc170be38908ad240fbb2f8f354vboxsync return VERR_NOT_IMPLEMENTED;
1389294d44ac76b0a25f5655756c9d39855a73efvboxsync }
73ba84f95f918cc170be38908ad240fbb2f8f354vboxsync pThis->bMode = bMode;
73ba84f95f918cc170be38908ad240fbb2f8f354vboxsync CidetCoreInitializeCtxTemplate(pThis);
73ba84f95f918cc170be38908ad240fbb2f8f354vboxsync return VINF_SUCCESS;
73ba84f95f918cc170be38908ad240fbb2f8f354vboxsync}
73ba84f95f918cc170be38908ad240fbb2f8f354vboxsync
73ba84f95f918cc170be38908ad240fbb2f8f354vboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncbool CidetCoreIsEncodingCompatibleWithInstruction(PCIDETCORE pThis)
1389294d44ac76b0a25f5655756c9d39855a73efvboxsync{
1389294d44ac76b0a25f5655756c9d39855a73efvboxsync return true;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync}
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync/**
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * Selects the next address size mode.
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync *
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * @returns @c true if done, @c false if the next wheel needs to be moved.
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * @param pThis The core state structure.
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncstatic bool cidetCoreSetupNextBaseEncoding_AddressSize(PCIDETCORE pThis)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync{
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (pThis->fAddrSizePrf)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync /*
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * Reset to default.
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pThis->cbAddrMode = CIDETMODE_GET_BYTE_COUNT(pThis->bMode);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pThis->fAddrSizePrf = false;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
359416647a711739d1b14addbf399178949a1a60vboxsync else
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
359416647a711739d1b14addbf399178949a1a60vboxsync /*
359416647a711739d1b14addbf399178949a1a60vboxsync * The other addressing size.
359416647a711739d1b14addbf399178949a1a60vboxsync */
359416647a711739d1b14addbf399178949a1a60vboxsync if (CIDETMODE_IS_64BIT(pThis->bMode))
359416647a711739d1b14addbf399178949a1a60vboxsync pThis->cbAddrMode = 4;
359416647a711739d1b14addbf399178949a1a60vboxsync else if (CIDETMODE_IS_32BIT(pThis->bMode))
359416647a711739d1b14addbf399178949a1a60vboxsync pThis->cbAddrMode = 2;
359416647a711739d1b14addbf399178949a1a60vboxsync else
359416647a711739d1b14addbf399178949a1a60vboxsync {
359416647a711739d1b14addbf399178949a1a60vboxsync AssertRelease(CIDETMODE_IS_16BIT(pThis->bMode));
359416647a711739d1b14addbf399178949a1a60vboxsync pThis->cbAddrMode = 2;
359416647a711739d1b14addbf399178949a1a60vboxsync }
359416647a711739d1b14addbf399178949a1a60vboxsync pThis->fAddrSizePrf = true;
359416647a711739d1b14addbf399178949a1a60vboxsync }
359416647a711739d1b14addbf399178949a1a60vboxsync return pThis->fAddrSizePrf;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync}
359416647a711739d1b14addbf399178949a1a60vboxsync
359416647a711739d1b14addbf399178949a1a60vboxsync
359416647a711739d1b14addbf399178949a1a60vboxsync/**
359416647a711739d1b14addbf399178949a1a60vboxsync * Selects the first REG encoding.
359416647a711739d1b14addbf399178949a1a60vboxsync *
359416647a711739d1b14addbf399178949a1a60vboxsync * @param pThis The core state structure.
359416647a711739d1b14addbf399178949a1a60vboxsync */
359416647a711739d1b14addbf399178949a1a60vboxsyncstatic void cidetCoreSetupFirstBaseEncoding_MrmReg(PCIDETCORE pThis)
359416647a711739d1b14addbf399178949a1a60vboxsync{
359416647a711739d1b14addbf399178949a1a60vboxsync pThis->aOperands[pThis->idxMrmRegOp].iReg = 0;
359416647a711739d1b14addbf399178949a1a60vboxsync pThis->aOperands[pThis->idxMrmRegOp].fIsMem = false;
359416647a711739d1b14addbf399178949a1a60vboxsync pThis->aOperands[pThis->idxMrmRegOp].fIsRipRelative = false;
359416647a711739d1b14addbf399178949a1a60vboxsync pThis->aOperands[pThis->idxMrmRegOp].fIsHighByteRegister = false;
359416647a711739d1b14addbf399178949a1a60vboxsync pThis->aOperands[pThis->idxMrmRegOp].cbMemDisp = 0;
359416647a711739d1b14addbf399178949a1a60vboxsync pThis->aOperands[pThis->idxMrmRegOp].iMemBaseReg = UINT8_MAX;
359416647a711739d1b14addbf399178949a1a60vboxsync pThis->aOperands[pThis->idxMrmRegOp].iMemIndexReg = UINT8_MAX;
359416647a711739d1b14addbf399178949a1a60vboxsync pThis->aOperands[pThis->idxMrmRegOp].uMemScale = 1;
359416647a711739d1b14addbf399178949a1a60vboxsync pThis->aOperands[pThis->idxMrmRegOp].iEffSeg = UINT8_MAX;
359416647a711739d1b14addbf399178949a1a60vboxsync pThis->bModRm &= ~X86_MODRM_REG_MASK;
359416647a711739d1b14addbf399178949a1a60vboxsync pThis->fRexR = false;
359416647a711739d1b14addbf399178949a1a60vboxsync}
359416647a711739d1b14addbf399178949a1a60vboxsync
359416647a711739d1b14addbf399178949a1a60vboxsync
359416647a711739d1b14addbf399178949a1a60vboxsync/**
359416647a711739d1b14addbf399178949a1a60vboxsync * Selects the next REG (ModR/M) encoding.
359416647a711739d1b14addbf399178949a1a60vboxsync *
359416647a711739d1b14addbf399178949a1a60vboxsync * @returns @c true if done, @c false if the next wheel needs to be moved.
359416647a711739d1b14addbf399178949a1a60vboxsync * @param pThis The core state structure.
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * @param iReg The value of MODRM.REG /w REX.R applied.
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncstatic bool cidetCoreSetupNextBaseEncoding_MrmReg(PCIDETCORE pThis, uint8_t iReg)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync{
359416647a711739d1b14addbf399178949a1a60vboxsync Assert(pThis->idxMrmRegOp < RT_ELEMENTS(pThis->aOperands) && !pThis->aOperands[pThis->idxMrmRegOp].fIsMem);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync Assert(iReg < 16);
359416647a711739d1b14addbf399178949a1a60vboxsync
359416647a711739d1b14addbf399178949a1a60vboxsync /*
359416647a711739d1b14addbf399178949a1a60vboxsync * Clear the collision flags here because of the byte register kludge.
359416647a711739d1b14addbf399178949a1a60vboxsync */
46737b2c6b2da473108a7670c3682d88474bd8b9vboxsync pThis->fHasRegCollisionDirect = false;
359416647a711739d1b14addbf399178949a1a60vboxsync pThis->fHasRegCollisionMemBase = false;
359416647a711739d1b14addbf399178949a1a60vboxsync pThis->fHasRegCollisionMemIndex = false;
359416647a711739d1b14addbf399178949a1a60vboxsync pThis->fHasRegCollisionMem = false;
359416647a711739d1b14addbf399178949a1a60vboxsync
359416647a711739d1b14addbf399178949a1a60vboxsync /*
359416647a711739d1b14addbf399178949a1a60vboxsync * Clear the REX prefix and high byte register tracking too. ASSUMES MrmReg is after MrmRmMod.
359416647a711739d1b14addbf399178949a1a60vboxsync */
359416647a711739d1b14addbf399178949a1a60vboxsync Assert(!pThis->fNoRexPrefixMrmRm);
359416647a711739d1b14addbf399178949a1a60vboxsync Assert(!pThis->fHasHighByteRegInMrmRm);
ad290511521ce8388a9926b165241ecf83c330a7vboxsync pThis->fNoRexPrefixMrmReg = false;
359416647a711739d1b14addbf399178949a1a60vboxsync pThis->fNoRexPrefix = false;
359416647a711739d1b14addbf399178949a1a60vboxsync pThis->fHasHighByteRegInMrmReg = false;
359416647a711739d1b14addbf399178949a1a60vboxsync pThis->aOperands[pThis->idxMrmRegOp].fIsHighByteRegister = false;
359416647a711739d1b14addbf399178949a1a60vboxsync
359416647a711739d1b14addbf399178949a1a60vboxsync /*
41fcf8465b641c7083d3b440451f17c1210fce33vboxsync * Special kludge for ah, ch, dh, bh, spl, bpl, sil, and dil.
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * Needs extra care in 64-bit mode and special collision detection code.
359416647a711739d1b14addbf399178949a1a60vboxsync */
41fcf8465b641c7083d3b440451f17c1210fce33vboxsync CIDET_DPRINTF(("aOperands[%u].cb=%u fGpr=%u iReg=%d fRex=%d fRexW=%u fRexX=%u fRexB=%u fRexR=%d\n",
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pThis->idxMrmRegOp, pThis->aOperands[pThis->idxMrmRegOp].cb, CIDET_OF_K_IS_GPR(pThis->fMrmRegOp), iReg,
ad290511521ce8388a9926b165241ecf83c330a7vboxsync pThis->fRex, pThis->fRexW, pThis->fRexX, pThis->fRexB, pThis->fRexR));
359416647a711739d1b14addbf399178949a1a60vboxsync if ( pThis->aOperands[pThis->idxMrmRegOp].cb == 1
bdbed0b8e7fb553d01417fdc976a76f3b287dbe2vboxsync && CIDET_OF_K_IS_GPR(pThis->fMrmRegOp)
359416647a711739d1b14addbf399178949a1a60vboxsync && iReg >= 3
bdbed0b8e7fb553d01417fdc976a76f3b287dbe2vboxsync && ( iReg <= 6
bdbed0b8e7fb553d01417fdc976a76f3b287dbe2vboxsync || (CIDETMODE_IS_64BIT(pThis->bMode) && iReg == 7 && !pThis->fRex)) )
bdbed0b8e7fb553d01417fdc976a76f3b287dbe2vboxsync
bdbed0b8e7fb553d01417fdc976a76f3b287dbe2vboxsync {
bdbed0b8e7fb553d01417fdc976a76f3b287dbe2vboxsync if (!pThis->fRex && iReg >= 4 && CIDETMODE_IS_64BIT(pThis->bMode) && !pThis->fNoRexPrefix)
ad290511521ce8388a9926b165241ecf83c330a7vboxsync {
bdbed0b8e7fb553d01417fdc976a76f3b287dbe2vboxsync /* The AMD64 low variants: spl, bpl, sil and dil. */
ad290511521ce8388a9926b165241ecf83c330a7vboxsync pThis->fRex = true;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pThis->fHasStackRegInMrmReg = iReg == X86_GREG_xSP;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
359416647a711739d1b14addbf399178949a1a60vboxsync /* Check for collisions. */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (pThis->idxMrmRmOp < RT_ELEMENTS(pThis->aOperands))
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
41fcf8465b641c7083d3b440451f17c1210fce33vboxsync Assert(!pThis->fHasHighByteRegInMrmRm);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (!pThis->aOperands[pThis->idxMrmRmOp].fIsMem)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pThis->fHasRegCollisionDirect = CIDET_OF_K_IS_GPR(pThis->fMrmRmOp)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync && iReg == pThis->aOperands[pThis->idxMrmRmOp].iReg;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync else
359416647a711739d1b14addbf399178949a1a60vboxsync {
329df9696e709dc71611f504a4774f323545be0avboxsync Assert(!pThis->fUsesVexIndexRegs || pThis->aOperands[pThis->idxMrmRmOp].iMemIndexReg == UINT8_MAX);
359416647a711739d1b14addbf399178949a1a60vboxsync
3fa7a7e633f46a212052b510cdb8cee41f279a67vboxsync pThis->fHasRegCollisionMemBase = iReg == pThis->aOperands[pThis->idxMrmRmOp].iMemBaseReg;
359416647a711739d1b14addbf399178949a1a60vboxsync pThis->fHasRegCollisionMemIndex = iReg == pThis->aOperands[pThis->idxMrmRmOp].iMemIndexReg;
359416647a711739d1b14addbf399178949a1a60vboxsync pThis->fHasRegCollisionMem = pThis->fHasRegCollisionMemBase || pThis->fHasRegCollisionMemIndex;
359416647a711739d1b14addbf399178949a1a60vboxsync }
359416647a711739d1b14addbf399178949a1a60vboxsync }
3fa7a7e633f46a212052b510cdb8cee41f279a67vboxsync }
329df9696e709dc71611f504a4774f323545be0avboxsync else
359416647a711739d1b14addbf399178949a1a60vboxsync {
359416647a711739d1b14addbf399178949a1a60vboxsync /* Next register: ah, ch, dh and bh. */
abac45bdfa95437daba28dd2d94bf7e0a25f75cdvboxsync iReg++;
359416647a711739d1b14addbf399178949a1a60vboxsync pThis->aOperands[pThis->idxMrmRegOp].iReg = iReg;
359416647a711739d1b14addbf399178949a1a60vboxsync pThis->bModRm &= ~X86_MODRM_REG_MASK;
359416647a711739d1b14addbf399178949a1a60vboxsync pThis->bModRm |= (iReg & X86_MODRM_REG_SMASK) << X86_MODRM_REG_SHIFT;
359416647a711739d1b14addbf399178949a1a60vboxsync pThis->fRex = false;
359416647a711739d1b14addbf399178949a1a60vboxsync pThis->fRexR = false;
359416647a711739d1b14addbf399178949a1a60vboxsync pThis->fNoRexPrefixMrmReg = true;
359416647a711739d1b14addbf399178949a1a60vboxsync pThis->fNoRexPrefix = true;
359416647a711739d1b14addbf399178949a1a60vboxsync pThis->fHasHighByteRegInMrmReg = true;
359416647a711739d1b14addbf399178949a1a60vboxsync pThis->fHasStackRegInMrmReg = false;
4ecd4ad59281328476ad14f2baa51716b6f5f804vboxsync pThis->aOperands[pThis->idxMrmRegOp].fIsHighByteRegister = true;
359416647a711739d1b14addbf399178949a1a60vboxsync Assert(!pThis->fRexW); Assert(!pThis->fRexX); Assert(!pThis->fRexB);
359416647a711739d1b14addbf399178949a1a60vboxsync
359416647a711739d1b14addbf399178949a1a60vboxsync /* Check for collisions. */
359416647a711739d1b14addbf399178949a1a60vboxsync if (pThis->idxMrmRmOp < RT_ELEMENTS(pThis->aOperands))
4ecd4ad59281328476ad14f2baa51716b6f5f804vboxsync {
359416647a711739d1b14addbf399178949a1a60vboxsync if (!pThis->aOperands[pThis->idxMrmRmOp].fIsMem)
359416647a711739d1b14addbf399178949a1a60vboxsync pThis->fHasRegCollisionDirect = CIDET_OF_K_IS_GPR(pThis->fMrmRmOp)
329df9696e709dc71611f504a4774f323545be0avboxsync && ( ( pThis->aOperands[pThis->idxMrmRmOp].cb == 1
359416647a711739d1b14addbf399178949a1a60vboxsync && iReg == pThis->aOperands[pThis->idxMrmRmOp].iReg
359416647a711739d1b14addbf399178949a1a60vboxsync && pThis->fHasHighByteRegInMrmRm)
359416647a711739d1b14addbf399178949a1a60vboxsync || ( pThis->aOperands[pThis->idxMrmRmOp].cb > 1
359416647a711739d1b14addbf399178949a1a60vboxsync && iReg - 4 == pThis->aOperands[pThis->idxMrmRmOp].iReg));
359416647a711739d1b14addbf399178949a1a60vboxsync else
359416647a711739d1b14addbf399178949a1a60vboxsync {
359416647a711739d1b14addbf399178949a1a60vboxsync Assert(!pThis->fUsesVexIndexRegs || pThis->aOperands[pThis->idxMrmRmOp].iMemIndexReg == UINT8_MAX);
329df9696e709dc71611f504a4774f323545be0avboxsync
46737b2c6b2da473108a7670c3682d88474bd8b9vboxsync pThis->fHasRegCollisionMemBase = iReg - 4 == pThis->aOperands[pThis->idxMrmRmOp].iMemBaseReg;
359416647a711739d1b14addbf399178949a1a60vboxsync pThis->fHasRegCollisionMemIndex = iReg - 4 == pThis->aOperands[pThis->idxMrmRmOp].iMemIndexReg;
359416647a711739d1b14addbf399178949a1a60vboxsync pThis->fHasRegCollisionMem = pThis->fHasRegCollisionMemBase || pThis->fHasRegCollisionMemIndex;
359416647a711739d1b14addbf399178949a1a60vboxsync }
3fa7a7e633f46a212052b510cdb8cee41f279a67vboxsync }
359416647a711739d1b14addbf399178949a1a60vboxsync }
359416647a711739d1b14addbf399178949a1a60vboxsync return true;
329df9696e709dc71611f504a4774f323545be0avboxsync }
329df9696e709dc71611f504a4774f323545be0avboxsync
359416647a711739d1b14addbf399178949a1a60vboxsync Assert(!pThis->fRex || (iReg == 7 && CIDETMODE_IS_64BIT(pThis->bMode)));
3fa7a7e633f46a212052b510cdb8cee41f279a67vboxsync pThis->fRex = false;
359416647a711739d1b14addbf399178949a1a60vboxsync
359416647a711739d1b14addbf399178949a1a60vboxsync /*
3fa7a7e633f46a212052b510cdb8cee41f279a67vboxsync * Next register.
46737b2c6b2da473108a7670c3682d88474bd8b9vboxsync */
3fa7a7e633f46a212052b510cdb8cee41f279a67vboxsync iReg = (iReg + 1) & (CIDETMODE_IS_64BIT(pThis->bMode) ? 15 : 7);
3fa7a7e633f46a212052b510cdb8cee41f279a67vboxsync
359416647a711739d1b14addbf399178949a1a60vboxsync pThis->aOperands[pThis->idxMrmRegOp].iReg = iReg;
3fa7a7e633f46a212052b510cdb8cee41f279a67vboxsync pThis->bModRm &= ~X86_MODRM_REG_MASK;
3fa7a7e633f46a212052b510cdb8cee41f279a67vboxsync pThis->bModRm |= (iReg & X86_MODRM_REG_SMASK) << X86_MODRM_REG_SHIFT;
359416647a711739d1b14addbf399178949a1a60vboxsync pThis->fRexR = iReg >= 8;
359416647a711739d1b14addbf399178949a1a60vboxsync pThis->fHasStackRegInMrmReg = iReg == X86_GREG_xSP && CIDET_OF_K_IS_GPR(pThis->fMrmRegOp);
359416647a711739d1b14addbf399178949a1a60vboxsync
359416647a711739d1b14addbf399178949a1a60vboxsync /*
359416647a711739d1b14addbf399178949a1a60vboxsync * Register collision detection.
359416647a711739d1b14addbf399178949a1a60vboxsync */
359416647a711739d1b14addbf399178949a1a60vboxsync if (pThis->idxMrmRmOp < RT_ELEMENTS(pThis->aOperands))
359416647a711739d1b14addbf399178949a1a60vboxsync {
359416647a711739d1b14addbf399178949a1a60vboxsync if (!pThis->aOperands[pThis->idxMrmRmOp].fIsMem)
359416647a711739d1b14addbf399178949a1a60vboxsync pThis->fHasRegCollisionDirect = iReg == pThis->aOperands[pThis->idxMrmRmOp].iReg
359416647a711739d1b14addbf399178949a1a60vboxsync && CIDET_OF_K_IS_SAME(pThis->fMrmRmOp, pThis->fMrmRegOp);
359416647a711739d1b14addbf399178949a1a60vboxsync else if (CIDET_OF_K_IS_GPR(pThis->fMrmRegOp))
359416647a711739d1b14addbf399178949a1a60vboxsync {
359416647a711739d1b14addbf399178949a1a60vboxsync Assert(!pThis->fUsesVexIndexRegs || pThis->aOperands[pThis->idxMrmRmOp].iMemIndexReg == UINT8_MAX);
359416647a711739d1b14addbf399178949a1a60vboxsync pThis->fHasRegCollisionMemBase = iReg == pThis->aOperands[pThis->idxMrmRmOp].iMemBaseReg;
359416647a711739d1b14addbf399178949a1a60vboxsync pThis->fHasRegCollisionMemIndex = iReg == pThis->aOperands[pThis->idxMrmRmOp].iMemIndexReg;
359416647a711739d1b14addbf399178949a1a60vboxsync pThis->fHasRegCollisionMem = pThis->fHasRegCollisionMemBase || pThis->fHasRegCollisionMemIndex;
359416647a711739d1b14addbf399178949a1a60vboxsync }
359416647a711739d1b14addbf399178949a1a60vboxsync }
359416647a711739d1b14addbf399178949a1a60vboxsync Assert(!pThis->fSib);
359416647a711739d1b14addbf399178949a1a60vboxsync
359416647a711739d1b14addbf399178949a1a60vboxsync return iReg != 0;
359416647a711739d1b14addbf399178949a1a60vboxsync}
3fa7a7e633f46a212052b510cdb8cee41f279a67vboxsync
3fa7a7e633f46a212052b510cdb8cee41f279a67vboxsync
359416647a711739d1b14addbf399178949a1a60vboxsync/**
09f4b412099acda62997fd82c8608075c453b3ebvboxsync * Selects the next MOD & R/M encoding, 16-bit addressing variant.
359416647a711739d1b14addbf399178949a1a60vboxsync *
359416647a711739d1b14addbf399178949a1a60vboxsync * @param pThis The core state structure.
359416647a711739d1b14addbf399178949a1a60vboxsync * @param iReg The value of MODRM.REG /w REX.R applied.
359416647a711739d1b14addbf399178949a1a60vboxsync */
359416647a711739d1b14addbf399178949a1a60vboxsyncstatic void cidetCoreSetupFirstBaseEncoding_MrmRmMod_16bit(PCIDETCORE pThis, uint8_t iReg)
359416647a711739d1b14addbf399178949a1a60vboxsync{
359416647a711739d1b14addbf399178949a1a60vboxsync if (CidetInstrHasMrmRegOperand(pThis->pCurInstr))
359416647a711739d1b14addbf399178949a1a60vboxsync {
359416647a711739d1b14addbf399178949a1a60vboxsync pThis->aOperands[pThis->idxMrmRmOp].iReg = 0;
359416647a711739d1b14addbf399178949a1a60vboxsync pThis->aOperands[pThis->idxMrmRmOp].fIsMem = false;
359416647a711739d1b14addbf399178949a1a60vboxsync pThis->aOperands[pThis->idxMrmRmOp].fIsRipRelative = false;
359416647a711739d1b14addbf399178949a1a60vboxsync pThis->aOperands[pThis->idxMrmRmOp].fIsHighByteRegister = false;
359416647a711739d1b14addbf399178949a1a60vboxsync pThis->aOperands[pThis->idxMrmRmOp].cbMemDisp = 0;
359416647a711739d1b14addbf399178949a1a60vboxsync pThis->aOperands[pThis->idxMrmRmOp].iMemBaseReg = UINT8_MAX;
359416647a711739d1b14addbf399178949a1a60vboxsync pThis->aOperands[pThis->idxMrmRmOp].iMemIndexReg = UINT8_MAX;
359416647a711739d1b14addbf399178949a1a60vboxsync pThis->aOperands[pThis->idxMrmRmOp].uMemScale = 1;
359416647a711739d1b14addbf399178949a1a60vboxsync pThis->aOperands[pThis->idxMrmRmOp].iEffSeg = UINT8_MAX;
359416647a711739d1b14addbf399178949a1a60vboxsync pThis->bModRm &= ~(X86_MODRM_RM_MASK | X86_MODRM_MOD_MASK);
09f4b412099acda62997fd82c8608075c453b3ebvboxsync pThis->bModRm |= 3 << X86_MODRM_MOD_SHIFT;
09f4b412099acda62997fd82c8608075c453b3ebvboxsync pThis->fRexB = false;
359416647a711739d1b14addbf399178949a1a60vboxsync pThis->fRexX = false;
359416647a711739d1b14addbf399178949a1a60vboxsync pThis->fHasMemoryOperand = false;
359416647a711739d1b14addbf399178949a1a60vboxsync pThis->fHasRegCollisionDirect = iReg == 0
09f4b412099acda62997fd82c8608075c453b3ebvboxsync && CIDET_OF_K_IS_SAME(pThis->fMrmRmOp, pThis->fMrmRegOp);
359416647a711739d1b14addbf399178949a1a60vboxsync pThis->fHasRegCollisionMem = false;
359416647a711739d1b14addbf399178949a1a60vboxsync pThis->fHasRegCollisionMemBase = false;
09f4b412099acda62997fd82c8608075c453b3ebvboxsync pThis->fHasRegCollisionMemIndex = false;
09f4b412099acda62997fd82c8608075c453b3ebvboxsync pThis->fHasStackRegInMrmRmBase = false;
359416647a711739d1b14addbf399178949a1a60vboxsync }
359416647a711739d1b14addbf399178949a1a60vboxsync else
359416647a711739d1b14addbf399178949a1a60vboxsync {
359416647a711739d1b14addbf399178949a1a60vboxsync Assert(CidetInstrHasMrmMemOperand(pThis->pCurInstr));
359416647a711739d1b14addbf399178949a1a60vboxsync pThis->aOperands[pThis->idxMrmRmOp].iReg = UINT8_MAX;
359416647a711739d1b14addbf399178949a1a60vboxsync pThis->aOperands[pThis->idxMrmRmOp].fIsMem = true;
359416647a711739d1b14addbf399178949a1a60vboxsync pThis->aOperands[pThis->idxMrmRmOp].fIsRipRelative = false;
359416647a711739d1b14addbf399178949a1a60vboxsync pThis->aOperands[pThis->idxMrmRmOp].fIsHighByteRegister = false;
359416647a711739d1b14addbf399178949a1a60vboxsync pThis->aOperands[pThis->idxMrmRmOp].cbMemDisp = 0;
359416647a711739d1b14addbf399178949a1a60vboxsync pThis->aOperands[pThis->idxMrmRmOp].iMemBaseReg = X86_GREG_xBX;
359416647a711739d1b14addbf399178949a1a60vboxsync pThis->aOperands[pThis->idxMrmRmOp].iMemIndexReg = X86_GREG_xSI;
359416647a711739d1b14addbf399178949a1a60vboxsync pThis->aOperands[pThis->idxMrmRmOp].uMemScale = 1;
359416647a711739d1b14addbf399178949a1a60vboxsync pThis->aOperands[pThis->idxMrmRmOp].iEffSeg = UINT8_MAX;
359416647a711739d1b14addbf399178949a1a60vboxsync pThis->bModRm &= ~(X86_MODRM_RM_MASK | X86_MODRM_MOD_MASK);
359416647a711739d1b14addbf399178949a1a60vboxsync pThis->fRexB = false;
359416647a711739d1b14addbf399178949a1a60vboxsync pThis->fRexX = false;
359416647a711739d1b14addbf399178949a1a60vboxsync pThis->fHasMemoryOperand = true;
359416647a711739d1b14addbf399178949a1a60vboxsync pThis->fHasRegCollisionDirect = false;
359416647a711739d1b14addbf399178949a1a60vboxsync iReg -= pThis->fHasHighByteRegInMrmReg * 4;
359416647a711739d1b14addbf399178949a1a60vboxsync pThis->fHasRegCollisionMemBase = iReg == X86_GREG_xBX && CIDET_OF_K_IS_GPR(pThis->fMrmRegOp);
359416647a711739d1b14addbf399178949a1a60vboxsync pThis->fHasRegCollisionMemIndex = iReg == X86_GREG_xSI && CIDET_OF_K_IS_GPR(pThis->fMrmRegOp);
359416647a711739d1b14addbf399178949a1a60vboxsync pThis->fHasRegCollisionMem = pThis->fHasRegCollisionMemBase || pThis->fHasRegCollisionMemIndex;
359416647a711739d1b14addbf399178949a1a60vboxsync pThis->fHasStackRegInMrmRmBase = false;
09f4b412099acda62997fd82c8608075c453b3ebvboxsync }
359416647a711739d1b14addbf399178949a1a60vboxsync}
359416647a711739d1b14addbf399178949a1a60vboxsync
09f4b412099acda62997fd82c8608075c453b3ebvboxsync
09f4b412099acda62997fd82c8608075c453b3ebvboxsync/**
359416647a711739d1b14addbf399178949a1a60vboxsync * Selects the next MOD & R/M encoding, 16-bit addressing variant.
09f4b412099acda62997fd82c8608075c453b3ebvboxsync *
359416647a711739d1b14addbf399178949a1a60vboxsync * @returns @c true if done, @c false if the next wheel needs to be moved.
359416647a711739d1b14addbf399178949a1a60vboxsync * @param pThis The core state structure.
09f4b412099acda62997fd82c8608075c453b3ebvboxsync * @param iReg The value of MODRM.REG /w REX.R applied.
09f4b412099acda62997fd82c8608075c453b3ebvboxsync */
359416647a711739d1b14addbf399178949a1a60vboxsyncstatic bool cidetCoreSetupNextBaseEncoding_MrmRmMod_16bit(PCIDETCORE pThis, uint8_t iReg)
09f4b412099acda62997fd82c8608075c453b3ebvboxsync{
359416647a711739d1b14addbf399178949a1a60vboxsync AssertRelease(!pThis->fRexB);
359416647a711739d1b14addbf399178949a1a60vboxsync AssertRelease(!pThis->fRexX);
359416647a711739d1b14addbf399178949a1a60vboxsync uint8_t iRm = pThis->bModRm & X86_MODRM_RM_MASK;
359416647a711739d1b14addbf399178949a1a60vboxsync uint8_t iMod = (pThis->bModRm >> X86_MODRM_MOD_SHIFT) & X86_MODRM_MOD_SMASK;
09f4b412099acda62997fd82c8608075c453b3ebvboxsync if (iMod == 3)
359416647a711739d1b14addbf399178949a1a60vboxsync {
09f4b412099acda62997fd82c8608075c453b3ebvboxsync /*
359416647a711739d1b14addbf399178949a1a60vboxsync * Register access mode.
359416647a711739d1b14addbf399178949a1a60vboxsync */
359416647a711739d1b14addbf399178949a1a60vboxsync Assert(pThis->idxMrmRmOp < RT_ELEMENTS(pThis->aOperands) && !pThis->aOperands[pThis->idxMrmRmOp].fIsMem);
359416647a711739d1b14addbf399178949a1a60vboxsync Assert(!pThis->fHasMemoryOperand);
359416647a711739d1b14addbf399178949a1a60vboxsync Assert(!pThis->fHasRegCollisionMem);
359416647a711739d1b14addbf399178949a1a60vboxsync Assert(!pThis->fHasRegCollisionMemBase);
359416647a711739d1b14addbf399178949a1a60vboxsync Assert(!pThis->fHasRegCollisionMemIndex);
09f4b412099acda62997fd82c8608075c453b3ebvboxsync if (iRm < 7)
359416647a711739d1b14addbf399178949a1a60vboxsync {
359416647a711739d1b14addbf399178949a1a60vboxsync iRm++;
359416647a711739d1b14addbf399178949a1a60vboxsync pThis->aOperands[pThis->idxMrmRmOp].iReg = iRm;
359416647a711739d1b14addbf399178949a1a60vboxsync pThis->bModRm &= ~X86_MODRM_RM_MASK;
359416647a711739d1b14addbf399178949a1a60vboxsync pThis->bModRm |= iRm;
359416647a711739d1b14addbf399178949a1a60vboxsync pThis->fHasRegCollisionDirect = iRm == iReg
359416647a711739d1b14addbf399178949a1a60vboxsync && CIDET_OF_K_IS_SAME(pThis->fMrmRmOp, pThis->fMrmRegOp);
359416647a711739d1b14addbf399178949a1a60vboxsync pThis->fHasStackRegInMrmRmBase = iRm == X86_GREG_xSP && CIDET_OF_K_IS_GPR(pThis->fMrmRmOp);
359416647a711739d1b14addbf399178949a1a60vboxsync return true;
359416647a711739d1b14addbf399178949a1a60vboxsync }
359416647a711739d1b14addbf399178949a1a60vboxsync
09f4b412099acda62997fd82c8608075c453b3ebvboxsync /* If no memory modes, we're done. */
359416647a711739d1b14addbf399178949a1a60vboxsync if (!CidetInstrHasMrmMemOperand(pThis->pCurInstr))
09f4b412099acda62997fd82c8608075c453b3ebvboxsync {
09f4b412099acda62997fd82c8608075c453b3ebvboxsync cidetCoreSetupFirstBaseEncoding_MrmRmMod_16bit(pThis, iReg);
359416647a711739d1b14addbf399178949a1a60vboxsync return false;
359416647a711739d1b14addbf399178949a1a60vboxsync }
359416647a711739d1b14addbf399178949a1a60vboxsync
359416647a711739d1b14addbf399178949a1a60vboxsync /* Next mode: 16-bit memory addressing without displacement. */
359416647a711739d1b14addbf399178949a1a60vboxsync pThis->aOperands[pThis->idxMrmRmOp].fIsMem = true;
359416647a711739d1b14addbf399178949a1a60vboxsync pThis->aOperands[pThis->idxMrmRmOp].cbMemDisp = 0;
359416647a711739d1b14addbf399178949a1a60vboxsync iMod = 0;
09f4b412099acda62997fd82c8608075c453b3ebvboxsync }
359416647a711739d1b14addbf399178949a1a60vboxsync else
09f4b412099acda62997fd82c8608075c453b3ebvboxsync {
359416647a711739d1b14addbf399178949a1a60vboxsync /*
359416647a711739d1b14addbf399178949a1a60vboxsync * Memory access mode.
359416647a711739d1b14addbf399178949a1a60vboxsync */
359416647a711739d1b14addbf399178949a1a60vboxsync Assert(pThis->idxMrmRmOp < RT_ELEMENTS(pThis->aOperands) && pThis->aOperands[pThis->idxMrmRmOp].fIsMem);
09f4b412099acda62997fd82c8608075c453b3ebvboxsync Assert(pThis->fHasMemoryOperand);
09f4b412099acda62997fd82c8608075c453b3ebvboxsync if (iRm < 7)
359416647a711739d1b14addbf399178949a1a60vboxsync {
09f4b412099acda62997fd82c8608075c453b3ebvboxsync iRm++;
359416647a711739d1b14addbf399178949a1a60vboxsync switch (iRm)
359416647a711739d1b14addbf399178949a1a60vboxsync {
359416647a711739d1b14addbf399178949a1a60vboxsync case 1:
359416647a711739d1b14addbf399178949a1a60vboxsync pThis->aOperands[pThis->idxMrmRmOp].iMemBaseReg = X86_GREG_xBX;
359416647a711739d1b14addbf399178949a1a60vboxsync pThis->aOperands[pThis->idxMrmRmOp].iMemIndexReg = X86_GREG_xDI;
09f4b412099acda62997fd82c8608075c453b3ebvboxsync break;
359416647a711739d1b14addbf399178949a1a60vboxsync case 2:
359416647a711739d1b14addbf399178949a1a60vboxsync pThis->aOperands[pThis->idxMrmRmOp].iMemBaseReg = X86_GREG_xBP;
359416647a711739d1b14addbf399178949a1a60vboxsync pThis->aOperands[pThis->idxMrmRmOp].iMemIndexReg = X86_GREG_xSI;
359416647a711739d1b14addbf399178949a1a60vboxsync break;
359416647a711739d1b14addbf399178949a1a60vboxsync case 3:
359416647a711739d1b14addbf399178949a1a60vboxsync pThis->aOperands[pThis->idxMrmRmOp].iMemBaseReg = X86_GREG_xBP;
359416647a711739d1b14addbf399178949a1a60vboxsync pThis->aOperands[pThis->idxMrmRmOp].iMemIndexReg = X86_GREG_xDI;
359416647a711739d1b14addbf399178949a1a60vboxsync break;
09f4b412099acda62997fd82c8608075c453b3ebvboxsync case 4:
09f4b412099acda62997fd82c8608075c453b3ebvboxsync pThis->aOperands[pThis->idxMrmRmOp].iMemBaseReg = UINT8_MAX;
dc959f60f6d3e0cba86f7da4d39aa475913a7e10vboxsync pThis->aOperands[pThis->idxMrmRmOp].iMemIndexReg = X86_GREG_xSI;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync break;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync case 5:
dc959f60f6d3e0cba86f7da4d39aa475913a7e10vboxsync pThis->aOperands[pThis->idxMrmRmOp].iMemBaseReg = UINT8_MAX;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pThis->aOperands[pThis->idxMrmRmOp].iMemIndexReg = X86_GREG_xDI;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync break;
dc959f60f6d3e0cba86f7da4d39aa475913a7e10vboxsync case 6:
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (iMod == 0)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pThis->aOperands[pThis->idxMrmRmOp].cbMemDisp = 2;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pThis->aOperands[pThis->idxMrmRmOp].iMemBaseReg = UINT8_MAX;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync else
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pThis->aOperands[pThis->idxMrmRmOp].iMemBaseReg = X86_GREG_xBP;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pThis->aOperands[pThis->idxMrmRmOp].iMemIndexReg = UINT8_MAX;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync break;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync case 7:
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (iMod == 0)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pThis->aOperands[pThis->idxMrmRmOp].cbMemDisp = 0;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pThis->aOperands[pThis->idxMrmRmOp].iMemBaseReg = X86_GREG_xBX;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pThis->aOperands[pThis->idxMrmRmOp].iMemIndexReg = UINT8_MAX;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync break;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync default: AssertReleaseFailed();
dc959f60f6d3e0cba86f7da4d39aa475913a7e10vboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pThis->bModRm &= ~X86_MODRM_RM_MASK;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pThis->bModRm |= iRm;
dc959f60f6d3e0cba86f7da4d39aa475913a7e10vboxsync if (CIDET_OF_K_IS_GPR(pThis->fMrmRegOp))
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync iReg -= pThis->fHasHighByteRegInMrmReg * 4;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pThis->fHasRegCollisionMemBase = iReg == pThis->aOperands[pThis->idxMrmRmOp].iMemBaseReg;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pThis->fHasRegCollisionMemIndex = iReg == pThis->aOperands[pThis->idxMrmRmOp].iMemIndexReg;
4c98b8b05f3783351cf256cc90cd4478fb28b62bvboxsync pThis->fHasRegCollisionMem = pThis->fHasRegCollisionMemBase || pThis->fHasRegCollisionMemIndex;
4c98b8b05f3783351cf256cc90cd4478fb28b62bvboxsync }
4c98b8b05f3783351cf256cc90cd4478fb28b62bvboxsync return true;
4c98b8b05f3783351cf256cc90cd4478fb28b62bvboxsync }
4c98b8b05f3783351cf256cc90cd4478fb28b62bvboxsync
4c98b8b05f3783351cf256cc90cd4478fb28b62bvboxsync /* Last mode? */
4c98b8b05f3783351cf256cc90cd4478fb28b62bvboxsync if (iMod >= 2)
4c98b8b05f3783351cf256cc90cd4478fb28b62bvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync cidetCoreSetupFirstBaseEncoding_MrmRmMod_16bit(pThis, iReg);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return false;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
4c98b8b05f3783351cf256cc90cd4478fb28b62bvboxsync
4c98b8b05f3783351cf256cc90cd4478fb28b62bvboxsync /* Next memory addressing mode (if any). */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync iMod++;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pThis->aOperands[pThis->idxMrmRmOp].cbMemDisp++;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pThis->aOperands[pThis->idxMrmRmOp].iMemBaseReg = X86_GREG_xBX;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pThis->aOperands[pThis->idxMrmRmOp].iMemIndexReg = X86_GREG_xSI;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pThis->aOperands[pThis->idxMrmRmOp].uMemScale = 1;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pThis->bModRm &= ~(X86_MODRM_RM_MASK | X86_MODRM_MOD_MASK);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pThis->bModRm |= iMod << X86_MODRM_MOD_SHIFT;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pThis->fHasMemoryOperand = true;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pThis->fHasRegCollisionDirect = false;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pThis->fHasStackRegInMrmRmBase = false;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (CIDET_OF_K_IS_GPR(pThis->fMrmRmOp))
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync iReg -= pThis->fHasHighByteRegInMrmReg * 4;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pThis->fHasRegCollisionMemBase = iReg == X86_GREG_xBX;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pThis->fHasRegCollisionMemIndex = iReg == X86_GREG_xSI;
4c98b8b05f3783351cf256cc90cd4478fb28b62bvboxsync pThis->fHasRegCollisionMem = pThis->fHasRegCollisionMemBase || pThis->fHasRegCollisionMemIndex;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return true;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync}
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync/**
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * Selects the first MOD & R/M encoding, 32-bit and 64-bit addressing variant.
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync *
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * @param pThis The core state structure.
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * @param iReg The value of MODRM.REG /w REX.R applied.
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * @param f64Bit Set if 64-bit, clear if 32-bit.
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncstatic void cidetCoreSetupFirstBaseEncoding_MrmRmMod_32bit64bit(PCIDETCORE pThis, uint8_t iReg, bool f64Bit)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync{
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (CidetInstrHasMrmRegOperand(pThis->pCurInstr))
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pThis->aOperands[pThis->idxMrmRmOp].iReg = 0;
4c98b8b05f3783351cf256cc90cd4478fb28b62bvboxsync pThis->aOperands[pThis->idxMrmRmOp].fIsMem = false;
4c98b8b05f3783351cf256cc90cd4478fb28b62bvboxsync pThis->aOperands[pThis->idxMrmRmOp].fIsRipRelative = false;
4c98b8b05f3783351cf256cc90cd4478fb28b62bvboxsync pThis->aOperands[pThis->idxMrmRmOp].fIsHighByteRegister = false;
4c98b8b05f3783351cf256cc90cd4478fb28b62bvboxsync pThis->aOperands[pThis->idxMrmRmOp].cbMemDisp = 0;
4c98b8b05f3783351cf256cc90cd4478fb28b62bvboxsync pThis->aOperands[pThis->idxMrmRmOp].iMemBaseReg = UINT8_MAX;
4c98b8b05f3783351cf256cc90cd4478fb28b62bvboxsync pThis->aOperands[pThis->idxMrmRmOp].iMemIndexReg = UINT8_MAX;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pThis->aOperands[pThis->idxMrmRmOp].uMemScale = 1;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pThis->aOperands[pThis->idxMrmRmOp].iEffSeg = UINT8_MAX;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pThis->bModRm &= ~(X86_MODRM_RM_MASK | X86_MODRM_MOD_MASK);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pThis->bModRm |= 3 << X86_MODRM_MOD_SHIFT;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pThis->fRexB = false;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pThis->fRexX = false;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pThis->fHasMemoryOperand = false;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pThis->fHasRegCollisionDirect = iReg == 0
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync && CIDET_OF_K_IS_SAME(pThis->fMrmRmOp, pThis->fMrmRegOp);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pThis->fHasRegCollisionMem = false;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pThis->fHasRegCollisionMemBase = false;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pThis->fHasRegCollisionMemIndex = false;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pThis->fHasStackRegInMrmRmBase = false;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync else
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync Assert(CidetInstrHasMrmMemOperand(pThis->pCurInstr));
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pThis->aOperands[pThis->idxMrmRmOp].iReg = UINT8_MAX;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pThis->aOperands[pThis->idxMrmRmOp].fIsMem = true;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pThis->aOperands[pThis->idxMrmRmOp].fIsRipRelative = false;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pThis->aOperands[pThis->idxMrmRmOp].fIsHighByteRegister = false;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pThis->aOperands[pThis->idxMrmRmOp].cbMemDisp = 0;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pThis->aOperands[pThis->idxMrmRmOp].iMemBaseReg = 0;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pThis->aOperands[pThis->idxMrmRmOp].iMemIndexReg = UINT8_MAX;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pThis->aOperands[pThis->idxMrmRmOp].uMemScale = 1;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pThis->aOperands[pThis->idxMrmRmOp].iEffSeg = UINT8_MAX;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pThis->bModRm &= ~(X86_MODRM_RM_MASK | X86_MODRM_MOD_MASK);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pThis->fRexB = false;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pThis->fRexX = false;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pThis->fHasMemoryOperand = true;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pThis->fHasRegCollisionDirect = false;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pThis->fHasRegCollisionMemIndex = false;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pThis->fHasRegCollisionMemBase = iReg == pThis->fHasHighByteRegInMrmReg * 4 && CIDET_OF_K_IS_GPR(pThis->fMrmRegOp);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pThis->fHasRegCollisionMem = pThis->fHasRegCollisionMemBase;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pThis->fHasStackRegInMrmRmBase = false;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
359416647a711739d1b14addbf399178949a1a60vboxsync}
359416647a711739d1b14addbf399178949a1a60vboxsync
359416647a711739d1b14addbf399178949a1a60vboxsync
359416647a711739d1b14addbf399178949a1a60vboxsync/**
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * Selects the next MOD & R/M encoding, 32-bit and 64-bit addressing variant.
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync *
cb0578a5309e1fc264e5a4acc30543bea075be43vboxsync * @returns @c true if done, @c false if the next wheel needs to be moved.
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * @param pThis The core state structure.
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * @param iReg The value of MODRM.REG /w REX.R applied.
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * @param f64Bit Set if 64-bit, clear if 32-bit.
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncstatic bool cidetCoreSetupNextBaseEncoding_MrmRmMod_32bit64bit(PCIDETCORE pThis, uint8_t iReg, bool f64Bit)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync{
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync AssertRelease(!pThis->fRexX || CIDETMODE_IS_64BIT(pThis->bMode));
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync AssertRelease(!pThis->fRexB || CIDETMODE_IS_64BIT(pThis->bMode));
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync uint8_t iRm = (pThis->bModRm & X86_MODRM_RM_MASK) + pThis->fRexB * 8;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync uint8_t iMod = (pThis->bModRm >> X86_MODRM_MOD_SHIFT) & X86_MODRM_MOD_SMASK;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (iMod == 3)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync /*
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * Register access mode.
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync Assert(pThis->idxMrmRmOp < RT_ELEMENTS(pThis->aOperands) && !pThis->aOperands[pThis->idxMrmRmOp].fIsMem);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync Assert(!pThis->fHasMemoryOperand);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync Assert(!pThis->fHasRegCollisionMem);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync Assert(!pThis->fHasRegCollisionMemBase);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync Assert(!pThis->fHasRegCollisionMemIndex);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (CIDETMODE_IS_64BIT(pThis->bMode) && !pThis->fRexX && !pThis->fNoRexPrefix) /* should be ignored. */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pThis->fRexX = true;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return true;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync /* Reset the byte register kludges variables. */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pThis->aOperands[pThis->idxMrmRmOp].fIsHighByteRegister = false;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pThis->fHasHighByteRegInMrmRm = false;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pThis->fNoRexPrefixMrmRm = false;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pThis->fNoRexPrefix = pThis->fNoRexPrefixMrmReg;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (iRm < (CIDETMODE_IS_64BIT(pThis->bMode) && !pThis->fNoRexPrefix ? 15 : 7))
105b1a31b6037dbe14acb8d09e60da540885202bvboxsync {
105b1a31b6037dbe14acb8d09e60da540885202bvboxsync /*
105b1a31b6037dbe14acb8d09e60da540885202bvboxsync * Byte register kludge.
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if ( pThis->aOperands[pThis->idxMrmRmOp].cb == 1
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync && CIDET_OF_K_IS_GPR(pThis->fMrmRegOp)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync && iRm >= 3
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync && ( iRm <= 6
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync || (iRm == 7 && CIDETMODE_IS_64BIT(pThis->bMode) && !pThis->fRexX) ) )
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (!pThis->fRexX && iRm >= 4 && CIDETMODE_IS_64BIT(pThis->bMode) && !pThis->fNoRexPrefix)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync /* The AMD64 low variants: spl, bpl, sil and dil. (Using fRexX here as REG covers fRex.) */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pThis->fRexX = true;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pThis->fHasRegCollisionDirect = CIDET_OF_K_IS_GPR(pThis->fMrmRegOp)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync && iRm == iReg - pThis->fHasHighByteRegInMrmReg * 4;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pThis->fHasStackRegInMrmRmBase = iRm == X86_GREG_xSP && CIDET_OF_K_IS_GPR(pThis->fMrmRegOp);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync else
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync /* Next register: ah, ch, dh and bh. */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync iRm++;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pThis->aOperands[pThis->idxMrmRmOp].iReg = iRm;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pThis->bModRm &= ~X86_MODRM_RM_MASK;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pThis->bModRm |= iRm & X86_MODRM_RM_MASK;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pThis->fRexB = false;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pThis->fRexX = false;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (!pThis->fRexR && !pThis->fRexW && !pThis->fRex)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pThis->fNoRexPrefixMrmRm = true;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pThis->fNoRexPrefix = true;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pThis->fHasHighByteRegInMrmRm = true;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pThis->aOperands[pThis->idxMrmRmOp].fIsHighByteRegister = true;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pThis->fHasRegCollisionDirect = CIDET_OF_K_IS_GPR(pThis->fMrmRegOp)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync && iRm - 4 == iReg - pThis->fHasHighByteRegInMrmReg * 4;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pThis->fHasStackRegInMrmRmBase = false;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync else
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync /* Can't do the high stuff, so do the spl, bpl, sil and dil variation instead.
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync Note! We don't set the RexX yet since the base register or operand width holds it down. */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pThis->fHasRegCollisionDirect = CIDET_OF_K_IS_GPR(pThis->fMrmRegOp)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync && iRm == iReg - pThis->fHasHighByteRegInMrmReg * 4;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pThis->fHasStackRegInMrmRmBase = iRm == X86_GREG_xSP && CIDET_OF_K_IS_GPR(pThis->fMrmRegOp);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync /*
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * Normal register.
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync else
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync iRm++;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pThis->aOperands[pThis->idxMrmRmOp].iReg = iRm;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pThis->bModRm &= ~X86_MODRM_RM_MASK;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pThis->bModRm |= iRm & X86_MODRM_RM_MASK;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pThis->fRexB = iRm >= 8;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pThis->fRexX = false;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pThis->fHasRegCollisionDirect = iRm == iReg && CIDET_OF_K_IS_SAME(pThis->fMrmRmOp, pThis->fMrmRegOp);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pThis->fHasStackRegInMrmRmBase = iRm == X86_GREG_xSP && CIDET_OF_K_IS_GPR(pThis->fMrmRegOp);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return true;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync /* If no memory modes, we're done. */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (!CidetInstrHasMrmMemOperand(pThis->pCurInstr))
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync cidetCoreSetupFirstBaseEncoding_MrmRmMod_32bit64bit(pThis, iReg, f64Bit);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return false;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync /* Next mode: 32-bit/64-bit memory addressing without displacement. */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pThis->aOperands[pThis->idxMrmRmOp].fIsMem = true;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pThis->aOperands[pThis->idxMrmRmOp].cbMemDisp = 0;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync iMod = 0;
ad290511521ce8388a9926b165241ecf83c330a7vboxsync }
cb0578a5309e1fc264e5a4acc30543bea075be43vboxsync else
cb0578a5309e1fc264e5a4acc30543bea075be43vboxsync {
cb0578a5309e1fc264e5a4acc30543bea075be43vboxsync /*
cb0578a5309e1fc264e5a4acc30543bea075be43vboxsync * Memory access mode.
cb0578a5309e1fc264e5a4acc30543bea075be43vboxsync */
cb0578a5309e1fc264e5a4acc30543bea075be43vboxsync Assert(pThis->idxMrmRmOp < RT_ELEMENTS(pThis->aOperands) && pThis->aOperands[pThis->idxMrmRmOp].fIsMem);
cb0578a5309e1fc264e5a4acc30543bea075be43vboxsync Assert(pThis->fHasMemoryOperand);
cb0578a5309e1fc264e5a4acc30543bea075be43vboxsync Assert(!pThis->fHasStackRegInMrmRmBase);
cb0578a5309e1fc264e5a4acc30543bea075be43vboxsync if (iRm < (CIDETMODE_IS_64BIT(pThis->bMode) && !pThis->fNoRexPrefix ? 15 : 7))
cb0578a5309e1fc264e5a4acc30543bea075be43vboxsync {
cb0578a5309e1fc264e5a4acc30543bea075be43vboxsync iRm++;
cb0578a5309e1fc264e5a4acc30543bea075be43vboxsync if (iRm == 12)
cb0578a5309e1fc264e5a4acc30543bea075be43vboxsync iRm++; /* Leave REX.B=1 to the next-sib-base function. */
cb0578a5309e1fc264e5a4acc30543bea075be43vboxsync if (iRm == 4)
cb0578a5309e1fc264e5a4acc30543bea075be43vboxsync {
cb0578a5309e1fc264e5a4acc30543bea075be43vboxsync /* SIB */
cb0578a5309e1fc264e5a4acc30543bea075be43vboxsync pThis->aOperands[pThis->idxMrmRmOp].iMemBaseReg = 0;
cb0578a5309e1fc264e5a4acc30543bea075be43vboxsync pThis->aOperands[pThis->idxMrmRmOp].iMemIndexReg = 0;
cb0578a5309e1fc264e5a4acc30543bea075be43vboxsync pThis->fSib = true;
cb0578a5309e1fc264e5a4acc30543bea075be43vboxsync pThis->bSib = 0;
cb0578a5309e1fc264e5a4acc30543bea075be43vboxsync }
cb0578a5309e1fc264e5a4acc30543bea075be43vboxsync else if ((iRm & 7) == 5 && iMod == 0)
cb0578a5309e1fc264e5a4acc30543bea075be43vboxsync {
cb0578a5309e1fc264e5a4acc30543bea075be43vboxsync /* Absolute or wrt rip addressing. */
cb0578a5309e1fc264e5a4acc30543bea075be43vboxsync pThis->aOperands[pThis->idxMrmRmOp].fIsRipRelative = CIDETMODE_IS_64BIT(pThis->bMode);
cb0578a5309e1fc264e5a4acc30543bea075be43vboxsync pThis->aOperands[pThis->idxMrmRmOp].iMemBaseReg = UINT8_MAX;
cb0578a5309e1fc264e5a4acc30543bea075be43vboxsync pThis->aOperands[pThis->idxMrmRmOp].iMemIndexReg = UINT8_MAX;
cb0578a5309e1fc264e5a4acc30543bea075be43vboxsync pThis->aOperands[pThis->idxMrmRmOp].cbMemDisp = 4;
cb0578a5309e1fc264e5a4acc30543bea075be43vboxsync }
cb0578a5309e1fc264e5a4acc30543bea075be43vboxsync else
cb0578a5309e1fc264e5a4acc30543bea075be43vboxsync {
cb0578a5309e1fc264e5a4acc30543bea075be43vboxsync if ((iRm & 7) == 6 && iMod == 0)
cb0578a5309e1fc264e5a4acc30543bea075be43vboxsync {
cb0578a5309e1fc264e5a4acc30543bea075be43vboxsync pThis->aOperands[pThis->idxMrmRmOp].cbMemDisp = 0;
cb0578a5309e1fc264e5a4acc30543bea075be43vboxsync pThis->aOperands[pThis->idxMrmRmOp].fIsRipRelative = false;
cb0578a5309e1fc264e5a4acc30543bea075be43vboxsync }
cb0578a5309e1fc264e5a4acc30543bea075be43vboxsync pThis->aOperands[pThis->idxMrmRmOp].iMemBaseReg = iRm;
cb0578a5309e1fc264e5a4acc30543bea075be43vboxsync pThis->aOperands[pThis->idxMrmRmOp].iMemIndexReg = UINT8_MAX;
cb0578a5309e1fc264e5a4acc30543bea075be43vboxsync }
cb0578a5309e1fc264e5a4acc30543bea075be43vboxsync pThis->aOperands[pThis->idxMrmRmOp].uMemScale = 1;
cb0578a5309e1fc264e5a4acc30543bea075be43vboxsync pThis->bModRm &= ~X86_MODRM_RM_MASK;
cb0578a5309e1fc264e5a4acc30543bea075be43vboxsync pThis->bModRm |= iRm & X86_MODRM_RM_MASK;
cb0578a5309e1fc264e5a4acc30543bea075be43vboxsync pThis->fRexB = iRm >= 8;
cb0578a5309e1fc264e5a4acc30543bea075be43vboxsync pThis->fRexX = false;
cb0578a5309e1fc264e5a4acc30543bea075be43vboxsync if (CIDET_OF_K_IS_GPR(pThis->fMrmRegOp))
cb0578a5309e1fc264e5a4acc30543bea075be43vboxsync {
cb0578a5309e1fc264e5a4acc30543bea075be43vboxsync iReg -= pThis->fHasHighByteRegInMrmReg * 4;
cb0578a5309e1fc264e5a4acc30543bea075be43vboxsync pThis->fHasRegCollisionMemBase = iReg == pThis->aOperands[pThis->idxMrmRmOp].iMemBaseReg;
cb0578a5309e1fc264e5a4acc30543bea075be43vboxsync pThis->fHasRegCollisionMemIndex = iReg == pThis->aOperands[pThis->idxMrmRmOp].iMemIndexReg;
cb0578a5309e1fc264e5a4acc30543bea075be43vboxsync pThis->fHasRegCollisionMem = pThis->fHasRegCollisionMemBase || pThis->fHasRegCollisionMemIndex;
cb0578a5309e1fc264e5a4acc30543bea075be43vboxsync }
cb0578a5309e1fc264e5a4acc30543bea075be43vboxsync return true;
ad290511521ce8388a9926b165241ecf83c330a7vboxsync }
cb0578a5309e1fc264e5a4acc30543bea075be43vboxsync
cb0578a5309e1fc264e5a4acc30543bea075be43vboxsync /* Last mode? */
ad290511521ce8388a9926b165241ecf83c330a7vboxsync if (iMod >= 2)
cb0578a5309e1fc264e5a4acc30543bea075be43vboxsync {
cb0578a5309e1fc264e5a4acc30543bea075be43vboxsync cidetCoreSetupFirstBaseEncoding_MrmRmMod_32bit64bit(pThis, iReg, f64Bit);
cb0578a5309e1fc264e5a4acc30543bea075be43vboxsync return false;
cb0578a5309e1fc264e5a4acc30543bea075be43vboxsync }
cb0578a5309e1fc264e5a4acc30543bea075be43vboxsync
cb0578a5309e1fc264e5a4acc30543bea075be43vboxsync /* Next memory addressing mode (if any). */
cb0578a5309e1fc264e5a4acc30543bea075be43vboxsync iMod++;
ad290511521ce8388a9926b165241ecf83c330a7vboxsync pThis->aOperands[pThis->idxMrmRmOp].cbMemDisp = iMod == 1 ? 1 : 4;
cb0578a5309e1fc264e5a4acc30543bea075be43vboxsync }
cb0578a5309e1fc264e5a4acc30543bea075be43vboxsync pThis->aOperands[pThis->idxMrmRmOp].iMemBaseReg = 0;
cb0578a5309e1fc264e5a4acc30543bea075be43vboxsync pThis->aOperands[pThis->idxMrmRmOp].iMemIndexReg = UINT8_MAX;
cb0578a5309e1fc264e5a4acc30543bea075be43vboxsync pThis->aOperands[pThis->idxMrmRmOp].uMemScale = 1;
cb0578a5309e1fc264e5a4acc30543bea075be43vboxsync pThis->bModRm &= ~(X86_MODRM_RM_MASK | X86_MODRM_MOD_MASK);
cb0578a5309e1fc264e5a4acc30543bea075be43vboxsync pThis->bModRm |= iMod << X86_MODRM_MOD_SHIFT;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pThis->fRexB = false;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pThis->fRexX = false;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pThis->fHasMemoryOperand = true;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pThis->fHasRegCollisionDirect = false;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pThis->fHasRegCollisionMemIndex = false;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pThis->fHasRegCollisionMemBase = iReg == pThis->fHasHighByteRegInMrmReg * 4
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync && CIDET_OF_K_IS_GPR(pThis->fMrmRmOp);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pThis->fHasRegCollisionMem = pThis->fHasRegCollisionMemBase;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pThis->fHasStackRegInMrmRmBase = false;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return true;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync}
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync/**
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * Selects the next MOD & R/M encoding.
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync *
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * @returns @c true if done, @c false if the next wheel needs to be moved.
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * @param pThis The core state structure.
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * @param iReg The value of MODRM.REG /w REX.R applied.
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncstatic bool cidetCoreSetupNextBaseEncoding_MrmRmMod(PCIDETCORE pThis, uint8_t iReg)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync{
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (pThis->cbAddrMode == 2)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return cidetCoreSetupNextBaseEncoding_MrmRmMod_16bit(pThis, iReg);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (pThis->cbAddrMode == 4)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return cidetCoreSetupNextBaseEncoding_MrmRmMod_32bit64bit(pThis, iReg, false);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (pThis->cbAddrMode == 8)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return cidetCoreSetupNextBaseEncoding_MrmRmMod_32bit64bit(pThis, iReg, true);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync AssertReleaseFailedReturn(false);
105b1a31b6037dbe14acb8d09e60da540885202bvboxsync}
105b1a31b6037dbe14acb8d09e60da540885202bvboxsync
105b1a31b6037dbe14acb8d09e60da540885202bvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync/**
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * Selects the next SIB base register (/ encoding).
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync *
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * @returns @c true if done, @c false if the next wheel needs to be moved.
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * @param pThis The core state structure.
2721dfb0e330d57ba888311520f5a343c64e7cefvboxsync * @param iReg The value of MODRM.REG /w REX.R applied.
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncstatic bool cidetCoreSetupNextBaseEncoding_SibBase(PCIDETCORE pThis, uint8_t iReg)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync{
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync AssertRelease(!pThis->fRexB || CIDETMODE_IS_64BIT(pThis->bMode));
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync uint8_t iBase = (pThis->bSib & X86_SIB_BASE_MASK) + pThis->fRexB * 8;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync iBase = (iBase + 1) & (CIDETMODE_IS_64BIT(pThis->bMode) && !pThis->fNoRexPrefix ? 15 : 7);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if ((iBase & 7) == 5 && (pThis->bModRm & X86_MODRM_MOD_MASK) == 0)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pThis->aOperands[pThis->idxMrmRmOp].cbMemDisp = 4;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pThis->aOperands[pThis->idxMrmRmOp].iMemBaseReg = UINT8_MAX;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync else
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if ((iBase & 7) == 6 && (pThis->bModRm & X86_MODRM_MOD_MASK) == 0)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pThis->aOperands[pThis->idxMrmRmOp].cbMemDisp = 0;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pThis->aOperands[pThis->idxMrmRmOp].iMemBaseReg = iBase;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pThis->bSib &= ~X86_SIB_BASE_MASK;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pThis->bSib |= iBase & X86_SIB_BASE_MASK;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pThis->fRexB = iBase >= 8;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pThis->fHasRegCollisionMemBase = pThis->aOperands[pThis->idxMrmRmOp].iMemBaseReg
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync == iReg - pThis->fHasHighByteRegInMrmReg * 4
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync && CIDET_OF_K_IS_GPR(pThis->fMrmRegOp);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pThis->fHasRegCollisionMem = pThis->fHasRegCollisionMemBase || pThis->fHasRegCollisionMemIndex;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pThis->fHasStackRegInMrmRmBase = iBase == X86_GREG_xSP;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return iBase != 0;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync}
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync/**
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * Selects the next SIB index register (/ encoding).
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync *
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * @returns @c true if done, @c false if the next wheel needs to be moved.
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * @param pThis The core state structure.
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * @param iReg The value of MODRM.REG /w REX.R applied.
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncstatic bool cidetCoreSetupNextBaseEncoding_SibIndex(PCIDETCORE pThis, uint8_t iReg)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync{
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync AssertRelease(!pThis->fRexX || CIDETMODE_IS_64BIT(pThis->bMode));
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync Assert(pThis->idxMrmRmOp < RT_ELEMENTS(pThis->aOperands) && pThis->aOperands[pThis->idxMrmRmOp].fIsMem);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync uint8_t iIndex = ((pThis->bSib >> X86_SIB_INDEX_SHIFT) & X86_SIB_INDEX_SMASK) + pThis->fRexX * 8;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync iIndex = (iIndex + 1) & (CIDETMODE_IS_64BIT(pThis->bMode) && !pThis->fNoRexPrefix ? 15 : 7);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (iIndex == 4 && !pThis->fUsesVexIndexRegs)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pThis->aOperands[pThis->idxMrmRmOp].iMemIndexReg = UINT8_MAX;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync else
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pThis->aOperands[pThis->idxMrmRmOp].iMemIndexReg = iIndex;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pThis->bSib &= ~X86_SIB_INDEX_MASK;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pThis->bSib |= (iIndex & X86_SIB_INDEX_SMASK) << X86_SIB_INDEX_SHIFT;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pThis->fRexX = iIndex >= 8;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pThis->fHasRegCollisionMemIndex = pThis->aOperands[pThis->idxMrmRmOp].iMemIndexReg
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync == iReg - pThis->fHasHighByteRegInMrmReg * 4
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync && ( !pThis->fUsesVexIndexRegs
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync ? CIDET_OF_K_IS_GPR(pThis->fMrmRegOp) : CIDET_OF_K_IS_VRX(pThis->fMrmRegOp) );
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pThis->fHasRegCollisionMem = pThis->fHasRegCollisionMemBase || pThis->fHasRegCollisionMemIndex;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return iIndex != 0;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync}
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync/**
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * Selects the next SIB scale.
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync *
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * @returns @c true if done, @c false if the next wheel needs to be moved.
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * @param pThis The core state structure.
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * @param iReg The value of MODRM.REG /w REX.R applied.
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync */
4c98b8b05f3783351cf256cc90cd4478fb28b62bvboxsyncstatic bool cidetCoreSetupNextBaseEncoding_SibScale(PCIDETCORE pThis, uint8_t iReg)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync{
4c98b8b05f3783351cf256cc90cd4478fb28b62bvboxsync switch ((pThis->bSib >> X86_SIB_SCALE_SHIFT) & X86_SIB_SCALE_SMASK)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync case 0:
4c98b8b05f3783351cf256cc90cd4478fb28b62bvboxsync pThis->bSib |= 1 << X86_SIB_SCALE_SHIFT;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pThis->aOperands[pThis->idxMrmRmOp].uMemScale = 2;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return true;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync case 1:
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pThis->bSib &= ~X86_SIB_SCALE_MASK;
4c98b8b05f3783351cf256cc90cd4478fb28b62bvboxsync pThis->bSib |= 2 << X86_SIB_SCALE_SHIFT;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pThis->aOperands[pThis->idxMrmRmOp].uMemScale = 4;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return true;
4c98b8b05f3783351cf256cc90cd4478fb28b62bvboxsync case 2:
4c98b8b05f3783351cf256cc90cd4478fb28b62bvboxsync pThis->bSib |= 3 << X86_SIB_SCALE_SHIFT;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pThis->aOperands[pThis->idxMrmRmOp].uMemScale = 8;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return true;
ad290511521ce8388a9926b165241ecf83c330a7vboxsync case 3:
cb0578a5309e1fc264e5a4acc30543bea075be43vboxsync pThis->bSib &= ~X86_SIB_SCALE_MASK;
cb0578a5309e1fc264e5a4acc30543bea075be43vboxsync pThis->aOperands[pThis->idxMrmRmOp].uMemScale = 1;
cb0578a5309e1fc264e5a4acc30543bea075be43vboxsync return false;
cb0578a5309e1fc264e5a4acc30543bea075be43vboxsync
cb0578a5309e1fc264e5a4acc30543bea075be43vboxsync default: AssertReleaseFailedReturn(false);
cb0578a5309e1fc264e5a4acc30543bea075be43vboxsync }
cb0578a5309e1fc264e5a4acc30543bea075be43vboxsync}
cb0578a5309e1fc264e5a4acc30543bea075be43vboxsync
cb0578a5309e1fc264e5a4acc30543bea075be43vboxsync
cb0578a5309e1fc264e5a4acc30543bea075be43vboxsync/**
cb0578a5309e1fc264e5a4acc30543bea075be43vboxsync * Selects the next segment prefix.
cb0578a5309e1fc264e5a4acc30543bea075be43vboxsync *
ad290511521ce8388a9926b165241ecf83c330a7vboxsync * @returns @c true if done, @c false if the next wheel needs to be moved.
cb0578a5309e1fc264e5a4acc30543bea075be43vboxsync * @param pThis The core state structure.
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncstatic bool cidetCoreSetupNextBaseEncoding_SegmentPrefix(PCIDETCORE pThis)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync{
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if ( pThis->fHasMemoryOperand
4c98b8b05f3783351cf256cc90cd4478fb28b62bvboxsync && (pThis->fTestCfg & CIDET_TESTCFG_SEG_PRF_MASK))
4c98b8b05f3783351cf256cc90cd4478fb28b62bvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync switch (pThis->uSegPrf)
4c98b8b05f3783351cf256cc90cd4478fb28b62bvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync case X86_SREG_COUNT:
4c98b8b05f3783351cf256cc90cd4478fb28b62bvboxsync pThis->uSegPrf = X86_SREG_ES;
4c98b8b05f3783351cf256cc90cd4478fb28b62bvboxsync if (pThis->fTestCfg & CIDET_TESTCFG_SEG_PRF_ES)
4c98b8b05f3783351cf256cc90cd4478fb28b62bvboxsync return true;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync /* fall thru */
4c98b8b05f3783351cf256cc90cd4478fb28b62bvboxsync case X86_SREG_ES:
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pThis->uSegPrf = X86_SREG_CS;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (pThis->fTestCfg & CIDET_TESTCFG_SEG_PRF_CS)
4c98b8b05f3783351cf256cc90cd4478fb28b62bvboxsync return true;
4c98b8b05f3783351cf256cc90cd4478fb28b62bvboxsync /* fall thru */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync case X86_SREG_CS:
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pThis->uSegPrf = X86_SREG_SS;
4c98b8b05f3783351cf256cc90cd4478fb28b62bvboxsync if (pThis->fTestCfg & CIDET_TESTCFG_SEG_PRF_SS)
4c98b8b05f3783351cf256cc90cd4478fb28b62bvboxsync return true;
3fa7a7e633f46a212052b510cdb8cee41f279a67vboxsync /* fall thru */
4c98b8b05f3783351cf256cc90cd4478fb28b62bvboxsync case X86_SREG_SS:
4c98b8b05f3783351cf256cc90cd4478fb28b62bvboxsync pThis->uSegPrf = X86_SREG_DS;
09f4b412099acda62997fd82c8608075c453b3ebvboxsync if (pThis->fTestCfg & CIDET_TESTCFG_SEG_PRF_DS)
3fa7a7e633f46a212052b510cdb8cee41f279a67vboxsync return true;
09f4b412099acda62997fd82c8608075c453b3ebvboxsync /* fall thru */
67b8a5a52c43a79ea7e159dbbeec99687fb9cd3bvboxsync case X86_SREG_DS:
4c98b8b05f3783351cf256cc90cd4478fb28b62bvboxsync pThis->uSegPrf = X86_SREG_FS;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (pThis->fTestCfg & CIDET_TESTCFG_SEG_PRF_FS)
4c98b8b05f3783351cf256cc90cd4478fb28b62bvboxsync return true;
c7d2f5508ab9703a7a6c5cce5c9d4bf335af660avboxsync /* fall thru */
5295c362853081eaa3944247171746a3aad9a826vboxsync case X86_SREG_FS:
3a343ca21a267ec3c54e2317e2ed18fe99b8ebbbvboxsync pThis->uSegPrf = X86_SREG_GS;
4c98b8b05f3783351cf256cc90cd4478fb28b62bvboxsync if (pThis->fTestCfg & CIDET_TESTCFG_SEG_PRF_GS)
3a343ca21a267ec3c54e2317e2ed18fe99b8ebbbvboxsync return true;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync /* fall thru */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync case X86_SREG_GS:
4c98b8b05f3783351cf256cc90cd4478fb28b62bvboxsync break;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync default: AssertReleaseFailedBreak();
105b1a31b6037dbe14acb8d09e60da540885202bvboxsync }
105b1a31b6037dbe14acb8d09e60da540885202bvboxsync pThis->uSegPrf = X86_SREG_COUNT;
ad290511521ce8388a9926b165241ecf83c330a7vboxsync }
67b8a5a52c43a79ea7e159dbbeec99687fb9cd3bvboxsync return false;
ad290511521ce8388a9926b165241ecf83c330a7vboxsync}
67b8a5a52c43a79ea7e159dbbeec99687fb9cd3bvboxsync
105b1a31b6037dbe14acb8d09e60da540885202bvboxsync
105b1a31b6037dbe14acb8d09e60da540885202bvboxsync/**
105b1a31b6037dbe14acb8d09e60da540885202bvboxsync * Updates the variable sized operands.
105b1a31b6037dbe14acb8d09e60da540885202bvboxsync *
ad290511521ce8388a9926b165241ecf83c330a7vboxsync * @param pThis The core state structure.
7b6926b2bf44f326f40e1d9d1ce33a4dff0a2c67vboxsync */
ad290511521ce8388a9926b165241ecf83c330a7vboxsyncstatic void cidetCoreUpdateOperandSizes(PCIDETCORE pThis)
105b1a31b6037dbe14acb8d09e60da540885202bvboxsync{
6b2a50fc09aa4f7ce2082284f082d97a2c738321vboxsync uint8_t iOp = pThis->cOperands;
3fa7a7e633f46a212052b510cdb8cee41f279a67vboxsync while (iOp-- > 0)
3fa7a7e633f46a212052b510cdb8cee41f279a67vboxsync pThis->aOperands[iOp].cb = (uint8_t)CidetCoreGetOperandSize(pThis, iOp);
3fa7a7e633f46a212052b510cdb8cee41f279a67vboxsync}
3fa7a7e633f46a212052b510cdb8cee41f279a67vboxsync
3fa7a7e633f46a212052b510cdb8cee41f279a67vboxsync
3fa7a7e633f46a212052b510cdb8cee41f279a67vboxsync/**
3fa7a7e633f46a212052b510cdb8cee41f279a67vboxsync * Selects the next operand size.
3fa7a7e633f46a212052b510cdb8cee41f279a67vboxsync *
3fa7a7e633f46a212052b510cdb8cee41f279a67vboxsync * @returns @c true if done, @c false if the next wheel needs to be moved.
3fa7a7e633f46a212052b510cdb8cee41f279a67vboxsync * @param pThis The core state structure.
3fa7a7e633f46a212052b510cdb8cee41f279a67vboxsync */
3fa7a7e633f46a212052b510cdb8cee41f279a67vboxsyncstatic bool cidetCoreSetupNextBaseEncoding_OperandSize(PCIDETCORE pThis)
3fa7a7e633f46a212052b510cdb8cee41f279a67vboxsync{
3fa7a7e633f46a212052b510cdb8cee41f279a67vboxsync if (CidetInstrRespondsToOperandSizePrefixes(pThis->pCurInstr))
3fa7a7e633f46a212052b510cdb8cee41f279a67vboxsync {
3fa7a7e633f46a212052b510cdb8cee41f279a67vboxsync if (CIDETMODE_IS_64BIT(pThis->bMode))
3fa7a7e633f46a212052b510cdb8cee41f279a67vboxsync {
3fa7a7e633f46a212052b510cdb8cee41f279a67vboxsync switch (pThis->fOpSizePrf + pThis->fRexW * 2)
3fa7a7e633f46a212052b510cdb8cee41f279a67vboxsync {
3fa7a7e633f46a212052b510cdb8cee41f279a67vboxsync case 0:
3fa7a7e633f46a212052b510cdb8cee41f279a67vboxsync pThis->fOpSizePrf = true;
3fa7a7e633f46a212052b510cdb8cee41f279a67vboxsync cidetCoreUpdateOperandSizes(pThis);
3fa7a7e633f46a212052b510cdb8cee41f279a67vboxsync return true;
3fa7a7e633f46a212052b510cdb8cee41f279a67vboxsync case 1:
3fa7a7e633f46a212052b510cdb8cee41f279a67vboxsync pThis->fOpSizePrf = false;
3fa7a7e633f46a212052b510cdb8cee41f279a67vboxsync if (pThis->fNoRexPrefix)
3fa7a7e633f46a212052b510cdb8cee41f279a67vboxsync break;
3fa7a7e633f46a212052b510cdb8cee41f279a67vboxsync pThis->fRexW = true;
3fa7a7e633f46a212052b510cdb8cee41f279a67vboxsync cidetCoreUpdateOperandSizes(pThis);
3fa7a7e633f46a212052b510cdb8cee41f279a67vboxsync return true;
3fa7a7e633f46a212052b510cdb8cee41f279a67vboxsync case 2:
3fa7a7e633f46a212052b510cdb8cee41f279a67vboxsync pThis->fOpSizePrf = true; /* check that it's ignored. */
3fa7a7e633f46a212052b510cdb8cee41f279a67vboxsync cidetCoreUpdateOperandSizes(pThis);
3fa7a7e633f46a212052b510cdb8cee41f279a67vboxsync return true;
3fa7a7e633f46a212052b510cdb8cee41f279a67vboxsync default: AssertReleaseFailed();
3fa7a7e633f46a212052b510cdb8cee41f279a67vboxsync case 3:
3fa7a7e633f46a212052b510cdb8cee41f279a67vboxsync break;
3fa7a7e633f46a212052b510cdb8cee41f279a67vboxsync }
3fa7a7e633f46a212052b510cdb8cee41f279a67vboxsync }
3fa7a7e633f46a212052b510cdb8cee41f279a67vboxsync else
3fa7a7e633f46a212052b510cdb8cee41f279a67vboxsync {
3fa7a7e633f46a212052b510cdb8cee41f279a67vboxsync if (!pThis->fOpSizePrf)
3fa7a7e633f46a212052b510cdb8cee41f279a67vboxsync {
3fa7a7e633f46a212052b510cdb8cee41f279a67vboxsync pThis->fOpSizePrf = true;
3fa7a7e633f46a212052b510cdb8cee41f279a67vboxsync cidetCoreUpdateOperandSizes(pThis);
3fa7a7e633f46a212052b510cdb8cee41f279a67vboxsync return true;
3fa7a7e633f46a212052b510cdb8cee41f279a67vboxsync }
3fa7a7e633f46a212052b510cdb8cee41f279a67vboxsync }
3fa7a7e633f46a212052b510cdb8cee41f279a67vboxsync pThis->fRexW = false;
3fa7a7e633f46a212052b510cdb8cee41f279a67vboxsync pThis->fOpSizePrf = false;
3fa7a7e633f46a212052b510cdb8cee41f279a67vboxsync cidetCoreUpdateOperandSizes(pThis);
3fa7a7e633f46a212052b510cdb8cee41f279a67vboxsync }
3fa7a7e633f46a212052b510cdb8cee41f279a67vboxsync return false;
3fa7a7e633f46a212052b510cdb8cee41f279a67vboxsync}
3fa7a7e633f46a212052b510cdb8cee41f279a67vboxsync
3fa7a7e633f46a212052b510cdb8cee41f279a67vboxsync
3fa7a7e633f46a212052b510cdb8cee41f279a67vboxsyncbool CidetCoreSetupNextBaseEncoding(PCIDETCORE pThis)
6b2a50fc09aa4f7ce2082284f082d97a2c738321vboxsync{
6b2a50fc09aa4f7ce2082284f082d97a2c738321vboxsync if (pThis->fUsesModRm)
6b2a50fc09aa4f7ce2082284f082d97a2c738321vboxsync {
6b2a50fc09aa4f7ce2082284f082d97a2c738321vboxsync /*
73ba84f95f918cc170be38908ad240fbb2f8f354vboxsync * The wheels are lined up as follows:
73ba84f95f918cc170be38908ad240fbb2f8f354vboxsync * 1. Address size prefix.
73ba84f95f918cc170be38908ad240fbb2f8f354vboxsync * 2. MODRM.MOD
5159c4c6485473c77871b515c15b59c3caa60b46vboxsync * 3. MODRM.REG + REX.R
5159c4c6485473c77871b515c15b59c3caa60b46vboxsync * 4. MODRM.R/M + REX.B
5159c4c6485473c77871b515c15b59c3caa60b46vboxsync * 5. SIB - MODRM.R/M == 4 && MODRM.MOD != 3:
5159c4c6485473c77871b515c15b59c3caa60b46vboxsync * 5a) SIB.BASE + REX.B
5159c4c6485473c77871b515c15b59c3caa60b46vboxsync * 5b) SIB.INDEX + REX.X
5159c4c6485473c77871b515c15b59c3caa60b46vboxsync * 5c) SIB.SCALE
5159c4c6485473c77871b515c15b59c3caa60b46vboxsync * 6. Segment prefix overrides if applicable and supported (memory).
5159c4c6485473c77871b515c15b59c3caa60b46vboxsync * 7. Operand size prefix and REX.W if applicable.
5159c4c6485473c77871b515c15b59c3caa60b46vboxsync */
5159c4c6485473c77871b515c15b59c3caa60b46vboxsync if (cidetCoreSetupNextBaseEncoding_OperandSize(pThis))
5159c4c6485473c77871b515c15b59c3caa60b46vboxsync return true;
5159c4c6485473c77871b515c15b59c3caa60b46vboxsync if (cidetCoreSetupNextBaseEncoding_SegmentPrefix(pThis))
5159c4c6485473c77871b515c15b59c3caa60b46vboxsync return true;
5159c4c6485473c77871b515c15b59c3caa60b46vboxsync
5159c4c6485473c77871b515c15b59c3caa60b46vboxsync /* The ModR/M register value for collision detection. */
5159c4c6485473c77871b515c15b59c3caa60b46vboxsync uint8_t iReg = ((pThis->bModRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) + pThis->fRexR * 8;
5159c4c6485473c77871b515c15b59c3caa60b46vboxsync
5159c4c6485473c77871b515c15b59c3caa60b46vboxsync if (pThis->fSib)
5159c4c6485473c77871b515c15b59c3caa60b46vboxsync {
5159c4c6485473c77871b515c15b59c3caa60b46vboxsync AssertRelease(pThis->fHasMemoryOperand);
5159c4c6485473c77871b515c15b59c3caa60b46vboxsync if (cidetCoreSetupNextBaseEncoding_SibScale(pThis, iReg))
5159c4c6485473c77871b515c15b59c3caa60b46vboxsync return true;
5159c4c6485473c77871b515c15b59c3caa60b46vboxsync if (cidetCoreSetupNextBaseEncoding_SibIndex(pThis, iReg))
5159c4c6485473c77871b515c15b59c3caa60b46vboxsync return true;
5159c4c6485473c77871b515c15b59c3caa60b46vboxsync if (cidetCoreSetupNextBaseEncoding_SibBase(pThis, iReg))
73ba84f95f918cc170be38908ad240fbb2f8f354vboxsync return true;
73ba84f95f918cc170be38908ad240fbb2f8f354vboxsync Assert(pThis->bSib == 0);
6b2a50fc09aa4f7ce2082284f082d97a2c738321vboxsync pThis->fSib = false;
6b2a50fc09aa4f7ce2082284f082d97a2c738321vboxsync }
6b2a50fc09aa4f7ce2082284f082d97a2c738321vboxsync
6b2a50fc09aa4f7ce2082284f082d97a2c738321vboxsync if (cidetCoreSetupNextBaseEncoding_MrmRmMod(pThis, iReg))
3fa7a7e633f46a212052b510cdb8cee41f279a67vboxsync return true;
3fa7a7e633f46a212052b510cdb8cee41f279a67vboxsync if (cidetCoreSetupNextBaseEncoding_MrmReg(pThis, iReg))
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return true;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (cidetCoreSetupNextBaseEncoding_AddressSize(pThis))
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return true;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync else
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync AssertFailedReturn(false);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return false;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync}
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncbool CidetCoreSetupFirstBaseEncoding(PCIDETCORE pThis)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync{
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync /*
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * Reset all the knobs and wheels.
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pThis->fSib = false;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pThis->uSegPrf = X86_SREG_COUNT;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pThis->fAddrSizePrf = false;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pThis->fOpSizePrf = false;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pThis->fRexW = false;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pThis->fRexR = false;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pThis->fRexX = false;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pThis->fRexB = false;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pThis->fRex = false;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pThis->bModRm = 0;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pThis->bSib = 0;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync /* Indicators. */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pThis->cbAddrMode = CIDETMODE_GET_BYTE_COUNT(pThis->bMode);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pThis->fHasMemoryOperand = false;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pThis->fHasRegCollisionMem = false;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pThis->fHasRegCollisionMemBase = false;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pThis->fHasRegCollisionMemIndex = false;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pThis->fHasStackRegInMrmRmBase = false;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync /*
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * Now, drill down on the instruction encoding.
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (pThis->pCurInstr->fFlags & CIDET_IF_MODRM)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync Assert(pThis->fUsesModRm == true);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync cidetCoreSetupFirstBaseEncoding_MrmReg(pThis);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (pThis->cbAddrMode == 2)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync cidetCoreSetupFirstBaseEncoding_MrmRmMod_16bit(pThis, 0);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync else if (pThis->cbAddrMode == 4)
ad290511521ce8388a9926b165241ecf83c330a7vboxsync cidetCoreSetupFirstBaseEncoding_MrmRmMod_32bit64bit(pThis, 0, false);
67b8a5a52c43a79ea7e159dbbeec99687fb9cd3bvboxsync else if (pThis->cbAddrMode == 8)
ad290511521ce8388a9926b165241ecf83c330a7vboxsync cidetCoreSetupFirstBaseEncoding_MrmRmMod_32bit64bit(pThis, 0, true);
67b8a5a52c43a79ea7e159dbbeec99687fb9cd3bvboxsync else
105b1a31b6037dbe14acb8d09e60da540885202bvboxsync AssertReleaseFailedReturn(false);
105b1a31b6037dbe14acb8d09e60da540885202bvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync else
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync AssertFailedReturn(false);
3fa7a7e633f46a212052b510cdb8cee41f279a67vboxsync return true;
3fa7a7e633f46a212052b510cdb8cee41f279a67vboxsync}
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync/**
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * The next memory operand configuration.
3a343ca21a267ec3c54e2317e2ed18fe99b8ebbbvboxsync *
3a343ca21a267ec3c54e2317e2ed18fe99b8ebbbvboxsync * @returns true if new one to test, false if we've reached end already.
3a343ca21a267ec3c54e2317e2ed18fe99b8ebbbvboxsync * @param pThis The core state structure.
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncbool CidetCoreSetupNextMemoryOperandConfig(PCIDETCORE pThis)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync{
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return false;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync}
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync/**
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * Sets up the first memory operand configuration and counts memory operands.
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync *
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * @returns true on success, false if no data buffers configured or failure.
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * @param pThis The core state structure.
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncbool CidetCoreSetupFirstMemoryOperandConfig(PCIDETCORE pThis)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync{
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pThis->cMemoryOperands = 0;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync PCIDETBUF pDataBuf = &pThis->DataBuf;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync uint8_t idxOp = pThis->cOperands;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync while (idxOp-- > 0)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (!pThis->aOperands[idxOp].fIsMem)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pThis->aOperands[idxOp].pDataBuf = NULL;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync else
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (RT_UNLIKELY(!pThis->cDataBufConfigs))
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return false;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pDataBuf->idxCfg = 0;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pDataBuf->pCfg = &pThis->paDataBufConfigs[0];
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pDataBuf->off = 0;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pDataBuf->cb = pThis->aOperands[idxOp].cb;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pDataBuf->cbSegLimit = UINT16_MAX;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pDataBuf->offSegBase = 0;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pDataBuf->fActive = false;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pDataBuf->idxOp = idxOp;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pDataBuf->fXcptAfterInstruction = false;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pDataBuf->enmExpectXcpt = kCidetExpectXcpt_None;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pThis->aOperands[idxOp].pDataBuf = pDataBuf;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pThis->cMemoryOperands++;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pDataBuf++;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync /** @todo implement more than one memory operand. */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync AssertReleaseReturn(pThis->cMemoryOperands <= 1, false);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return true;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync}
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync/**
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * The next code buffer configuration.
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync *
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * @returns true if new one to test, false if we've reached end already.
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * @param pThis The core state structure.
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncbool CidetCoreSetupNextCodeBufferConfig(PCIDETCORE pThis)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync{
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return false;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync}
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync/**
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * Sets up the first code buffer configuration.
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync *
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * @returns true on success, false if no data buffers configured or failure.
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * @param pThis The core state structure.
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncbool CidetCoreSetupFirstCodeBufferConfig(PCIDETCORE pThis)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync{
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync Assert(pThis->cCodeBufConfigs > 0);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync Assert(CIDETBUF_IS_CODE(pThis->paCodeBufConfigs[0].fFlags));
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pThis->CodeBuf.idxCfg = 0;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pThis->CodeBuf.pCfg = &pThis->paCodeBufConfigs[0];
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pThis->CodeBuf.off = 0;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pThis->CodeBuf.cb = 0x1000;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pThis->CodeBuf.cbSegLimit = UINT16_MAX;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pThis->CodeBuf.offSegBase = 0;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pThis->CodeBuf.fActive = true;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pThis->CodeBuf.idxOp = 7;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pThis->CodeBuf.fXcptAfterInstruction = false;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pThis->CodeBuf.enmExpectXcpt = kCidetExpectXcpt_None;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return true;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync}
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync/**
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * Gets the (encoded) size of the given operand in the current context.
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync *
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * @returns Size in bytes.
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * @param pThis The core state structure (for context).
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * @param iOp The operand index.
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncuint32_t CidetCoreGetOperandSize(PCIDETCORE pThis, uint8_t iOp)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync{
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync Assert(iOp < RT_ELEMENTS(pThis->aOperands));
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync uint32_t cbOp = g_acbCidetOfSizes[(pThis->aOperands[iOp].fFlags & CIDET_OF_Z_MASK) >> CIDET_OF_Z_SHIFT];
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (cbOp == UINT16_MAX)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync Assert((pThis->aOperands[iOp].fFlags & CIDET_OF_Z_MASK) == CIDET_OF_Z_VAR_WDQ);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (CIDETMODE_IS_64BIT(pThis->bMode))
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (pThis->fRexW)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync cbOp = 8;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync else if (!pThis->fOpSizePrf)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync cbOp = 4;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync else
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync cbOp = 2;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync else if (CIDETMODE_IS_32BIT(pThis->bMode))
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync cbOp = !pThis->fOpSizePrf ? 4 : 2;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync else
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
ad290511521ce8388a9926b165241ecf83c330a7vboxsync Assert(CIDETMODE_IS_16BIT(pThis->bMode));
cb0578a5309e1fc264e5a4acc30543bea075be43vboxsync cbOp = !pThis->fOpSizePrf ? 2 : 4;
cb0578a5309e1fc264e5a4acc30543bea075be43vboxsync }
cb0578a5309e1fc264e5a4acc30543bea075be43vboxsync return cbOp;
cb0578a5309e1fc264e5a4acc30543bea075be43vboxsync }
cb0578a5309e1fc264e5a4acc30543bea075be43vboxsync
cb0578a5309e1fc264e5a4acc30543bea075be43vboxsync if (cbOp == UINT16_MAX - 1)
cb0578a5309e1fc264e5a4acc30543bea075be43vboxsync {
cb0578a5309e1fc264e5a4acc30543bea075be43vboxsync Assert((pThis->aOperands[iOp].fFlags & CIDET_OF_Z_MASK) == CIDET_OF_Z_SPECIAL);
cb0578a5309e1fc264e5a4acc30543bea075be43vboxsync AssertReleaseFailedReturn(0);
cb0578a5309e1fc264e5a4acc30543bea075be43vboxsync }
cb0578a5309e1fc264e5a4acc30543bea075be43vboxsync
cb0578a5309e1fc264e5a4acc30543bea075be43vboxsync if (cbOp)
cb0578a5309e1fc264e5a4acc30543bea075be43vboxsync {
cb0578a5309e1fc264e5a4acc30543bea075be43vboxsync#ifdef VBOX_STRICT
cb0578a5309e1fc264e5a4acc30543bea075be43vboxsync switch (cbOp)
cb0578a5309e1fc264e5a4acc30543bea075be43vboxsync {
cb0578a5309e1fc264e5a4acc30543bea075be43vboxsync case 1: Assert((pThis->aOperands[iOp].fFlags & CIDET_OF_Z_MASK) == CIDET_OF_Z_BYTE); break;
cb0578a5309e1fc264e5a4acc30543bea075be43vboxsync case 2: Assert((pThis->aOperands[iOp].fFlags & CIDET_OF_Z_MASK) == CIDET_OF_Z_WORD); break;
fdb57e5580007400346665b64c0e14ca1d149019vboxsync case 4: Assert((pThis->aOperands[iOp].fFlags & CIDET_OF_Z_MASK) == CIDET_OF_Z_DWORD); break;
fdb57e5580007400346665b64c0e14ca1d149019vboxsync case 8: Assert((pThis->aOperands[iOp].fFlags & CIDET_OF_Z_MASK) == CIDET_OF_Z_QWORD); break;
fdb57e5580007400346665b64c0e14ca1d149019vboxsync case 10: Assert((pThis->aOperands[iOp].fFlags & CIDET_OF_Z_MASK) == CIDET_OF_Z_TBYTE); break;
fdb57e5580007400346665b64c0e14ca1d149019vboxsync case 16: Assert((pThis->aOperands[iOp].fFlags & CIDET_OF_Z_MASK) == CIDET_OF_Z_OWORD); break;
fdb57e5580007400346665b64c0e14ca1d149019vboxsync case 32: Assert((pThis->aOperands[iOp].fFlags & CIDET_OF_Z_MASK) == CIDET_OF_Z_YWORD); break;
fdb57e5580007400346665b64c0e14ca1d149019vboxsync case 64: Assert((pThis->aOperands[iOp].fFlags & CIDET_OF_Z_MASK) == CIDET_OF_Z_ZWORD); break;
fdb57e5580007400346665b64c0e14ca1d149019vboxsync default: AssertFailed();
cb0578a5309e1fc264e5a4acc30543bea075be43vboxsync }
cb0578a5309e1fc264e5a4acc30543bea075be43vboxsync#endif
cb0578a5309e1fc264e5a4acc30543bea075be43vboxsync return cbOp;
cb0578a5309e1fc264e5a4acc30543bea075be43vboxsync }
cb0578a5309e1fc264e5a4acc30543bea075be43vboxsync AssertReleaseFailedReturn(0);
cb0578a5309e1fc264e5a4acc30543bea075be43vboxsync}
cb0578a5309e1fc264e5a4acc30543bea075be43vboxsync
cb0578a5309e1fc264e5a4acc30543bea075be43vboxsync
fdb57e5580007400346665b64c0e14ca1d149019vboxsyncbool CideCoreSetInstruction(PCIDETCORE pThis, PCCIDETINSTR pInstr)
fdb57e5580007400346665b64c0e14ca1d149019vboxsync{
fdb57e5580007400346665b64c0e14ca1d149019vboxsync AssertReleaseMsgReturn(RT_VALID_PTR(pInstr), ("%p\n", pInstr), false);
fdb57e5580007400346665b64c0e14ca1d149019vboxsync
fdb57e5580007400346665b64c0e14ca1d149019vboxsync pThis->pCurInstr = pInstr;
fdb57e5580007400346665b64c0e14ca1d149019vboxsync
fdb57e5580007400346665b64c0e14ca1d149019vboxsync /*
fdb57e5580007400346665b64c0e14ca1d149019vboxsync * Extract info from the instruction descriptor.
fdb57e5580007400346665b64c0e14ca1d149019vboxsync */
fdb57e5580007400346665b64c0e14ca1d149019vboxsync pThis->fUsesModRm = false;
fdb57e5580007400346665b64c0e14ca1d149019vboxsync pThis->fUsesVexIndexRegs = false;
fdb57e5580007400346665b64c0e14ca1d149019vboxsync pThis->idxMrmRegOp = 7;
fdb57e5580007400346665b64c0e14ca1d149019vboxsync pThis->idxMrmRmOp = 7;
fdb57e5580007400346665b64c0e14ca1d149019vboxsync pThis->fMrmRegOp = 0;
fdb57e5580007400346665b64c0e14ca1d149019vboxsync pThis->fMrmRmOp = 0;
fdb57e5580007400346665b64c0e14ca1d149019vboxsync pThis->fInstrFlags = pInstr->fFlags;
fdb57e5580007400346665b64c0e14ca1d149019vboxsync pThis->cOperands = pInstr->cOperands;
fdb57e5580007400346665b64c0e14ca1d149019vboxsync if (pInstr->fFlags & CIDET_IF_MODRM)
fdb57e5580007400346665b64c0e14ca1d149019vboxsync {
fdb57e5580007400346665b64c0e14ca1d149019vboxsync pThis->fUsesModRm = true;
fdb57e5580007400346665b64c0e14ca1d149019vboxsync for (uint8_t iOp = 0; iOp < pInstr->cOperands; iOp++)
7ea49b4765b66fc68d2e6c1cb2a647b53a4aea24vboxsync if (pInstr->afOperands[iOp] & CIDET_OF_M_REG)
fdb57e5580007400346665b64c0e14ca1d149019vboxsync {
fdb57e5580007400346665b64c0e14ca1d149019vboxsync pThis->idxMrmRegOp = iOp;
fdb57e5580007400346665b64c0e14ca1d149019vboxsync pThis->fMrmRegOp = pInstr->afOperands[iOp];
fdb57e5580007400346665b64c0e14ca1d149019vboxsync }
fdb57e5580007400346665b64c0e14ca1d149019vboxsync else if (pInstr->afOperands[iOp] & CIDET_OF_M_RM)
fdb57e5580007400346665b64c0e14ca1d149019vboxsync {
fdb57e5580007400346665b64c0e14ca1d149019vboxsync pThis->idxMrmRmOp = iOp;
fdb57e5580007400346665b64c0e14ca1d149019vboxsync pThis->fMrmRmOp = pInstr->afOperands[iOp];
fdb57e5580007400346665b64c0e14ca1d149019vboxsync }
fdb57e5580007400346665b64c0e14ca1d149019vboxsync }
fdb57e5580007400346665b64c0e14ca1d149019vboxsync else
fdb57e5580007400346665b64c0e14ca1d149019vboxsync AssertFailedReturn(false);
fdb57e5580007400346665b64c0e14ca1d149019vboxsync
fdb57e5580007400346665b64c0e14ca1d149019vboxsync uint8_t iOp;
fdb57e5580007400346665b64c0e14ca1d149019vboxsync for (iOp = 0; iOp < pInstr->cOperands; iOp++)
fdb57e5580007400346665b64c0e14ca1d149019vboxsync {
fdb57e5580007400346665b64c0e14ca1d149019vboxsync pThis->aOperands[iOp].fFlags = pInstr->afOperands[iOp];
fdb57e5580007400346665b64c0e14ca1d149019vboxsync pThis->aOperands[iOp].iReg = UINT8_MAX;
fdb57e5580007400346665b64c0e14ca1d149019vboxsync pThis->aOperands[iOp].cb = (uint8_t)CidetCoreGetOperandSize(pThis, iOp);
fdb57e5580007400346665b64c0e14ca1d149019vboxsync pThis->aOperands[iOp].fIsImmediate = (pInstr->afOperands[iOp] & CIDET_OF_K_MASK) == CIDET_OF_K_IMM;
fdb57e5580007400346665b64c0e14ca1d149019vboxsync pThis->aOperands[iOp].fIsMem = (pInstr->afOperands[iOp] & CIDET_OF_K_MASK) == CIDET_OF_K_MEM;
fdb57e5580007400346665b64c0e14ca1d149019vboxsync pThis->aOperands[iOp].fIsRipRelative = false;
fdb57e5580007400346665b64c0e14ca1d149019vboxsync pThis->aOperands[iOp].cbMemDisp = 0;
fdb57e5580007400346665b64c0e14ca1d149019vboxsync pThis->aOperands[iOp].iMemBaseReg = UINT8_MAX;
fdb57e5580007400346665b64c0e14ca1d149019vboxsync pThis->aOperands[iOp].iMemIndexReg = UINT8_MAX;
fdb57e5580007400346665b64c0e14ca1d149019vboxsync pThis->aOperands[iOp].uMemScale = 1;
fdb57e5580007400346665b64c0e14ca1d149019vboxsync pThis->aOperands[iOp].iEffSeg = UINT8_MAX;
fdb57e5580007400346665b64c0e14ca1d149019vboxsync pThis->aOperands[iOp].offSeg = UINT64_MAX;
fdb57e5580007400346665b64c0e14ca1d149019vboxsync pThis->aOperands[iOp].uEffAddr = UINT64_MAX;
fdb57e5580007400346665b64c0e14ca1d149019vboxsync pThis->aOperands[iOp].uImmDispValue = UINT64_MAX;
fdb57e5580007400346665b64c0e14ca1d149019vboxsync pThis->aOperands[iOp].uMemBaseRegValue = UINT64_MAX;
fdb57e5580007400346665b64c0e14ca1d149019vboxsync pThis->aOperands[iOp].uMemIndexRegValue = UINT64_MAX;
fdb57e5580007400346665b64c0e14ca1d149019vboxsync pThis->aOperands[iOp].In.pv = NULL;
fdb57e5580007400346665b64c0e14ca1d149019vboxsync pThis->aOperands[iOp].Expected.pv = NULL;
fdb57e5580007400346665b64c0e14ca1d149019vboxsync pThis->aOperands[iOp].pDataBuf = NULL;
fdb57e5580007400346665b64c0e14ca1d149019vboxsync }
fdb57e5580007400346665b64c0e14ca1d149019vboxsync
fdb57e5580007400346665b64c0e14ca1d149019vboxsync for (; iOp < RT_ELEMENTS(pThis->aOperands); iOp++)
fdb57e5580007400346665b64c0e14ca1d149019vboxsync {
fdb57e5580007400346665b64c0e14ca1d149019vboxsync pThis->aOperands[iOp].fFlags = 0;
fdb57e5580007400346665b64c0e14ca1d149019vboxsync pThis->aOperands[iOp].iReg = UINT8_MAX;
fdb57e5580007400346665b64c0e14ca1d149019vboxsync pThis->aOperands[iOp].cb = 0;
fdb57e5580007400346665b64c0e14ca1d149019vboxsync pThis->aOperands[iOp].fIsImmediate = false;
fdb57e5580007400346665b64c0e14ca1d149019vboxsync pThis->aOperands[iOp].fIsMem = false;
fdb57e5580007400346665b64c0e14ca1d149019vboxsync pThis->aOperands[iOp].fIsRipRelative = false;
fdb57e5580007400346665b64c0e14ca1d149019vboxsync pThis->aOperands[iOp].cbMemDisp = 0;
fdb57e5580007400346665b64c0e14ca1d149019vboxsync pThis->aOperands[iOp].iMemBaseReg = UINT8_MAX;
fdb57e5580007400346665b64c0e14ca1d149019vboxsync pThis->aOperands[iOp].iMemIndexReg = UINT8_MAX;
fdb57e5580007400346665b64c0e14ca1d149019vboxsync pThis->aOperands[iOp].uMemScale = 1;
fdb57e5580007400346665b64c0e14ca1d149019vboxsync pThis->aOperands[iOp].iEffSeg = UINT8_MAX;
fdb57e5580007400346665b64c0e14ca1d149019vboxsync pThis->aOperands[iOp].offSeg = UINT64_MAX;
fdb57e5580007400346665b64c0e14ca1d149019vboxsync pThis->aOperands[iOp].uEffAddr = UINT64_MAX;
fdb57e5580007400346665b64c0e14ca1d149019vboxsync pThis->aOperands[iOp].uImmDispValue = UINT64_MAX;
fdb57e5580007400346665b64c0e14ca1d149019vboxsync pThis->aOperands[iOp].uMemBaseRegValue = UINT64_MAX;
fdb57e5580007400346665b64c0e14ca1d149019vboxsync pThis->aOperands[iOp].uMemIndexRegValue = UINT64_MAX;
fdb57e5580007400346665b64c0e14ca1d149019vboxsync pThis->aOperands[iOp].In.pv = NULL;
fdb57e5580007400346665b64c0e14ca1d149019vboxsync pThis->aOperands[iOp].Expected.pv = NULL;
fdb57e5580007400346665b64c0e14ca1d149019vboxsync pThis->aOperands[iOp].pDataBuf = NULL;
1389294d44ac76b0a25f5655756c9d39855a73efvboxsync }
1389294d44ac76b0a25f5655756c9d39855a73efvboxsync
fdb57e5580007400346665b64c0e14ca1d149019vboxsync /*
fdb57e5580007400346665b64c0e14ca1d149019vboxsync * Reset various things.
fdb57e5580007400346665b64c0e14ca1d149019vboxsync */
fdb57e5580007400346665b64c0e14ca1d149019vboxsync pThis->iInOut = 0;
fdb57e5580007400346665b64c0e14ca1d149019vboxsync
fdb57e5580007400346665b64c0e14ca1d149019vboxsync return true;
fdb57e5580007400346665b64c0e14ca1d149019vboxsync}
fdb57e5580007400346665b64c0e14ca1d149019vboxsync
fdb57e5580007400346665b64c0e14ca1d149019vboxsync
fdb57e5580007400346665b64c0e14ca1d149019vboxsyncbool CidetCoreSetupInOut(PCIDETCORE pThis)
fdb57e5580007400346665b64c0e14ca1d149019vboxsync{
fdb57e5580007400346665b64c0e14ca1d149019vboxsync /*
fdb57e5580007400346665b64c0e14ca1d149019vboxsync * Enumerate the operands.
fdb57e5580007400346665b64c0e14ca1d149019vboxsync */
cb0578a5309e1fc264e5a4acc30543bea075be43vboxsync uint8_t *pbBuf = &pThis->abBuf[0];
cb0578a5309e1fc264e5a4acc30543bea075be43vboxsync pbBuf = RT_ALIGN_PT(pbBuf, 16, uint8_t *);
cb0578a5309e1fc264e5a4acc30543bea075be43vboxsync
cb0578a5309e1fc264e5a4acc30543bea075be43vboxsync uint8_t idxOp = pThis->cOperands;
cb0578a5309e1fc264e5a4acc30543bea075be43vboxsync while (idxOp-- > 0)
ad290511521ce8388a9926b165241ecf83c330a7vboxsync {
cb0578a5309e1fc264e5a4acc30543bea075be43vboxsync if (pThis->aOperands[idxOp].fIsMem)
cb0578a5309e1fc264e5a4acc30543bea075be43vboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync /*
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * Memory operand.
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync Assert(pThis->aOperands[idxOp].fIsMem);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync /* Set the In & Expected members to point to temporary buffer space. */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pThis->aOperands[idxOp].Expected.pu8 = pbBuf;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pbBuf += pThis->aOperands[idxOp].cb;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pbBuf = RT_ALIGN_PT(pbBuf, 16, uint8_t *);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pThis->aOperands[idxOp].In.pu8 = pbBuf;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pbBuf += pThis->aOperands[idxOp].cb;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pbBuf = RT_ALIGN_PT(pbBuf, 16, uint8_t *);
e6ad2e18e663b076aeabfec994947514566a7accvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync /* Initialize the buffer we're gonna use. */
e6ad2e18e663b076aeabfec994947514566a7accvboxsync pThis->aOperands[idxOp].iEffSeg = pThis->uSegPrf != X86_SREG_COUNT
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync ? pThis->uSegPrf
e6ad2e18e663b076aeabfec994947514566a7accvboxsync : !(pThis->aOperands[idxOp].fFlags & CIDET_OF_ALWAYS_SEG_ES) ? X86_SREG_DS
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync : X86_SREG_ES;
e6ad2e18e663b076aeabfec994947514566a7accvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync PCIDETBUF pDataBuf = pThis->aOperands[idxOp].pDataBuf;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync AssertReleaseReturn(pDataBuf, false);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync Assert(pDataBuf->cb == pThis->aOperands[idxOp].cb);
e6ad2e18e663b076aeabfec994947514566a7accvboxsync Assert(pDataBuf->idxOp == idxOp);
e6ad2e18e663b076aeabfec994947514566a7accvboxsync if (!pThis->pfnReInitDataBuf(pThis, pDataBuf))
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pThis->cSkippedReInitDataBuf++;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return false;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
3ea1dbf096240fc221aea99352a74c17a367a9b6vboxsync pDataBuf->fActive = true;
3ea1dbf096240fc221aea99352a74c17a367a9b6vboxsync
3ea1dbf096240fc221aea99352a74c17a367a9b6vboxsync /* Calc buffer related operand members. */
3ea1dbf096240fc221aea99352a74c17a367a9b6vboxsync pThis->aOperands[idxOp].uEffAddr = pDataBuf->uEffBufAddr + pDataBuf->off;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync uint64_t offSeg = pThis->aOperands[idxOp].uEffAddr - pDataBuf->uSegBase;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pThis->aOperands[idxOp].offSeg = offSeg;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync AssertRelease(offSeg <= g_au64ByteSizeToMask[pThis->cbAddrMode]);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync /*
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * Select register and displacement values for the buffer addressing (works on offSeg).
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync uint8_t const iMemIndexReg = pThis->aOperands[idxOp].iMemIndexReg;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync uint8_t const iMemBaseReg = pThis->aOperands[idxOp].iMemBaseReg;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (pThis->aOperands[idxOp].fIsRipRelative)
e6ad2e18e663b076aeabfec994947514566a7accvboxsync {
dc959f60f6d3e0cba86f7da4d39aa475913a7e10vboxsync /* rip relative. */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pThis->aOperands[idxOp].uImmDispValue = offSeg - (pThis->InCtx.rip + pThis->cbInstr);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync Assert(pThis->aOperands[idxOp].cbMemDisp == 4);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if ( (int64_t)pThis->aOperands[idxOp].uImmDispValue > INT32_MAX
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync || (int64_t)pThis->aOperands[idxOp].uImmDispValue < INT32_MIN)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pThis->cSkippedDataBufWrtRip++;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return false;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync else if (iMemBaseReg != UINT8_MAX)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if ( iMemBaseReg != iMemIndexReg
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync || pThis->fUsesVexIndexRegs)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync /* [base] or [base + disp] or [base + index * scale] or [base + index * scale + disp] */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (pThis->aOperands[idxOp].cbMemDisp > 0)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pThis->aOperands[idxOp].uImmDispValue = CidetCoreGetRandS64(pThis, pThis->aOperands[idxOp].cbMemDisp);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync offSeg -= (int64_t)pThis->aOperands[idxOp].uImmDispValue;
dc959f60f6d3e0cba86f7da4d39aa475913a7e10vboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (iMemIndexReg != UINT8_MAX)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pThis->aOperands[idxOp].uMemIndexRegValue = CidetCoreGetRandU64(pThis, pThis->cbAddrMode);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync offSeg -= pThis->aOperands[idxOp].uMemIndexRegValue * pThis->aOperands[idxOp].uMemScale;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pThis->aOperands[idxOp].uMemBaseRegValue = offSeg & g_au64ByteSizeToMask[pThis->cbAddrMode];
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync else
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync /* base == index; [base + index * scale] or [base * (scale + 1)]. */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync uint8_t const uEffScale = pThis->aOperands[idxOp].uMemScale + 1;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (pThis->aOperands[idxOp].cbMemDisp > 0)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pThis->aOperands[idxOp].uImmDispValue = CidetCoreGetRandS64(pThis, pThis->aOperands[idxOp].cbMemDisp);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync offSeg -= (int64_t)pThis->aOperands[idxOp].uImmDispValue;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync offSeg &= g_au64ByteSizeToMask[pThis->cbAddrMode];
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync uint8_t uRemainder = offSeg % uEffScale;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (uRemainder != 0)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync Assert(pThis->aOperands[idxOp].cbMemDisp < 8);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync Assert( (int64_t)pThis->aOperands[idxOp].uImmDispValue
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync <= g_ai64ByteSizeToMax[pThis->aOperands[idxOp].cbMemDisp]);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pThis->aOperands[idxOp].uImmDispValue = (int64_t)pThis->aOperands[idxOp].uImmDispValue
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync + uRemainder;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync offSeg -= uRemainder;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if ( (int64_t)pThis->aOperands[idxOp].uImmDispValue
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync > g_ai64ByteSizeToMax[pThis->aOperands[idxOp].cbMemDisp])
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pThis->aOperands[idxOp].uImmDispValue -= uEffScale;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync offSeg += uEffScale;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync Assert(offSeg % uEffScale == 0);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync else
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync offSeg &= g_au64ByteSizeToMask[pThis->cbAddrMode];
e6ad2e18e663b076aeabfec994947514566a7accvboxsync if (offSeg % uEffScale != 0)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
e6ad2e18e663b076aeabfec994947514566a7accvboxsync pThis->cSkippedSameBaseIndexRemainder++;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return false;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
e6ad2e18e663b076aeabfec994947514566a7accvboxsync offSeg /= uEffScale;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pThis->aOperands[idxOp].uMemBaseRegValue = pThis->aOperands[idxOp].uMemIndexRegValue = offSeg;
e6ad2e18e663b076aeabfec994947514566a7accvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync else if (iMemIndexReg != UINT8_MAX)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
e6ad2e18e663b076aeabfec994947514566a7accvboxsync /* [index * scale] or [index * scale + disp] */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (pThis->aOperands[idxOp].cbMemDisp > 0)
e6ad2e18e663b076aeabfec994947514566a7accvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pThis->aOperands[idxOp].uImmDispValue = CidetCoreGetRandS64(pThis, pThis->aOperands[idxOp].cbMemDisp);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync offSeg -= (int64_t)pThis->aOperands[idxOp].uImmDispValue;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pThis->aOperands[idxOp].uImmDispValue += offSeg & (RT_BIT_64(pThis->aOperands[idxOp].uMemScale) - 1);
9cdd4d805ecb43126372f7cf12e4032836cb738avboxsync offSeg &= ~(RT_BIT_64(pThis->aOperands[idxOp].uMemScale) - 1);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync else if (offSeg & (RT_BIT_64(pThis->aOperands[idxOp].uMemScale) - 1))
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pThis->cSkippedOnlyIndexRemainder++;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return false;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pThis->aOperands[idxOp].uMemIndexRegValue = offSeg / pThis->aOperands[idxOp].uMemScale;
105b1a31b6037dbe14acb8d09e60da540885202bvboxsync Assert((offSeg % pThis->aOperands[idxOp].uMemScale) == 0);
105b1a31b6037dbe14acb8d09e60da540885202bvboxsync AssertRelease(!pThis->fUsesVexIndexRegs); /** @todo implement VEX indexing */
105b1a31b6037dbe14acb8d09e60da540885202bvboxsync }
105b1a31b6037dbe14acb8d09e60da540885202bvboxsync else
105b1a31b6037dbe14acb8d09e60da540885202bvboxsync {
105b1a31b6037dbe14acb8d09e60da540885202bvboxsync /* [disp] */
105b1a31b6037dbe14acb8d09e60da540885202bvboxsync Assert( pThis->aOperands[idxOp].cbMemDisp == 8
105b1a31b6037dbe14acb8d09e60da540885202bvboxsync || pThis->aOperands[idxOp].cbMemDisp == 4
105b1a31b6037dbe14acb8d09e60da540885202bvboxsync || pThis->aOperands[idxOp].cbMemDisp == 2
105b1a31b6037dbe14acb8d09e60da540885202bvboxsync || pThis->aOperands[idxOp].cbMemDisp == 1);
105b1a31b6037dbe14acb8d09e60da540885202bvboxsync if ( pThis->aOperands[idxOp].cbMemDisp == 4
105b1a31b6037dbe14acb8d09e60da540885202bvboxsync ? (int64_t)offSeg != (int32_t)offSeg
1389294d44ac76b0a25f5655756c9d39855a73efvboxsync : pThis->aOperands[idxOp].cbMemDisp == 2
1389294d44ac76b0a25f5655756c9d39855a73efvboxsync ? (int64_t)offSeg != (int16_t)offSeg
105b1a31b6037dbe14acb8d09e60da540885202bvboxsync : pThis->aOperands[idxOp].cbMemDisp == 1
105b1a31b6037dbe14acb8d09e60da540885202bvboxsync ? (int64_t)offSeg != (int8_t)offSeg
105b1a31b6037dbe14acb8d09e60da540885202bvboxsync : false /* 8 */)
105b1a31b6037dbe14acb8d09e60da540885202bvboxsync {
105b1a31b6037dbe14acb8d09e60da540885202bvboxsync pThis->cSkippedDirectAddressingOverflow++;
1389294d44ac76b0a25f5655756c9d39855a73efvboxsync return false;
105b1a31b6037dbe14acb8d09e60da540885202bvboxsync }
105b1a31b6037dbe14acb8d09e60da540885202bvboxsync pThis->aOperands[idxOp].uImmDispValue = offSeg;
105b1a31b6037dbe14acb8d09e60da540885202bvboxsync }
105b1a31b6037dbe14acb8d09e60da540885202bvboxsync
105b1a31b6037dbe14acb8d09e60da540885202bvboxsync /*
105b1a31b6037dbe14acb8d09e60da540885202bvboxsync * Modify the input and expected output contexts with the base and
105b1a31b6037dbe14acb8d09e60da540885202bvboxsync * index register values. To simplify verification and the work
105b1a31b6037dbe14acb8d09e60da540885202bvboxsync * here, we update the uMemBaseRegValue and uMemIndexRegValue
105b1a31b6037dbe14acb8d09e60da540885202bvboxsync * members to reflect the whole register.
c58dc77ef4af214d7ae06910fa5ab18587d2ae08vboxsync */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (iMemBaseReg != UINT8_MAX)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (pThis->cbAddrMode == 4)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pThis->aOperands[idxOp].uMemBaseRegValue &= UINT32_MAX;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pThis->aOperands[idxOp].uMemBaseRegValue |= pThis->InCtx.aGRegs[iMemBaseReg] & UINT64_C(0xffffffff00000000);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync else if (pThis->cbAddrMode == 2)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pThis->aOperands[idxOp].uMemBaseRegValue &= UINT16_MAX;
c58dc77ef4af214d7ae06910fa5ab18587d2ae08vboxsync pThis->aOperands[idxOp].uMemBaseRegValue |= pThis->InCtx.aGRegs[iMemBaseReg] & UINT64_C(0xffffffffffff0000);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pThis->InCtx.aGRegs[iMemBaseReg] = pThis->aOperands[idxOp].uMemBaseRegValue;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pThis->ExpectedCtx.aGRegs[iMemBaseReg] = pThis->aOperands[idxOp].uMemBaseRegValue;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (iMemIndexReg != UINT8_MAX)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (pThis->cbAddrMode == 4)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pThis->aOperands[idxOp].uMemIndexRegValue &= UINT32_MAX;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pThis->aOperands[idxOp].uMemIndexRegValue |= pThis->InCtx.aGRegs[iMemIndexReg] & UINT64_C(0xffffffff00000000);
e6ad2e18e663b076aeabfec994947514566a7accvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync else if (pThis->cbAddrMode == 2)
e6ad2e18e663b076aeabfec994947514566a7accvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pThis->aOperands[idxOp].uMemIndexRegValue &= UINT16_MAX;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pThis->aOperands[idxOp].uMemIndexRegValue |= pThis->InCtx.aGRegs[iMemIndexReg] & UINT64_C(0xffffffffffff0000);
e6ad2e18e663b076aeabfec994947514566a7accvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pThis->InCtx.aGRegs[iMemIndexReg] = pThis->aOperands[idxOp].uMemIndexRegValue;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pThis->ExpectedCtx.aGRegs[iMemIndexReg] = pThis->aOperands[idxOp].uMemIndexRegValue;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync else
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync /*
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * Non-memory, so clear the memory related members.
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync Assert(!pThis->aOperands[idxOp].fIsMem);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pThis->aOperands[idxOp].iEffSeg = UINT8_MAX;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pThis->aOperands[idxOp].offSeg = UINT64_MAX;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pThis->aOperands[idxOp].uEffAddr = UINT64_MAX;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pThis->aOperands[idxOp].pDataBuf = NULL;
423b1ce7f19ff0687e825ddc42d8bc6c68a4c9cdvboxsync
423b1ce7f19ff0687e825ddc42d8bc6c68a4c9cdvboxsync switch (pThis->aOperands[idxOp].fFlags & CIDET_OF_K_MASK)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
423b1ce7f19ff0687e825ddc42d8bc6c68a4c9cdvboxsync case CIDET_OF_K_GPR:
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (!pThis->aOperands[idxOp].fIsHighByteRegister)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
423b1ce7f19ff0687e825ddc42d8bc6c68a4c9cdvboxsync pThis->aOperands[idxOp].In.pv = &pThis->InCtx.aGRegs[pThis->aOperands[idxOp].iReg];
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pThis->aOperands[idxOp].Expected.pv = &pThis->ExpectedCtx.aGRegs[pThis->aOperands[idxOp].iReg];
ad290511521ce8388a9926b165241ecf83c330a7vboxsync }
423b1ce7f19ff0687e825ddc42d8bc6c68a4c9cdvboxsync else
ad290511521ce8388a9926b165241ecf83c330a7vboxsync {
ad290511521ce8388a9926b165241ecf83c330a7vboxsync pThis->aOperands[idxOp].In.pv = &pThis->InCtx.aGRegs[pThis->aOperands[idxOp].iReg - 4];
423b1ce7f19ff0687e825ddc42d8bc6c68a4c9cdvboxsync pThis->aOperands[idxOp].In.pu8++;
ad290511521ce8388a9926b165241ecf83c330a7vboxsync pThis->aOperands[idxOp].Expected.pv = &pThis->ExpectedCtx.aGRegs[pThis->aOperands[idxOp].iReg - 4];
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pThis->aOperands[idxOp].Expected.pu8++;
423b1ce7f19ff0687e825ddc42d8bc6c68a4c9cdvboxsync }
423b1ce7f19ff0687e825ddc42d8bc6c68a4c9cdvboxsync break;
fdb57e5580007400346665b64c0e14ca1d149019vboxsync
423b1ce7f19ff0687e825ddc42d8bc6c68a4c9cdvboxsync case CIDET_OF_K_IMM:
fdb57e5580007400346665b64c0e14ca1d149019vboxsync pThis->aOperands[idxOp].In.pv = NULL;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pThis->aOperands[idxOp].Expected.pv = NULL;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync break;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
ad290511521ce8388a9926b165241ecf83c330a7vboxsync case CIDET_OF_K_SREG:
cb0578a5309e1fc264e5a4acc30543bea075be43vboxsync if (pThis->aOperands[idxOp].iReg < RT_ELEMENTS(pThis->InCtx.aSRegs))
cb0578a5309e1fc264e5a4acc30543bea075be43vboxsync {
cb0578a5309e1fc264e5a4acc30543bea075be43vboxsync pThis->aOperands[idxOp].In.pv = &pThis->InCtx.aSRegs[pThis->aOperands[idxOp].iReg];
cb0578a5309e1fc264e5a4acc30543bea075be43vboxsync pThis->aOperands[idxOp].Expected.pv = &pThis->ExpectedCtx.aSRegs[pThis->aOperands[idxOp].iReg];
cb0578a5309e1fc264e5a4acc30543bea075be43vboxsync }
cb0578a5309e1fc264e5a4acc30543bea075be43vboxsync else
cb0578a5309e1fc264e5a4acc30543bea075be43vboxsync {
cb0578a5309e1fc264e5a4acc30543bea075be43vboxsync pThis->aOperands[idxOp].In.pv = NULL;
cb0578a5309e1fc264e5a4acc30543bea075be43vboxsync pThis->aOperands[idxOp].Expected.pv = NULL;
cb0578a5309e1fc264e5a4acc30543bea075be43vboxsync }
cb0578a5309e1fc264e5a4acc30543bea075be43vboxsync break;
cb0578a5309e1fc264e5a4acc30543bea075be43vboxsync
fdb57e5580007400346665b64c0e14ca1d149019vboxsync case CIDET_OF_K_CR:
fdb57e5580007400346665b64c0e14ca1d149019vboxsync case CIDET_OF_K_SSE:
fdb57e5580007400346665b64c0e14ca1d149019vboxsync case CIDET_OF_K_AVX:
fdb57e5580007400346665b64c0e14ca1d149019vboxsync case CIDET_OF_K_AVX512:
fdb57e5580007400346665b64c0e14ca1d149019vboxsync case CIDET_OF_K_FPU:
fdb57e5580007400346665b64c0e14ca1d149019vboxsync case CIDET_OF_K_MMX:
fdb57e5580007400346665b64c0e14ca1d149019vboxsync case CIDET_OF_K_AVXFUTURE:
fdb57e5580007400346665b64c0e14ca1d149019vboxsync case CIDET_OF_K_SPECIAL:
fdb57e5580007400346665b64c0e14ca1d149019vboxsync case CIDET_OF_K_TEST:
fdb57e5580007400346665b64c0e14ca1d149019vboxsync /** @todo Implement testing these registers. */
fdb57e5580007400346665b64c0e14ca1d149019vboxsync case CIDET_OF_K_NONE:
fdb57e5580007400346665b64c0e14ca1d149019vboxsync default:
fdb57e5580007400346665b64c0e14ca1d149019vboxsync AssertReleaseFailedReturn(false);
fdb57e5580007400346665b64c0e14ca1d149019vboxsync }
fdb57e5580007400346665b64c0e14ca1d149019vboxsync }
fdb57e5580007400346665b64c0e14ca1d149019vboxsync }
fdb57e5580007400346665b64c0e14ca1d149019vboxsync AssertRelease((uintptr_t)pbBuf - (uintptr_t)&pThis->abBuf[0] <= sizeof(pThis->abBuf));
fdb57e5580007400346665b64c0e14ca1d149019vboxsync
fdb57e5580007400346665b64c0e14ca1d149019vboxsync /*
fdb57e5580007400346665b64c0e14ca1d149019vboxsync * Call instruction specific setup function (for operand values and flags).
fdb57e5580007400346665b64c0e14ca1d149019vboxsync */
fdb57e5580007400346665b64c0e14ca1d149019vboxsync int rc = pThis->pCurInstr->pfnSetupInOut(pThis, false /*fInvalid*/);
fdb57e5580007400346665b64c0e14ca1d149019vboxsync if (RT_FAILURE(rc))
fdb57e5580007400346665b64c0e14ca1d149019vboxsync {
423b1ce7f19ff0687e825ddc42d8bc6c68a4c9cdvboxsync pThis->cSkippedSetupInOut++;
fdb57e5580007400346665b64c0e14ca1d149019vboxsync return false;
fdb57e5580007400346665b64c0e14ca1d149019vboxsync }
fdb57e5580007400346665b64c0e14ca1d149019vboxsync
fdb57e5580007400346665b64c0e14ca1d149019vboxsync /*
423b1ce7f19ff0687e825ddc42d8bc6c68a4c9cdvboxsync * Do the 2nd set of the memory operand preparations.
fdb57e5580007400346665b64c0e14ca1d149019vboxsync */
cb0578a5309e1fc264e5a4acc30543bea075be43vboxsync if (pThis->fHasMemoryOperand)
cb0578a5309e1fc264e5a4acc30543bea075be43vboxsync {
ad290511521ce8388a9926b165241ecf83c330a7vboxsync idxOp = pThis->cOperands;
cb0578a5309e1fc264e5a4acc30543bea075be43vboxsync while (idxOp-- > 0)
cb0578a5309e1fc264e5a4acc30543bea075be43vboxsync if (pThis->aOperands[idxOp].fIsMem)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync Assert(pThis->aOperands[idxOp].pDataBuf);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (!pThis->pfnSetupDataBuf(pThis, pThis->aOperands[idxOp].pDataBuf, pThis->aOperands[idxOp].In.pv))
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pThis->cSkippedSetupDataBuf++;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return false;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync Assert( pThis->aOperands[idxOp].iMemBaseReg == UINT8_MAX
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync || pThis->InCtx.aGRegs[pThis->aOperands[idxOp].iMemBaseReg] == pThis->aOperands[idxOp].uMemBaseRegValue);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync Assert( pThis->aOperands[idxOp].iMemIndexReg == UINT8_MAX
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync || ( !pThis->fUsesVexIndexRegs
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync ? pThis->InCtx.aGRegs[pThis->aOperands[idxOp].iMemIndexReg]
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync == pThis->aOperands[idxOp].uMemIndexRegValue
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync : false /** @todo VEX indexing */));
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return true;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync}
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync/**
105b1a31b6037dbe14acb8d09e60da540885202bvboxsync * Figures the instruction length.
105b1a31b6037dbe14acb8d09e60da540885202bvboxsync *
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * This is a duplicate of CidetCoreAssemble() with the buffer updates removed.
e6ad2e18e663b076aeabfec994947514566a7accvboxsync *
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * @returns true and pThis->cbInstr on success, false on failure.
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * @param pThis The core state structure (for context).
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncbool CidetCoreAssembleLength(PCIDETCORE pThis)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync{
e6ad2e18e663b076aeabfec994947514566a7accvboxsync uint8_t off = 0;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync /*
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * Prefixes.
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (1)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
e6ad2e18e663b076aeabfec994947514566a7accvboxsync if (pThis->fAddrSizePrf)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync off++;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (pThis->fOpSizePrf)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync off++;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync else
9cdd4d805ecb43126372f7cf12e4032836cb738avboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync /** @todo prefix list. */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync /*
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * Prefixes that must come right before the opcode.
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync /** @todo VEX and EVEX. */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (pThis->fVex)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync /** @todo VEX and EVEX. */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync else if (pThis->fEvex)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync /** @todo VEX and EVEX. */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync else
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (pThis->fRexB || pThis->fRexX || pThis->fRexR || pThis->fRexW || pThis->fRex)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync off++;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync /*
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * The opcode.
3fa7a7e633f46a212052b510cdb8cee41f279a67vboxsync */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync uint8_t const *pbOpcode = pThis->pCurInstr->abOpcode;
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync switch (pThis->pCurInstr->cbOpcode)
5793d23a719d4902824a3649b6fef3822ddd5fc7vboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync case 3: off++;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync case 2: off++;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync case 1: off++;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync break;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync default:
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync AssertReleaseFailedReturn(false);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync /*
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * Mod R/M
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (pThis->fUsesModRm)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync off++;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (pThis->fSib)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync off++;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (pThis->idxMrmRmOp < RT_ELEMENTS(pThis->aOperands))
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync uint64_t uDispValue = pThis->aOperands[pThis->idxMrmRmOp].uImmDispValue;
3fa7a7e633f46a212052b510cdb8cee41f279a67vboxsync switch (pThis->aOperands[pThis->idxMrmRmOp].cbMemDisp)
3fa7a7e633f46a212052b510cdb8cee41f279a67vboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync case 0: break;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync case 8:
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync case 7:
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync case 6:
3fa7a7e633f46a212052b510cdb8cee41f279a67vboxsync case 5:
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync case 4:
3fa7a7e633f46a212052b510cdb8cee41f279a67vboxsync case 3:
3fa7a7e633f46a212052b510cdb8cee41f279a67vboxsync case 2:
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync case 1:
3fa7a7e633f46a212052b510cdb8cee41f279a67vboxsync break;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync default: AssertReleaseFailedReturn(false);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
3fa7a7e633f46a212052b510cdb8cee41f279a67vboxsync off += pThis->aOperands[pThis->idxMrmRmOp].cbMemDisp;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
3fa7a7e633f46a212052b510cdb8cee41f279a67vboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync /*
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * Immediates.
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync uint8_t iOp = pThis->cOperands;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync while (iOp-- > 0)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if ((pThis->aOperands[iOp].fFlags & CIDET_OF_K_MASK) == CIDET_OF_K_IMM)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync uint64_t uImmValue = pThis->aOperands[iOp].uImmDispValue;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync switch (pThis->aOperands[iOp].cb)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync case 8:
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync case 7:
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync case 6:
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync case 5:
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync case 4:
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync case 3:
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync case 2:
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync case 1:
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync break;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync default: AssertReleaseFailedReturn(false);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync off += pThis->aOperands[iOp].cb;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pThis->cbInstr = off;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return true;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync}
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync/**
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * Assembles the instruction.
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync *
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * This is a duplicate of CidetCoreAssembleLength() with buffer writes.
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync *
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * @returns true and pThis->cbInstr and pThis->abInstr on success, false on
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * failure.
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * @param pThis The core state structure (for context).
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncbool CidetCoreAssemble(PCIDETCORE pThis)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync{
eb2d4958f7faf812c3bdb2d7587d815022f0bd55vboxsync uint8_t off = 0;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync /*
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * Prefixes.
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (1)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (pThis->fAddrSizePrf)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pThis->abInstr[off++] = 0x67;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (pThis->fOpSizePrf)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pThis->abInstr[off++] = 0x66;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync else
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync /** @todo prefix list. */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync /*
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * Prefixes that must come right before the opcode.
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync /** @todo VEX and EVEX. */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (pThis->fVex)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync /** @todo VEX and EVEX. */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync else if (pThis->fEvex)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync /** @todo VEX and EVEX. */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync else
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (pThis->fRexB || pThis->fRexX || pThis->fRexR || pThis->fRexW || pThis->fRex)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pThis->abInstr[off++] = 0x40 | (pThis->fRexB * 1) | (pThis->fRexX * 2) | (pThis->fRexR * 4) | (pThis->fRexW * 8);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync /*
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * The opcode.
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync uint8_t const *pbOpcode = pThis->pCurInstr->abOpcode;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync switch (pThis->pCurInstr->cbOpcode)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync case 3: pThis->abInstr[off++] = *pbOpcode++;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync case 2: pThis->abInstr[off++] = *pbOpcode++;
441b60f8b0601cc1718368c9c3ef082223ad12a2vboxsync case 1: pThis->abInstr[off++] = *pbOpcode++;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync break;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync default:
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync AssertReleaseFailedReturn(false);
2721dfb0e330d57ba888311520f5a343c64e7cefvboxsync }
2721dfb0e330d57ba888311520f5a343c64e7cefvboxsync
ad290511521ce8388a9926b165241ecf83c330a7vboxsync /*
7b6926b2bf44f326f40e1d9d1ce33a4dff0a2c67vboxsync * Mod R/M
ad290511521ce8388a9926b165241ecf83c330a7vboxsync */
e6ad2e18e663b076aeabfec994947514566a7accvboxsync if (pThis->fUsesModRm)
441b60f8b0601cc1718368c9c3ef082223ad12a2vboxsync {
441b60f8b0601cc1718368c9c3ef082223ad12a2vboxsync pThis->abInstr[off++] = pThis->bModRm;
441b60f8b0601cc1718368c9c3ef082223ad12a2vboxsync if (pThis->fSib)
441b60f8b0601cc1718368c9c3ef082223ad12a2vboxsync pThis->abInstr[off++] = pThis->bSib;
441b60f8b0601cc1718368c9c3ef082223ad12a2vboxsync if (pThis->idxMrmRmOp < RT_ELEMENTS(pThis->aOperands))
441b60f8b0601cc1718368c9c3ef082223ad12a2vboxsync {
441b60f8b0601cc1718368c9c3ef082223ad12a2vboxsync uint64_t uDispValue = pThis->aOperands[pThis->idxMrmRmOp].uImmDispValue;
441b60f8b0601cc1718368c9c3ef082223ad12a2vboxsync switch (pThis->aOperands[pThis->idxMrmRmOp].cbMemDisp)
441b60f8b0601cc1718368c9c3ef082223ad12a2vboxsync {
441b60f8b0601cc1718368c9c3ef082223ad12a2vboxsync case 0: break;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync case 8: pThis->abInstr[off + 3] = (uDispValue >> 56) & UINT8_C(0xff);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync case 7: pThis->abInstr[off + 3] = (uDispValue >> 48) & UINT8_C(0xff);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync case 6: pThis->abInstr[off + 3] = (uDispValue >> 40) & UINT8_C(0xff);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync case 5: pThis->abInstr[off + 3] = (uDispValue >> 32) & UINT8_C(0xff);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync case 4: pThis->abInstr[off + 3] = (uDispValue >> 24) & UINT8_C(0xff);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync case 3: pThis->abInstr[off + 2] = (uDispValue >> 16) & UINT8_C(0xff);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync case 2: pThis->abInstr[off + 1] = (uDispValue >> 8) & UINT8_C(0xff);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync case 1: pThis->abInstr[off] = uDispValue & UINT8_C(0xff);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync break;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync default: AssertReleaseFailedReturn(false);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync off += pThis->aOperands[pThis->idxMrmRmOp].cbMemDisp;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync /*
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * Immediates.
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync uint8_t iOp = pThis->cOperands;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync while (iOp-- > 0)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if ((pThis->aOperands[iOp].fFlags & CIDET_OF_K_MASK) == CIDET_OF_K_IMM)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync uint64_t uImmValue = pThis->aOperands[iOp].uImmDispValue;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync switch (pThis->aOperands[iOp].cb)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync case 8: pThis->abInstr[off + 3] = (uImmValue >> 56) & UINT8_C(0xff);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync case 7: pThis->abInstr[off + 3] = (uImmValue >> 48) & UINT8_C(0xff);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync case 6: pThis->abInstr[off + 3] = (uImmValue >> 40) & UINT8_C(0xff);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync case 5: pThis->abInstr[off + 3] = (uImmValue >> 32) & UINT8_C(0xff);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync case 4: pThis->abInstr[off + 3] = (uImmValue >> 24) & UINT8_C(0xff);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync case 3: pThis->abInstr[off + 2] = (uImmValue >> 16) & UINT8_C(0xff);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync case 2: pThis->abInstr[off + 1] = (uImmValue >> 8) & UINT8_C(0xff);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync case 1: pThis->abInstr[off] = uImmValue & UINT8_C(0xff);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync break;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync default: AssertReleaseFailedReturn(false);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync off += pThis->aOperands[iOp].cb;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pThis->cbInstr = off;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return true;
4c98b8b05f3783351cf256cc90cd4478fb28b62bvboxsync}
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncbool CidetCoreReInitCodeBuf(PCIDETCORE pThis)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync{
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync /*
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * Re-initialize the buffer. Requires instruction length and positioning.
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (CidetCoreAssembleLength(pThis))
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
73ba84f95f918cc170be38908ad240fbb2f8f354vboxsync pThis->CodeBuf.cb = pThis->cbInstr;
6b2a50fc09aa4f7ce2082284f082d97a2c738321vboxsync pThis->CodeBuf.off = CIDET_CODE_BUF_SIZE - PAGE_SIZE - pThis->cbInstr;
73ba84f95f918cc170be38908ad240fbb2f8f354vboxsync if (pThis->pfnReInitCodeBuf(pThis, &pThis->CodeBuf))
c2e22ad3bb703daa53362d626dd2b4965e511142vboxsync {
c2e22ad3bb703daa53362d626dd2b4965e511142vboxsync pThis->CodeBuf.fActive = true;
c2e22ad3bb703daa53362d626dd2b4965e511142vboxsync
c2e22ad3bb703daa53362d626dd2b4965e511142vboxsync /*
c2e22ad3bb703daa53362d626dd2b4965e511142vboxsync * Update the RIP and CS values in the input and expected contexts.
c2e22ad3bb703daa53362d626dd2b4965e511142vboxsync */
c2e22ad3bb703daa53362d626dd2b4965e511142vboxsync pThis->InCtx.rip = pThis->CodeBuf.uEffBufAddr + pThis->CodeBuf.offActive - pThis->CodeBuf.uSegBase;
71c0735a959eefb3e0b7a3bd8c8640a5660584cavboxsync pThis->ExpectedCtx.rip = pThis->InCtx.rip + pThis->cbInstr; /** @todo account for expected traps. */
71c0735a959eefb3e0b7a3bd8c8640a5660584cavboxsync if (pThis->CodeBuf.uSeg != UINT32_MAX)
71c0735a959eefb3e0b7a3bd8c8640a5660584cavboxsync {
73ba84f95f918cc170be38908ad240fbb2f8f354vboxsync pThis->InCtx.aSRegs[X86_SREG_CS] = pThis->CodeBuf.uSeg;
73ba84f95f918cc170be38908ad240fbb2f8f354vboxsync pThis->ExpectedCtx.aSRegs[X86_SREG_CS] = pThis->CodeBuf.uSeg;
73ba84f95f918cc170be38908ad240fbb2f8f354vboxsync }
73ba84f95f918cc170be38908ad240fbb2f8f354vboxsync return true;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync else
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pThis->cSkippedReInitCodeBuf++;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync else
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pThis->cSkippedAssemble++;
4c98b8b05f3783351cf256cc90cd4478fb28b62bvboxsync return false;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync}
4c98b8b05f3783351cf256cc90cd4478fb28b62bvboxsync
4c98b8b05f3783351cf256cc90cd4478fb28b62bvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync#ifdef CIDET_DEBUG_DISAS
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync/**
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * @callback_method_impl{FNDISREADBYTES}
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncstatic DECLCALLBACK(int) cidetCoreDisReadBytes(PDISSTATE pDis, uint8_t offInstr, uint8_t cbMinRead, uint8_t cbMaxRead)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync{
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync PCIDETCORE pThis = (PCIDETCORE)pDis->pvUser;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync memcpy(&pDis->abInstr[offInstr], &pThis->abInstr[offInstr], cbMaxRead);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pDis->cbCachedInstr = offInstr + cbMaxRead;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return VINF_SUCCESS;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync}
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync#endif
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncbool CidetCoreSetupCodeBuf(PCIDETCORE pThis, unsigned iSubTest)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync{
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (CidetCoreAssemble(pThis))
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync //CIDET_DPRINTF(("%04u: %.*Rhxs\n", i, pThis->cbInstr, pThis->abInstr));
9cdd4d805ecb43126372f7cf12e4032836cb738avboxsync#ifdef CIDET_DEBUG_DISAS
73ba84f95f918cc170be38908ad240fbb2f8f354vboxsync DISCPUSTATE Dis;
73ba84f95f918cc170be38908ad240fbb2f8f354vboxsync char szInstr[80] = {0};
73ba84f95f918cc170be38908ad240fbb2f8f354vboxsync uint32_t cbInstr;
73ba84f95f918cc170be38908ad240fbb2f8f354vboxsync int rcDis = DISInstrToStrEx(pThis->InCtx.rip,
73ba84f95f918cc170be38908ad240fbb2f8f354vboxsync CIDETMODE_IS_64BIT(pThis->bMode) ? DISCPUMODE_64BIT
73ba84f95f918cc170be38908ad240fbb2f8f354vboxsync : CIDETMODE_IS_32BIT(pThis->bMode) ? DISCPUMODE_32BIT : DISCPUMODE_16BIT,
73ba84f95f918cc170be38908ad240fbb2f8f354vboxsync cidetCoreDisReadBytes,
73ba84f95f918cc170be38908ad240fbb2f8f354vboxsync pThis,
73ba84f95f918cc170be38908ad240fbb2f8f354vboxsync DISOPTYPE_ALL,
6b2a50fc09aa4f7ce2082284f082d97a2c738321vboxsync &Dis,
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync &cbInstr,
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync szInstr, sizeof(szInstr));
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync CIDET_DPRINTF(("%04u: %s", iSubTest, szInstr));
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync Assert(cbInstr == pThis->cbInstr);
73ba84f95f918cc170be38908ad240fbb2f8f354vboxsync#endif
73ba84f95f918cc170be38908ad240fbb2f8f354vboxsync if (pThis->pfnSetupCodeBuf(pThis, &pThis->CodeBuf, pThis->abInstr))
73ba84f95f918cc170be38908ad240fbb2f8f354vboxsync {
73ba84f95f918cc170be38908ad240fbb2f8f354vboxsync return true;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pThis->cSkippedSetupCodeBuf++;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync else
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pThis->cSkippedAssemble++;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return false;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync}
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync/**
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * Compares the output with the output expectations.
1389294d44ac76b0a25f5655756c9d39855a73efvboxsync *
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * @returns true if ok, false if not (calls pfnFailure too).
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * @param pThis The core state structure.
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncbool CidetCoreCheckResults(PCIDETCORE pThis)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync{
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (memcmp(&pThis->ActualCtx, &pThis->ExpectedCtx, CIDETCPUCTX_COMPARE_SIZE) == 0)
4c98b8b05f3783351cf256cc90cd4478fb28b62bvboxsync return true;
4c98b8b05f3783351cf256cc90cd4478fb28b62bvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync unsigned cDiffs = 0;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync#define IF_FIELD_DIFFERS_SET_ERROR(a_Field, a_Fmt) \
4c98b8b05f3783351cf256cc90cd4478fb28b62bvboxsync if (pThis->ActualCtx.a_Field != pThis->ExpectedCtx.a_Field) \
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync { \
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync CidetCoreSetError(pThis, #a_Field " differs: got %#llx expected %#llx", \
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pThis->ActualCtx.a_Field, pThis->ExpectedCtx.a_Field); \
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync cDiffs++; \
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync } else do { } while (0)
1389294d44ac76b0a25f5655756c9d39855a73efvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync IF_FIELD_DIFFERS_SET_ERROR(rip, "%#010llx");
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync IF_FIELD_DIFFERS_SET_ERROR(rfl, "%#010llx");
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync IF_FIELD_DIFFERS_SET_ERROR(aGRegs[X86_GREG_xAX], "%#010llx");
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync IF_FIELD_DIFFERS_SET_ERROR(aGRegs[X86_GREG_xBX], "%#010llx");
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync IF_FIELD_DIFFERS_SET_ERROR(aGRegs[X86_GREG_xCX], "%#010llx");
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync IF_FIELD_DIFFERS_SET_ERROR(aGRegs[X86_GREG_xDX], "%#010llx");
4c98b8b05f3783351cf256cc90cd4478fb28b62bvboxsync IF_FIELD_DIFFERS_SET_ERROR(aGRegs[X86_GREG_xSP], "%#010llx");
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync IF_FIELD_DIFFERS_SET_ERROR(aGRegs[X86_GREG_xBP], "%#010llx");
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync IF_FIELD_DIFFERS_SET_ERROR(aGRegs[X86_GREG_xSI], "%#010llx");
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync IF_FIELD_DIFFERS_SET_ERROR(aGRegs[X86_GREG_xDI], "%#010llx");
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync IF_FIELD_DIFFERS_SET_ERROR(aGRegs[X86_GREG_x8], "%#010llx");
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync IF_FIELD_DIFFERS_SET_ERROR(aGRegs[X86_GREG_x9], "%#010llx");
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync IF_FIELD_DIFFERS_SET_ERROR(aGRegs[X86_GREG_x9], "%#010llx");
be99a23d38fa03a9e93de71398f43ce4c4d7c685vboxsync IF_FIELD_DIFFERS_SET_ERROR(aGRegs[X86_GREG_x10], "%#010llx");
be99a23d38fa03a9e93de71398f43ce4c4d7c685vboxsync IF_FIELD_DIFFERS_SET_ERROR(aGRegs[X86_GREG_x11], "%#010llx");
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync IF_FIELD_DIFFERS_SET_ERROR(aGRegs[X86_GREG_x12], "%#010llx");
73ba84f95f918cc170be38908ad240fbb2f8f354vboxsync IF_FIELD_DIFFERS_SET_ERROR(aGRegs[X86_GREG_x13], "%#010llx");
73ba84f95f918cc170be38908ad240fbb2f8f354vboxsync IF_FIELD_DIFFERS_SET_ERROR(aGRegs[X86_GREG_x14], "%#010llx");
73ba84f95f918cc170be38908ad240fbb2f8f354vboxsync IF_FIELD_DIFFERS_SET_ERROR(aGRegs[X86_GREG_x15], "%#010llx");
73ba84f95f918cc170be38908ad240fbb2f8f354vboxsync IF_FIELD_DIFFERS_SET_ERROR(aSRegs[X86_SREG_CS], "%#06x");
73ba84f95f918cc170be38908ad240fbb2f8f354vboxsync IF_FIELD_DIFFERS_SET_ERROR(aSRegs[X86_SREG_SS], "%#06x");
73ba84f95f918cc170be38908ad240fbb2f8f354vboxsync IF_FIELD_DIFFERS_SET_ERROR(aSRegs[X86_SREG_DS], "%#06x");
73ba84f95f918cc170be38908ad240fbb2f8f354vboxsync IF_FIELD_DIFFERS_SET_ERROR(aSRegs[X86_SREG_ES], "%#06x");
73ba84f95f918cc170be38908ad240fbb2f8f354vboxsync IF_FIELD_DIFFERS_SET_ERROR(aSRegs[X86_SREG_FS], "%#06x");
73ba84f95f918cc170be38908ad240fbb2f8f354vboxsync IF_FIELD_DIFFERS_SET_ERROR(aSRegs[X86_SREG_GS], "%#06x");
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync IF_FIELD_DIFFERS_SET_ERROR(uXcpt, "%#04x");
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync IF_FIELD_DIFFERS_SET_ERROR(uErr, "%#04llx");
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync IF_FIELD_DIFFERS_SET_ERROR(cr2, "%#010llx");
73ba84f95f918cc170be38908ad240fbb2f8f354vboxsync#ifndef CIDET_REDUCED_CTX
73ba84f95f918cc170be38908ad240fbb2f8f354vboxsync IF_FIELD_DIFFERS_SET_ERROR(tr, "%#06x");
73ba84f95f918cc170be38908ad240fbb2f8f354vboxsync IF_FIELD_DIFFERS_SET_ERROR(ldtr, "%#06x");
73ba84f95f918cc170be38908ad240fbb2f8f354vboxsync IF_FIELD_DIFFERS_SET_ERROR(cr0, "%#010llx");
a7ba3d5f31ca70d04a3933e570374e5ec5eff84avboxsync IF_FIELD_DIFFERS_SET_ERROR(cr3, "%#010llx");
b6b29a7e040f2b46480aa596fe0861bb16ce3da5vboxsync IF_FIELD_DIFFERS_SET_ERROR(cr4, "%#010llx");
b6b29a7e040f2b46480aa596fe0861bb16ce3da5vboxsync IF_FIELD_DIFFERS_SET_ERROR(cr8, "%#010llx");
b6b29a7e040f2b46480aa596fe0861bb16ce3da5vboxsync IF_FIELD_DIFFERS_SET_ERROR(dr0, "%#010llx");
b6b29a7e040f2b46480aa596fe0861bb16ce3da5vboxsync IF_FIELD_DIFFERS_SET_ERROR(dr1, "%#010llx");
ad290511521ce8388a9926b165241ecf83c330a7vboxsync IF_FIELD_DIFFERS_SET_ERROR(dr2, "%#010llx");
fc080a2caa666d6cdc9f978d31b49587fdc91125vboxsync IF_FIELD_DIFFERS_SET_ERROR(dr3, "%#010llx");
ad290511521ce8388a9926b165241ecf83c330a7vboxsync IF_FIELD_DIFFERS_SET_ERROR(dr6, "%#010llx");
b6b29a7e040f2b46480aa596fe0861bb16ce3da5vboxsync IF_FIELD_DIFFERS_SET_ERROR(dr7, "%#010llx");
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync#endif
b6b29a7e040f2b46480aa596fe0861bb16ce3da5vboxsync
b6b29a7e040f2b46480aa596fe0861bb16ce3da5vboxsyncAssertMsgFailed(("cDiffs=%d\n", cDiffs));
b6b29a7e040f2b46480aa596fe0861bb16ce3da5vboxsync Assert(cDiffs > 0);
b6b29a7e040f2b46480aa596fe0861bb16ce3da5vboxsync return cDiffs == 0;
b6b29a7e040f2b46480aa596fe0861bb16ce3da5vboxsync}
b6b29a7e040f2b46480aa596fe0861bb16ce3da5vboxsync
b6b29a7e040f2b46480aa596fe0861bb16ce3da5vboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncbool CidetCoreTest_Basic(PCIDETCORE pThis)
a7ba3d5f31ca70d04a3933e570374e5ec5eff84avboxsync{
b6b29a7e040f2b46480aa596fe0861bb16ce3da5vboxsync /*
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * Iterate all encodings.
73ba84f95f918cc170be38908ad240fbb2f8f354vboxsync */
73ba84f95f918cc170be38908ad240fbb2f8f354vboxsync if (!CidetCoreSetupFirstBaseEncoding(pThis))
73ba84f95f918cc170be38908ad240fbb2f8f354vboxsync return CidetCoreSetError(pThis, "CidetCoreSetupFirstBaseEncoding failed");
73ba84f95f918cc170be38908ad240fbb2f8f354vboxsync unsigned cExecuted = 0;
73ba84f95f918cc170be38908ad240fbb2f8f354vboxsync unsigned cSkipped = 0;
73ba84f95f918cc170be38908ad240fbb2f8f354vboxsync do
73ba84f95f918cc170be38908ad240fbb2f8f354vboxsync {
73ba84f95f918cc170be38908ad240fbb2f8f354vboxsync /*
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * Iterate data buffer configurations (one iteration if none).
b6b29a7e040f2b46480aa596fe0861bb16ce3da5vboxsync */
b6b29a7e040f2b46480aa596fe0861bb16ce3da5vboxsync if (CidetCoreSetupFirstMemoryOperandConfig(pThis))
b6b29a7e040f2b46480aa596fe0861bb16ce3da5vboxsync {
b6b29a7e040f2b46480aa596fe0861bb16ce3da5vboxsync do
b6b29a7e040f2b46480aa596fe0861bb16ce3da5vboxsync {
b6b29a7e040f2b46480aa596fe0861bb16ce3da5vboxsync /*
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * Iterate code buffer configurations.
6b2a50fc09aa4f7ce2082284f082d97a2c738321vboxsync */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (!CidetCoreSetupFirstCodeBufferConfig(pThis))
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return CidetCoreSetError(pThis, "CidetCoreSetupFirstMemoryOperandConfig failed");
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync do
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync /*
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * Set up inputs and expected outputs, then emit the test code.
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pThis->InCtx = pThis->InTemplateCtx;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pThis->InCtx.fTrickyStack = pThis->fHasStackRegInMrmRmBase || pThis->fHasStackRegInMrmReg;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pThis->ExpectedCtx = pThis->InCtx;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if ( CidetCoreReInitCodeBuf(pThis)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync && CidetCoreSetupInOut(pThis)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync && CidetCoreSetupCodeBuf(pThis, cSkipped + cExecuted)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync )
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (pThis->pfnExecute(pThis))
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync cExecuted++;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
4c98b8b05f3783351cf256cc90cd4478fb28b62bvboxsync /*
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * Check the result against our expectations.
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync CidetCoreCheckResults(pThis);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync /** @todo check result. */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync else
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync cSkipped++;
4c98b8b05f3783351cf256cc90cd4478fb28b62bvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync else
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync cSkipped++;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync } while (CidetCoreSetupNextCodeBufferConfig(pThis));
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync } while (CidetCoreSetupNextMemoryOperandConfig(pThis));
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync else
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync cSkipped++;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync } while (CidetCoreSetupNextBaseEncoding(pThis));
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync CIDET_DPRINTF(("CidetCoreTest_Basic: cExecuted=%u cSkipped=%u\n"
9cdd4d805ecb43126372f7cf12e4032836cb738avboxsync " cSkippedSetupInOut =%u\n"
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync " cSkippedReInitDataBuf =%u\n"
9cdd4d805ecb43126372f7cf12e4032836cb738avboxsync " cSkippedSetupDataBuf =%u\n"
9cdd4d805ecb43126372f7cf12e4032836cb738avboxsync " cSkippedDataBufWrtRip =%u\n"
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync " cSkippedAssemble =%u\n"
9cdd4d805ecb43126372f7cf12e4032836cb738avboxsync " cSkippedReInitCodeBuf =%u\n"
9cdd4d805ecb43126372f7cf12e4032836cb738avboxsync " cSkippedSetupCodeBuf =%u\n"
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync " cSkippedSameBaseIndexRemainder =%u\n"
9cdd4d805ecb43126372f7cf12e4032836cb738avboxsync " cSkippedOnlyIndexRemainder =%u\n"
9cdd4d805ecb43126372f7cf12e4032836cb738avboxsync " cSkippedDirectAddressingOverflow =%u\n"
9cdd4d805ecb43126372f7cf12e4032836cb738avboxsync ,
9cdd4d805ecb43126372f7cf12e4032836cb738avboxsync cExecuted, cSkipped,
9cdd4d805ecb43126372f7cf12e4032836cb738avboxsync pThis->cSkippedSetupInOut,
9cdd4d805ecb43126372f7cf12e4032836cb738avboxsync pThis->cSkippedReInitDataBuf,
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pThis->cSkippedSetupDataBuf,
9cdd4d805ecb43126372f7cf12e4032836cb738avboxsync pThis->cSkippedDataBufWrtRip,
9cdd4d805ecb43126372f7cf12e4032836cb738avboxsync pThis->cSkippedAssemble,
9cdd4d805ecb43126372f7cf12e4032836cb738avboxsync pThis->cSkippedReInitCodeBuf,
9cdd4d805ecb43126372f7cf12e4032836cb738avboxsync pThis->cSkippedSetupCodeBuf,
9cdd4d805ecb43126372f7cf12e4032836cb738avboxsync pThis->cSkippedSameBaseIndexRemainder,
9cdd4d805ecb43126372f7cf12e4032836cb738avboxsync pThis->cSkippedOnlyIndexRemainder,
9cdd4d805ecb43126372f7cf12e4032836cb738avboxsync pThis->cSkippedDirectAddressingOverflow
9cdd4d805ecb43126372f7cf12e4032836cb738avboxsync ));
9cdd4d805ecb43126372f7cf12e4032836cb738avboxsync
9cdd4d805ecb43126372f7cf12e4032836cb738avboxsync return true;
9cdd4d805ecb43126372f7cf12e4032836cb738avboxsync}
9cdd4d805ecb43126372f7cf12e4032836cb738avboxsync
9cdd4d805ecb43126372f7cf12e4032836cb738avboxsync
9cdd4d805ecb43126372f7cf12e4032836cb738avboxsyncbool CidetCoreTestInstruction(PCIDETCORE pThis, PCCIDETINSTR pInstr)
9cdd4d805ecb43126372f7cf12e4032836cb738avboxsync{
9cdd4d805ecb43126372f7cf12e4032836cb738avboxsync AssertReleaseMsgReturn(RT_VALID_PTR(pThis), ("%p\n", pThis), false);
9cdd4d805ecb43126372f7cf12e4032836cb738avboxsync AssertReleaseReturn(pThis->u32Magic == CIDETCORE_MAGIC, false);
9cdd4d805ecb43126372f7cf12e4032836cb738avboxsync AssertReleaseReturn(pThis->cCodeBufConfigs > 0, false);
9cdd4d805ecb43126372f7cf12e4032836cb738avboxsync
9cdd4d805ecb43126372f7cf12e4032836cb738avboxsync if (!CideCoreSetInstruction(pThis, pInstr))
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return CidetCoreSetError(pThis, "CideCoreSetInstruction failed");
9cdd4d805ecb43126372f7cf12e4032836cb738avboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync bool fResult = CidetCoreTest_Basic(pThis);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return fResult;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync}
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync