VirtualBox

Changeset 96157 in vbox


Ignore:
Timestamp:
Aug 12, 2022 9:53:32 AM (2 years ago)
Author:
vboxsync
Message:

IPRT/strttofloat.cpp: Some fixes and blind attempt at making it build on sparc. bugref:10261

Location:
trunk
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/include/iprt/cdefs.h

    r96042 r96157  
    11221122 * IEEE quadruple precision floating (128-bit).
    11231123 * @note Currently not able to detect this, so must be explicitly defined. */
    1124 #if 0
     1124#if defined(RT_ARCH_SPARC) || defined(RT_ARCH_SPARC64)
    11251125# define RT_COMPILER_WITH_128BIT_LONG_DOUBLE
    11261126#endif
  • trunk/include/iprt/types.h

    r96151 r96157  
    15511551#ifdef RT_COMPILER_WITH_128BIT_LONG_DOUBLE
    15521552    /** Long double view. */
    1553     long double lrd;
     1553    long double lrd, r;
    15541554#endif
    15551555    /** 128-bit view. */
     
    15781578#define RTFLOAT128U_INIT_C(a_fSign, a_uFractionHi, a_uFractionLo, a_uExponent) \
    15791579    RTFLOAT128U_INIT((a_fSign), UINT64_C(a_uFractionHi), UINT64_C(a_uFractionLo), (a_uExponent))
     1580
     1581#define RTFLOAT128U_INIT_ZERO(a_fSign)               RTFLOAT128U_INIT((a_fSign), UINT64_C(0), UINT64_C(0), 0)
     1582#define RTFLOAT128U_INIT_INF(a_fSign)                RTFLOAT128U_INIT((a_fSign), UINT64_C(0), UINT64_C(0), RTFLOAT128U_EXP_MAX)
     1583#define RTFLOAT128U_INIT_SNAN(a_fSign)               RTFLOAT128U_INIT((a_fSign), UINT64_C(0), UINT64_C(1), RTFLOAT128U_EXP_MAX)
     1584#define RTFLOAT128U_INIT_SNAN_EX(a_fSign, a_uValHi, a_uValLo) \
     1585    RTFLOAT128U_INIT((a_fSign), (a_uValHi), (a_uValHi) || (a_uValLo) ? (a_uValLo) : UINT64_C(1), RTFLOAT128U_EXP_MAX)
     1586#define RTFLOAT128U_INIT_SIGNALLING_NAN(a_fSign)     RTFLOAT128U_INIT_SNAN(a_fSign)
     1587#define RTFLOAT128U_INIT_QNAN(a_fSign) \
     1588    RTFLOAT128U_INIT((a_fSign), RT_BIT_64(RTFLOAT128U_FRACTION_BITS - 1 - 64), UINT64_C(1), RTFLOAT128U_EXP_MAX)
     1589#define RTFLOAT128U_INIT_QNAN_EX(a_fSign, a_uValHi, a_uValLo) \
     1590    RTFLOAT128U_INIT((a_fSign), RT_BIT_64(RTFLOAT128U_FRACTION_BITS - 1 - 64) | (a_uValHi), \
     1591                     (a_uValLo) || (a_uValHi) ? (a_uValLo) : UINT64_C(1), RTFLOAT128U_EXP_MAX)
     1592#define RTFLOAT128U_INIT_QUIET_NAN(a_fSign)          RTFLOAT128U_INIT_QNAN(a_fSign)
     1593#define RTFLOAT128U_INIT_NAN_EX(a_fQuiet, a_fSign, a_uValHi, a_uValLo) \
     1594    RTFLOAT128U_INIT((a_fSign), \
     1595                     ((a_fQuiet) ? RT_BIT_64(RTFLOAT128U_FRACTION_BITS - 1 - 64) : 0) | (a_uValHi), \
     1596                     (a_uValLo) || (a_uValHi) || (a_fQuiet) /*?*/ ? (a_uValLo) : UINT64_C(1), \
     1597                     RTFLOAT128U_EXP_MAX)
     1598
    15801599/** The exponent bias for the RTFLOAT128U format. */
    15811600#define RTFLOAT128U_EXP_BIAS                    (16383)
  • trunk/src/VBox/Runtime/Makefile.kmk

    r96154 r96157  
    26132613endif
    26142614VBoxRT_SDKS                   += VBOX_OPENSSL
    2615 if1of ($(KBUILD_TARGET), $(VBOX_SUPPORTED_HOST_ARCHS))
     2615if1of ($(KBUILD_TARGET_ARCH), $(VBOX_SUPPORTED_HOST_ARCHS))
    26162616VBoxRT_SDKS                   += VBOX_SOFTFLOAT
    26172617endif
  • trunk/src/VBox/Runtime/common/string/strtofloat.cpp

    r96156 r96157  
    4343#endif
    4444
    45 #if defined(SOFTFLOAT_FAST_INT64) /** @todo better softfloat indicator? */
     45#if defined(SOFTFLOAT_FAST_INT64) && !defined(RT_COMPILER_WITH_128BIT_LONG_DOUBLE) /** @todo better softfloat indicator? */
    4646# define USE_SOFTFLOAT /* for scaling by power of 10 */
    4747#endif
     
    5656typedef struct FLOATUNION
    5757{
     58#ifdef RT_COMPILER_WITH_128BIT_LONG_DOUBLE
     59    RTFLOAT128U lrd;
     60#elif defined(RT_COMPILER_WITH_80BIT_LONG_DOUBLE)
    5861    RTFLOAT80U2 lrd;
     62#endif
    5963    RTFLOAT64U  rd;
    6064    RTFLOAT32U  r;
     
    6569#define RET_TYPE_LONG_DOUBLE  2
    6670
    67 #ifdef RT_COMPILER_WITH_80BIT_LONG_DOUBLE
     71#ifdef RT_COMPILER_WITH_128BIT_LONG_DOUBLE
     72typedef RTFLOAT128U LONG_DOUBLE_U_T;
     73typedef __uint128_t UINT_MANTISSA_T;
     74# define UINT_MANTISSA_T_BITS   128
     75#elif defined(RT_COMPILER_WITH_80BIT_LONG_DOUBLE)
    6876typedef RTFLOAT80U2 LONG_DOUBLE_U_T;
     77typedef uint64_t    UINT_MANTISSA_T;
     78# define UINT_MANTISSA_T_BITS   64
    6979#else
    7080typedef RTFLOAT64U  LONG_DOUBLE_U_T;
     81typedef uint64_t    UINT_MANTISSA_T;
     82# define UINT_MANTISSA_T_BITS   64
    7183#endif
    7284
     
    89101    RTFLOAT32U_EXP_MAX - 1 - RTFLOAT32U_EXP_BIAS,
    90102    RTFLOAT64U_EXP_MAX - 1 - RTFLOAT64U_EXP_BIAS,
    91 #ifdef RT_COMPILER_WITH_80BIT_LONG_DOUBLE
     103#if defined(RT_COMPILER_WITH_128BIT_LONG_DOUBLE)
     104    RTFLOAT128U_EXP_MAX - 1 - RTFLOAT128U_EXP_BIAS,
     105#elif defined(RT_COMPILER_WITH_80BIT_LONG_DOUBLE)
    92106    RTFLOAT80U_EXP_MAX - 1 - RTFLOAT80U_EXP_BIAS,
    93107#else
     
    101115    1 - RTFLOAT32U_EXP_BIAS,
    102116    1 - RTFLOAT64U_EXP_BIAS,
    103 #ifdef RT_COMPILER_WITH_80BIT_LONG_DOUBLE
     117#if defined(RT_COMPILER_WITH_128BIT_LONG_DOUBLE)
     118    1 - RTFLOAT128U_EXP_BIAS,
     119#elif defined(RT_COMPILER_WITH_80BIT_LONG_DOUBLE)
    104120    1 - RTFLOAT80U_EXP_BIAS,
    105121#else
     
    112128static uint64_t const g_fNanMasks[3] =
    113129{
    114     RT_BIT_64(RTFLOAT32U_FRACTION_BITS - 1) - 1,    /* 22=quiet(1) / silent(0) */
    115     RT_BIT_64(RTFLOAT64U_FRACTION_BITS - 1) - 1,    /* 51=quiet(1) / silent(0) */
    116 #ifdef RT_COMPILER_WITH_80BIT_LONG_DOUBLE
    117     RT_BIT_64(RTFLOAT80U_FRACTION_BITS - 1) - 1,    /* bit 63=NaN; bit 62=quiet(1) / silent(0) */
     130    RT_BIT_64(RTFLOAT32U_FRACTION_BITS - 1) - 1,        /* 22=quiet(1) / silent(0) */
     131    RT_BIT_64(RTFLOAT64U_FRACTION_BITS - 1) - 1,        /* 51=quiet(1) / silent(0) */
     132#if defined(RT_COMPILER_WITH_128BIT_LONG_DOUBLE)
     133    RT_BIT_64(RTFLOAT128U_FRACTION_BITS - 1 - 64) - 1,  /* 111=quiet(1) / silent(0) */
     134#elif defined(RT_COMPILER_WITH_80BIT_LONG_DOUBLE)
     135    RT_BIT_64(RTFLOAT80U_FRACTION_BITS - 1) - 1,        /* bit 63=NaN; bit 62=quiet(1) / silent(0) */
    118136#else
    119137    RT_BIT_64(RTFLOAT64U_FRACTION_BITS - 1) - 1,
     
    122140
    123141#if 0 /* unused */
    124 #ifdef RT_COMPILER_WITH_80BIT_LONG_DOUBLE
     142# if defined(RT_COMPILER_WITH_80BIT_LONG_DOUBLE) || defined(RT_COMPILER_WITH_128BIT_LONG_DOUBLE)
    125143static const long double g_lrdPowerMin10 = 1e4931L;
    126144static const long double g_lrdPowerMax10 = 1e4932L;
    127 #else
     145# else
    128146static const long double g_lrdPowerMin10 = 1e307L;
    129147static const long double g_lrdPowerMax10 = 1e308L;
    130 #endif
     148# endif
    131149#endif
    132150
     
    230248    1e128L,
    231249    1e256L,
    232 # ifdef RT_COMPILER_WITH_80BIT_LONG_DOUBLE
     250# if defined(RT_COMPILER_WITH_80BIT_LONG_DOUBLE) || defined(RT_COMPILER_WITH_128BIT_LONG_DOUBLE)
    233251    1e512L,
    234252    1e1024L,
     
    297315    softfloat_state_t   SoftState = SOFTFLOAT_STATE_INIT_DEFAULTS();
    298316    float128_t          Val;
    299 #ifdef RT_COMPILER_WITH_80BIT_LONG_DOUBLE
     317# ifdef RT_COMPILER_WITH_80BIT_LONG_DOUBLE
    300318    extFloat80M         Tmp = EXTFLOAT80M_INIT(pVal->s2.uSignAndExponent, pVal->s2.uMantissa);
    301319    extF80M_to_f128M(&Tmp, &Val, &SoftState);
    302 #else
     320# else
    303321    float64_t           Tmp = { pVal->u };
    304322    f64_to_f128M(Tmp, &Val, &SoftState);
    305 #endif
     323# endif
    306324
    307325    /*
     
    355373        f128M_div(&Val, &Factor, &Val, &SoftState);
    356374
    357 #ifdef RT_COMPILER_WITH_80BIT_LONG_DOUBLE
     375# ifdef RT_COMPILER_WITH_80BIT_LONG_DOUBLE
    358376    f128M_to_extF80M(&Val, &Tmp, &SoftState);
    359377    pVal->s2.uSignAndExponent = Tmp.signExp;
    360378    pVal->s2.uMantissa        = Tmp.signif;
    361 #else
     379# else
    362380    Tmp = f128M_to_f64(&Val, &SoftState);
    363381    pVal->u = Tmp.v;
    364 #endif
     382# endif
    365383
    366384    /*
     
    371389        rc = VINF_SUCCESS;
    372390    else if (SoftState.exceptionFlags & softfloat_flag_underflow)
    373     {
    374 RTAssertMsg2("VERR_FLOAT_UNDERFLOW r128=%.16Rhxs r64=%.8Rhxs\n", &Val, &Tmp);
    375391        rc = VERR_FLOAT_UNDERFLOW;
    376     }
    377392    else
    378393        rc = VERR_FLOAT_OVERFLOW;
    379394
    380 #else
     395#else  /* !USE_SOFTFLOAT */
    381396# if 0
    382397    /*
     
    453468# endif
    454469
    455 #endif
     470#endif /* !USE_SOFTFLOAT */
    456471    return rc;
    457472}
     
    535550
    536551        case RET_TYPE_LONG_DOUBLE:
    537 #ifdef RT_COMPILER_WITH_80BIT_LONG_DOUBLE
    538         {
     552#if defined(RT_COMPILER_WITH_80BIT_LONG_DOUBLE) || defined(RT_COMPILER_WITH_128BIT_LONG_DOUBLE)
     553        {
     554# if defined(RT_COMPILER_WITH_80BIT_LONG_DOUBLE)
    539555            RTFLOAT80U2 const uRet = RTFLOAT80U_INIT_INF(!fPositive);
     556# else
     557            RTFLOAT128U const uRet = RTFLOAT128U_INIT_INF(!fPositive);
     558# endif
    540559            pRet->lrd.lrd = uRet.lrd;
    541560            break;
     
    574593 * @param   cchTag  The length of the tag string value.
    575594 * @param   pfQuiet Where to return the type of NaN.  Default is quiet.
     595 * @param   puHiNum Where to rturn the high 64-bits of the tag.
    576596 */
    577 static uint64_t rtStrParseNanTag(const char *pchTag, size_t cchTag, bool *pfQuiet)
     597static uint64_t rtStrParseNanTag(const char *pchTag, size_t cchTag, bool *pfQuiet, uint64_t *puHiNum)
    578598{
    579599    *pfQuiet = true;
     
    591611     * Parse the number, ignoring overflows and stopping on non-xdigit.
    592612     */
     613    *puHiNum = 0;
    593614    uint64_t uRet = 0;
     615    unsigned iXDigit = 0;
    594616    while (cchTag > 0)
    595617    {
     
    598620        if (uchDigit >= 16)
    599621            break;
    600         uRet *= 16;
    601         uRet += uchDigit;
     622        iXDigit++;
     623        if (iXDigit >= 16)
     624            *puHiNum = (*puHiNum << 4) | (uRet >> 60);
     625        uRet <<= 4;
     626        uRet  += uchDigit;
    602627        pchTag++;
    603628        cchTag--;
     
    642667    bool     fQuiet = true;
    643668    uint64_t uNum   = 1;
     669    uint64_t uHiNum = 0;
    644670    if (cchMax >= 2 && *psz == '(')
    645671    {
     
    650676        if (ch == ')')
    651677        {
    652             uNum = rtStrParseNanTag(psz + 1, cch - 1, &fQuiet);
     678            uNum = rtStrParseNanTag(psz + 1, cch - 1, &fQuiet, &uHiNum);
    653679            psz    += cch + 1;
    654680            cchMax -= cch + 1;
    655681
    656682            Assert(iRetType < RT_ELEMENTS(g_fNanMasks));
    657             uNum &= g_fNanMasks[iRetType];
    658             if (!uNum)
    659                 uNum = 1; /* must not be zero, or it'll turn into an infinity */
     683#if defined(RT_COMPILER_WITH_128BIT_LONG_DOUBLE)
     684            if (iRetType == RET_TYPE_LONG_DOUBLE)
     685            {
     686                uHiNum &= g_fNanMasks[RET_TYPE_LONG_DOUBLE];
     687                if (!uNum && !uHiNum)
     688                    uNum = 1; /* must not be zero, or it'll turn into an infinity */
     689            }
     690            else
     691#endif
     692            {
     693                uNum &= g_fNanMasks[iRetType];
     694                if (!uNum)
     695                    uNum = 1; /* must not be zero, or it'll turn into an infinity */
     696            }
    660697        }
    661698    }
     
    674711
    675712        case RET_TYPE_LONG_DOUBLE:
    676 #ifdef RT_COMPILER_WITH_80BIT_LONG_DOUBLE
    677         {
     713#if defined(RT_COMPILER_WITH_80BIT_LONG_DOUBLE) || defined(RT_COMPILER_WITH_128BIT_LONG_DOUBLE)
     714        {
     715# if defined(RT_COMPILER_WITH_80BIT_LONG_DOUBLE)
    678716            RTFLOAT80U2 const uRet = RTFLOAT80U_INIT_NAN_EX(fQuiet, !fPositive, uNum);
     717# else
     718            RTFLOAT128U const uRet = RTFLOAT128U_INIT_NAN_EX(fQuiet, !fPositive, uHiNum, uNum);
     719# endif
    679720            pRet->lrd = uRet;
    680721            break;
     
    719760
    720761        case RET_TYPE_LONG_DOUBLE:
    721 #ifdef RT_COMPILER_WITH_80BIT_LONG_DOUBLE
     762#if defined(RT_COMPILER_WITH_80BIT_LONG_DOUBLE) || defined(RT_COMPILER_WITH_128BIT_LONG_DOUBLE)
    722763            pRet->lrd.lrd = fPositive ? +0.0L : -0.0L;
    723764            break;
     
    765806                                            unsigned iRetType, FLOATUNION *pRet)
    766807{
    767 #ifdef RT_COMPILER_WITH_80BIT_LONG_DOUBLE
     808#if defined(RT_COMPILER_WITH_80BIT_LONG_DOUBLE) || defined(RT_COMPILER_WITH_128BIT_LONG_DOUBLE)
    768809    Assert(iRetType == RET_TYPE_LONG_DOUBLE);
    769810    pRet->lrd = *pVal;
     
    782823 */
    783824static int rtStrToLongDoubleReturnValue(const char *psz, char **ppszNext, size_t cchMax,
    784                                         bool fPositive, uint64_t uMantissa, int32_t iExponent,
     825                                        bool fPositive, UINT_MANTISSA_T uMantissa, int32_t iExponent,
    785826                                        unsigned iRetType, FLOATUNION *pRet)
    786827{
     
    794835                /* Produce a subnormal value if it's within range, otherwise return zero. */
    795836                if (iExponent < -RTFLOAT32U_FRACTION_BITS)
    796                     return rtStrToLongDoubleReturnZero(psz, ppszNext, cchMax, fPositive, VWRN_FLOAT_UNDERFLOW, iRetType, pRet);
     837                    return rtStrToLongDoubleReturnZero(psz, ppszNext, cchMax, fPositive, VERR_FLOAT_UNDERFLOW, iRetType, pRet);
    797838                rc = VWRN_FLOAT_UNDERFLOW;
    798839                uMantissa >>= -iExponent + 1;
     
    800841            }
    801842            else if (iExponent >= RTFLOAT32U_EXP_MAX)
    802                 return rtStrToLongDoubleReturnInf(psz, ppszNext, cchMax, fPositive, VWRN_FLOAT_OVERFLOW, iRetType, pRet);
    803 
    804             pRet->r.s.uFraction = (uMantissa >> (63 - RTFLOAT32U_FRACTION_BITS)) & (RT_BIT_64(RTFLOAT32U_FRACTION_BITS) - 1);
     843                return rtStrToLongDoubleReturnInf(psz, ppszNext, cchMax, fPositive, VERR_FLOAT_OVERFLOW, iRetType, pRet);
     844
     845            pRet->r.s.uFraction = (uMantissa >> (UINT_MANTISSA_T_BITS - 1 - RTFLOAT32U_FRACTION_BITS))
     846                                & (RT_BIT_32(RTFLOAT32U_FRACTION_BITS) - 1);
    805847            pRet->r.s.uExponent = iExponent;
    806848            pRet->r.s.fSign     = !fPositive;
     
    809851        case RET_TYPE_LONG_DOUBLE:
    810852#ifdef RT_COMPILER_WITH_80BIT_LONG_DOUBLE
     853# if UINT_MANTISSA_T_BITS != 64
     854#  error Unsupported UINT_MANTISSA_T_BITS count.
     855# endif
    811856            iExponent += RTFLOAT80U_EXP_BIAS;
    812857            if (iExponent <= 0)
     
    814859                /* Produce a subnormal value if it's within range, otherwise return zero. */
    815860                if (iExponent < -RTFLOAT80U_FRACTION_BITS)
    816                     return rtStrToLongDoubleReturnZero(psz, ppszNext, cchMax, fPositive, VWRN_FLOAT_UNDERFLOW, iRetType, pRet);
     861                    return rtStrToLongDoubleReturnZero(psz, ppszNext, cchMax, fPositive, VERR_FLOAT_UNDERFLOW, iRetType, pRet);
    817862                rc = VWRN_FLOAT_UNDERFLOW;
    818863                uMantissa >>= -iExponent + 1;
     
    820865            }
    821866            else if (iExponent >= RTFLOAT80U_EXP_MAX)
    822                 return rtStrToLongDoubleReturnInf(psz, ppszNext, cchMax, fPositive, VWRN_FLOAT_OVERFLOW, iRetType, pRet);
     867                return rtStrToLongDoubleReturnInf(psz, ppszNext, cchMax, fPositive, VERR_FLOAT_OVERFLOW, iRetType, pRet);
    823868
    824869            pRet->lrd.s.uMantissa = uMantissa;
    825870            pRet->lrd.s.uExponent = iExponent;
    826871            pRet->lrd.s.fSign     = !fPositive;
     872            break;
     873#elif defined(RT_COMPILER_WITH_128BIT_LONG_DOUBLE)
     874            iExponent += RTFLOAT128U_EXP_BIAS;
     875            uMantissa >>= 128 - RTFLOAT128U_FRACTION_BITS;
     876            if (iExponent <= 0)
     877            {
     878                /* Produce a subnormal value if it's within range, otherwise return zero. */
     879                if (iExponent < -RTFLOAT128U_FRACTION_BITS)
     880                    return rtStrToLongDoubleReturnZero(psz, ppszNext, cchMax, fPositive, VERR_FLOAT_UNDERFLOW, iRetType, pRet);
     881                rc = VWRN_FLOAT_UNDERFLOW;
     882                uMantissa >>= -iExponent + 1;
     883                iExponent   = 0;
     884            }
     885            else if (iExponent >= RTFLOAT80U_EXP_MAX)
     886                return rtStrToLongDoubleReturnInf(psz, ppszNext, cchMax, fPositive, VERR_FLOAT_OVERFLOW, iRetType, pRet);
     887            pRet->lrd.s64.uFractionHi = (uint64_t)(uMantissa >> 64) & (RT_BIT_64(RTFLOAT128U_FRACTION_BITS - 64) - 1);
     888            pRet->lrd.s64.uFractionLo = (uint64_t)uMantissa;
     889            pRet->lrd.s64.uExponent   = iExponent;
     890            pRet->lrd.s64.fSign       = !fPositive;
    827891            break;
    828892#else
     
    836900                /* Produce a subnormal value if it's within range, otherwise return zero. */
    837901                if (iExponent < -RTFLOAT64U_FRACTION_BITS)
    838                     return rtStrToLongDoubleReturnZero(psz, ppszNext, cchMax, fPositive, VWRN_FLOAT_UNDERFLOW, iRetType, pRet);
     902                    return rtStrToLongDoubleReturnZero(psz, ppszNext, cchMax, fPositive, VERR_FLOAT_UNDERFLOW, iRetType, pRet);
    839903                rc = VWRN_FLOAT_UNDERFLOW;
    840904                uMantissa >>= -iExponent + 1;
     
    842906            }
    843907            else if (iExponent >= RTFLOAT64U_EXP_MAX)
    844                 return rtStrToLongDoubleReturnInf(psz, ppszNext, cchMax, fPositive, VWRN_FLOAT_OVERFLOW, iRetType, pRet);
    845 
    846             pRet->rd.s64.uFraction = (uMantissa >> (63 - RTFLOAT64U_FRACTION_BITS)) & (RT_BIT_64(RTFLOAT64U_FRACTION_BITS) - 1);
     908                return rtStrToLongDoubleReturnInf(psz, ppszNext, cchMax, fPositive, VERR_FLOAT_OVERFLOW, iRetType, pRet);
     909
     910            pRet->rd.s64.uFraction = (uMantissa >> (UINT_MANTISSA_T_BITS - 1 - RTFLOAT64U_FRACTION_BITS))
     911                                   & (RT_BIT_64(RTFLOAT64U_FRACTION_BITS) - 1);
    847912            pRet->rd.s64.uExponent = iExponent;
    848913            pRet->rd.s64.fSign     = !fPositive;
     
    917982     * Check for hex prefix.
    918983     */
    919 #ifdef RT_COMPILER_WITH_80BIT_LONG_DOUBLE
     984#ifdef RT_COMPILER_WITH_128BIT_LONG_DOUBLE
     985    unsigned cMaxDigits      = 33;
     986#elif defined(RT_COMPILER_WITH_80BIT_LONG_DOUBLE)
    920987    unsigned cMaxDigits      = 19;
    921988#else
     
    9361003     * Now, parse the mantissa.
    9371004     */
     1005#ifdef RT_COMPILER_WITH_128BIT_LONG_DOUBLE
     1006    uint8_t     abDigits[36];
     1007#else
    9381008    uint8_t     abDigits[20];
     1009#endif
    9391010    unsigned    cDigits           = 0;
    9401011    unsigned    cFractionDigits   = 0;
     
    10501121    if (uBase == 16)
    10511122    {
    1052         uint64_t uMantissa = 0;
     1123        UINT_MANTISSA_T uMantissa = 0;
    10531124        for (unsigned iDigit = 0; iDigit < cDigits; iDigit++)
    10541125        {
    1055             uMantissa |= (uint64_t)abDigits[iDigit] << (64 - 4 - iDigit * 4);
     1126            uMantissa |= (UINT_MANTISSA_T)abDigits[iDigit] << (UINT_MANTISSA_T_BITS - 4 - iDigit * 4);
    10561127            iExponent += 4;
    10571128        }
     
    10591130
    10601131        /* Shift to the left till the most significant bit is 1. */
    1061         if (!(uMantissa & RT_BIT_64(63)))
    1062         {
     1132        if (!((uMantissa >> (UINT_MANTISSA_T_BITS - 1)) & 1))
     1133        {
     1134#if UINT_MANTISSA_T_BITS == 64
    10631135            unsigned cShift = 64 - ASMBitLastSetU64(uMantissa);
    10641136            uMantissa <<= cShift;
    10651137            iExponent  -= cShift;
    10661138            Assert(uMantissa & RT_BIT_64(63));
     1139#else
     1140            do
     1141            {
     1142                uMantissa <<= 1;
     1143                iExponent  -= 1;
     1144            } while (!((uMantissa >> (UINT_MANTISSA_T_BITS - 1)) & 1));
     1145#endif
    10671146        }
    10681147
     
    10801159     * the compiler/CPU for the mantissa.
    10811160     */
    1082     uint64_t uMantissa = 0;
     1161    UINT_MANTISSA_T uMantissa = 0;
    10831162    for (unsigned iDigit = 0; iDigit < cDigits; iDigit++)
    10841163    {
     
    11011180#ifdef RT_COMPILER_WITH_80BIT_LONG_DOUBLE
    11021181        if (!RTFLOAT80U_IS_NORMAL(&uTmp))
     1182#elif defined(RT_COMPILER_WITH_128BIT_LONG_DOUBLE)
     1183        if (!RTFLOAT128U_IS_NORMAL(&uTmp))
    11031184#else
    11041185        if (!RTFLOAT64U_IS_NORMAL(&uTmp))
     
    11071188#ifdef RT_COMPILER_WITH_80BIT_LONG_DOUBLE
    11081189            if (RTFLOAT80U_IS_DENORMAL(&uTmp) && iRetType == RET_TYPE_LONG_DOUBLE)
     1190#elif defined(RT_COMPILER_WITH_128BIT_LONG_DOUBLE)
     1191            if (RTFLOAT128U_IS_SUBNORMAL(&uTmp) && iRetType == RET_TYPE_LONG_DOUBLE)
    11091192#else
    11101193            if (RTFLOAT64U_IS_SUBNORMAL(&uTmp) && iRetType != RET_TYPE_FLOAT)
     
    11291212    iExponent = uTmp.s.uExponent - RTFLOAT80U_EXP_BIAS;
    11301213    uMantissa = uTmp.s.uMantissa;
     1214# if UINT_MANTISSA_T_BITS > 64
     1215    uMantissa <<= UINT_MANTISSA_T_BITS - 64;
     1216# endif
     1217#elif defined(RT_COMPILER_WITH_128BIT_LONG_DOUBLE)
     1218    Assert(RTFLOAT128U_IS_NORMAL(&uTmp));
     1219    if (iRetType == RET_TYPE_LONG_DOUBLE)
     1220    {
     1221        pRet->lrd = uTmp;
     1222        return rtStrToLongDoubleReturnChecks(psz, ppszNext, cchMax, VINF_SUCCESS);
     1223    }
     1224    fPositive  = uTmp.s64.fSign;
     1225    iExponent  = uTmp.s64.uExponent - RTFLOAT128U_EXP_BIAS;
     1226    uMantissa  = (UINT_MANTISSA_T)uTmp.s64.uFractionHi << (UINT_MANTISSA_T_BITS - RTFLOAT128U_FRACTION_BITS - 1 + 64);
     1227    uMantissa |= (UINT_MANTISSA_T)uTmp.s64.uFractionLo << (UINT_MANTISSA_T_BITS - RTFLOAT128U_FRACTION_BITS - 1);
     1228    uMantissa |= (UINT_MANTISSA_T)1 << (UINT_MANTISSA_T_BITS - 1);
    11311229#else
    11321230    Assert(RTFLOAT64U_IS_NORMAL(&uTmp));
     
    11401238    iExponent = uTmp.s64.uExponent - RTFLOAT64U_EXP_BIAS;
    11411239    uMantissa = uTmp.s64.uFraction | RT_BIT_64(RTFLOAT64U_FRACTION_BITS);
     1240# if UINT_MANTISSA_T_BITS > 64
     1241    uMantissa <<= UINT_MANTISSA_T_BITS - 64;
     1242# endif
    11421243#endif
    11431244    return rtStrToLongDoubleReturnValue(psz, ppszNext, cchMax, fPositive, uMantissa, iExponent, iRetType, pRet);
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