VirtualBox

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


Ignore:
Timestamp:
Jun 23, 2022 3:13:43 PM (3 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
151951
Message:

ValKit/bs3-cpu-instr-2: Added simple POPCNT test. bugref:9898

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

Legend:

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

    r95346 r95357  
    191191extern FNBS3FAR     BS3_CMN_NM(bs3CpuInstr2_mulx_ECX_ECX_EBX_EDX_icebp);
    192192extern FNBS3FAR     BS3_CMN_NM(bs3CpuInstr2_mulx_EAX_ECX_FSxBX_EDX_icebp);
     193
     194extern FNBS3FAR     BS3_CMN_NM(bs3CpuInstr2_popcnt_AX_BX_icebp);
     195extern FNBS3FAR     BS3_CMN_NM(bs3CpuInstr2_popcnt_EAX_EBX_icebp);
     196extern FNBS3FAR     BS3_CMN_NM(bs3CpuInstr2_popcnt_RAX_RBX_icebp);
     197extern FNBS3FAR     BS3_CMN_NM(bs3CpuInstr2_popcnt_AX_FSxBX_icebp);
     198extern FNBS3FAR     BS3_CMN_NM(bs3CpuInstr2_popcnt_EAX_FSxBX_icebp);
     199extern FNBS3FAR     BS3_CMN_NM(bs3CpuInstr2_popcnt_RAX_FSxBX_icebp);
    193200
    194201# if ARCH_BITS == 64
     
    22982305                if (uMemSrc1 != uMemSrc1Expect)
    22992306                    Bs3TestFailedF("Expected uMemSrc1 = %#06RX64, got %#06RX64", (uint64_t)uMemSrc1Expect, (uint64_t)uMemSrc1);
     2307            }
     2308        }
     2309        Ctx.rflags.u16 &= ~X86_EFL_STATUS_BITS;
     2310    }
     2311
     2312    return 0;
     2313}
     2314
     2315
     2316/*
     2317 * POPCNT - Intel: POPCNT; AMD: ABM.
     2318 */
     2319BS3_DECL_FAR(uint8_t) BS3_CMN_NM(bs3CpuInstr2_popcnt)(uint8_t bMode)
     2320{
     2321    static const struct
     2322    {
     2323        FPFNBS3FAR      pfnWorker;
     2324        bool            fMemSrc;
     2325        uint8_t         cWidth;
     2326        uint8_t         cbInstr;
     2327        RTCCUINTXREG    uSrc;
     2328        RTCCUINTXREG    uDst;
     2329        uint16_t        fEFlags;
     2330    } s_aTests[] =
     2331    {
     2332        /* 16-bit register width */
     2333        {   BS3_CMN_NM(bs3CpuInstr2_popcnt_AX_BX_icebp),      false,  16, 4 + (ARCH_BITS != 16),    // #0
     2334            0,                      /* -> */ 0,     X86_EFL_ZF },
     2335        {   BS3_CMN_NM(bs3CpuInstr2_popcnt_AX_BX_icebp),      false,  16, 4 + (ARCH_BITS != 16),    // #1
     2336            ~(RTCCUINTXREG)0,       /* -> */ 16,    0 },
     2337        {   BS3_CMN_NM(bs3CpuInstr2_popcnt_AX_BX_icebp),      false,  16, 4 + (ARCH_BITS != 16),    // #2
     2338            UINT16_C(0xffff),       /* -> */ 16,    0 },
     2339        {   BS3_CMN_NM(bs3CpuInstr2_popcnt_AX_BX_icebp),      false,  16, 4 + (ARCH_BITS != 16),    // #3
     2340            UINT16_C(0x0304),       /* -> */ 3,     0 },
     2341        {   BS3_CMN_NM(bs3CpuInstr2_popcnt_AX_FSxBX_icebp),   true,   16, 5 + (ARCH_BITS != 16),    // #4
     2342            UINT16_C(0xd569),       /* -> */ 9,     0},
     2343        {   BS3_CMN_NM(bs3CpuInstr2_popcnt_AX_FSxBX_icebp),   true,   16, 5 + (ARCH_BITS != 16),    // #5
     2344            0,                      /* -> */ 0,     X86_EFL_ZF },
     2345
     2346        /* 32-bit register width */
     2347        {   BS3_CMN_NM(bs3CpuInstr2_popcnt_EAX_EBX_icebp),    false,  32, 4 + (ARCH_BITS == 16),    // #6
     2348            0,                      /* -> */ 0,     X86_EFL_ZF },
     2349        {   BS3_CMN_NM(bs3CpuInstr2_popcnt_EAX_EBX_icebp),    false,  32, 4 + (ARCH_BITS == 16),    // #7
     2350            ~(RTCCUINTXREG)0,       /* -> */ 32,    0},
     2351        {   BS3_CMN_NM(bs3CpuInstr2_popcnt_EAX_EBX_icebp),    false,  32, 4 + (ARCH_BITS == 16),    // #8
     2352            UINT32_C(0x01020304),   /* -> */ 5,     0},
     2353        {   BS3_CMN_NM(bs3CpuInstr2_popcnt_EAX_FSxBX_icebp),  true,   32, 5 + (ARCH_BITS == 16),    // #9
     2354            0,                      /* -> */ 0,     X86_EFL_ZF },
     2355        {   BS3_CMN_NM(bs3CpuInstr2_popcnt_EAX_FSxBX_icebp),  true,   32, 5 + (ARCH_BITS == 16),    // #10
     2356            UINT32_C(0x49760948),   /* -> */ 12,     0 },
     2357
     2358#if ARCH_BITS == 64
     2359        /* 64-bit register width */
     2360        {   BS3_CMN_NM(bs3CpuInstr2_popcnt_RAX_RBX_icebp),    false,  64, 5,                        // #11
     2361            0,                              /* -> */ 0,     X86_EFL_ZF },
     2362        {   BS3_CMN_NM(bs3CpuInstr2_popcnt_RAX_RBX_icebp),    false,  64, 5,                        // #12
     2363            ~(RTCCUINTXREG)0,               /* -> */ 64,    0 },
     2364        {   BS3_CMN_NM(bs3CpuInstr2_popcnt_RAX_RBX_icebp),    false,  64, 5,                        // #13
     2365            UINT64_C(0x1234123412341234),   /* -> */ 5*4,   0 },
     2366        {   BS3_CMN_NM(bs3CpuInstr2_popcnt_RAX_FSxBX_icebp),  true,   64, 6,                        // #14
     2367            0,                              /* -> */ 0,     X86_EFL_ZF },
     2368        {   BS3_CMN_NM(bs3CpuInstr2_popcnt_RAX_FSxBX_icebp),  true,   64, 6,                        // #15
     2369            ~(RTCCUINTXREG)0,               /* -> */ 64,    0 },
     2370        {   BS3_CMN_NM(bs3CpuInstr2_popcnt_RAX_FSxBX_icebp),  true,   64, 6,                        // #16
     2371            UINT64_C(0x5908760293769087),   /* -> */ 26,    0 },
     2372#endif
     2373    };
     2374
     2375    BS3REGCTX       Ctx;
     2376    BS3TRAPFRAME    TrapFrame;
     2377    unsigned        i, j;
     2378    bool const      fSupportsPopCnt = (g_uBs3CpuDetected & BS3CPU_F_CPUID)
     2379                                   && (ASMCpuId_ECX(1) & X86_CPUID_FEATURE_ECX_POPCNT);
     2380
     2381    /* Ensure the structures are allocated before we sample the stack pointer. */
     2382    Bs3MemSet(&Ctx, 0, sizeof(Ctx));
     2383    Bs3MemSet(&TrapFrame, 0, sizeof(TrapFrame));
     2384
     2385    /*
     2386     * Create test context.
     2387     */
     2388    Bs3RegCtxSaveEx(&Ctx, bMode, 512);
     2389
     2390    /*
     2391     * Do the tests twice, first with all flags set, then once again with
     2392     * flags cleared.  The flags are not supposed to be touched at all.
     2393     */
     2394    Ctx.rflags.u16 |= X86_EFL_STATUS_BITS;
     2395    for (j = 0; j < 2; j++)
     2396    {
     2397        for (i = 0; i < RT_ELEMENTS(s_aTests); i++)
     2398        {
     2399            bool const    fOkay       = fSupportsPopCnt;
     2400            uint8_t const bExpectXcpt = fOkay ? X86_XCPT_DB : X86_XCPT_UD;
     2401            uint64_t      uExpectRax, uExpectRip;
     2402            RTCCUINTXREG  uMemSrc, uMemSrcExpect;
     2403
     2404            Ctx.rax.uCcXReg = RTCCUINTXREG_MAX * 1019;
     2405            if (!s_aTests[i].fMemSrc)
     2406            {
     2407                Ctx.rbx.uCcXReg          = s_aTests[i].uSrc;
     2408                uMemSrcExpect = uMemSrc = ~s_aTests[i].uSrc;
     2409            }
     2410            else
     2411            {
     2412                uMemSrcExpect = uMemSrc = s_aTests[i].uSrc;
     2413                Bs3RegCtxSetGrpSegFromCurPtr(&Ctx, &Ctx.rbx, &Ctx.fs, &uMemSrc);
     2414            }
     2415            Bs3RegCtxSetRipCsFromCurPtr(&Ctx, s_aTests[i].pfnWorker);
     2416            uExpectRax = fOkay ? s_aTests[i].uDst : Ctx.rax.u;
     2417            if (s_aTests[i].cWidth == 16)
     2418                uExpectRax = (uExpectRax & UINT16_MAX) | (Ctx.rax.u & ~(uint64_t)UINT16_MAX);
     2419
     2420            uExpectRip = Ctx.rip.u + (fOkay ? s_aTests[i].cbInstr + 1 : 0);
     2421            Bs3TrapSetJmpAndRestore(&Ctx, &TrapFrame);
     2422
     2423            if (   TrapFrame.bXcpt != bExpectXcpt
     2424                || TrapFrame.Ctx.rip.u != uExpectRip
     2425                || TrapFrame.Ctx.rbx.u != Ctx.rbx.u
     2426                || TrapFrame.Ctx.rax.u != uExpectRax
     2427                || (TrapFrame.Ctx.rflags.u16 & X86_EFL_STATUS_BITS) != (fOkay ? s_aTests[i].fEFlags : Ctx.rflags.u16)
     2428                /* check that nothing else really changed: */
     2429                || TrapFrame.Ctx.rcx.u != Ctx.rcx.u
     2430                || TrapFrame.Ctx.rdx.u != Ctx.rdx.u
     2431                || TrapFrame.Ctx.rsp.u != Ctx.rsp.u
     2432                || TrapFrame.Ctx.rbp.u != Ctx.rbp.u
     2433                || TrapFrame.Ctx.rsi.u != Ctx.rsi.u
     2434                || TrapFrame.Ctx.rdi.u != Ctx.rdi.u
     2435                || uMemSrc != uMemSrcExpect
     2436               )
     2437            {
     2438                Bs3TestFailedF("test #%i failed: input %#" RTCCUINTXREG_XFMT, i, s_aTests[i].uSrc);
     2439                if (TrapFrame.bXcpt != bExpectXcpt)
     2440                    Bs3TestFailedF("Expected bXcpt = %#x, got %#x", bExpectXcpt, TrapFrame.bXcpt);
     2441                if (TrapFrame.Ctx.rip.u != uExpectRip)
     2442                    Bs3TestFailedF("Expected RIP = %#06RX64, got %#06RX64", uExpectRip, TrapFrame.Ctx.rip.u);
     2443                if (TrapFrame.Ctx.rax.u != uExpectRax)
     2444                    Bs3TestFailedF("Expected RAX = %#06RX64, got %#06RX64", uExpectRax, TrapFrame.Ctx.rax.u);
     2445                if (TrapFrame.Ctx.rbx.u != Ctx.rbx.u)
     2446                    Bs3TestFailedF("Expected RBX = %#06RX64, got %#06RX64 (dst)", Ctx.rbx.u, TrapFrame.Ctx.rbx.u);
     2447                if ((TrapFrame.Ctx.rflags.u16 & X86_EFL_STATUS_BITS) != (fOkay ? s_aTests[i].fEFlags : Ctx.rflags.u16))
     2448                    Bs3TestFailedF("Expected EFLAGS = %#06RX32, got %#06RX32",
     2449                                   fOkay ? s_aTests[i].fEFlags : Ctx.rflags.u16, TrapFrame.Ctx.rflags.u16 & X86_EFL_STATUS_BITS);
     2450
     2451                if (TrapFrame.Ctx.rcx.u != Ctx.rcx.u)
     2452                    Bs3TestFailedF("Expected RCX = %#06RX64, got %#06RX64", Ctx.rcx.u, TrapFrame.Ctx.rcx.u);
     2453                if (TrapFrame.Ctx.rdx.u != Ctx.rdx.u)
     2454                    Bs3TestFailedF("Expected RDX = %#06RX64, got %#06RX64 (src)", Ctx.rdx.u, TrapFrame.Ctx.rdx.u);
     2455                if (TrapFrame.Ctx.rsp.u != Ctx.rsp.u)
     2456                    Bs3TestFailedF("Expected RSP = %#06RX64, got %#06RX64", Ctx.rsp.u, TrapFrame.Ctx.rsp.u);
     2457                if (TrapFrame.Ctx.rbp.u != Ctx.rbp.u)
     2458                    Bs3TestFailedF("Expected RBP = %#06RX64, got %#06RX64", Ctx.rbp.u, TrapFrame.Ctx.rbp.u);
     2459                if (TrapFrame.Ctx.rsi.u != Ctx.rsi.u)
     2460                    Bs3TestFailedF("Expected RSI = %#06RX64, got %#06RX64", Ctx.rsi.u, TrapFrame.Ctx.rsi.u);
     2461                if (TrapFrame.Ctx.rdi.u != Ctx.rdi.u)
     2462                    Bs3TestFailedF("Expected RDI = %#06RX64, got %#06RX64", Ctx.rdi.u, TrapFrame.Ctx.rdi.u);
     2463                if (uMemSrc != uMemSrcExpect)
     2464                    Bs3TestFailedF("Expected uMemSrc = %#06RX64, got %#06RX64", (uint64_t)uMemSrcExpect, (uint64_t)uMemSrc);
    23002465            }
    23012466        }
  • trunk/src/VBox/ValidationKit/bootsectors/bs3-cpu-instr-2-template.mac

    r95346 r95357  
    494494BS3_PROC_END_CMN   bs3CpuInstr2_mulx_EAX_ECX_FSxBX_EDX_icebp
    495495
     496
     497;
     498; POPCNT
     499;
     500BS3_PROC_BEGIN_CMN bs3CpuInstr2_popcnt_AX_BX_icebp, BS3_PBC_NEAR
     501        popcnt  ax, bx
     502.again:
     503        icebp
     504        jmp     .again
     505BS3_PROC_END_CMN   bs3CpuInstr2_popcnt_AX_BX_icebp
     506
     507BS3_PROC_BEGIN_CMN bs3CpuInstr2_popcnt_EAX_EBX_icebp, BS3_PBC_NEAR
     508        popcnt  eax, ebx
     509.again:
     510        icebp
     511        jmp     .again
     512BS3_PROC_END_CMN   bs3CpuInstr2_popcnt_EAX_EBX_icebp
     513
     514 %if TMPL_BITS == 64
     515BS3_PROC_BEGIN_CMN bs3CpuInstr2_popcnt_RAX_RBX_icebp, BS3_PBC_NEAR
     516        popcnt  rax, rbx
     517.again:
     518        icebp
     519        jmp     .again
     520BS3_PROC_END_CMN   bs3CpuInstr2_popcnt_RAX_RBX_icebp
     521 %endif
     522
     523
     524BS3_PROC_BEGIN_CMN bs3CpuInstr2_popcnt_AX_FSxBX_icebp, BS3_PBC_NEAR
     525        popcnt  ax, [fs:xBX]
     526.again:
     527        icebp
     528        jmp     .again
     529BS3_PROC_END_CMN   bs3CpuInstr2_popcnt_AX_FSxBX_icebp
     530
     531BS3_PROC_BEGIN_CMN bs3CpuInstr2_popcnt_EAX_FSxBX_icebp, BS3_PBC_NEAR
     532        popcnt  eax, [fs:xBX]
     533.again:
     534        icebp
     535        jmp     .again
     536BS3_PROC_END_CMN   bs3CpuInstr2_popcnt_EAX_FSxBX_icebp
     537
     538 %if TMPL_BITS == 64
     539BS3_PROC_BEGIN_CMN bs3CpuInstr2_popcnt_RAX_FSxBX_icebp, BS3_PBC_NEAR
     540        popcnt  rax, [fs:xBX]
     541.again:
     542        icebp
     543        jmp     .again
     544BS3_PROC_END_CMN   bs3CpuInstr2_popcnt_RAX_FSxBX_icebp
     545 %endif
     546
     547
     548
    496549;
    497550; CMPXCHG16B
  • trunk/src/VBox/ValidationKit/bootsectors/bs3-cpu-instr-2.c

    r95346 r95357  
    5454BS3TESTMODE_PROTOTYPES_CMN(bs3CpuInstr2_shrx);
    5555BS3TESTMODE_PROTOTYPES_CMN(bs3CpuInstr2_mulx);
     56BS3TESTMODE_PROTOTYPES_CMN(bs3CpuInstr2_popcnt);
    5657BS3TESTMODE_PROTOTYPES_CMN_64(bs3CpuInstr2_cmpxchg16b);
    5758BS3TESTMODE_PROTOTYPES_CMN_64(bs3CpuInstr2_wrfsbase);
     
    9394    BS3TESTMODEENTRY_CMN("mulx",  bs3CpuInstr2_mulx),
    9495#endif
     96    BS3TESTMODEENTRY_CMN("popcnt",  bs3CpuInstr2_popcnt), /* Intel: POPCNT; AMD: ABM */
    9597#if 1
    9698    BS3TESTMODEENTRY_CMN_64("cmpxchg16b", bs3CpuInstr2_cmpxchg16b),
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