VirtualBox

Changeset 53579 in vbox for trunk/src/VBox


Ignore:
Timestamp:
Dec 19, 2014 7:24:09 PM (10 years ago)
Author:
vboxsync
Message:

cidet: More code...

Location:
trunk/src/VBox/ValidationKit/utils/cpu
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/ValidationKit/utils/cpu/cidet-app.cpp

    r53576 r53579  
    136136 * we've already handled the first exception while executing. */
    137137static PCIDETAPP volatile   g_pExecutingThis;
     138#ifdef USE_SIGNALS
     139/** The default signal mask. */
     140static sigset_t             g_ProcSigMask;
     141/** The alternative signal stack. */
     142static stack_t              g_AltStack;
     143#endif
    138144
    139145
     
    800806         *       code with IEM, we better skip unnecessary trips to ring-0.
    801807         */
     808        uint8_t * const pbStartEpilogue = pbDst;
    802809
    803810        /* jmp      $+6 */
     
    819826        *pbDst++ = 0x00;
    820827        *pbDst++ = 0x00;
     828        uint8_t offRipAdjust = (uint8_t)(uintptr_t)(pbStartEpilogue - pbDst);
    821829
    822830        /* push     xCX */
     
    828836        *pbDst++ = 0x4c;
    829837        *pbDst++ = 0x24;
    830         *pbDst++ = 0x08;
    831 
    832         /* lea      xCX, [xCX - 14] */
     838        *pbDst++ = sizeof(uintptr_t);
     839
     840        /* lea      xCX, [xCX - 24] */
    833841        *pbDst++ = 0x48;
    834842        *pbDst++ = 0x8d;
    835843        *pbDst++ = 0x49;
    836         *pbDst++ = 0xf2;
     844        *pbDst++ = offRipAdjust;
    837845
    838846        /* mov      xCX, [xSP + xCB] */
     
    841849        *pbDst++ = 0x4c;
    842850        *pbDst++ = 0x24;
    843         *pbDst++ = 0x08;
     851        *pbDst++ = sizeof(uintptr_t);
    844852
    845853        /* mov      xCX, &pThis->ActualCtx */
     
    950958        /* Won't end up here... */
    951959    }
     960    g_pExecutingThis = NULL;
    952961#else
    953962    CidetAppExecute(&((PCIDETAPP)pThis)->ExecuteCtx, &pThis->InCtx);
     963    if (g_pExecutingThis)
     964        g_pExecutingThis = NULL;
     965    else
     966    {
     967        RTTESTI_CHECK_RC(sigprocmask(SIG_SETMASK, &g_ProcSigMask, NULL), 0);
     968        RTTESTI_CHECK_RC(sigaltstack(&g_AltStack, NULL), 0);
     969    }
    954970#endif
    955     g_pExecutingThis = NULL;
    956971
    957972    return true;
     
    11691184     * Set up signal handlers with alternate stack.
    11701185     */
     1186    /* Get the default signal mask. */
     1187    RTTESTI_CHECK_RC_RET(sigprocmask(SIG_BLOCK, NULL, &g_ProcSigMask), 0, RTEXITCODE_FAILURE);
     1188
    11711189    /* Alternative stack so we can play with esp/rsp. */
    1172     stack_t AltStack;
    1173     RT_ZERO(AltStack);
    1174     AltStack.ss_flags = 0;
     1190    RT_ZERO(g_AltStack);
     1191    g_AltStack.ss_flags = 0;
    11751192# ifdef SIGSTKSZ
    1176     AltStack.ss_size  = RT_MAX(SIGSTKSZ, _128K);
     1193    g_AltStack.ss_size  = RT_MAX(SIGSTKSZ, _128K);
    11771194# else
    1178     AltStack.ss_size  = _128K;
     1195    g_AltStack.ss_size  = _128K;
    11791196# endif
    1180     AltStack.ss_sp    = RTMemPageAlloc(AltStack.ss_size);
    1181     RTTESTI_CHECK_RET(AltStack.ss_sp != NULL, RTEXITCODE_FAILURE);
    1182     RTTESTI_CHECK_RC_RET(sigaltstack(&AltStack, NULL), 0, RTEXITCODE_FAILURE);
     1197    g_AltStack.ss_sp    = RTMemPageAlloc(g_AltStack.ss_size);
     1198    RTTESTI_CHECK_RET(g_AltStack.ss_sp != NULL, RTEXITCODE_FAILURE);
     1199    RTTESTI_CHECK_RC_RET(sigaltstack(&g_AltStack, NULL), 0, RTEXITCODE_FAILURE);
    11831200
    11841201    /* Default signal action config. */
  • trunk/src/VBox/ValidationKit/utils/cpu/cidet-core.cpp

    r53575 r53579  
    248248{
    249249    pThis->InTemplateCtx.rip = UINT64_MAX;
    250     pThis->InTemplateCtx.rfl = X86_EFL_1 | X86_EFL_ID | X86_EFL_IF | X86_EFL_RF;
     250    pThis->InTemplateCtx.rfl = X86_EFL_1 | X86_EFL_ID | X86_EFL_IF;
    251251
    252252    unsigned i = RT_ELEMENTS(pThis->InTemplateCtx.aGRegs);
     
    358358
    359359/**
     360 * Selects the first REG encoding.
     361 *
     362 * @param   pThis               The core state structure.
     363 */
     364static void cidetCoreSetupFirstBaseEncoding_MrmReg(PCIDETCORE pThis)
     365{
     366    pThis->aOperands[pThis->idxMrmRegOp].iReg            = 0;
     367    pThis->aOperands[pThis->idxMrmRegOp].fIsMem          = false;
     368    pThis->aOperands[pThis->idxMrmRegOp].fIsRipRelative  = false;
     369    pThis->aOperands[pThis->idxMrmRegOp].fIsHighByteRegister = false;
     370    pThis->aOperands[pThis->idxMrmRegOp].cbMemDisp       = 0;
     371    pThis->aOperands[pThis->idxMrmRegOp].iMemBaseReg     = UINT8_MAX;
     372    pThis->aOperands[pThis->idxMrmRegOp].iMemIndexReg    = UINT8_MAX;
     373    pThis->aOperands[pThis->idxMrmRegOp].uMemScale       = 1;
     374    pThis->aOperands[pThis->idxMrmRegOp].iEffSeg         = UINT8_MAX;
     375    pThis->bModRm  &= ~X86_MODRM_REG_MASK;
     376    pThis->fRexR    = false;
     377}
     378
     379
     380/**
    360381 * Selects the next REG (ModR/M) encoding.
    361382 *
     
    543564        pThis->fHasMemoryOperand           = true;
    544565        pThis->fHasRegCollisionDirect      = false;
     566        iReg -= pThis->fHasHighByteRegInMrmReg * 4;
    545567        pThis->fHasRegCollisionMemBase     = iReg == X86_GREG_xBX && CIDET_OF_K_IS_GPR(pThis->fMrmRegOp);
    546568        pThis->fHasRegCollisionMemIndex    = iReg == X86_GREG_xSI && CIDET_OF_K_IS_GPR(pThis->fMrmRegOp);
     
    652674            if (CIDET_OF_K_IS_GPR(pThis->fMrmRmOp))
    653675            {
     676                iReg -= pThis->fHasHighByteRegInMrmReg * 4;
    654677                pThis->fHasRegCollisionMemBase = iReg == pThis->aOperands[pThis->idxMrmRmOp].iMemBaseReg;
    655678                pThis->fHasRegCollisionMemIndex = iReg == pThis->aOperands[pThis->idxMrmRmOp].iMemIndexReg;
     
    680703    if (CIDET_OF_K_IS_GPR(pThis->fMrmRmOp))
    681704    {
    682         pThis->fHasRegCollisionMemBase = iReg == X86_GREG_xBX;
     705        iReg -= pThis->fHasHighByteRegInMrmReg * 4;
     706        pThis->fHasRegCollisionMemBase  = iReg == X86_GREG_xBX;
    683707        pThis->fHasRegCollisionMemIndex = iReg == X86_GREG_xSI;
    684708        pThis->fHasRegCollisionMem = pThis->fHasRegCollisionMemBase || pThis->fHasRegCollisionMemIndex;
     
    738762        pThis->fHasRegCollisionDirect      = false;
    739763        pThis->fHasRegCollisionMemIndex    = false;
    740         pThis->fHasRegCollisionMemBase     = iReg == 0 && CIDET_OF_K_IS_GPR(pThis->fMrmRegOp);
     764        pThis->fHasRegCollisionMemBase     = iReg == pThis->fHasHighByteRegInMrmReg * 4 && CIDET_OF_K_IS_GPR(pThis->fMrmRegOp);
    741765        pThis->fHasRegCollisionMem         = pThis->fHasRegCollisionMemBase;
    742766        pThis->fHasStackRegInMrmRmBase     = false;
     
    842866                pThis->fRexB   = iRm >= 8;
    843867                pThis->fRexX   = false;
    844                 pThis->fHasRegCollisionDirect = iRm == iReg - pThis->fHasHighByteRegInMrmReg * 4
    845                                             && CIDET_OF_K_IS_SAME(pThis->fMrmRmOp, pThis->fMrmRegOp);
     868                pThis->fHasRegCollisionDirect = iRm == iReg && CIDET_OF_K_IS_SAME(pThis->fMrmRmOp, pThis->fMrmRegOp);
    846869                pThis->fHasStackRegInMrmRmBase = iRm == X86_GREG_xSP && CIDET_OF_K_IS_GPR(pThis->fMrmRegOp);
    847870            }
     
    907930            if (CIDET_OF_K_IS_GPR(pThis->fMrmRmOp))
    908931            {
     932                if (pThis->fHasHighByteRegInMrmReg)
     933                    iReg -= 4;
    909934                pThis->fHasRegCollisionMemBase = iReg == pThis->aOperands[pThis->idxMrmRmOp].iMemBaseReg;
    910935                pThis->fHasRegCollisionMemIndex = iReg == pThis->aOperands[pThis->idxMrmRmOp].iMemIndexReg;
     
    935960    pThis->fHasRegCollisionDirect = false;
    936961    pThis->fHasRegCollisionMemIndex = false;
    937     pThis->fHasRegCollisionMemBase = iReg == X86_GREG_xAX && CIDET_OF_K_IS_GPR(pThis->fMrmRmOp);
     962    pThis->fHasRegCollisionMemBase = iReg == pThis->fHasHighByteRegInMrmReg * 4
     963                                  && CIDET_OF_K_IS_GPR(pThis->fMrmRmOp);
    938964    pThis->fHasRegCollisionMem = pThis->fHasRegCollisionMemBase;
    939965    pThis->fHasStackRegInMrmRmBase = false;
     
    9901016    pThis->bSib  |= iBase & X86_SIB_BASE_MASK;
    9911017    pThis->fRexB  = iBase >= 8;
    992     pThis->fHasRegCollisionMemBase = pThis->aOperands[pThis->idxMrmRmOp].iMemBaseReg == iReg
     1018    pThis->fHasRegCollisionMemBase =    pThis->aOperands[pThis->idxMrmRmOp].iMemBaseReg
     1019                                     == iReg - pThis->fHasHighByteRegInMrmReg * 4
    9931020                                  && CIDET_OF_K_IS_GPR(pThis->fMrmRegOp);
    9941021    pThis->fHasRegCollisionMem = pThis->fHasRegCollisionMemBase || pThis->fHasRegCollisionMemIndex;
     
    10211048    pThis->bSib |= (iIndex & X86_SIB_INDEX_SMASK) << X86_SIB_INDEX_SHIFT;
    10221049    pThis->fRexX = iIndex >= 8;
    1023     pThis->fHasRegCollisionMemIndex = pThis->aOperands[pThis->idxMrmRmOp].iMemIndexReg == iReg
     1050    pThis->fHasRegCollisionMemIndex =     pThis->aOperands[pThis->idxMrmRmOp].iMemIndexReg
     1051                                       == iReg - pThis->fHasHighByteRegInMrmReg * 4
    10241052                                   && (  !pThis->fUsesVexIndexRegs
    10251053                                       ? CIDET_OF_K_IS_GPR(pThis->fMrmRegOp) : CIDET_OF_K_IS_VRX(pThis->fMrmRegOp) );
     
    12631291    {
    12641292        Assert(pThis->fUsesModRm == true);
     1293        cidetCoreSetupFirstBaseEncoding_MrmReg(pThis);
    12651294        if (pThis->cbAddrMode == 2)
    12661295            cidetCoreSetupFirstBaseEncoding_MrmRmMod_16bit(pThis, 0);
     
    15561585            Assert(pDataBuf->idxOp == idxOp);
    15571586            if (!pThis->pfnReInitDataBuf(pThis, pDataBuf))
     1587            {
     1588                pThis->cSkippedReInitDataBuf++;
    15581589                return false;
     1590            }
    15591591            pDataBuf->fActive = true;
    15601592
     
    15771609                if (   (int64_t)pThis->aOperands[idxOp].uImmDispValue > INT32_MAX
    15781610                    || (int64_t)pThis->aOperands[idxOp].uImmDispValue < INT32_MIN)
     1611                {
     1612                    pThis->cSkippedDataBufWrtRip++;
    15791613                    return false;
     1614                }
    15801615            }
    15811616            else if (iMemBaseReg != UINT8_MAX)
     
    16301665                        offSeg &= g_au64ByteSizeToMask[pThis->cbAddrMode];
    16311666                        if (offSeg % uEffScale != 0)
     1667                        {
     1668                            pThis->cSkippedSameBaseIndexRemainder++;
    16321669                            return false;
     1670                        }
    16331671                    }
    16341672                    offSeg /= uEffScale;
     
    16471685                }
    16481686                else if (offSeg & (RT_BIT_64(pThis->aOperands[idxOp].uMemScale) - 1))
     1687                {
     1688                    pThis->cSkippedOnlyIndexRemainder++;
    16491689                    return false;
     1690                }
    16501691
    16511692                pThis->aOperands[idxOp].uMemIndexRegValue = offSeg / pThis->aOperands[idxOp].uMemScale;
     
    16671708                    ? (int64_t)offSeg != (int8_t)offSeg
    16681709                    : false /* 8 */)
    1669                        return false;
     1710                {
     1711                    pThis->cSkippedDirectAddressingOverflow++;
     1712                    return false;
     1713                }
    16701714                pThis->aOperands[idxOp].uImmDispValue = offSeg;
    16711715            }
     
    17231767            {
    17241768                case CIDET_OF_K_GPR:
    1725                     pThis->aOperands[idxOp].In.pv = &pThis->InCtx.aGRegs[pThis->aOperands[idxOp].iReg];
    1726                     pThis->aOperands[idxOp].Expected.pv = &pThis->ExpectedCtx.aGRegs[pThis->aOperands[idxOp].iReg];
    17271769                    if (!pThis->aOperands[idxOp].fIsHighByteRegister)
    17281770                    {
     1771                        pThis->aOperands[idxOp].In.pv = &pThis->InCtx.aGRegs[pThis->aOperands[idxOp].iReg];
     1772                        pThis->aOperands[idxOp].Expected.pv = &pThis->ExpectedCtx.aGRegs[pThis->aOperands[idxOp].iReg];
     1773                    }
     1774                    else
     1775                    {
     1776                        pThis->aOperands[idxOp].In.pv = &pThis->InCtx.aGRegs[pThis->aOperands[idxOp].iReg - 4];
    17291777                        pThis->aOperands[idxOp].In.pu8++;
     1778                        pThis->aOperands[idxOp].Expected.pv = &pThis->ExpectedCtx.aGRegs[pThis->aOperands[idxOp].iReg - 4];
    17301779                        pThis->aOperands[idxOp].Expected.pu8++;
    17311780                    }
     
    17731822    int rc = pThis->pCurInstr->pfnSetupInOut(pThis, false /*fInvalid*/);
    17741823    if (RT_FAILURE(rc))
     1824    {
     1825        pThis->cSkippedSetupInOut++;
    17751826        return false;
     1827    }
    17761828
    17771829    /*
     
    17861838                Assert(pThis->aOperands[idxOp].pDataBuf);
    17871839                if (!pThis->pfnSetupDataBuf(pThis, pThis->aOperands[idxOp].pDataBuf, pThis->aOperands[idxOp].In.pv))
     1840                {
     1841                    pThis->cSkippedSetupDataBuf++;
    17881842                    return false;
     1843                }
     1844
    17891845                Assert(   pThis->aOperands[idxOp].iMemBaseReg == UINT8_MAX
    17901846                       || pThis->InCtx.aGRegs[pThis->aOperands[idxOp].iMemBaseReg] == pThis->aOperands[idxOp].uMemBaseRegValue);
     
    20612117            return true;
    20622118        }
    2063     }
     2119        else
     2120            pThis->cSkippedReInitCodeBuf++;
     2121    }
     2122    else
     2123        pThis->cSkippedAssemble++;
    20642124    return false;
    20652125}
     
    21052165            return true;
    21062166        }
    2107     }
     2167        pThis->cSkippedSetupCodeBuf++;
     2168    }
     2169    else
     2170        pThis->cSkippedAssemble++;
    21082171    return false;
     2172}
     2173
     2174
     2175/**
     2176 * Compares the output with the output expectations.
     2177 *
     2178 * @returns true if ok, false if not (calls pfnFailure too).
     2179 * @param   pThis           The core state structure.
     2180 */
     2181bool CidetCoreCheckResults(PCIDETCORE pThis)
     2182{
     2183    if (memcmp(&pThis->ActualCtx, &pThis->ExpectedCtx, CIDETCPUCTX_COMPARE_SIZE) == 0)
     2184        return true;
     2185
     2186    unsigned cDiffs = 0;
     2187#define IF_FIELD_DIFFERS_SET_ERROR(a_Field, a_Fmt) \
     2188        if (pThis->ActualCtx.a_Field != pThis->ExpectedCtx.a_Field) \
     2189        { \
     2190            CidetCoreSetError(pThis, #a_Field " differs: got %#llx expected %#llx", \
     2191                              pThis->ActualCtx.a_Field, pThis->ExpectedCtx.a_Field); \
     2192            cDiffs++; \
     2193        } else do { } while (0)
     2194
     2195    IF_FIELD_DIFFERS_SET_ERROR(rip,                    "%#010llx");
     2196    IF_FIELD_DIFFERS_SET_ERROR(rfl,                    "%#010llx");
     2197    IF_FIELD_DIFFERS_SET_ERROR(aGRegs[X86_GREG_xAX],   "%#010llx");
     2198    IF_FIELD_DIFFERS_SET_ERROR(aGRegs[X86_GREG_xBX],   "%#010llx");
     2199    IF_FIELD_DIFFERS_SET_ERROR(aGRegs[X86_GREG_xCX],   "%#010llx");
     2200    IF_FIELD_DIFFERS_SET_ERROR(aGRegs[X86_GREG_xDX],   "%#010llx");
     2201    IF_FIELD_DIFFERS_SET_ERROR(aGRegs[X86_GREG_xSP],   "%#010llx");
     2202    IF_FIELD_DIFFERS_SET_ERROR(aGRegs[X86_GREG_xBP],   "%#010llx");
     2203    IF_FIELD_DIFFERS_SET_ERROR(aGRegs[X86_GREG_xSI],   "%#010llx");
     2204    IF_FIELD_DIFFERS_SET_ERROR(aGRegs[X86_GREG_xDI],   "%#010llx");
     2205    IF_FIELD_DIFFERS_SET_ERROR(aGRegs[X86_GREG_x8],    "%#010llx");
     2206    IF_FIELD_DIFFERS_SET_ERROR(aGRegs[X86_GREG_x9],    "%#010llx");
     2207    IF_FIELD_DIFFERS_SET_ERROR(aGRegs[X86_GREG_x9],    "%#010llx");
     2208    IF_FIELD_DIFFERS_SET_ERROR(aGRegs[X86_GREG_x10],   "%#010llx");
     2209    IF_FIELD_DIFFERS_SET_ERROR(aGRegs[X86_GREG_x11],   "%#010llx");
     2210    IF_FIELD_DIFFERS_SET_ERROR(aGRegs[X86_GREG_x12],   "%#010llx");
     2211    IF_FIELD_DIFFERS_SET_ERROR(aGRegs[X86_GREG_x13],   "%#010llx");
     2212    IF_FIELD_DIFFERS_SET_ERROR(aGRegs[X86_GREG_x14],   "%#010llx");
     2213    IF_FIELD_DIFFERS_SET_ERROR(aGRegs[X86_GREG_x15],   "%#010llx");
     2214    IF_FIELD_DIFFERS_SET_ERROR(aSRegs[X86_SREG_CS],    "%#06x");
     2215    IF_FIELD_DIFFERS_SET_ERROR(aSRegs[X86_SREG_SS],    "%#06x");
     2216    IF_FIELD_DIFFERS_SET_ERROR(aSRegs[X86_SREG_DS],    "%#06x");
     2217    IF_FIELD_DIFFERS_SET_ERROR(aSRegs[X86_SREG_ES],    "%#06x");
     2218    IF_FIELD_DIFFERS_SET_ERROR(aSRegs[X86_SREG_FS],    "%#06x");
     2219    IF_FIELD_DIFFERS_SET_ERROR(aSRegs[X86_SREG_GS],    "%#06x");
     2220    IF_FIELD_DIFFERS_SET_ERROR(tr,                     "%#06x");
     2221    IF_FIELD_DIFFERS_SET_ERROR(ldtr,                   "%#06x");
     2222    IF_FIELD_DIFFERS_SET_ERROR(cr0,                    "%#010llx");
     2223    IF_FIELD_DIFFERS_SET_ERROR(cr2,                    "%#010llx");
     2224    IF_FIELD_DIFFERS_SET_ERROR(cr3,                    "%#010llx");
     2225    IF_FIELD_DIFFERS_SET_ERROR(cr4,                    "%#010llx");
     2226    IF_FIELD_DIFFERS_SET_ERROR(cr8,                    "%#010llx");
     2227    IF_FIELD_DIFFERS_SET_ERROR(dr0,                    "%#010llx");
     2228    IF_FIELD_DIFFERS_SET_ERROR(dr1,                    "%#010llx");
     2229    IF_FIELD_DIFFERS_SET_ERROR(dr2,                    "%#010llx");
     2230    IF_FIELD_DIFFERS_SET_ERROR(dr3,                    "%#010llx");
     2231    IF_FIELD_DIFFERS_SET_ERROR(dr6,                    "%#010llx");
     2232    IF_FIELD_DIFFERS_SET_ERROR(dr7,                    "%#010llx");
     2233    IF_FIELD_DIFFERS_SET_ERROR(uXcpt,                  "%#04x");
     2234    IF_FIELD_DIFFERS_SET_ERROR(uErr,                   "%#04llx");
     2235
     2236AssertBreakpoint();
     2237    Assert(cDiffs > 0);
     2238    return cDiffs == 0;
    21092239}
    21102240
     
    21532283                             * Check the result against our expectations.
    21542284                             */
     2285                            CidetCoreCheckResults(pThis);
    21552286                            /** @todo check result. */
    21562287
     
    21672298            cSkipped++;
    21682299    } while (CidetCoreSetupNextBaseEncoding(pThis));
    2169     CIDET_DPRINTF(("CidetCoreTest_Basic: cExecuted=%u cSkipped=%u\n", cExecuted, cSkipped));
     2300
     2301    CIDET_DPRINTF(("CidetCoreTest_Basic: cExecuted=%u cSkipped=%u\n"
     2302                   "  cSkippedSetupInOut               =%u\n"
     2303                   "  cSkippedReInitDataBuf            =%u\n"
     2304                   "  cSkippedSetupDataBuf             =%u\n"
     2305                   "  cSkippedDataBufWrtRip            =%u\n"
     2306                   "  cSkippedAssemble                 =%u\n"
     2307                   "  cSkippedReInitCodeBuf            =%u\n"
     2308                   "  cSkippedSetupCodeBuf             =%u\n"
     2309                   "  cSkippedSameBaseIndexRemainder   =%u\n"
     2310                   "  cSkippedOnlyIndexRemainder       =%u\n"
     2311                   "  cSkippedDirectAddressingOverflow =%u\n"
     2312                   ,
     2313                   cExecuted, cSkipped,
     2314                   pThis->cSkippedSetupInOut,
     2315                   pThis->cSkippedReInitDataBuf,
     2316                   pThis->cSkippedSetupDataBuf,
     2317                   pThis->cSkippedDataBufWrtRip,
     2318                   pThis->cSkippedAssemble,
     2319                   pThis->cSkippedReInitCodeBuf,
     2320                   pThis->cSkippedSetupCodeBuf,
     2321                   pThis->cSkippedSameBaseIndexRemainder,
     2322                   pThis->cSkippedOnlyIndexRemainder,
     2323                   pThis->cSkippedDirectAddressingOverflow
     2324                   ));
    21702325
    21712326    return true;
  • trunk/src/VBox/ValidationKit/utils/cpu/cidet-instr-1.cpp

    r53576 r53579  
    3131*******************************************************************************/
    3232#include "cidet.h"
    33 
     33#include <VBox/err.h>
     34
     35
     36/*******************************************************************************
     37*   Defined Constants And Macros                                               *
     38*******************************************************************************/
     39/*
     40 * Shorter defines for the EFLAGS to save table space.
     41 */
     42#undef  CF
     43#undef  PF
     44#undef  AF
     45#undef  ZF
     46#undef  SF
     47#undef  OF
     48
     49#define CF X86_EFL_CF
     50#define PF X86_EFL_PF
     51#define AF X86_EFL_AF
     52#define ZF X86_EFL_ZF
     53#define SF X86_EFL_SF
     54#define OF X86_EFL_OF
     55
     56
     57/*******************************************************************************
     58*   Structures and Typedefs                                                    *
     59*******************************************************************************/
     60typedef struct CIDET2IN1OUTWITHFLAGSU8ENTRY
     61{
     62    uint8_t     uIn1;
     63    uint8_t     uIn2;
     64    uint16_t    fEFlagsIn;
     65    uint8_t     uOut;
     66    uint16_t    fEFlagsOut;
     67} CIDET2IN1OUTWITHFLAGSU8ENTRY;
     68typedef CIDET2IN1OUTWITHFLAGSU8ENTRY const *PCCIDET2IN1OUTWITHFLAGSU8ENTRY;
     69
     70typedef struct CIDET2IN1OUTWITHFLAGSU16ENTRY
     71{
     72    uint16_t    uIn1;
     73    uint16_t    uIn2;
     74    uint16_t    fEFlagsIn;
     75    uint16_t    uOut;
     76    uint16_t    fEFlagsOut;
     77} CIDET2IN1OUTWITHFLAGSU16ENTRY;
     78typedef CIDET2IN1OUTWITHFLAGSU16ENTRY const *PCCIDET2IN1OUTWITHFLAGSU16ENTRY;
     79
     80typedef struct CIDET2IN1OUTWITHFLAGSU32ENTRY
     81{
     82    uint32_t    uIn1;
     83    uint32_t    uIn2;
     84    uint16_t    fEFlagsIn;
     85    uint32_t    uOut;
     86    uint16_t    fEFlagsOut;
     87} CIDET2IN1OUTWITHFLAGSU32ENTRY;
     88typedef CIDET2IN1OUTWITHFLAGSU32ENTRY const *PCCIDET2IN1OUTWITHFLAGSU32ENTRY;
     89
     90typedef struct CIDET2IN1OUTWITHFLAGSU64ENTRY
     91{
     92    uint64_t    uIn1;
     93    uint64_t    uIn2;
     94    uint16_t    fEFlagsIn;
     95    uint64_t    uOut;
     96    uint16_t    fEFlagsOut;
     97} CIDET2IN1OUTWITHFLAGSU64ENTRY;
     98typedef CIDET2IN1OUTWITHFLAGSU64ENTRY const *PCCIDET2IN1OUTWITHFLAGSU64ENTRY;
     99
     100typedef struct CIDET2IN1OUTWITHFLAGS
     101{
     102    PCCIDET2IN1OUTWITHFLAGSU8ENTRY  pa8Entries;
     103    PCCIDET2IN1OUTWITHFLAGSU16ENTRY pa16Entries;
     104    PCCIDET2IN1OUTWITHFLAGSU32ENTRY pa32Entries;
     105    PCCIDET2IN1OUTWITHFLAGSU64ENTRY pa64Entries;
     106    uint16_t c8Entries;
     107    uint16_t c16Entries;
     108    uint16_t c32Entries;
     109    uint16_t c64Entries;
     110    uint32_t fRelevantEFlags;
     111} CIDET2IN1OUTWITHFLAGS;
     112
     113#define CIDET2IN1OUTWITHFLAGS_INITIALIZER(a_fRelevantEFlags) \
     114    { \
     115        &s_a8Results[0], &s_a16Results[0], &s_a32Results[0], &s_a64Results[0], \
     116        RT_ELEMENTS(s_a8Results), RT_ELEMENTS(s_a16Results), RT_ELEMENTS(s_a32Results), RT_ELEMENTS(s_a64Results), \
     117        (a_fRelevantEFlags) \
     118    }
     119
     120
     121/**
     122 * Generic worker for a FNCIDETSETUPINOUT function with two GPR/MEM registers,
     123 * storing result in the first and flags.
     124 *
     125 * @returns See FNCIDETSETUPINOUT.
     126 * @param   pThis           The core CIDET state structure.  The InCtx
     127 *                          and ExpectedCtx members will be modified.
     128 * @param   fInvalid        When set, get the next invalid operands that will
     129 *                          cause exceptions/faults.
     130 * @param   pResults        The result collection.
     131 */
     132static int CidetGenericIn2Out1WithFlags(PCIDETCORE pThis, bool fInvalid, CIDET2IN1OUTWITHFLAGS const *pResults)
     133{
     134    int rc;
     135
     136    Assert(pThis->idxMrmRegOp < 2);
     137    Assert(pThis->idxMrmRmOp  < 2);
     138    Assert(pThis->idxMrmRmOp != pThis->idxMrmRegOp);
     139
     140    if (!fInvalid)
     141    {
     142        if (   !pThis->fHasRegCollisionDirect
     143            && !pThis->fHasRegCollisionMem)
     144        {
     145            pThis->InCtx.rfl       &= ~(uint64_t)pResults->fRelevantEFlags;
     146            pThis->ExpectedCtx.rfl &= ~(uint64_t)pResults->fRelevantEFlags;
     147            switch (pThis->aOperands[0].cb)
     148            {
     149                case 1:
     150                {
     151                    uint16_t                       idx    = ++pThis->iInOut % pResults->c8Entries;
     152                    PCCIDET2IN1OUTWITHFLAGSU8ENTRY pEntry = &pResults->pa8Entries[idx];
     153                    rc = idx ? VINF_SUCCESS : VINF_EOF;
     154
     155                    *pThis->aOperands[0].In.pu8       = pEntry->uIn1;
     156                    *pThis->aOperands[1].In.pu8       = pEntry->uIn2;
     157                    pThis->InCtx.rfl                 |= pEntry->fEFlagsIn;
     158
     159                    *pThis->aOperands[0].Expected.pu8 = pEntry->uOut;
     160                    *pThis->aOperands[1].Expected.pu8 = pEntry->uIn2;
     161                    pThis->ExpectedCtx.rfl           |= pEntry->fEFlagsOut;
     162                    break;
     163                }
     164
     165                case 2:
     166                {
     167                    uint16_t                        idx    = ++pThis->iInOut % pResults->c16Entries;
     168                    PCCIDET2IN1OUTWITHFLAGSU16ENTRY pEntry = &pResults->pa16Entries[idx];
     169                    rc = idx ? VINF_SUCCESS : VINF_EOF;
     170
     171                    *pThis->aOperands[0].In.pu16       = pEntry->uIn1;
     172                    *pThis->aOperands[1].In.pu16       = pEntry->uIn2;
     173                    pThis->InCtx.rfl                  |= pEntry->fEFlagsIn;
     174
     175                    *pThis->aOperands[0].Expected.pu16 = pEntry->uOut;
     176                    *pThis->aOperands[1].Expected.pu16 = pEntry->uIn2;
     177                    pThis->ExpectedCtx.rfl            |= pEntry->fEFlagsOut;
     178                    break;
     179                }
     180
     181                case 4:
     182                {
     183                    uint16_t                        idx    = ++pThis->iInOut % pResults->c32Entries;
     184                    PCCIDET2IN1OUTWITHFLAGSU32ENTRY pEntry = &pResults->pa32Entries[idx];
     185                    rc = idx ? VINF_SUCCESS : VINF_EOF;
     186
     187                    *pThis->aOperands[0].In.pu32       = pEntry->uIn1;
     188                    *pThis->aOperands[1].In.pu32       = pEntry->uIn2;
     189                    pThis->InCtx.rfl                  |= pEntry->fEFlagsIn;
     190
     191                    *pThis->aOperands[0].Expected.pu32 = pEntry->uOut;
     192                    if (!pThis->aOperands[0].fIsMem)
     193                        pThis->aOperands[0].Expected.pu32[0] = 0;
     194                    *pThis->aOperands[1].Expected.pu32 = pEntry->uIn2;
     195                    pThis->ExpectedCtx.rfl            |= pEntry->fEFlagsOut;
     196                    break;
     197                }
     198
     199                case 8:
     200                {
     201                    uint16_t                        idx    = ++pThis->iInOut % pResults->c64Entries;
     202                    PCCIDET2IN1OUTWITHFLAGSU64ENTRY pEntry = &pResults->pa64Entries[idx];
     203                    rc = idx ? VINF_SUCCESS : VINF_EOF;
     204
     205                    *pThis->aOperands[0].In.pu64       = pEntry->uIn1;
     206                    *pThis->aOperands[1].In.pu64       = pEntry->uIn2;
     207                    pThis->InCtx.rfl                  |= pEntry->fEFlagsIn;
     208
     209                    *pThis->aOperands[0].Expected.pu64 = pEntry->uOut;
     210                    *pThis->aOperands[1].Expected.pu64 = pEntry->uIn2;
     211                    pThis->ExpectedCtx.rfl            |= pEntry->fEFlagsOut;
     212                    break;
     213                }
     214
     215                default:
     216                    AssertFailed();
     217                    rc = VERR_INTERNAL_ERROR_3;
     218            }
     219        }
     220        else
     221            rc = VERR_NOT_SUPPORTED;
     222    }
     223    else
     224        rc = VERR_NO_DATA;
     225    return rc;
     226}
    34227
    35228
    36229static DECLCALLBACK(int) cidetInOutAdd(PCIDETCORE pThis, bool fInvalid)
    37230{
    38     return 0;
     231    static const CIDET2IN1OUTWITHFLAGSU8ENTRY s_a8Results[] =
     232    {
     233        { UINT8_C(0x00), UINT8_C(0x00), 0, UINT8_C(0x00), ZF | PF },
     234    };
     235    static const CIDET2IN1OUTWITHFLAGSU16ENTRY s_a16Results[] =
     236    {
     237        { UINT16_C(0x0000), UINT16_C(0x0000), 0, UINT16_C(0x0000), ZF | PF },
     238    };
     239    static const CIDET2IN1OUTWITHFLAGSU32ENTRY s_a32Results[] =
     240    {
     241        { UINT32_C(0x00000000), UINT32_C(0x00000000), 0, UINT32_C(0x00000000), ZF | PF },
     242    };
     243    static const CIDET2IN1OUTWITHFLAGSU64ENTRY s_a64Results[] =
     244    {
     245        { UINT64_C(0x0000000000000000), UINT64_C(0x0000000000000000), 0, UINT64_C(0x0000000000000000), ZF | PF },
     246    };
     247    static const CIDET2IN1OUTWITHFLAGS s_Results = CIDET2IN1OUTWITHFLAGS_INITIALIZER(CF | PF | AF | SF | OF);
     248    return CidetGenericIn2Out1WithFlags(pThis, fInvalid, &s_Results);
    39249}
    40250
  • trunk/src/VBox/ValidationKit/utils/cpu/cidet.h

    r53576 r53579  
    111111 * @retval  VERR_NO_DATA if @a fInvalid is set and there are no invalid operand
    112112 *          values for this instruction.
     113 * @retval  VERR_NOT_SUPPORTED if something in the setup prevents us from
     114 *          comming up with working set of inputs and outputs.
    113115 *
    114116 * @param   pThis           The core CIDET state structure.  The InCtx
     
    172174    uint64_t            dr7;
    173175
     176    uint64_t            uErr;           /**< Exception error code.  UINT64_MAX if not applicable.  (Not for input context.) */
     177    uint32_t            uXcpt;          /**< Exception number.  UINT32_MAX if no exception.  (Not for input context.) */
     178
    174179    uint32_t            fIgnoredRFlags; /**< Only for expected result. */
    175     uint32_t            uXcpt;          /**< Exception number.  UINT32_MAX if no exception.  (Not for input context.) */
    176     uint64_t            uErr;           /**< Exception error code.  UINT64_MAX if not applicable.  (Not for input context.) */
    177 
    178180    bool                fTrickyStack;   /**< Set if the stack might be bad.  May come at the cost of accurate flags (32-bit). */
    179 
    180181} CIDETCPUCTX;
    181182typedef CIDETCPUCTX *PCIDETCPUCTX;
    182183typedef CIDETCPUCTX const *PCCIDETCPUCTX;
     184
     185/** Number of bytes of CIDETCPUCTX that can be compared quickly using memcmp.
     186 * Anything following these bytes are not relevant to the compare.  */
     187#define CIDETCPUCTX_COMPARE_SIZE    RT_UOFFSETOF(CIDETCPUCTX, fIgnoredRFlags)
    183188
    184189
     
    10241029    uint8_t             abBuf[0x2000];
    10251030
     1031
     1032    /** Number of skipped tests because of pfnSetupInOut failures. */
     1033    uint32_t            cSkippedSetupInOut;
     1034    /** Number of skipped tests because of pfnReInitDataBuf failures. */
     1035    uint32_t            cSkippedReInitDataBuf;
     1036    /** Number of skipped tests because of pfnSetupDataBuf failures. */
     1037    uint32_t            cSkippedSetupDataBuf;
     1038    /** Number of skipped tests because RIP relative addressing constraints. */
     1039    uint32_t            cSkippedDataBufWrtRip;
     1040    /** Number of skipped tests because of assemble failures. */
     1041    uint32_t            cSkippedAssemble;
     1042    /** Number of skipped tests because of pfnReInitCodeBuf failures. */
     1043    uint32_t            cSkippedReInitCodeBuf;
     1044    /** Number of skipped tests because of pfnSetupCodeBuf failures. */
     1045    uint32_t            cSkippedSetupCodeBuf;
     1046    /** Number of skipped tests because the base and index registers are the same
     1047     * one and there was a remainder when trying to point to the data buffer. */
     1048    uint32_t            cSkippedSameBaseIndexRemainder;
     1049    /** Number of skipped tests because index-only addressing left a remainder. */
     1050    uint32_t            cSkippedOnlyIndexRemainder;
     1051    /** Number of skipped tests because of direct addressing overflowed. */
     1052    uint32_t            cSkippedDirectAddressingOverflow;
     1053
     1054
    10261055} CIDETCORE;
    10271056/** Pointer to the CIDET core state. */
  • trunk/src/VBox/ValidationKit/utils/cpu/cidet.mac

    r53548 r53579  
    3434    .aGRegs             resq 16
    3535    .aSRegs             resw 6
     36
    3637    .tr                 resw 1
    3738    .ldtr               resw 1
     
    4142    .cr4                resq 1
    4243    .cr8                resq 1
     44    .dr0                resq 1
     45    .dr1                resq 1
     46    .dr2                resq 1
     47    .dr3                resq 1
     48    .dr6                resq 1
     49    .dr7                resq 1
     50
     51    .uErr               resq 1
     52    .uXcpt              resd 1
     53
    4354    .fIgnoredRFlags     resd 1
    44     .uXcpt              resd 1
    45     .uErr               resq 1
    4655    .fTrickyStack       resb 1
    4756endstruc
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette