github.com/igggame/nebulas-go@v2.1.0+incompatible/nbre/3rd_party/SoftFloat-3e/source/f128M_roundToInt.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, 2017 The Regents of the University of
     8  California.  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_roundToInt(
    48       const float128_t *aPtr,
    49       uint_fast8_t roundingMode,
    50       bool exact,
    51       float128_t *zPtr
    52   )
    53  {
    54  
    55      *zPtr = f128_roundToInt( *aPtr, roundingMode, exact );
    56  
    57  }
    58  
    59  #else
    60  
    61  void
    62   f128M_roundToInt(
    63       const float128_t *aPtr,
    64       uint_fast8_t roundingMode,
    65       bool exact,
    66       float128_t *zPtr
    67   )
    68  {
    69      const uint32_t *aWPtr;
    70      uint32_t *zWPtr;
    71      uint32_t ui96;
    72      int32_t exp;
    73      uint32_t sigExtra;
    74      bool sign;
    75      uint_fast8_t bitPos;
    76      bool roundNear;
    77      unsigned int index, lastIndex;
    78      bool extra;
    79      uint32_t wordA, bit, wordZ;
    80      uint_fast8_t carry;
    81      uint32_t extrasMask;
    82  
    83      /*------------------------------------------------------------------------
    84      *------------------------------------------------------------------------*/
    85      aWPtr = (const uint32_t *) aPtr;
    86      zWPtr = (uint32_t *) zPtr;
    87      /*------------------------------------------------------------------------
    88      *------------------------------------------------------------------------*/
    89      ui96 = aWPtr[indexWordHi( 4 )];
    90      exp = expF128UI96( ui96 );
    91      /*------------------------------------------------------------------------
    92      *------------------------------------------------------------------------*/
    93      if ( exp < 0x3FFF ) {
    94          zWPtr[indexWord( 4, 2 )] = 0;
    95          zWPtr[indexWord( 4, 1 )] = 0;
    96          zWPtr[indexWord( 4, 0 )] = 0;
    97          sigExtra = aWPtr[indexWord( 4, 2 )];
    98          if ( !sigExtra ) {
    99              sigExtra = aWPtr[indexWord( 4, 1 )] | aWPtr[indexWord( 4, 0 )];
   100          }
   101          if ( !sigExtra && !(ui96 & 0x7FFFFFFF) ) goto ui96;
   102          if ( exact ) softfloat_exceptionFlags |= softfloat_flag_inexact;
   103          sign = signF128UI96( ui96 );
   104          switch ( roundingMode ) {
   105           case softfloat_round_near_even:
   106              if ( !fracF128UI96( ui96 ) && !sigExtra ) break;
   107           case softfloat_round_near_maxMag:
   108              if ( exp == 0x3FFE ) goto mag1;
   109              break;
   110           case softfloat_round_min:
   111              if ( sign ) goto mag1;
   112              break;
   113           case softfloat_round_max:
   114              if ( !sign ) goto mag1;
   115              break;
   116  #ifdef SOFTFLOAT_ROUND_ODD
   117           case softfloat_round_odd:
   118              goto mag1;
   119  #endif
   120          }
   121          ui96 = packToF128UI96( sign, 0, 0 );
   122          goto ui96;
   123       mag1:
   124          ui96 = packToF128UI96( sign, 0x3FFF, 0 );
   125          goto ui96;
   126      }
   127      /*------------------------------------------------------------------------
   128      *------------------------------------------------------------------------*/
   129      if ( 0x406F <= exp ) {
   130          if (
   131              (exp == 0x7FFF)
   132                  && (fracF128UI96( ui96 )
   133                          || (aWPtr[indexWord( 4, 2 )] | aWPtr[indexWord( 4, 1 )]
   134                                  | aWPtr[indexWord( 4, 0 )]))
   135          ) {
   136              softfloat_propagateNaNF128M( aWPtr, 0, zWPtr );
   137              return;
   138          }
   139          zWPtr[indexWord( 4, 2 )] = aWPtr[indexWord( 4, 2 )];
   140          zWPtr[indexWord( 4, 1 )] = aWPtr[indexWord( 4, 1 )];
   141          zWPtr[indexWord( 4, 0 )] = aWPtr[indexWord( 4, 0 )];
   142          goto ui96;
   143      }
   144      /*------------------------------------------------------------------------
   145      *------------------------------------------------------------------------*/
   146      bitPos = 0x406F - exp;
   147      roundNear =
   148             (roundingMode == softfloat_round_near_maxMag)
   149          || (roundingMode == softfloat_round_near_even);
   150      bitPos -= roundNear;
   151      index = indexWordLo( 4 );
   152      lastIndex = indexWordHi( 4 );
   153      extra = 0;
   154      for (;;) {
   155          wordA = aWPtr[index];
   156          if ( bitPos < 32 ) break;
   157          if ( wordA ) extra = 1;
   158          zWPtr[index] = 0;
   159          index += wordIncr;
   160          bitPos -= 32;
   161      }
   162      bit = (uint32_t) 1<<bitPos;
   163      if ( roundNear ) {
   164          wordZ = wordA + bit;
   165          carry = (wordZ < wordA);
   166          bit <<= 1;
   167          extrasMask = bit - 1;
   168          if ( exact && (extra || (wordA & extrasMask)) ) {
   169              softfloat_exceptionFlags |= softfloat_flag_inexact;
   170          }
   171          if (
   172              (roundingMode == softfloat_round_near_even)
   173                  && !extra && !(wordZ & extrasMask)
   174          ) {
   175              if ( !bit ) {
   176                  zWPtr[index] = wordZ;
   177                  index += wordIncr;
   178                  wordZ = aWPtr[index] + carry;
   179                  carry &= !wordZ;
   180                  zWPtr[index] = wordZ & ~1;
   181                  goto propagateCarry;
   182              }
   183              wordZ &= ~bit;
   184          }
   185      } else {
   186          wordZ = wordA;
   187          carry = 0;
   188          extrasMask = bit - 1;
   189          if ( extra || (wordA & extrasMask) ) {
   190              if ( exact ) softfloat_exceptionFlags |= softfloat_flag_inexact;
   191              if (
   192                  roundingMode
   193                      == (signF128UI96( ui96 ) ? softfloat_round_min
   194                              : softfloat_round_max)
   195              ) {
   196                  wordZ += bit;
   197                  carry = (wordZ < wordA);
   198  #ifdef SOFTFLOAT_ROUND_ODD
   199              } else if ( roundingMode == softfloat_round_odd ) {
   200                  wordZ |= bit;
   201  #endif
   202              }
   203          }
   204      }
   205      wordZ &= ~extrasMask;
   206      zWPtr[index] = wordZ;
   207   propagateCarry:
   208      while ( index != lastIndex ) {
   209          index += wordIncr;
   210          wordZ = aWPtr[index] + carry;
   211          zWPtr[index] = wordZ;
   212          carry &= !wordZ;
   213      }
   214      return;
   215      /*------------------------------------------------------------------------
   216      *------------------------------------------------------------------------*/
   217   ui96:
   218      zWPtr[indexWordHi( 4 )] = ui96;
   219  
   220  }
   221  
   222  #endif
   223