VirtualBox

Ignore:
Timestamp:
Apr 14, 2022 1:48:52 PM (3 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
150967
Message:

VMM/IEM,libs/softfloat,tstIEMAImpl: C implementation of fadd helper and related rounding tweaks for SoftFloat. Improved floating point test value generation to make sure we cover all types of input before we go full random. This means increasing the minimum number of tests to 160 for the binary floating point instructions, to cover all basic combinations. bugref:9898

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

Legend:

Unmodified
Added
Removed
  • trunk/src/libs/softfloat-3e/source/include/softfloat_types.h

    r94558 r94606  
    9696    /* softfloat_flag_inexact and friends. */
    9797    uint8_t exceptionFlags;
     98    /** Masked exceptions (only underflow is relevant). */
     99    uint8_t exceptionMask;
    98100    /* extF80: rounding precsision: 32, 64 or 80 */
    99101    uint8_t roundingPrecision;
    100102} softfloat_state_t;
    101 # define SOFTFLOAT_STATE_INIT_DEFAULTS() { softfloat_round_near_even, softfloat_tininess_afterRounding, 0, 80 }
     103# define SOFTFLOAT_STATE_INIT_DEFAULTS() { softfloat_round_near_even, softfloat_tininess_afterRounding, 0, 0x3f, 80 }
    102104#else
    103105# undef  VBOX_WITHOUT_SOFTFLOAT_GLOBALS
  • trunk/src/libs/softfloat-3e/source/s_roundPackToExtF80.c

    r94564 r94606  
    4040#include "internals.h"
    4141#include "softfloat.h"
     42#include <iprt/types.h> /* VBox: RTFLOAT80U_EXP_BIAS_UNDERFLOW_ADJUST */
     43//#include <iprt/assert.h>
    4244
    4345extFloat80_t
     
    5759    struct uint64_extra sig64Extra;
    5860    union { struct extFloat80M s; extFloat80_t f; } uZ;
     61    //RTAssertMsg2("softfloat_roundPackToExtF80: exp=%d sig=%RX64 sigExtra=%RX64 rp=%d\n", exp, sig, sigExtra, roundingPrecision);
    5962
    6063    /*------------------------------------------------------------------------
     
    8790            /*----------------------------------------------------------------
    8891            *----------------------------------------------------------------*/
     92            bool fUnmaskedUnderflow = false;                                                /* VBox: unmasked underflow bias */
    8993            isTiny =
    9094                   (softfloat_detectTininess
     
    9296                || (exp < 0)
    9397                || (sig <= (uint64_t) (sig + roundIncrement));
    94             sig = softfloat_shiftRightJam64( sig, 1 - exp );
     98            if (    (pState->exceptionMask & softfloat_flag_underflow)                      /* VBox: unmasked underflow bias */
     99                 || (exp == -63 && sig == 0 && sigExtra == 0) /* zero */ ) {                /* VBox: unmasked underflow bias */
     100                sig = softfloat_shiftRightJam64(sig, 1 - exp);
     101            } else {                                                                        /* VBox: unmasked underflow bias */
     102                //RTAssertMsg2("softfloat_roundPackToExtF80: #UE - bias adj: %d -> %d; sig=%#RX64\n", exp, exp + RTFLOAT80U_EXP_BIAS_UNDERFLOW_ADJUST, sig); /* VBox: unmasked underflow bias */
     103                softfloat_raiseFlags( softfloat_flag_underflow SOFTFLOAT_STATE_ARG_COMMA ); /* VBox: unmasked underflow bias */
     104                exp += RTFLOAT80U_EXP_BIAS_UNDERFLOW_ADJUST;                                /* VBox: unmasked underflow bias */
     105                fUnmaskedUnderflow = true;                                                  /* VBox: unmasked underflow bias */
     106            }                                                                               /* VBox: unmasked underflow bias */
     107            uint64_t const uOldSig = sig; /* VBox */
    95108            roundBits = sig & roundMask;
    96109            if ( roundBits ) {
    97110                if ( isTiny ) softfloat_raiseFlags( softfloat_flag_underflow SOFTFLOAT_STATE_ARG_COMMA );
    98111                softfloat_exceptionFlags |= softfloat_flag_inexact;
    99                 if ( roundIncrement ) softfloat_exceptionFlags |= softfloat_flag_c1; /* VBox */
    100112#ifdef SOFTFLOAT_ROUND_ODD
    101113                if ( roundingMode == softfloat_round_odd ) {
     
    105117            }
    106118            sig += roundIncrement;
    107             exp = ((sig & UINT64_C( 0x8000000000000000 )) != 0);
     119            if ( !fUnmaskedUnderflow ) {                                /* VBox: unmasked underflow bias */
     120                exp = ((sig & UINT64_C( 0x8000000000000000 )) != 0);
     121            }                                                           /* VBox: unmasked underflow bias */
    108122            roundIncrement = roundMask + 1;
    109123            if ( roundNearEven && (roundBits<<1 == roundIncrement) ) {
     
    111125            }
    112126            sig &= ~roundMask;
     127            if ( sig > uOldSig ) {                                      /* VBox: C1 */
     128                softfloat_exceptionFlags |= softfloat_flag_c1;          /* VBox: C1 */
     129                //RTAssertMsg2("softfloat_roundPackToExtF80: C1 #1\n"); /* VBox: C1 */
     130            }                                                           /* VBox: C1 */
    113131            goto packReturn;
    114132        }
     
    122140    /*------------------------------------------------------------------------
    123141    *------------------------------------------------------------------------*/
    124     { /* VBox*/
    125     uint64_t const uOldSig = sig; /* VBox */
     142    {                                                                   /* VBox: C1 */
     143    uint64_t const uOldSig = sig;                                       /* VBox: C1 */
    126144    if ( roundBits ) {
    127145        softfloat_exceptionFlags |= softfloat_flag_inexact;
     
    129147        if ( roundingMode == softfloat_round_odd ) {
    130148            sig = (sig & ~roundMask) | (roundMask + 1);
    131             if ( sig > uOldSig ) softfloat_exceptionFlags |= softfloat_flag_c1; /* VBox */
     149            if ( sig > uOldSig ) {                                      /* VBox: C1 */
     150                softfloat_exceptionFlags |= softfloat_flag_c1;          /* VBox: C1 */
     151                //RTAssertMsg2("softfloat_roundPackToExtF80: C1 #2\n"); /* VBox: C1 */
     152            }                                                           /* VBox: C1 */
    132153            goto packReturn;
    133154        }
     
    138159        ++exp;
    139160        sig = UINT64_C( 0x8000000000000000 );
    140         softfloat_exceptionFlags |= softfloat_flag_c1; /* VBox */
     161        softfloat_exceptionFlags |= softfloat_flag_c1;                  /* VBox: C1 */
     162        //RTAssertMsg2("softfloat_roundPackToExtF80: C1 #3\n");         /* VBox: C1 */
    141163    }
    142164    roundIncrement = roundMask + 1;
     
    145167    }
    146168    sig &= ~roundMask;
    147     if ( sig > uOldSig ) softfloat_exceptionFlags |= softfloat_flag_c1; /* VBox */
     169    if ( sig > uOldSig ) {                                              /* VBox: C1 */
     170        softfloat_exceptionFlags |= softfloat_flag_c1;                  /* VBox: C1 */
     171        //RTAssertMsg2("softfloat_roundPackToExtF80: C1 #4\n");         /* VBox: C1 */
     172    }                                                                   /* VBox: C1 */
    148173    goto packReturn;
    149     } /* VBox */
     174    }                                                                   /* VBox: C1 */
    150175    /*------------------------------------------------------------------------
    151176    *------------------------------------------------------------------------*/
     
    164189            /*----------------------------------------------------------------
    165190            *----------------------------------------------------------------*/
     191            bool fUnmaskedUnderflow = false;                                                /* VBox: unmasked underflow bias */
    166192            isTiny =
    167193                   (softfloat_detectTininess
     
    170196                || ! doIncrement
    171197                || (sig < UINT64_C( 0xFFFFFFFFFFFFFFFF ));
    172             sig64Extra =
    173                 softfloat_shiftRightJam64Extra( sig, sigExtra, 1 - exp );
    174             exp = 0;
    175             sig = sig64Extra.v;
    176             sigExtra = sig64Extra.extra;
     198            if (    (pState->exceptionMask & softfloat_flag_underflow)                      /* VBox: unmasked underflow bias */
     199                 || (exp == -63 && sig == 0 && sigExtra == 0) /* zero */ ) {                /* VBox: unmasked underflow bias */
     200                sig64Extra =
     201                    softfloat_shiftRightJam64Extra( sig, sigExtra, 1 - exp );
     202                exp = 0;
     203                sig = sig64Extra.v;
     204                sigExtra = sig64Extra.extra;
     205            } else {                                                                        /* VBox: unmasked underflow bias */
     206                //RTAssertMsg2("softfloat_roundPackToExtF80: #UE/80 - bias adj: %d -> %d; sig=%#RX64'%016RX64\n", exp, exp + RTFLOAT80U_EXP_BIAS_UNDERFLOW_ADJUST, sig, sigExtra); /* VBox: unmasked underflow bias */
     207                softfloat_raiseFlags( softfloat_flag_underflow SOFTFLOAT_STATE_ARG_COMMA ); /* VBox: unmasked underflow bias */
     208                exp += RTFLOAT80U_EXP_BIAS_UNDERFLOW_ADJUST;                                /* VBox: unmasked underflow bias */
     209                fUnmaskedUnderflow = true;                                                  /* VBox: unmasked underflow bias */
     210            }                                                                               /* VBox: unmasked underflow bias */
    177211            if ( sigExtra ) {
    178212                if ( isTiny ) softfloat_raiseFlags( softfloat_flag_underflow SOFTFLOAT_STATE_ARG_COMMA );
     
    195229            }
    196230            if ( doIncrement ) {
    197                 softfloat_exceptionFlags |= softfloat_flag_c1; /* VBox */
     231                softfloat_exceptionFlags |= softfloat_flag_c1;              /* VBox: C1 */
     232                //RTAssertMsg2("softfloat_roundPackToExtF80: C1 #5\n");     /* VBox: C1 */
    198233                ++sig;
    199234                sig &=
     
    201236                         (! (sigExtra & UINT64_C( 0x7FFFFFFFFFFFFFFF ))
    202237                              & roundNearEven);
    203                 exp = ((sig & UINT64_C( 0x8000000000000000 )) != 0);
     238                if ( fUnmaskedUnderflow ) {                                 /* VBox: unmasked underflow bias */
     239                    exp = ((sig & UINT64_C( 0x8000000000000000 )) != 0);
     240                } else if ((sig & UINT64_C( 0x8000000000000000 )) != 0) {   /* VBox: unmasked underflow bias */
     241                    exp++;                                                  /* VBox: unmasked underflow bias */
     242                }                                                           /* VBox: unmasked underflow bias */
    204243            }
    205244            goto packReturn;
     
    225264                exp = 0x7FFF;
    226265                sig = UINT64_C( 0x8000000000000000 );
     266                softfloat_exceptionFlags |= softfloat_flag_c1; /* VBox: C1 - Returning infinity means we've rounded up. */
     267                //RTAssertMsg2("softfloat_roundPackToExtF80: C1 #6\n");
     268
     269                /* VBox: HACK ALERT! Some utterly weird behaviour, found with 'fadd 0,max', precision < 64 and rounding away from 0. */
     270                if ( !(pState->exceptionMask & softfloat_flag_overflow) ) /* VBox */
     271                    exp = 8191; /* => -8192 */                            /* VBox */
    227272            } else {
    228273                exp = 0x7FFE;
     
    249294            ++exp;
    250295            sig = UINT64_C( 0x8000000000000000 );
    251             softfloat_exceptionFlags |= softfloat_flag_c1; /* VBox */
     296            softfloat_exceptionFlags |= softfloat_flag_c1;              /* VBox: C1 */
     297            //RTAssertMsg2("softfloat_roundPackToExtF80: C1 #7\n");     /* VBox: C1 */
    252298        } else {
    253299            sig &=
     
    255301                     (! (sigExtra & UINT64_C( 0x7FFFFFFFFFFFFFFF ))
    256302                          & roundNearEven);
    257             if ( sig > uOldSig ) softfloat_exceptionFlags |= softfloat_flag_c1; /* VBox */
     303            if ( sig > uOldSig ) {                                      /* VBox: C1 */
     304                softfloat_exceptionFlags |= softfloat_flag_c1;          /* VBox: C1 */
     305                //RTAssertMsg2("softfloat_roundPackToExtF80: C1 #8\n"); /* VBox: C1 */
     306            }
    258307        }
    259308    }
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