github.com/igggame/nebulas-go@v2.1.0+incompatible/nbre/3rd_party/SoftFloat-3e/source/f128M_rem.c (about)

     1  
     2  /*============================================================================
     3  
     4  This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
     5  Package, Release 3e, by John R. Hauser.
     6  
     7  Copyright 2011, 2012, 2013, 2014 The Regents of the University of California.
     8  All rights reserved.
     9  
    10  Redistribution and use in source and binary forms, with or without
    11  modification, are permitted provided that the following conditions are met:
    12  
    13   1. Redistributions of source code must retain the above copyright notice,
    14      this list of conditions, and the following disclaimer.
    15  
    16   2. Redistributions in binary form must reproduce the above copyright notice,
    17      this list of conditions, and the following disclaimer in the documentation
    18      and/or other materials provided with the distribution.
    19  
    20   3. Neither the name of the University nor the names of its contributors may
    21      be used to endorse or promote products derived from this software without
    22      specific prior written permission.
    23  
    24  THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY
    25  EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
    26  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE
    27  DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
    28  DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
    29  (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
    30  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
    31  ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
    32  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
    33  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    34  
    35  =============================================================================*/
    36  
    37  #include <stdbool.h>
    38  #include <stdint.h>
    39  #include "platform.h"
    40  #include "internals.h"
    41  #include "specialize.h"
    42  #include "softfloat.h"
    43  
    44  #ifdef SOFTFLOAT_FAST_INT64
    45  
    46  void
    47   f128M_rem( const float128_t *aPtr, const float128_t *bPtr, float128_t *zPtr )
    48  {
    49  
    50      *zPtr = f128_rem( *aPtr, *bPtr );
    51  
    52  }
    53  
    54  #else
    55  
    56  void
    57   f128M_rem( const float128_t *aPtr, const float128_t *bPtr, float128_t *zPtr )
    58  {
    59      const uint32_t *aWPtr, *bWPtr;
    60      uint32_t *zWPtr, uiA96;
    61      int32_t expA, expB;
    62      uint32_t x[4], rem1[5], *remPtr;
    63      bool signRem;
    64      int32_t expDiff;
    65      uint32_t q, recip32;
    66      uint64_t q64;
    67      uint32_t rem2[5], *altRemPtr, *newRemPtr, wordMeanRem;
    68  
    69      /*------------------------------------------------------------------------
    70      *------------------------------------------------------------------------*/
    71      aWPtr = (const uint32_t *) aPtr;
    72      bWPtr = (const uint32_t *) bPtr;
    73      zWPtr = (uint32_t *) zPtr;
    74      /*------------------------------------------------------------------------
    75      *------------------------------------------------------------------------*/
    76      uiA96 = aWPtr[indexWordHi( 4 )];
    77      expA = expF128UI96( uiA96 );
    78      expB = expF128UI96( bWPtr[indexWordHi( 4 )] );
    79      /*------------------------------------------------------------------------
    80      *------------------------------------------------------------------------*/
    81      if ( (expA == 0x7FFF) || (expB == 0x7FFF) ) {
    82          if ( softfloat_tryPropagateNaNF128M( aWPtr, bWPtr, zWPtr ) ) return;
    83          if ( expA == 0x7FFF ) goto invalid;
    84          goto copyA;
    85      }
    86      /*------------------------------------------------------------------------
    87      *------------------------------------------------------------------------*/
    88      if ( expA < expB - 1 ) goto copyA;
    89      /*------------------------------------------------------------------------
    90      *------------------------------------------------------------------------*/
    91      expB = softfloat_shiftNormSigF128M( bWPtr, 13, x );
    92      if ( expB == -128 ) goto invalid;
    93      remPtr = &rem1[indexMultiwordLo( 5, 4 )];
    94      expA = softfloat_shiftNormSigF128M( aWPtr, 13, remPtr );
    95      if ( expA == -128 ) goto copyA;
    96      signRem = signF128UI96( uiA96 );
    97      /*------------------------------------------------------------------------
    98      *------------------------------------------------------------------------*/
    99      expDiff = expA - expB;
   100      if ( expDiff < 1 ) {
   101          if ( expDiff < -1 ) goto copyA;
   102          if ( expDiff ) {
   103              --expB;
   104              softfloat_add128M( x, x, x );
   105              q = 0;
   106          } else {
   107              q = (softfloat_compare128M( x, remPtr ) <= 0);
   108              if ( q ) softfloat_sub128M( remPtr, x, remPtr );
   109          }
   110      } else {
   111          recip32 =
   112              softfloat_approxRecip32_1(
   113                  ((uint64_t) x[indexWord( 4, 3 )]<<32 | x[indexWord( 4, 2 )])
   114                      >>30
   115              );
   116          expDiff -= 30;
   117          for (;;) {
   118              q64 = (uint64_t) remPtr[indexWordHi( 4 )] * recip32;
   119              if ( expDiff < 0 ) break;
   120              q = (q64 + 0x80000000)>>32;
   121              softfloat_remStep128MBy32( remPtr, 29, x, q, remPtr );
   122              if ( remPtr[indexWordHi( 4 )] & 0x80000000 ) {
   123                  softfloat_add128M( remPtr, x, remPtr );
   124              }
   125              expDiff -= 29;
   126          }
   127          /*--------------------------------------------------------------------
   128          | (`expDiff' cannot be less than -29 here.)
   129          *--------------------------------------------------------------------*/
   130          q = (uint32_t) (q64>>32)>>(~expDiff & 31);
   131          softfloat_remStep128MBy32( remPtr, expDiff + 30, x, q, remPtr );
   132          if ( remPtr[indexWordHi( 4 )] & 0x80000000 ) {
   133              altRemPtr = &rem2[indexMultiwordLo( 5, 4 )];
   134              softfloat_add128M( remPtr, x, altRemPtr );
   135              goto selectRem;
   136          }
   137      }
   138      /*------------------------------------------------------------------------
   139      *------------------------------------------------------------------------*/
   140      altRemPtr = &rem2[indexMultiwordLo( 5, 4 )];
   141      do {
   142          ++q;
   143          newRemPtr = altRemPtr;
   144          softfloat_sub128M( remPtr, x, newRemPtr );
   145          altRemPtr = remPtr;
   146          remPtr = newRemPtr;
   147      } while ( ! (remPtr[indexWordHi( 4 )] & 0x80000000) );
   148   selectRem:
   149      softfloat_add128M( remPtr, altRemPtr, x );
   150      wordMeanRem = x[indexWordHi( 4 )];
   151      if (
   152          (wordMeanRem & 0x80000000)
   153              || (! wordMeanRem && (q & 1) && ! x[indexWord( 4, 0 )]
   154                      && ! (x[indexWord( 4, 2 )] | x[indexWord( 4, 1 )]))
   155      ) {
   156          remPtr = altRemPtr;
   157      }
   158      if ( remPtr[indexWordHi( 4 )] & 0x80000000 ) {
   159          signRem = ! signRem;
   160          softfloat_negX128M( remPtr );
   161      }
   162      remPtr -= indexMultiwordLo( 5, 4 );
   163      remPtr[indexWordHi( 5 )] = 0;
   164      softfloat_normRoundPackMToF128M( signRem, expB + 18, remPtr, zWPtr );
   165      return;
   166      /*------------------------------------------------------------------------
   167      *------------------------------------------------------------------------*/
   168   invalid:
   169      softfloat_invalidF128M( zWPtr );
   170      return;
   171      /*------------------------------------------------------------------------
   172      *------------------------------------------------------------------------*/
   173   copyA:
   174      zWPtr[indexWordHi( 4 )] = uiA96;
   175      zWPtr[indexWord( 4, 2 )] = aWPtr[indexWord( 4, 2 )];
   176      zWPtr[indexWord( 4, 1 )] = aWPtr[indexWord( 4, 1 )];
   177      zWPtr[indexWord( 4, 0 )] = aWPtr[indexWord( 4, 0 )];
   178  
   179  }
   180  
   181  #endif
   182