VirtualBox

Changeset 94638 in vbox for trunk


Ignore:
Timestamp:
Apr 19, 2022 9:22:30 PM (3 years ago)
Author:
vboxsync
Message:

libs/softfloat: Cloned extF80_rem into extF80_partialRem for implementing the FPREM and FPREM1 x87 instructions. bugref:9898

Location:
trunk/src/libs/softfloat-3e
Files:
2 edited
1 copied

Legend:

Unmodified
Added
Removed
  • trunk/src/libs/softfloat-3e/Makefile.kmk

    r94548 r94638  
    267267        source/extF80_div.c \
    268268        source/extF80_rem.c \
     269        source/extF80_partialRem.c \
    269270        source/extF80_sqrt.c \
    270271        source/extF80_eq.c \
  • trunk/src/libs/softfloat-3e/source/extF80_partialRem.c

    r94621 r94638  
    4141#include "specialize.h"
    4242#include "softfloat.h"
    43 
    44 extFloat80_t extF80_rem( extFloat80_t a, extFloat80_t b SOFTFLOAT_STATE_DECL_COMMA )
     43#include <iprt/cdefs.h> /* RT_BIT_64 */
     44#include <iprt/x86.h>   /* X86_FSW_C? */
     45#include <iprt/assert.h>
     46
     47/** VBox: Copy of extF80_rem modified to fit FPREM and FPREM1. */
     48extFloat80_t extF80_partialRem( extFloat80_t a, extFloat80_t b, uint8_t roundingMode,
     49                                uint16_t *pfCxFlags, softfloat_state_t *pState )
    4550{
    4651    union { struct extFloat80M s; extFloat80_t f; } uA;
     
    6772    union { struct extFloat80M s; extFloat80_t f; } uZ;
    6873
     74    *pfCxFlags = 0; /* C2=0 - complete */                                                               /* VBox */
     75
    6976    /*------------------------------------------------------------------------
    7077    *------------------------------------------------------------------------*/
     
    8491    if ( expA == 0x7FFF ) {
    8592        if (
    86                (sigA & UINT64_C( 0x7FFFFFFFFFFFFFFF ))
    87             || ((expB == 0x7FFF) && (sigB & UINT64_C( 0x7FFFFFFFFFFFFFFF )))
     93               (sigA & UINT64_C( 0x7FFFFFFFFFFFFFFF ))                          /* VBox: NaN or Indefinite */
     94            || ((expB == 0x7FFF) && (sigB & UINT64_C( 0x7FFFFFFFFFFFFFFF )))    /* VBox: NaN or Indefinite */
    8895        ) {
    8996            goto propagateNaN;
    9097        }
    91         goto invalid;
     98        goto invalid;                                                           /* VBox: Infinity */
    9299    }
    93100    if ( expB == 0x7FFF ) {
    94         if ( sigB & UINT64_C( 0x7FFFFFFFFFFFFFFF ) ) goto propagateNaN;
     101        if ( sigB & UINT64_C( 0x7FFFFFFFFFFFFFFF ) ) goto propagateNaN;         /* VBox: NaN or Indefinite */
    95102        /*--------------------------------------------------------------------
    96103        | Argument b is an infinity.  Doubling `expB' is an easy way to ensure
     
    104111    if ( ! expB ) expB = 1;
    105112    if ( ! (sigB & UINT64_C( 0x8000000000000000 )) ) {
    106         if ( ! sigB ) goto invalid;
     113        if ( ! sigB ) goto invalid;                                             /* VBox: Zero -> /0 -> invalid. */
    107114        normExpSig = softfloat_normSubnormalExtF80Sig( sigB );
    108115        expB += normExpSig.exp;
     
    112119    if ( ! (sigA & UINT64_C( 0x8000000000000000 )) ) {
    113120        if ( ! sigA ) {
     121#if 0 /* A is zero. VBox: Don't mix denormals and zero returns! */                                      /* VBox */
    114122            expA = 0;
    115123            goto copyA;
     124#else                                                                                                   /* VBox */
     125            uiZ64 = packToExtF80UI64( signA, 0);                                                        /* VBox */
     126            uiZ0  = 0;                                                                                  /* VBox */
     127            goto uiZ;                                                                                   /* VBox */
     128#endif                                                                                                  /* VBox */
    116129        }
    117130        normExpSig = softfloat_normSubnormalExtF80Sig( sigA );
     
    122135    *------------------------------------------------------------------------*/
    123136    expDiff = expA - expB;
     137
     138    /*------------------------------------------------------------------------                             VBox
     139    | Do at most 63 rounds. If exponent difference is 64 or higher, return                                 VBox
     140    | a partial remainder.                                                                                 VBox
     141    *------------------------------------------------------------------------*/                         /* VBox */
     142    bool const fPartial = expDiff >= 64;                                                                /* VBox */
     143    if ( fPartial ) { /* VBox */                                                                        /* VBox */
     144        unsigned N = 32 + ((unsigned)expDiff % 32); /* (Amount of work documented by AMD.) */           /* VBox */
     145        expB         = expA - N;                                                                        /* VBox */
     146        expDiff      = N;                                                                               /* VBox */
     147        roundingMode = softfloat_round_minMag;                                                          /* VBox */
     148    }                                                                                                   /* VBox */
     149
     150    /*------------------------------------------------------------------------
     151    | The final rounds.
     152    *------------------------------------------------------------------------*/
    124153    if ( expDiff < -1 ) goto copyA;
    125154    rem = softfloat_shortShiftLeft128( 0, sigA, 32 );
    126155    shiftedSigB = softfloat_shortShiftLeft128( 0, sigB, 32 );
     156    uint64_t quotient = 0;                                                                              /* VBox */
    127157    if ( expDiff < 1 ) {
    128158        if ( expDiff ) {
     
    132162        } else {
    133163            q = (sigB <= sigA);
     164            quotient = q;                                                                               /* VBox */
    134165            if ( q ) {
    135166                rem =
     
    145176            if ( expDiff < 0 ) break;
    146177            q = (q64 + 0x80000000)>>32;
     178            quotient = (quotient << 29) + q;                                                            /* VBox */
    147179            rem = softfloat_shortShiftLeft128( rem.v64, rem.v0, 29 );
    148180            term = softfloat_mul64ByShifted32To128( sigB, q );
     
    152184                    softfloat_add128(
    153185                        rem.v64, rem.v0, shiftedSigB.v64, shiftedSigB.v0 );
     186                quotient--;                                                                             /* VBox */
    154187            }
    155188            expDiff -= 29;
     
    159192        *--------------------------------------------------------------------*/
    160193        q = (uint32_t) (q64>>32)>>(~expDiff & 31);
     194        quotient = (quotient << (expDiff + 30)) + q;                                                    /* VBox */
    161195        rem = softfloat_shortShiftLeft128( rem.v64, rem.v0, expDiff + 30 );
    162196        term = softfloat_mul64ByShifted32To128( sigB, q );
     
    174208        altRem = rem;
    175209        ++q;
     210        quotient++;                                                                                     /* VBox */
    176211        rem =
    177212            softfloat_sub128(
     
    179214    } while ( ! (rem.v64 & UINT64_C( 0x8000000000000000 )) );
    180215 selectRem:
    181     meanRem = softfloat_add128( rem.v64, rem.v0, altRem.v64, altRem.v0 );
    182     if (
    183         (meanRem.v64 & UINT64_C( 0x8000000000000000 ))
    184             || (! (meanRem.v64 | meanRem.v0) && (q & 1))
    185     ) {
    186         rem = altRem;
    187     }
     216    if (roundingMode == softfloat_round_near_even) {                                                    /* VBox */
     217        meanRem = softfloat_add128( rem.v64, rem.v0, altRem.v64, altRem.v0 );
     218        if (
     219            (meanRem.v64 & UINT64_C( 0x8000000000000000 ))
     220                || (! (meanRem.v64 | meanRem.v0) && (q & 1))
     221        ) {
     222            rem = altRem;
     223            quotient--;                                                                                 /* VBox */
     224        }
     225    }                                                                                                   /* VBox */
    188226    signRem = signA;
    189227    if ( rem.v64 & UINT64_C( 0x8000000000000000 ) ) {
    190         signRem = ! signRem;
    191         rem = softfloat_sub128( 0, 0, rem.v64, rem.v0 );
    192     }
     228        if (roundingMode != softfloat_round_near_even) {                                                /* VBox */
     229            rem = altRem;                                                                               /* VBox */
     230            quotient--;                                                                                 /* VBox */
     231        } else {                                                                                        /* VBox */
     232            signRem = ! signRem;
     233            rem = softfloat_sub128( 0, 0, rem.v64, rem.v0 );
     234            Assert(!fPartial);                                                                          /* VBox */
     235        }                                                                                               /* VBox */
     236    } else Assert(roundingMode == softfloat_round_near_even);                                           /* VBox */
     237
     238    /* VBox: Set pfCxFlags */                                                                           /* VBox */
     239    if ( fPartial ) {                                                                                   /* VBox */
     240        *pfCxFlags = X86_FSW_C2;                            /* C2 = 1 - incomplete */                   /* VBox */
     241    } else {                                                                                            /* VBox */
     242        *pfCxFlags = X86_FSW_CX_FROM_QUOTIENT( quotient );  /* C2 = 0 - complete */                     /* VBox */
     243    }                                                                                                   /* VBox */
     244
    193245    return
    194246        softfloat_normRoundPackToExtF80(
     
    212264 copyA:
    213265    if ( expA < 1 ) {
     266#if 0                                                                                                   /* VBox */
    214267        sigA >>= 1 - expA;
    215268        expA = 0;
     269#else                                                                                                   /* VBox */
     270        Assert(sigA != 0); /* We don't get here for zero values, only denormals. */                     /* VBox */
     271        /* Apply the bias adjust if underflows exceptions aren't masked, unless                            VBox
     272           the divisor is +/-Infinity.                                                                     VBox
     273           Note! extB has been tweaked, so don't use if for Inf classification. */                      /* VBox */
     274        if (    (pState->exceptionMask & softfloat_flag_underflow)                                      /* VBox */
     275             || (expExtF80UI64( b.signExp ) == 0x7fff && !(sigB & (RT_BIT_64( 63 ) - 1))) ) {           /* VBox */
     276            sigA >>= 1 - expA;                                                                          /* VBox */
     277            expA = 0;                                                                                   /* VBox */
     278        } else {                                                                                        /* VBox */
     279            softfloat_raiseFlags( softfloat_flag_underflow SOFTFLOAT_STATE_ARG_COMMA );                 /* VBox */
     280            expA = (expA + RTFLOAT80U_EXP_BIAS_ADJUST) & RTFLOAT80U_EXP_MAX;                            /* VBox */
     281        }                                                                                               /* VBox */
     282#endif                                                                                                  /* VBox */
    216283    }
    217284    uiZ64 = packToExtF80UI64( signA, expA );
  • trunk/src/libs/softfloat-3e/source/include/softfloat.h

    r94558 r94638  
    297297extFloat80_t extF80_div( extFloat80_t, extFloat80_t SOFTFLOAT_STATE_DECL_COMMA );
    298298extFloat80_t extF80_rem( extFloat80_t, extFloat80_t SOFTFLOAT_STATE_DECL_COMMA );
     299extFloat80_t extF80_partialRem( extFloat80_t a, extFloat80_t b, uint8_t roundingMode,                   /* VBox: FPREM/FPREM1 */
     300                                uint16_t *pfCxFlags, softfloat_state_t *pState );                       /* VBox: FPREM/FPREM1 */
    299301extFloat80_t extF80_sqrt( extFloat80_t SOFTFLOAT_STATE_DECL_COMMA );
    300302bool extF80_eq( extFloat80_t, extFloat80_t SOFTFLOAT_STATE_DECL_COMMA );
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