diff options
Diffstat (limited to 'source/extF80M_to_i64_r_minMag.c')
-rw-r--r-- | source/extF80M_to_i64_r_minMag.c | 114 |
1 files changed, 114 insertions, 0 deletions
diff --git a/source/extF80M_to_i64_r_minMag.c b/source/extF80M_to_i64_r_minMag.c new file mode 100644 index 0000000..04b5014 --- /dev/null +++ b/source/extF80M_to_i64_r_minMag.c @@ -0,0 +1,114 @@ + +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014 The Regents of the University of California +(Regents). All Rights Reserved. Redistribution and use in source and binary +forms, with or without modification, are permitted provided that the following +conditions are met: + +Redistributions of source code must retain the above copyright notice, +this list of conditions, and the following two paragraphs of disclaimer. +Redistributions in binary form must reproduce the above copyright notice, +this list of conditions, and the following two paragraphs of disclaimer in the +documentation and/or other materials provided with the distribution. Neither +the name of the Regents nor the names of its contributors may be used to +endorse or promote products derived from this software without specific prior +written permission. + +IN NO EVENT SHALL REGENTS BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, +SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING LOST PROFITS, ARISING +OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF REGENTS HAS +BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +REGENTS SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT LIMITED +TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE SOFTWARE AND ACCOMPANYING DOCUMENTATION, IF ANY, PROVIDED +HEREUNDER IS PROVIDED "AS IS". REGENTS HAS NO OBLIGATION TO PROVIDE +MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +=============================================================================*/ + +#include <stdbool.h> +#include <stdint.h> +#include "platform.h" +#include "internals.h" +#include "softfloat.h" + +#ifdef SOFTFLOAT_FAST_INT64 + +int_fast64_t extF80M_to_i64_r_minMag( const extFloat80_t *aPtr, bool exact ) +{ + + return extF80_to_i64_r_minMag( *aPtr, exact ); + +} + +#else + +int_fast64_t extF80M_to_i64_r_minMag( const extFloat80_t *aPtr, bool exact ) +{ + const struct extFloat80M *aSPtr; + uint_fast16_t uiA64; + int32_t exp; + uint64_t sig; + int32_t shiftCount; + bool raiseInexact; + int64_t z; + uint64_t absZ; + union { uint64_t ui; int64_t i; } u; + + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + aSPtr = (const struct extFloat80M *) aPtr; + uiA64 = aSPtr->signExp; + exp = expExtF80UI64( uiA64 ); + sig = aSPtr->signif; + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + if ( ! sig && (exp != 0x7FFF) ) return 0; + shiftCount = 0x403E - exp; + if ( 64 <= shiftCount ) { + raiseInexact = exact; + z = 0; + } else { + raiseInexact = false; + if ( shiftCount < 0 ) { + if ( shiftCount <= -63 ) goto invalid; + shiftCount = -shiftCount; + absZ = sig<<shiftCount; + if ( absZ>>shiftCount != sig ) goto invalid; + } else { + absZ = sig; + if ( shiftCount ) absZ >>= shiftCount; + if ( exact && shiftCount ) { + raiseInexact = (absZ<<shiftCount != sig); + } + } + if ( signExtF80UI64( uiA64 ) ) { + if ( UINT64_C( 0x8000000000000000 ) < absZ ) goto invalid; + u.ui = -absZ; + z = u.i; + } else { + if ( UINT64_C( 0x8000000000000000 ) <= absZ ) goto invalid; + z = absZ; + } + } + if ( raiseInexact ) softfloat_exceptionFlags |= softfloat_flag_inexact; + return z; + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + invalid: + softfloat_raiseFlags( softfloat_flag_invalid ); + return + ! signExtF80UI64( uiA64 ) + || ((exp == 0x7FFF) && (sig & UINT64_C( 0x7FFFFFFFFFFFFFFF ))) + ? UINT64_C( 0x7FFFFFFFFFFFFFFF ) + : -UINT64_C( 0x7FFFFFFFFFFFFFFF ) - 1; + +} + +#endif + |