VirtualBox

Changeset 95377 in vbox for trunk/src/VBox/ValidationKit


Ignore:
Timestamp:
Jun 26, 2022 9:33:17 PM (3 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
151972
Message:

ValKit/bs3-cpu-instr-3: More generalization, tentatively including MMX. Moving the Bs3TestCheckExtCtx function out to bs3kit. bugref:9898

Location:
trunk/src/VBox/ValidationKit/bootsectors
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/ValidationKit/bootsectors/bs3-cpu-instr-3-template.c

    r95373 r95377  
    11/* $Id$ */
    22/** @file
    3  * BS3Kit - bs3-cpu-instr-3, SSE and AVX instructions, C code template.
     3 * BS3Kit - bs3-cpu-instr-3 - MMX, SSE and AVX instructions, C code template.
    44 */
    55
     
    3838#ifdef BS3_INSTANTIATING_CMN
    3939/** Instruction set type and operand width. */
    40 typedef enum { T_INVALID, T_SSE, T_SSE2, T_SSE3, T_SSSE3, T_SSE4_1, T_SSE4_2, T_SSE4A, T_AVX_128, T_AVX_256, T_MAX } INPUT_TYPE_T;
     40typedef enum
     41{
     42    T_INVALID,
     43    T_MMX,
     44    T_AXMMX,
     45    T_SSE,
     46    T_128BITS = T_SSE,
     47    T_SSE2,
     48    T_SSE3,
     49    T_SSSE3,
     50    T_SSE4_1,
     51    T_SSE4_2,
     52    T_SSE4A,
     53    T_AVX_128,
     54    T_AVX2_128,
     55    T_AVX_256,
     56    T_256BITS = T_AVX_256,
     57    T_AVX2_256,
     58    T_MAX
     59} INPUT_TYPE_T;
    4160
    4261/** Memory or register rm variant. */
     
    5877    uint16_t    fAlignCheck : 1;
    5978    uint16_t    fMxCsrMM    : 1; /**< AMD only */
     79    uint8_t     bXcptMmx;
    6080    uint8_t     bXcptSse;
    6181    uint8_t     bXcptAvx;
     
    106126static const BS3CPUINSTR3_CONFIG_T g_aXcptConfig4[] =
    107127{
    108 /* fCr0Mp, Cr0Em, fCr0Ts, fCr4OsFxSR, fCr4OsXSave, fXcr0Sse, fXcr0Avx, fAligned, fAlignCheck, fMxCsrMM, bXcptSse,    bXcptAvx */
    109 /*   X87   SSE    SSE     SSE         AVX          AVX       AVX       SSE+AVX   AVX+AMD/SSE  AMD/SSE   */
    110     { 0,   0,     0,      1,          1,           1,        1,        1,        0,           0,        X86_XCPT_DB, X86_XCPT_DB }, /* #0 */
    111     { 1,   0,     0,      1,          1,           1,        1,        1,        0,           0,        X86_XCPT_DB, X86_XCPT_DB }, /* #1 */
    112     { 0,   1,     0,      1,          1,           1,        1,        1,        0,           0,        X86_XCPT_UD, X86_XCPT_DB }, /* #2 */
    113     { 0,   0,     1,      1,          1,           1,        1,        1,        0,           0,        X86_XCPT_NM, X86_XCPT_DB }, /* #3 */
    114     { 0,   1,     1,      1,          1,           1,        1,        1,        0,           0,        X86_XCPT_UD, X86_XCPT_DB }, /* #4 */
    115     { 0,   0,     0,      0,          1,           1,        1,        1,        0,           0,        X86_XCPT_UD, X86_XCPT_DB }, /* #5 */
    116     { 0,   0,     0,      1,          0,           1,        1,        1,        0,           0,        X86_XCPT_DB, X86_XCPT_UD }, /* #6 */
    117     { 0,   0,     0,      1,          1,           1,        0,        1,        0,           0,        X86_XCPT_DB, X86_XCPT_UD }, /* #7 */
    118     { 0,   0,     0,      1,          1,           0,        0,        1,        0,           0,        X86_XCPT_DB, X86_XCPT_UD }, /* #8 */
     128/*
     129 *   X87 SSE SSE SSE     AVX      AVX  AVX   SSE+AVX   AVX+AMD/SSE  AMD/SSE   <-- applies to
     130 *
     131 *   CR0 CR0 CR0 CR4     CR4      XCR0 XCR0
     132 *   MP, EM, TS, OSFXSR, OSXSAVE, SSE, AVX,  fAligned, fAlignCheck, fMxCsrMM, bXcptMmx,    bXcptSse,    bXcptAvx */
     133    { 0, 0,  0,  1,      1,       1,   1,    1,        0,           0,        X86_XCPT_DB, X86_XCPT_DB, X86_XCPT_DB }, /* #0 */
     134    { 1, 0,  0,  1,      1,       1,   1,    1,        0,           0,        X86_XCPT_DB, X86_XCPT_DB, X86_XCPT_DB }, /* #1 */
     135    { 0, 1,  0,  1,      1,       1,   1,    1,        0,           0,        X86_XCPT_UD, X86_XCPT_UD, X86_XCPT_DB }, /* #2 */
     136    { 0, 0,  1,  1,      1,       1,   1,    1,        0,           0,        X86_XCPT_NM, X86_XCPT_NM, X86_XCPT_DB }, /* #3 */
     137    { 0, 1,  1,  1,      1,       1,   1,    1,        0,           0,        X86_XCPT_UD, X86_XCPT_UD, X86_XCPT_DB }, /* #4 */
     138    { 0, 0,  0,  0,      1,       1,   1,    1,        0,           0,        X86_XCPT_UD, X86_XCPT_UD, X86_XCPT_DB }, /* #5 */
     139    { 0, 0,  0,  1,      0,       1,   1,    1,        0,           0,        X86_XCPT_DB, X86_XCPT_DB, X86_XCPT_UD }, /* #6 */
     140    { 0, 0,  0,  1,      1,       1,   0,    1,        0,           0,        X86_XCPT_DB, X86_XCPT_DB, X86_XCPT_UD }, /* #7 */
     141    { 0, 0,  0,  1,      1,       0,   0,    1,        0,           0,        X86_XCPT_DB, X86_XCPT_DB, X86_XCPT_UD }, /* #8 */
    119142    /* Memory misalignment: */
    120     { 0,   0,     0,      1,          1,           1,        1,        0,        0,           0,        X86_XCPT_GP, X86_XCPT_DB }, /* #9 */
    121     { 0,   0,     0,      1,          1,           1,        1,        0,        1,           0,        X86_XCPT_GP, X86_XCPT_AC }, /* #10 */
     143    { 0, 0,  0,  1,      1,       1,   1,    0,        0,           0,        X86_XCPT_GP, X86_XCPT_GP, X86_XCPT_DB }, /* #9 */
     144    { 0, 0,  0,  1,      1,       1,   1,    0,        1,           0,        X86_XCPT_GP, X86_XCPT_GP, X86_XCPT_AC }, /* #10 */
    122145    /* AMD only: */
    123     { 0,   0,     0,      1,          1,           1,        1,        0,        0,           1,        X86_XCPT_DB, X86_XCPT_DB }, /* #11 */
    124     { 0,   0,     0,      1,          1,           1,        1,        0,        1,           1,        X86_XCPT_AC, X86_XCPT_AC }, /* #12 */
     146    { 0, 0,  0,  1,      1,       1,   1,    0,        0,           1,        X86_XCPT_GP, X86_XCPT_DB, X86_XCPT_DB }, /* #11 */
     147    { 0, 0,  0,  1,      1,       1,   1,    0,        1,           1,        X86_XCPT_GP, X86_XCPT_AC, X86_XCPT_AC }, /* #12 */
    125148};
    126 
    127149#endif
    128150
     
    142164        if (g_uBs3CpuDetected & BS3CPU_F_CPUID)
    143165        {
    144             uint32_t fEcx, fEdx;
     166            uint32_t fEbx, fEcx, fEdx;
    145167            ASMCpuIdExSlow(1, 0, 0, 0, NULL, NULL, &fEcx, &fEdx);
     168            g_afTypeSupports[T_MMX]         = RT_BOOL(fEdx & X86_CPUID_FEATURE_EDX_MMX);
    146169            g_afTypeSupports[T_SSE]         = RT_BOOL(fEdx & X86_CPUID_FEATURE_EDX_SSE);
    147170            g_afTypeSupports[T_SSE2]        = RT_BOOL(fEdx & X86_CPUID_FEATURE_EDX_SSE2);
     
    153176            g_afTypeSupports[T_AVX_256]     = RT_BOOL(fEcx & X86_CPUID_FEATURE_ECX_AVX);
    154177
     178            if (ASMCpuId_EAX(0) >= 7)
     179            {
     180                ASMCpuIdExSlow(7, 0, 0, 0, NULL, &fEbx, NULL, NULL);
     181                g_afTypeSupports[T_AVX2_128] = RT_BOOL(fEbx & X86_CPUID_STEXT_FEATURE_EBX_AVX2);
     182                g_afTypeSupports[T_AVX2_256] = RT_BOOL(fEbx & X86_CPUID_STEXT_FEATURE_EBX_AVX2);
     183            }
     184
    155185            if (g_uBs3CpuDetected & BS3CPU_F_CPUID_EXT_LEAVES)
    156186            {
    157                 ASMCpuIdExSlow(UINT32_C(0x80000001), 0, 0, 0, NULL, NULL, &fEcx, NULL);
     187                ASMCpuIdExSlow(UINT32_C(0x80000001), 0, 0, 0, NULL, NULL, &fEcx, &fEdx);
     188                g_afTypeSupports[T_AXMMX]   = RT_BOOL(fEcx & X86_CPUID_AMD_FEATURE_EDX_AXMMX);
    158189                g_afTypeSupports[T_SSE4A]   = RT_BOOL(fEcx & X86_CPUID_AMD_FEATURE_ECX_SSE4A);
    159190                g_fAmdMisalignedSse         = RT_BOOL(fEcx & X86_CPUID_AMD_FEATURE_ECX_MISALNSSE);
     
    261292}
    262293
    263 
    264 static bool Bs3TestCheckExtCtx(PCBS3EXTCTX pActualExtCtx, PCBS3EXTCTX pExpectedExtCtx, uint16_t fFlags,
    265                                const char BS3_FAR *pszMode, uint16_t idTestStep)
    266 {
    267     /*
    268      * Make sure the context of a similar and valid before starting.
    269      */
    270     if (!pActualExtCtx || pActualExtCtx->u16Magic != BS3EXTCTX_MAGIC)
    271         return Bs3TestFailedF("%u - %s: invalid actual context pointer: %p", idTestStep, pszMode, pActualExtCtx);
    272     if (!pExpectedExtCtx || pExpectedExtCtx->u16Magic != BS3EXTCTX_MAGIC)
    273         return Bs3TestFailedF("%u - %s: invalid expected context pointer: %p", idTestStep, pszMode, pExpectedExtCtx);
    274     if (   pActualExtCtx->enmMethod != pExpectedExtCtx->enmMethod
    275         || pActualExtCtx->enmMethod == BS3EXTCTXMETHOD_INVALID
    276         || pActualExtCtx->enmMethod >= BS3EXTCTXMETHOD_END)
    277         return Bs3TestFailedF("%u - %s: mismatching or/and invalid context methods: %d vs %d",
    278                               idTestStep, pszMode, pActualExtCtx->enmMethod, pExpectedExtCtx->enmMethod);
    279     if (pActualExtCtx->cb != pExpectedExtCtx->cb)
    280         return Bs3TestFailedF("%u - %s: mismatching context sizes: %#x vs %#x",
    281                               idTestStep, pszMode, pActualExtCtx->cb, pExpectedExtCtx->cb);
    282 
    283     /*
    284      * Try get the job done quickly with a memory compare.
    285      */
    286     if (Bs3MemCmp(pActualExtCtx, pExpectedExtCtx, pActualExtCtx->cb) == 0)
    287         return true;
    288 
    289     Bs3TestFailedF("%u - %s: context memory differs", idTestStep, pszMode); // debug
    290     {
    291         uint8_t const BS3_FAR *pb1 = (uint8_t const BS3_FAR *)pActualExtCtx;
    292         uint8_t const BS3_FAR *pb2 = (uint8_t const BS3_FAR *)pExpectedExtCtx;
    293         unsigned const         cb  = pActualExtCtx->cb;
    294         unsigned               off;
    295         for (off = 0; off < cb; off++)
    296             if (pb1[off] != pb2[off])
    297             {
    298                 unsigned       cbDiff;
    299                 unsigned const offStart = off++;
    300                 while (off < cb && pb1[off] != pb2[off])
    301                     off++;
    302                 cbDiff = off - offStart;
    303                 switch (cbDiff)
    304                 {
    305                     case 1:
    306                         Bs3TestFailedF("%u - %s: Byte difference at %#x: %#04x, expected %#04x", idTestStep, pszMode, offStart,
    307                                        pb1[offStart], pb2[offStart]);
    308                         break;
    309                     case 2:
    310                         Bs3TestFailedF("%u - %s: Word difference at %#x: %#06x, expected %#06x", idTestStep, pszMode, offStart,
    311                                        RT_MAKE_U16(pb1[offStart], pb1[offStart + 1]),
    312                                        RT_MAKE_U16(pb2[offStart], pb2[offStart + 1]));
    313                         break;
    314                     case 4:
    315                         Bs3TestFailedF("%u - %s: Dword difference at %#x: %#010RX32, expected %#010RX32",
    316                                        idTestStep, pszMode, offStart,
    317                                        RT_MAKE_U32_FROM_U8(pb1[offStart], pb1[offStart + 1], pb1[offStart + 2], pb1[offStart + 3]),
    318                                        RT_MAKE_U32_FROM_U8(pb2[offStart], pb2[offStart + 1], pb2[offStart + 2], pb2[offStart + 3]));
    319                         break;
    320                     default:
    321                         Bs3TestFailedF("%u - %s: %#x..%#x differs", idTestStep, pszMode, offStart, off - 1);
    322                         Bs3TestFailedF("got      %.*Rhxs", off - offStart, &pb1[offStart]);
    323                         Bs3TestFailedF("expected %.*Rhxs", off - offStart, &pb2[offStart]);
    324                         break;
    325                 }
    326             }
    327     }
    328 
    329     if (pActualExtCtx->enmMethod == BS3EXTCTXMETHOD_ANCIENT)
    330         return Bs3TestFailedF("%u - %s: BS3EXTCTXMETHOD_ANCIENT not implemented", idTestStep, pszMode);
    331 
    332     /*
    333      * Check the x87 state.
    334      */
    335     if (   pActualExtCtx->enmMethod == BS3EXTCTXMETHOD_FXSAVE
    336         || (   pActualExtCtx->enmMethod == BS3EXTCTXMETHOD_XSAVE
    337             && (pActualExtCtx->fXcr0Nominal & XSAVE_C_X87)) )
    338     {
    339 
    340     }
    341 
    342     /*
    343      *
    344      */
    345 
    346     return false;
    347 }
    348294
    349295/**
     
    413359{
    414360    RTUINT256U      uSrc2;
    415     RTUINT256U      uSrc1; /**< uDstIn for SSE */
     361    RTUINT256U      uSrc1; /**< uDstIn for MMX & SSE */
    416362    RTUINT256U      uDstOut;
    417363} BS3CPUINSTR3_TEST1_VALUES_T;
     
    503449                BS3CPUINSTR3_TEST1_VALUES_T const BS3_FAR *paValues = paTests[iTest].paValues;
    504450                unsigned const  cValues     = paTests[iTest].cValues;
     451                bool const      fMmxInstr   = paTests[iTest].enmType < T_SSE;
    505452                bool const      fSseInstr   = paTests[iTest].enmType >= T_SSE && paTests[iTest].enmType < T_AVX_128;
    506453                uint8_t const   cbOperand   = paTests[iTest].enmType <= T_AVX_128 ? 128/8 : 256/8;
    507                 uint8_t const   cbAlign     = 16;
     454                uint8_t const   cbAlign     = fMmxInstr ? 8 : 16;
    508455                uint8_t         bXcptExpect = !g_afTypeSupports[paTests[iTest].enmType] ? X86_XCPT_UD
     456                                            : fMmxInstr ? paConfigs[iCfg].bXcptMmx
    509457                                            : fSseInstr ? paConfigs[iCfg].bXcptSse : paConfigs[iCfg].bXcptAvx;
    510458                uint16_t        idTestStep  = bRing * 10000 + iCfg * 100 + iTest * 10;
     
    515463                                                                      - !paConfigs[iCfg].fAligned];
    516464
    517                 /* If testing unaligned memory accesses, skip register-only tests.  This
    518                    allows setting bXcptSse and bXcptAvx to reflect the misaligned exceptions.  */
     465                /* If testing unaligned memory accesses, skip register-only tests.  This allows
     466                   setting bXcptMmx, bXcptSse and bXcptAvx to reflect the misaligned exceptions.  */
    519467                if (!paConfigs[iCfg].fAligned && paTests[iTest].enmRm != RM_MEM)
    520468                    continue;
     
    537485                     * Set up the context and some expectations.
    538486                     */
     487                    /* dest */
    539488                    if (paTests[iTest].iRegDst == UINT8_MAX)
    540489                    {
     
    547496                    }
    548497
    549                     if (paTests[iTest].iRegSrc1 != UINT8_MAX)
    550                         Bs3ExtCtxSetYmm(pExtCtx, paTests[iTest].iRegSrc1, &paValues[iVal].uSrc1, fSseInstr);
    551                     else
     498                    /* source #1 (/ destination for MMX and SSE) */
     499                    if (paTests[iTest].iRegSrc1 == UINT8_MAX)
    552500                    {
    553501                        BS3_ASSERT(paTests[iTest].enmRm == RM_MEM);
     
    558506                            uMemOpExpect = paValues[iVal].uSrc1;
    559507                    }
    560 
    561                     if (paTests[iTest].iRegSrc2 != UINT8_MAX)
    562                         Bs3ExtCtxSetYmm(pExtCtx, paTests[iTest].iRegSrc2, &paValues[iVal].uSrc2, fSseInstr);
     508                    else if (fMmxInstr)
     509                        Bs3ExtCtxSetMm(pExtCtx, paTests[iTest].iRegSrc1, paValues[iVal].uSrc1.QWords.qw0);
    563510                    else
     511                        Bs3ExtCtxSetYmm(pExtCtx, paTests[iTest].iRegSrc1, &paValues[iVal].uSrc1, fSseInstr);
     512
     513                    /* source #2 */
     514                    if (paTests[iTest].iRegSrc2 == UINT8_MAX)
    564515                    {
    565516                        BS3_ASSERT(paTests[iTest].enmRm == RM_MEM);
     
    568519                        uMemOpExpect = paValues[iVal].uSrc1;
    569520                    }
     521                    else if (fMmxInstr)
     522                        Bs3ExtCtxSetMm(pExtCtx, paTests[iTest].iRegSrc2, paValues[iVal].uSrc2.QWords.qw0);
     523                    else
     524                        Bs3ExtCtxSetYmm(pExtCtx, paTests[iTest].iRegSrc2, &paValues[iVal].uSrc2, fSseInstr);
     525
     526                    /* Memory pointer. */
    570527                    if (paTests[iTest].enmRm == RM_MEM)
    571528                    {
     
    589546
    590547                    if (bXcptExpect == X86_XCPT_DB && paTests[iTest].iRegDst != UINT8_MAX)
    591                         Bs3ExtCtxSetYmm(pExtCtx, paTests[iTest].iRegDst, &paValues[iVal].uDstOut, fSseInstr);
     548                    {
     549                        if (fMmxInstr)
     550                            Bs3ExtCtxSetMm(pExtCtx, paTests[iTest].iRegDst, paValues[iVal].uDstOut.QWords.qw0);
     551                        else
     552                            Bs3ExtCtxSetYmm(pExtCtx, paTests[iTest].iRegDst, &paValues[iVal].uDstOut, fSseInstr);
     553                    }
    592554                    Bs3TestCheckExtCtx(pExtCtxOut, pExtCtx, 0 /*fFlags*/, pszMode, idTestStep);
    593555
  • trunk/src/VBox/ValidationKit/bootsectors/bs3-cpu-instr-3-template.mac

    r95373 r95377  
    11; $Id$
    22;; @file
    3 ; BS3Kit - bs3-cpu-instr-3, SSE and AVX instructions, assembly template.
     3; BS3Kit - bs3-cpu-instr-3 - MMX, SSE and AVX instructions, assembly template.
    44;
    55
  • trunk/src/VBox/ValidationKit/bootsectors/bs3-cpu-instr-3.c

    r95373 r95377  
    11/* $Id$ */
    22/** @file
    3  * BS3Kit - bs3-cpu-instr-3, SSE and AVX instructions, 16-bit C code.
     3 * BS3Kit - bs3-cpu-instr-3 - MMX, SSE and AVX instructions, 16-bit C code.
    44 */
    55
Note: See TracChangeset for help on using the changeset viewer.

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