VirtualBox

Changeset 94256 in vbox for trunk/src/VBox/VMM


Ignore:
Timestamp:
Mar 15, 2022 10:34:35 PM (3 years ago)
Author:
vboxsync
Message:

VMM/IEM: Implemented C versions of fld1, fldz, and friends. Tests too. Added proper option parsing to tstIEMAImpl with some basic test selecting. bugref:9898

Location:
trunk/src/VBox/VMM
Files:
1 added
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/VMM/VMMAll/IEMAllAImplC.cpp

    r94225 r94256  
    32733273IEM_DECL_IMPL_DEF(void, iemAImpl_fld1,(PCX86FXSTATE pFpuState, PIEMFPURESULT pFpuRes))
    32743274{
    3275     RT_NOREF(pFpuState, pFpuRes);
    3276     AssertReleaseFailed();
     3275    pFpuRes->r80Result.sj64.fSign       = 0;
     3276    pFpuRes->r80Result.sj64.uExponent   = 0 + 16383;
     3277    pFpuRes->r80Result.sj64.fInteger    = 1;
     3278    pFpuRes->r80Result.sj64.u63Fraction = 0;
     3279
     3280    /*
     3281     * FPU status word:
     3282     *      - TOP is irrelevant, but we must match x86 assembly version.
     3283     *      - C1 is always cleared as we don't have any stack overflows.
     3284     *      - C0, C2, and C3 are undefined and Intel 10980XE does not touch them.
     3285     */
     3286    pFpuRes->FSW = (7 << X86_FSW_TOP_SHIFT) | (pFpuState->FSW & (X86_FSW_C0 | X86_FSW_C2 | X86_FSW_C3));
    32773287}
    32783288
     
    32803290IEM_DECL_IMPL_DEF(void, iemAImpl_fldl2e,(PCX86FXSTATE pFpuState, PIEMFPURESULT pFpuRes))
    32813291{
    3282     RT_NOREF(pFpuState, pFpuRes);
    3283     AssertReleaseFailed();
     3292    pFpuRes->r80Result.sj64.fSign       = 0;
     3293    pFpuRes->r80Result.sj64.uExponent   = 0 + 16383;
     3294    pFpuRes->r80Result.sj64.fInteger    = 1;
     3295    pFpuRes->r80Result.sj64.u63Fraction =    (pFpuState->FCW & X86_FCW_RC_MASK) == X86_FCW_RC_NEAREST
     3296                                          || (pFpuState->FCW & X86_FCW_RC_MASK) == X86_FCW_RC_UP
     3297                                        ? UINT64_C(0x38aa3b295c17f0bc) : UINT64_C(0x38aa3b295c17f0bb);
     3298    pFpuRes->FSW = (7 << X86_FSW_TOP_SHIFT) | (pFpuState->FSW & (X86_FSW_C0 | X86_FSW_C2 | X86_FSW_C3)); /* see iemAImpl_fld1 */
    32843299}
    32853300
     
    32873302IEM_DECL_IMPL_DEF(void, iemAImpl_fldl2t,(PCX86FXSTATE pFpuState, PIEMFPURESULT pFpuRes))
    32883303{
    3289     RT_NOREF(pFpuState, pFpuRes);
    3290     AssertReleaseFailed();
     3304    pFpuRes->r80Result.sj64.fSign       = 0;
     3305    pFpuRes->r80Result.sj64.uExponent   = 1 + 16383;
     3306    pFpuRes->r80Result.sj64.fInteger    = 1;
     3307    pFpuRes->r80Result.sj64.u63Fraction = (pFpuState->FCW & X86_FCW_RC_MASK) != X86_FCW_RC_UP
     3308                                        ? UINT64_C(0x549a784bcd1b8afe) : UINT64_C(0x549a784bcd1b8aff);
     3309    pFpuRes->FSW = (7 << X86_FSW_TOP_SHIFT) | (pFpuState->FSW & (X86_FSW_C0 | X86_FSW_C2 | X86_FSW_C3)); /* see iemAImpl_fld1 */
    32913310}
    32923311
     
    32943313IEM_DECL_IMPL_DEF(void, iemAImpl_fldlg2,(PCX86FXSTATE pFpuState, PIEMFPURESULT pFpuRes))
    32953314{
    3296     RT_NOREF(pFpuState, pFpuRes);
    3297     AssertReleaseFailed();
     3315    pFpuRes->r80Result.sj64.fSign       = 0;
     3316    pFpuRes->r80Result.sj64.uExponent   = -2 + 16383;
     3317    pFpuRes->r80Result.sj64.fInteger    = 1;
     3318    pFpuRes->r80Result.sj64.u63Fraction =    (pFpuState->FCW & X86_FCW_RC_MASK) == X86_FCW_RC_NEAREST
     3319                                          || (pFpuState->FCW & X86_FCW_RC_MASK) == X86_FCW_RC_UP
     3320                                        ? UINT64_C(0x1a209a84fbcff799) : UINT64_C(0x1a209a84fbcff798);
     3321    pFpuRes->FSW = (7 << X86_FSW_TOP_SHIFT) | (pFpuState->FSW & (X86_FSW_C0 | X86_FSW_C2 | X86_FSW_C3)); /* see iemAImpl_fld1 */
    32983322}
    32993323
     
    33013325IEM_DECL_IMPL_DEF(void, iemAImpl_fldln2,(PCX86FXSTATE pFpuState, PIEMFPURESULT pFpuRes))
    33023326{
    3303     RT_NOREF(pFpuState, pFpuRes);
    3304     AssertReleaseFailed();
     3327    pFpuRes->r80Result.sj64.fSign       = 0;
     3328    pFpuRes->r80Result.sj64.uExponent   = -1 + 16383;
     3329    pFpuRes->r80Result.sj64.fInteger    = 1;
     3330    pFpuRes->r80Result.sj64.u63Fraction =    (pFpuState->FCW & X86_FCW_RC_MASK) == X86_FCW_RC_NEAREST
     3331                                          || (pFpuState->FCW & X86_FCW_RC_MASK) == X86_FCW_RC_UP
     3332                                        ? UINT64_C(0x317217f7d1cf79ac) : UINT64_C(0x317217f7d1cf79ab);
     3333    pFpuRes->FSW = (7 << X86_FSW_TOP_SHIFT) | (pFpuState->FSW & (X86_FSW_C0 | X86_FSW_C2 | X86_FSW_C3)); /* see iemAImpl_fld1 */
    33053334}
    33063335
     
    33083337IEM_DECL_IMPL_DEF(void, iemAImpl_fldpi,(PCX86FXSTATE pFpuState, PIEMFPURESULT pFpuRes))
    33093338{
    3310     RT_NOREF(pFpuState, pFpuRes);
    3311     AssertReleaseFailed();
     3339    pFpuRes->r80Result.sj64.fSign       = 0;
     3340    pFpuRes->r80Result.sj64.uExponent   = 1 + 16383;
     3341    pFpuRes->r80Result.sj64.fInteger    = 1;
     3342    pFpuRes->r80Result.sj64.u63Fraction =    (pFpuState->FCW & X86_FCW_RC_MASK) == X86_FCW_RC_NEAREST
     3343                                          || (pFpuState->FCW & X86_FCW_RC_MASK) == X86_FCW_RC_UP
     3344                                        ? UINT64_C(0x490fdaa22168c235) : UINT64_C(0x490fdaa22168c234);
     3345    pFpuRes->FSW = (7 << X86_FSW_TOP_SHIFT) | (pFpuState->FSW & (X86_FSW_C0 | X86_FSW_C2 | X86_FSW_C3)); /* see iemAImpl_fld1 */
    33123346}
    33133347
     
    33153349IEM_DECL_IMPL_DEF(void, iemAImpl_fldz,(PCX86FXSTATE pFpuState, PIEMFPURESULT pFpuRes))
    33163350{
    3317     RT_NOREF(pFpuState, pFpuRes);
    3318     AssertReleaseFailed();
     3351    pFpuRes->r80Result.sj64.fSign       = 0;
     3352    pFpuRes->r80Result.sj64.uExponent   = 0;
     3353    pFpuRes->r80Result.sj64.fInteger    = 0;
     3354    pFpuRes->r80Result.sj64.u63Fraction = 0;
     3355    pFpuRes->FSW = (7 << X86_FSW_TOP_SHIFT) | (pFpuState->FSW & (X86_FSW_C0 | X86_FSW_C2 | X86_FSW_C3)); /* see iemAImpl_fld1 */
    33193356}
    33203357
  • trunk/src/VBox/VMM/testcase/tstIEMAImpl.cpp

    r94221 r94256  
    2626#include <iprt/assert.h>
    2727#include <iprt/ctype.h>
     28#include <iprt/getopt.h>
    2829#include <iprt/initterm.h>
    2930#include <iprt/message.h>
     
    340341
    341342
    342 static void GenerateHeader(PRTSTREAM pOut, const char *pszCpuDesc, const char *pszCpuType, const char *pszCpuSuffU)
     343static void GenerateHeader(PRTSTREAM pOut, const char *pszFileInfix,
     344                           const char *pszCpuDesc, const char *pszCpuType, const char *pszCpuSuffU)
    343345{
    344346    /* We want to tag the generated source code with the revision that produced it. */
     
    367369                 " */\n"
    368370                 "\n"
    369                  "#ifndef VMM_INCLUDED_SRC_testcase_tstIEMAImplData%s_h\n"
    370                  "#define VMM_INCLUDED_SRC_testcase_tstIEMAImplData%s_h\n"
     371                 "#ifndef VMM_INCLUDED_SRC_testcase_tstIEMAImplData%s%s_h\n"
     372                 "#define VMM_INCLUDED_SRC_testcase_tstIEMAImplData%s%s_h\n"
    371373                 "#ifndef RT_WITHOUT_PRAGMA_ONCE\n"
    372374                 "# pragma once\n"
     
    374376                 ,
    375377                 pszCpuType ? " " : "", pszCpuType ? pszCpuType : "", cchRev, pszRev, pszCpuDesc,
    376                  pszCpuSuffU,
    377                  pszCpuSuffU);
    378 }
    379 
    380 
    381 static RTEXITCODE GenerateFooterAndClose(PRTSTREAM pOut, const char *pszCpuType, const char *pszCpuSuff, RTEXITCODE rcExit)
     378                 pszFileInfix, pszCpuSuffU,
     379                 pszFileInfix, pszCpuSuffU);
     380}
     381
     382
     383static RTEXITCODE GenerateFooterAndClose(PRTSTREAM pOut, const char *pszFilename, const char *pszFileInfix,
     384                                         const char *pszCpuSuff, RTEXITCODE rcExit)
    382385{
    383386    RTStrmPrintf(pOut,
    384387                 "\n"
    385                  "#endif /* !VMM_INCLUDED_SRC_testcase_tstIEMAImplData%s_h */\n", pszCpuSuff);
     388                 "#endif /* !VMM_INCLUDED_SRC_testcase_tstIEMAImplData%s%s_h */\n", pszFileInfix, pszCpuSuff);
    386389    int rc = RTStrmClose(pOut);
    387390    if (RT_SUCCESS(rc))
    388391        return rcExit;
    389     return RTMsgErrorExitFailure("RTStrmClose failed on tstIEMAImplData%s%s.h: %Rrc",
    390                                  pszCpuType ? "-" : "", pszCpuType ? pszCpuType : "", rc);
     392    return RTMsgErrorExitFailure("RTStrmClose failed on %s: %Rrc", pszFilename, rc);
    391393}
    392394
     
    397399 * Test helpers.
    398400 */
     401static char     g_szBuf[16][256];
     402static unsigned g_idxBuf = 0;
     403
     404
    399405static const char *EFlagsDiff(uint32_t fActual, uint32_t fExpected)
    400406{
     
    403409
    404410    uint32_t const fXor = fActual ^ fExpected;
    405     static char    s_szBuf[256];
    406     size_t cch = RTStrPrintf(s_szBuf, sizeof(s_szBuf), " - %#x", fXor);
     411    char *pszBuf = g_szBuf[g_idxBuf++ % RT_ELEMENTS(g_szBuf)];
     412    size_t cch = RTStrPrintf(pszBuf, sizeof(g_szBuf[0]), " - %#x", fXor);
    407413
    408414    static struct
     
    433439    for (size_t i = 0; i < RT_ELEMENTS(s_aFlags); i++)
    434440        if (s_aFlags[i].fFlag & fXor)
    435             cch += RTStrPrintf(&s_szBuf[cch], sizeof(s_szBuf) - cch,
     441            cch += RTStrPrintf(&pszBuf[cch], sizeof(g_szBuf[0]) - cch,
    436442                               s_aFlags[i].fFlag & fActual ? "/%s" : "/!%s", s_aFlags[i].pszName);
    437     RTStrPrintf(&s_szBuf[cch], sizeof(s_szBuf) - cch, "");
    438     return s_szBuf;
     443    RTStrPrintf(&pszBuf[cch], sizeof(g_szBuf[0]) - cch, "");
     444    return pszBuf;
     445}
     446
     447
     448static const char *FswDiff(uint16_t fActual, uint16_t fExpected)
     449{
     450    if (fActual == fExpected)
     451        return "";
     452
     453    uint16_t const fXor = fActual ^ fExpected;
     454    char *pszBuf = g_szBuf[g_idxBuf++ % RT_ELEMENTS(g_szBuf)];
     455    size_t cch = RTStrPrintf(pszBuf, sizeof(g_szBuf[0]), " - %#x", fXor);
     456
     457    static struct
     458    {
     459        const char *pszName;
     460        uint32_t    fFlag;
     461    } const s_aFlags[] =
     462    {
     463#define FSW_ENTRY(a_Flags) { #a_Flags, X86_FSW_ ## a_Flags }
     464        FSW_ENTRY(IE),
     465        FSW_ENTRY(DE),
     466        FSW_ENTRY(ZE),
     467        FSW_ENTRY(OE),
     468        FSW_ENTRY(UE),
     469        FSW_ENTRY(PE),
     470        FSW_ENTRY(SF),
     471        FSW_ENTRY(ES),
     472        FSW_ENTRY(C0),
     473        FSW_ENTRY(C1),
     474        FSW_ENTRY(C2),
     475        FSW_ENTRY(C3),
     476        FSW_ENTRY(B),
     477    };
     478    for (size_t i = 0; i < RT_ELEMENTS(s_aFlags); i++)
     479        if (s_aFlags[i].fFlag & fXor)
     480            cch += RTStrPrintf(&pszBuf[cch], sizeof(g_szBuf[0]) - cch,
     481                               s_aFlags[i].fFlag & fActual ? "/%s" : "/!%s", s_aFlags[i].pszName);
     482    if (fXor & X86_FSW_TOP_MASK)
     483        cch += RTStrPrintf(&pszBuf[cch], sizeof(g_szBuf[0]) - cch, "/TOP%u!%u",
     484                           X86_FSW_TOP_GET(fActual), X86_FSW_TOP_GET(fExpected));
     485    RTStrPrintf(&pszBuf[cch], sizeof(g_szBuf[0]) - cch, "");
     486    return pszBuf;
     487}
     488
     489
     490static const char *FormatFcw(uint16_t fFcw)
     491{
     492    char *pszBuf = g_szBuf[g_idxBuf++ % RT_ELEMENTS(g_szBuf)];
     493
     494    const char *pszPC;
     495    switch (fFcw & X86_FCW_PC_MASK)
     496    {
     497        case X86_FCW_PC_24:     pszPC = "PC24"; break;
     498        case X86_FCW_PC_RSVD:   pszPC = "PCRSVD!"; break;
     499        case X86_FCW_PC_53:     pszPC = "PC53"; break;
     500        case X86_FCW_PC_64:     pszPC = "PC64"; break;
     501    }
     502
     503    const char *pszRC;
     504    switch (fFcw & X86_FCW_RC_MASK)
     505    {
     506        case X86_FCW_RC_NEAREST:    pszRC = "NEAR"; break;
     507        case X86_FCW_RC_DOWN:       pszRC = "DOWN"; break;
     508        case X86_FCW_RC_UP:         pszRC = "UP"; break;
     509        case X86_FCW_RC_ZERO:       pszRC = "ZERO"; break;
     510    }
     511    size_t cch = RTStrPrintf(&pszBuf[0], sizeof(g_szBuf[0]), "%s %s", pszPC, pszRC);
     512
     513    static struct
     514    {
     515        const char *pszName;
     516        uint32_t    fFlag;
     517    } const s_aFlags[] =
     518    {
     519#define FCW_ENTRY(a_Flags) { #a_Flags, X86_FCW_ ## a_Flags }
     520        FCW_ENTRY(IM),
     521        FCW_ENTRY(DM),
     522        FCW_ENTRY(ZM),
     523        FCW_ENTRY(OM),
     524        FCW_ENTRY(UM),
     525        FCW_ENTRY(PM),
     526        { "6M", 64 },
     527    };
     528    for (size_t i = 0; i < RT_ELEMENTS(s_aFlags); i++)
     529        if (fFcw & s_aFlags[i].fFlag)
     530            cch += RTStrPrintf(&pszBuf[cch], sizeof(g_szBuf[0]) - cch, " %s", s_aFlags[i].pszName);
     531
     532    RTStrPrintf(&pszBuf[cch], sizeof(g_szBuf[0]) - cch, "");
     533    return pszBuf;
     534}
     535
     536
     537static const char *FormatR80(PCRTFLOAT80U pr80)
     538{
     539    char *pszBuf = g_szBuf[g_idxBuf++ % RT_ELEMENTS(g_szBuf)];
     540    RTStrFormatR80(pszBuf, sizeof(g_szBuf[0]), pr80, 0, 0, RTSTR_F_SPECIAL);
     541    return pszBuf;
    439542}
    440543
     
    17971900
    17981901
     1902/*
     1903 * FPU constant loading.
     1904 */
     1905
     1906typedef struct FPU_LD_CONST_TEST_T
     1907{
     1908    uint16_t                fFcw;
     1909    uint16_t                fFswIn;
     1910    uint16_t                fFswOut;
     1911    RTFLOAT80U              rdResult;
     1912} FPU_LD_CONST_TEST_T;
     1913
     1914typedef struct FPU_LD_CONST_T
     1915{
     1916    const char                 *pszName;
     1917    PFNIEMAIMPLFPUR80LDCONST    pfn;
     1918    PFNIEMAIMPLFPUR80LDCONST    pfnNative;
     1919    FPU_LD_CONST_TEST_T const  *paTests;
     1920    uint32_t                    cTests;
     1921    uint32_t                    uExtra;
     1922    uint8_t                     idxCpuEflFlavour;
     1923} FPU_LD_CONST_T;
     1924
     1925#include "tstIEMAImplDataFpu.h"
     1926
     1927#ifndef HAVE_FPU_LOAD_CONST_TESTS
     1928static const FPU_LD_CONST_TEST_T g_aTests_fld1[]   = { {0} };
     1929static const FPU_LD_CONST_TEST_T g_aTests_fldl2t[] = { {0} };
     1930static const FPU_LD_CONST_TEST_T g_aTests_fldl2e[] = { {0} };
     1931static const FPU_LD_CONST_TEST_T g_aTests_fldpi[]  = { {0} };
     1932static const FPU_LD_CONST_TEST_T g_aTests_fldlg2[] = { {0} };
     1933static const FPU_LD_CONST_TEST_T g_aTests_fldln2[] = { {0} };
     1934static const FPU_LD_CONST_TEST_T g_aTests_fldz[]   = { {0} };
     1935#endif
     1936
     1937static const FPU_LD_CONST_T g_aFpuLdConst[] =
     1938{
     1939    ENTRY(fld1),
     1940    ENTRY(fldl2t),
     1941    ENTRY(fldl2e),
     1942    ENTRY(fldpi),
     1943    ENTRY(fldlg2),
     1944    ENTRY(fldln2),
     1945    ENTRY(fldz),
     1946};
     1947
     1948#ifdef TSTIEMAIMPL_WITH_GENERATOR
     1949static void FpuLoadConstGenerate(PRTSTREAM pOut, uint32_t cTests)
     1950{
     1951    RTStrmPrintf(pOut, "\n\n#define HAVE_FPU_LOAD_CONST_TESTS\n");
     1952    X86FXSTATE State;
     1953    RT_ZERO(State);
     1954    for (size_t iFn = 0; iFn < RT_ELEMENTS(g_aFpuLdConst); iFn++)
     1955    {
     1956        RTStrmPrintf(pOut, "static const FPU_LD_CONST_TEST_T g_aTests_%s[] =\n{\n", g_aFpuLdConst[iFn].pszName);
     1957        for (size_t iTest = 0; iTest < cTests; iTest += 4)
     1958        {
     1959            State.FCW = RandU16() & (X86_FCW_MASK_ALL | X86_FCW_PC_MASK);
     1960            State.FSW = RandU16() & (X86_FSW_C_MASK | X86_FSW_XCPT_ES_MASK | X86_FSW_TOP_MASK | X86_FSW_B);
     1961
     1962            for (size_t iRounding = 0; iRounding < 4; iRounding++)
     1963            {
     1964                IEMFPURESULT Res;
     1965                State.FCW = (State.FCW & ~X86_FCW_RC_MASK) | (iRounding << X86_FCW_RC_SHIFT);
     1966                g_aFpuLdConst[iFn].pfn(&State, &Res);
     1967                RTStrmPrintf(pOut, "    { %#06x, %#06x, %#06x, RTFLOAT80U_INIT_C(%d,%u,%#RX64) }, /* #%u */\n",
     1968                             State.FCW, State.FSW, Res.FSW,
     1969                             Res.r80Result.s.fSign, Res.r80Result.s.uExponent, Res.r80Result.s.u64Mantissa, iTest + iRounding);
     1970            }
     1971        }
     1972        RTStrmPrintf(pOut, "};\n");
     1973    }
     1974}
     1975#endif
     1976
     1977static void FpuLoadConstTest(void)
     1978{
     1979    /*
     1980     * Inputs:
     1981     *      - FSW: C0, C1, C2, C3
     1982     *      - FCW: Exception masks, Precision control, Rounding control.
     1983     *
     1984     * C1 set to 1 on stack overflow, zero otherwise.  C0, C2, and C3 are "undefined".
     1985     */
     1986    X86FXSTATE State;
     1987    RT_ZERO(State);
     1988    for (size_t iFn = 0; iFn < RT_ELEMENTS(g_aFpuLdConst); iFn++)
     1989    {
     1990        RTTestSub(g_hTest, g_aFpuLdConst[iFn].pszName);
     1991
     1992        uint32_t const              cTests  = g_aFpuLdConst[iFn].cTests;
     1993        FPU_LD_CONST_TEST_T const  *paTests = g_aFpuLdConst[iFn].paTests;
     1994        PFNIEMAIMPLFPUR80LDCONST    pfn     = g_aFpuLdConst[iFn].pfn;
     1995        uint32_t const cVars = 1 + (g_aFpuLdConst[iFn].idxCpuEflFlavour == g_idxCpuEflFlavour && g_aFpuLdConst[iFn].pfnNative);
     1996        for (uint32_t iVar = 0; iVar < cVars; iVar++)
     1997        {
     1998            for (uint32_t iTest = 0; iTest < cTests; iTest++)
     1999            {
     2000                State.FCW = paTests[iTest].fFcw;
     2001                State.FSW = paTests[iTest].fFswIn;
     2002                IEMFPURESULT Res;
     2003                pfn(&State, &Res);
     2004                if (   Res.FSW != paTests[iTest].fFswOut
     2005                    || !RTFLOAT80U_ARE_IDENTICAL(&Res.r80Result, &paTests[iTest].rdResult))
     2006                    RTTestFailed(g_hTest, "#%u%s: fcw=%#06x fsw=%#06x -> fsw=%#06x %s, expected %#06x %s%s%s (%s)\n",
     2007                                 iTest, iVar ? "/n" : "", paTests[iTest].fFcw, paTests[iTest].fFswIn,
     2008                                 Res.FSW, FormatR80(&Res.r80Result),
     2009                                 paTests[iTest].fFswOut, FormatR80(&paTests[iTest].rdResult),
     2010                                 FswDiff(Res.FSW, paTests[iTest].fFswOut),
     2011                                 !RTFLOAT80U_ARE_IDENTICAL(&Res.r80Result, &paTests[iTest].rdResult) ? " - val" : "",
     2012                                 FormatFcw(paTests[iTest].fFcw) );
     2013            }
     2014            pfn = g_aFpuLdConst[iFn].pfnNative;
     2015        }
     2016    }
     2017}
     2018
     2019
     2020
    17992021int main(int argc, char **argv)
    18002022{
     
    18162038
    18172039    /*
     2040     * Parse arguments.
     2041     */
     2042    enum { kModeNotSet, kModeTest, kModeGenerate }
     2043         enmMode       = kModeNotSet;
     2044    bool fInt          = true;
     2045    bool fFpu          = true;
     2046    bool fCpuData      = true;
     2047    bool fCommonData   = true;
     2048    RTGETOPTDEF const s_aOptions[] =
     2049    {
     2050        { "--generate",     'g', RTGETOPT_REQ_NOTHING },
     2051        { "--test",         't', RTGETOPT_REQ_NOTHING },
     2052        { "--all",          'a', RTGETOPT_REQ_NOTHING },
     2053        { "--only-fpu",     'f', RTGETOPT_REQ_NOTHING },
     2054        { "--only-int",     'i', RTGETOPT_REQ_NOTHING },
     2055        { "--only-common",  'm', RTGETOPT_REQ_NOTHING },
     2056        { "--only-cpu",     'c', RTGETOPT_REQ_NOTHING },
     2057    };
     2058
     2059    RTGETOPTSTATE State;
     2060    rc = RTGetOptInit(&State, argc, argv, s_aOptions, RT_ELEMENTS(s_aOptions), 1, 0);
     2061    AssertRCReturn(rc, RTEXITCODE_FAILURE);
     2062
     2063    RTGETOPTUNION ValueUnion;
     2064    while ((rc = RTGetOpt(&State, &ValueUnion)))
     2065    {
     2066        switch (rc)
     2067        {
     2068            case 'g':
     2069                enmMode     = kModeGenerate;
     2070                break;
     2071            case 't':
     2072                enmMode     = kModeTest;
     2073                break;
     2074            case 'a':
     2075                fCpuData    = true;
     2076                fCommonData = true;
     2077                fInt        = true;
     2078                fFpu        = true;
     2079                break;
     2080            case 'f':
     2081                fFpu        = true;
     2082                fInt        = false;
     2083                break;
     2084            case 'i':
     2085                fInt        = true;
     2086                fFpu        = false;
     2087                break;
     2088            case 'm':
     2089                fCommonData = true;
     2090                fCpuData    = false;
     2091                break;
     2092            case 'c':
     2093                fCpuData    = true;
     2094                fCommonData = false;
     2095                break;
     2096            case 'h':
     2097                RTPrintf("usage: %s <-g|-t> [options]\n"
     2098                         "\n"
     2099                         "Mode:\n"
     2100                         "  -g, --generate\n"
     2101                         "    Generate test data.\n"
     2102                         "  -t, --test\n"
     2103                         "    Execute tests.\n"
     2104                         "\n"
     2105                         "Options:\n"
     2106                         "  -a, --all\n"
     2107                         "    Include all tests and generates common + CPU test data. (default)\n"
     2108                         "  -i, --only-int\n"
     2109                         "    Only non-FPU tests.\n"
     2110                         "  -f, --only-fpu\n"
     2111                         "    Only FPU tests.\n"
     2112                         "  -m, --only-common\n"
     2113                         "    Only generate common test data.\n"
     2114                         "  -c, --only-cpu\n"
     2115                         "    Only generate CPU specific test data.\n"
     2116                         , argv[0]);
     2117                return RTEXITCODE_SUCCESS;
     2118            default:
     2119                return RTGetOptPrintError(rc, &ValueUnion);
     2120        }
     2121    }
     2122
     2123    /*
    18182124     * Generate data?
    18192125     */
    1820     if (argc > 2)
     2126    if (enmMode == kModeGenerate)
    18212127    {
    18222128#ifdef TSTIEMAIMPL_WITH_GENERATOR
     2129
    18232130        char szCpuDesc[256] = {0};
    18242131        RTMpGetDescription(NIL_RTCPUID, szCpuDesc, sizeof(szCpuDesc));
     
    18262133        const char * const pszCpuSuff  = g_idxCpuEflFlavour == IEMTARGETCPU_EFL_BEHAVIOR_AMD ? "_Amd" : "_Intel";
    18272134        const char * const pszCpuSuffU = g_idxCpuEflFlavour == IEMTARGETCPU_EFL_BEHAVIOR_AMD ? "_AMD" : "_INTEL";
    1828 
    1829         PRTSTREAM pStrmData = NULL;
    1830         rc = RTStrmOpen("tstIEMAImplData.h", "w", &pStrmData);
    1831         if (!pStrmData)
    1832             return RTMsgErrorExitFailure("Failed to open tstIEMAImplData.h for writing: %Rrc", rc);
    1833 
    1834         PRTSTREAM pStrmDataCpu = NULL;
    1835         rc = RTStrmOpenF("w", &pStrmDataCpu, "tstIEMAImplData-%s.h", pszCpuType);
    1836         if (!pStrmData)
    1837             return RTMsgErrorExitFailure("Failed to open tstIEMAImplData-%s.h for writing: %Rrc", pszCpuType, rc);
    1838 
    1839         GenerateHeader(pStrmData, szCpuDesc, NULL, "");
    1840         GenerateHeader(pStrmDataCpu, szCpuDesc, pszCpuType, pszCpuSuff);
     2135# if defined(RT_OS_WINDOWS) || defined(RT_OS_OS2)
     2136        const char * const pszBitBucket = "NUL";
     2137# else
     2138        const char * const pszBitBucket = "/dev/null";
     2139# endif
    18412140
    18422141        uint32_t cTests = 96;
     
    18442143        g_cZeroSrcTests = g_cZeroDstTests * 2;
    18452144
    1846         BinU8Generate( pStrmData, pStrmDataCpu, pszCpuSuffU, cTests);
    1847         BinU16Generate(pStrmData, pStrmDataCpu, pszCpuSuffU, cTests);
    1848         BinU32Generate(pStrmData, pStrmDataCpu, pszCpuSuffU, cTests);
    1849         BinU64Generate(pStrmData, pStrmDataCpu, pszCpuSuffU, cTests);
    1850         ShiftDblGenerate(pStrmDataCpu, pszCpuSuffU, RT_MAX(cTests, 128));
    1851         UnaryGenerate(pStrmData, cTests);
    1852         ShiftGenerate(pStrmDataCpu, pszCpuSuffU, cTests);
    1853         MulDivGenerate(pStrmDataCpu, pszCpuSuffU, cTests);
    1854 
    1855         return GenerateFooterAndClose(pStrmDataCpu, pszCpuType, pszCpuSuff,
    1856                                       GenerateFooterAndClose(pStrmData, NULL, "", RTEXITCODE_SUCCESS));
     2145        if (fInt)
     2146        {
     2147            const char *pszDataFile = fCommonData ? "tstIEMAImplData.h" : pszBitBucket;
     2148            PRTSTREAM   pStrmData   = NULL;
     2149            rc = RTStrmOpen(pszDataFile, "w", &pStrmData);
     2150            if (!pStrmData)
     2151                return RTMsgErrorExitFailure("Failed to open %s for writing: %Rrc", pszDataFile, rc);
     2152
     2153            const char *pszDataCpuFile = !fCpuData ? pszBitBucket : g_idxCpuEflFlavour == IEMTARGETCPU_EFL_BEHAVIOR_AMD
     2154                                       ? "tstIEMAImplData-Amd.h" : "tstIEMAImplData-Intel.h";
     2155            PRTSTREAM   pStrmDataCpu   = NULL;
     2156            rc = RTStrmOpen(pszDataCpuFile, "w", &pStrmDataCpu);
     2157            if (!pStrmData)
     2158                return RTMsgErrorExitFailure("Failed to open %s for writing: %Rrc", pszDataCpuFile, rc);
     2159
     2160            GenerateHeader(pStrmData, "", szCpuDesc, NULL, "");
     2161            GenerateHeader(pStrmDataCpu, "", szCpuDesc, pszCpuType, pszCpuSuff);
     2162
     2163            BinU8Generate( pStrmData, pStrmDataCpu, pszCpuSuffU, cTests);
     2164            BinU16Generate(pStrmData, pStrmDataCpu, pszCpuSuffU, cTests);
     2165            BinU32Generate(pStrmData, pStrmDataCpu, pszCpuSuffU, cTests);
     2166            BinU64Generate(pStrmData, pStrmDataCpu, pszCpuSuffU, cTests);
     2167            ShiftDblGenerate(pStrmDataCpu, pszCpuSuffU, RT_MAX(cTests, 128));
     2168            UnaryGenerate(pStrmData, cTests);
     2169            ShiftGenerate(pStrmDataCpu, pszCpuSuffU, cTests);
     2170            MulDivGenerate(pStrmDataCpu, pszCpuSuffU, cTests);
     2171
     2172            RTEXITCODE rcExit = GenerateFooterAndClose(pStrmDataCpu, pszDataCpuFile, "", pszCpuSuff,
     2173                                                       GenerateFooterAndClose(pStrmData, pszDataFile, "", "",
     2174                                                                              RTEXITCODE_SUCCESS));
     2175            if (rcExit != RTEXITCODE_SUCCESS)
     2176                return rcExit;
     2177        }
     2178
     2179        if (fFpu)
     2180        {
     2181            const char *pszDataFile = fCommonData ? "tstIEMAImplDataFpu.h" : pszBitBucket;
     2182            PRTSTREAM   pStrmData   = NULL;
     2183            rc = RTStrmOpen(pszDataFile, "w", &pStrmData);
     2184            if (!pStrmData)
     2185                return RTMsgErrorExitFailure("Failed to open %s for writing: %Rrc", pszDataFile, rc);
     2186
     2187            const char *pszDataCpuFile = !fCpuData ? pszBitBucket : g_idxCpuEflFlavour == IEMTARGETCPU_EFL_BEHAVIOR_AMD
     2188                                       ? "tstIEMAImplDataFpu-Amd.h" : "tstIEMAImplDataFpu-Intel.h";
     2189            PRTSTREAM   pStrmDataCpu   = NULL;
     2190            rc = RTStrmOpen(pszDataCpuFile, "w", &pStrmDataCpu);
     2191            if (!pStrmData)
     2192                return RTMsgErrorExitFailure("Failed to open %s for writing: %Rrc", pszDataCpuFile, rc);
     2193
     2194            GenerateHeader(pStrmData, "Fpu", szCpuDesc, NULL, "");
     2195            GenerateHeader(pStrmDataCpu, "Fpu", szCpuDesc, pszCpuType, pszCpuSuff);
     2196
     2197            FpuLoadConstGenerate(pStrmData, cTests);
     2198
     2199            RTEXITCODE rcExit = GenerateFooterAndClose(pStrmDataCpu, pszDataCpuFile, "Fpu", pszCpuSuff,
     2200                                                       GenerateFooterAndClose(pStrmData, pszDataFile, "Fpu", "",
     2201                                                                              RTEXITCODE_SUCCESS));
     2202            if (rcExit != RTEXITCODE_SUCCESS)
     2203                return rcExit;
     2204        }
     2205        return RTEXITCODE_SUCCESS;
    18572206#else
    18582207        return RTMsgErrorExitFailure("Test data generator not compiled in!");
     
    18662215    rc = RTTestCreate("tstIEMAimpl", &g_hTest);
    18672216    AssertRCReturn(rc, RTEXITCODE_FAILURE);
    1868     if (argc > 1)
     2217    if (enmMode == kModeTest)
    18692218    {
    18702219        /* Allocate guarded memory for use in the tests. */
     
    18862235        if (RTTestErrorCount(g_hTest) == 0)
    18872236        {
    1888             BinU8Test();
    1889             BinU16Test();
    1890             BinU32Test();
    1891             BinU64Test();
    1892             XchgTest();
    1893             XaddTest();
    1894             CmpXchgTest();
    1895             CmpXchg8bTest();
    1896             CmpXchg16bTest();
    1897             ShiftDblTest();
    1898             UnaryTest();
    1899             ShiftTest();
    1900             MulDivTest();
    1901             BswapTest();
     2237            if (fInt)
     2238            {
     2239                BinU8Test();
     2240                BinU16Test();
     2241                BinU32Test();
     2242                BinU64Test();
     2243                XchgTest();
     2244                XaddTest();
     2245                CmpXchgTest();
     2246                CmpXchg8bTest();
     2247                CmpXchg16bTest();
     2248                ShiftDblTest();
     2249                UnaryTest();
     2250                ShiftTest();
     2251                MulDivTest();
     2252                BswapTest();
     2253            }
     2254
     2255            if (fFpu)
     2256            {
     2257                FpuLoadConstTest();
     2258            }
    19022259        }
    19032260        return RTTestSummaryAndDestroy(g_hTest);
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