/*
* QEMU float support
*
- * Derived from SoftFloat.
+ * The code in this source file is derived from release 2a of the SoftFloat
+ * IEC/IEEE Floating-point Arithmetic Package. Those parts of the code (and
+ * some later contributions) are provided under that license, as detailed below.
+ * It has subsequently been modified by contributors to the QEMU Project,
+ * so some portions are provided under:
+ * the SoftFloat-2a license
+ * the BSD license
+ * GPL-v2-or-later
+ *
+ * Any future contributions to this file after December 1st 2014 will be
+ * taken to be licensed under the Softfloat-2a license unless specifically
+ * indicated otherwise.
*/
-/*============================================================================
-
+/*
+===============================================================================
This C source fragment is part of the SoftFloat IEC/IEEE Floating-point
-Arithmetic Package, Release 2b.
+Arithmetic Package, Release 2a.
Written by John R. Hauser. This work was made possible in part by the
International Computer Science Institute, located at Suite 600, 1947 Center
of this code was written as part of a project to build a fixed-point vector
processor in collaboration with the University of California at Berkeley,
overseen by Profs. Nelson Morgan and John Wawrzynek. More information
-is available through the Web page `http://www.cs.berkeley.edu/~jhauser/
+is available through the Web page `http://HTTP.CS.Berkeley.EDU/~jhauser/
arithmetic/SoftFloat.html'.
-THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE. Although reasonable effort has
-been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT TIMES
-RESULT IN INCORRECT BEHAVIOR. USE OF THIS SOFTWARE IS RESTRICTED TO PERSONS
-AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ALL LOSSES,
-COSTS, OR OTHER PROBLEMS THEY INCUR DUE TO THE SOFTWARE, AND WHO FURTHERMORE
-EFFECTIVELY INDEMNIFY JOHN HAUSER AND THE INTERNATIONAL COMPUTER SCIENCE
-INSTITUTE (possibly via similar legal warning) AGAINST ALL LOSSES, COSTS, OR
-OTHER PROBLEMS INCURRED BY THEIR CUSTOMERS AND CLIENTS DUE TO THE SOFTWARE.
+THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE. Although reasonable effort
+has been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT
+TIMES RESULT IN INCORRECT BEHAVIOR. USE OF THIS SOFTWARE IS RESTRICTED TO
+PERSONS AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ANY
+AND ALL LOSSES, COSTS, OR OTHER PROBLEMS ARISING FROM ITS USE.
Derivative works are acceptable, even for commercial purposes, so long as
-(1) the source code for the derivative work includes prominent notice that
-the work is derivative, and (2) the source code includes prominent notice with
-these four paragraphs for those parts of this code that are retained.
+(1) they include prominent notice that the work is derivative, and (2) they
+include prominent notice akin to these four paragraphs for those parts of
+this code that are retained.
-=============================================================================*/
+===============================================================================
+*/
-#if defined(TARGET_MIPS) || defined(TARGET_SH4) || defined(TARGET_UNICORE32)
-#define SNAN_BIT_IS_ONE 1
-#else
-#define SNAN_BIT_IS_ONE 0
-#endif
+/* BSD licensing:
+ * Copyright (c) 2006, Fabrice Bellard
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its contributors
+ * may be used to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/* Portions of this work are licensed under the terms of the GNU GPL,
+ * version 2 or later. See the COPYING file in the top-level directory.
+ */
#if defined(TARGET_XTENSA)
/* Define for architectures which deviate from IEEE in not supporting
/*----------------------------------------------------------------------------
| The pattern for a default generated half-precision NaN.
*----------------------------------------------------------------------------*/
+float16 float16_default_nan(float_status *status)
+{
#if defined(TARGET_ARM)
-const float16 float16_default_nan = const_float16(0x7E00);
-#elif SNAN_BIT_IS_ONE
-const float16 float16_default_nan = const_float16(0x7DFF);
+ return const_float16(0x7E00);
+#else
+ if (status->snan_bit_is_one) {
+ return const_float16(0x7DFF);
+ } else {
+#if defined(TARGET_MIPS)
+ return const_float16(0x7E00);
#else
-const float16 float16_default_nan = const_float16(0xFE00);
+ return const_float16(0xFE00);
+#endif
+ }
#endif
+}
/*----------------------------------------------------------------------------
| The pattern for a default generated single-precision NaN.
*----------------------------------------------------------------------------*/
+float32 float32_default_nan(float_status *status)
+{
#if defined(TARGET_SPARC)
-const float32 float32_default_nan = const_float32(0x7FFFFFFF);
+ return const_float32(0x7FFFFFFF);
#elif defined(TARGET_PPC) || defined(TARGET_ARM) || defined(TARGET_ALPHA) || \
- defined(TARGET_XTENSA)
-const float32 float32_default_nan = const_float32(0x7FC00000);
-#elif SNAN_BIT_IS_ONE
-const float32 float32_default_nan = const_float32(0x7FBFFFFF);
+ defined(TARGET_XTENSA) || defined(TARGET_S390X) || defined(TARGET_TRICORE)
+ return const_float32(0x7FC00000);
+#elif defined(TARGET_HPPA)
+ return const_float32(0x7FA00000);
+#else
+ if (status->snan_bit_is_one) {
+ return const_float32(0x7FBFFFFF);
+ } else {
+#if defined(TARGET_MIPS)
+ return const_float32(0x7FC00000);
#else
-const float32 float32_default_nan = const_float32(0xFFC00000);
+ return const_float32(0xFFC00000);
#endif
+ }
+#endif
+}
/*----------------------------------------------------------------------------
| The pattern for a default generated double-precision NaN.
*----------------------------------------------------------------------------*/
+float64 float64_default_nan(float_status *status)
+{
#if defined(TARGET_SPARC)
-const float64 float64_default_nan = const_float64(LIT64( 0x7FFFFFFFFFFFFFFF ));
-#elif defined(TARGET_PPC) || defined(TARGET_ARM) || defined(TARGET_ALPHA)
-const float64 float64_default_nan = const_float64(LIT64( 0x7FF8000000000000 ));
-#elif SNAN_BIT_IS_ONE
-const float64 float64_default_nan = const_float64(LIT64( 0x7FF7FFFFFFFFFFFF ));
+ return const_float64(LIT64(0x7FFFFFFFFFFFFFFF));
+#elif defined(TARGET_PPC) || defined(TARGET_ARM) || defined(TARGET_ALPHA) || \
+ defined(TARGET_S390X)
+ return const_float64(LIT64(0x7FF8000000000000));
+#elif defined(TARGET_HPPA)
+ return const_float64(LIT64(0x7FF4000000000000));
+#else
+ if (status->snan_bit_is_one) {
+ return const_float64(LIT64(0x7FF7FFFFFFFFFFFF));
+ } else {
+#if defined(TARGET_MIPS)
+ return const_float64(LIT64(0x7FF8000000000000));
#else
-const float64 float64_default_nan = const_float64(LIT64( 0xFFF8000000000000 ));
+ return const_float64(LIT64(0xFFF8000000000000));
+#endif
+ }
#endif
+}
/*----------------------------------------------------------------------------
| The pattern for a default generated extended double-precision NaN.
*----------------------------------------------------------------------------*/
-#if SNAN_BIT_IS_ONE
-#define floatx80_default_nan_high 0x7FFF
-#define floatx80_default_nan_low LIT64( 0xBFFFFFFFFFFFFFFF )
-#else
-#define floatx80_default_nan_high 0xFFFF
-#define floatx80_default_nan_low LIT64( 0xC000000000000000 )
-#endif
+floatx80 floatx80_default_nan(float_status *status)
+{
+ floatx80 r;
-const floatx80 floatx80_default_nan
- = make_floatx80_init(floatx80_default_nan_high, floatx80_default_nan_low);
+ if (status->snan_bit_is_one) {
+ r.low = LIT64(0xBFFFFFFFFFFFFFFF);
+ r.high = 0x7FFF;
+ } else {
+ r.low = LIT64(0xC000000000000000);
+ r.high = 0xFFFF;
+ }
+ return r;
+}
/*----------------------------------------------------------------------------
-| The pattern for a default generated quadruple-precision NaN. The `high' and
-| `low' values hold the most- and least-significant bits, respectively.
+| The pattern for a default generated quadruple-precision NaN.
*----------------------------------------------------------------------------*/
-#if SNAN_BIT_IS_ONE
-#define float128_default_nan_high LIT64( 0x7FFF7FFFFFFFFFFF )
-#define float128_default_nan_low LIT64( 0xFFFFFFFFFFFFFFFF )
+float128 float128_default_nan(float_status *status)
+{
+ float128 r;
+
+ if (status->snan_bit_is_one) {
+ r.low = LIT64(0xFFFFFFFFFFFFFFFF);
+ r.high = LIT64(0x7FFF7FFFFFFFFFFF);
+ } else {
+ r.low = LIT64(0x0000000000000000);
+#if defined(TARGET_S390X) || defined(TARGET_PPC)
+ r.high = LIT64(0x7FFF800000000000);
#else
-#define float128_default_nan_high LIT64( 0xFFFF800000000000 )
-#define float128_default_nan_low LIT64( 0x0000000000000000 )
+ r.high = LIT64(0xFFFF800000000000);
#endif
-
-const float128 float128_default_nan
- = make_float128_init(float128_default_nan_high, float128_default_nan_low);
+ }
+ return r;
+}
/*----------------------------------------------------------------------------
| Raises the exceptions specified by `flags'. Floating-point traps can be
| should be simply `float_exception_flags |= flags;'.
*----------------------------------------------------------------------------*/
-void float_raise( int8 flags STATUS_PARAM )
+void float_raise(uint8_t flags, float_status *status)
{
- STATUS(float_exception_flags) |= flags;
+ status->float_exception_flags |= flags;
}
/*----------------------------------------------------------------------------
} commonNaNT;
#ifdef NO_SIGNALING_NANS
-int float16_is_quiet_nan(float16 a_)
+int float16_is_quiet_nan(float16 a_, float_status *status)
{
return float16_is_any_nan(a_);
}
-int float16_is_signaling_nan(float16 a_)
+int float16_is_signaling_nan(float16 a_, float_status *status)
{
return 0;
}
| NaN; otherwise returns 0.
*----------------------------------------------------------------------------*/
-int float16_is_quiet_nan(float16 a_)
+int float16_is_quiet_nan(float16 a_, float_status *status)
{
uint16_t a = float16_val(a_);
-#if SNAN_BIT_IS_ONE
- return (((a >> 9) & 0x3F) == 0x3E) && (a & 0x1FF);
-#else
- return ((a & ~0x8000) >= 0x7c80);
-#endif
+ if (status->snan_bit_is_one) {
+ return (((a >> 9) & 0x3F) == 0x3E) && (a & 0x1FF);
+ } else {
+ return ((a & ~0x8000) >= 0x7C80);
+ }
}
/*----------------------------------------------------------------------------
| NaN; otherwise returns 0.
*----------------------------------------------------------------------------*/
-int float16_is_signaling_nan(float16 a_)
+int float16_is_signaling_nan(float16 a_, float_status *status)
{
uint16_t a = float16_val(a_);
-#if SNAN_BIT_IS_ONE
- return ((a & ~0x8000) >= 0x7c80);
-#else
- return (((a >> 9) & 0x3F) == 0x3E) && (a & 0x1FF);
-#endif
+ if (status->snan_bit_is_one) {
+ return ((a & ~0x8000) >= 0x7C80);
+ } else {
+ return (((a >> 9) & 0x3F) == 0x3E) && (a & 0x1FF);
+ }
}
#endif
| Returns a quiet NaN if the half-precision floating point value `a' is a
| signaling NaN; otherwise returns `a'.
*----------------------------------------------------------------------------*/
-float16 float16_maybe_silence_nan(float16 a_)
+float16 float16_maybe_silence_nan(float16 a_, float_status *status)
{
- if (float16_is_signaling_nan(a_)) {
-#if SNAN_BIT_IS_ONE
-# if defined(TARGET_MIPS) || defined(TARGET_SH4) || defined(TARGET_UNICORE32)
- return float16_default_nan;
-# else
-# error Rules for silencing a signaling NaN are target-specific
-# endif
-#else
- uint16_t a = float16_val(a_);
- a |= (1 << 9);
- return make_float16(a);
-#endif
+ if (float16_is_signaling_nan(a_, status)) {
+ if (status->snan_bit_is_one) {
+ return float16_default_nan(status);
+ } else {
+ uint16_t a = float16_val(a_);
+ a |= (1 << 9);
+ return make_float16(a);
+ }
}
return a_;
}
| exception is raised.
*----------------------------------------------------------------------------*/
-static commonNaNT float16ToCommonNaN( float16 a STATUS_PARAM )
+static commonNaNT float16ToCommonNaN(float16 a, float_status *status)
{
commonNaNT z;
- if ( float16_is_signaling_nan( a ) ) float_raise( float_flag_invalid STATUS_VAR );
+ if (float16_is_signaling_nan(a, status)) {
+ float_raise(float_flag_invalid, status);
+ }
z.sign = float16_val(a) >> 15;
z.low = 0;
- z.high = ((uint64_t) float16_val(a))<<54;
+ z.high = ((uint64_t) float16_val(a)) << 54;
return z;
}
| precision floating-point format.
*----------------------------------------------------------------------------*/
-static float16 commonNaNToFloat16(commonNaNT a STATUS_PARAM)
+static float16 commonNaNToFloat16(commonNaNT a, float_status *status)
{
- uint16_t mantissa = a.high>>54;
+ uint16_t mantissa = a.high >> 54;
- if (STATUS(default_nan_mode)) {
- return float16_default_nan;
+ if (status->default_nan_mode) {
+ return float16_default_nan(status);
}
if (mantissa) {
return make_float16(((((uint16_t) a.sign) << 15)
| (0x1F << 10) | mantissa));
} else {
- return float16_default_nan;
+ return float16_default_nan(status);
}
}
#ifdef NO_SIGNALING_NANS
-int float32_is_quiet_nan(float32 a_)
+int float32_is_quiet_nan(float32 a_, float_status *status)
{
return float32_is_any_nan(a_);
}
-int float32_is_signaling_nan(float32 a_)
+int float32_is_signaling_nan(float32 a_, float_status *status)
{
return 0;
}
| NaN; otherwise returns 0.
*----------------------------------------------------------------------------*/
-int float32_is_quiet_nan( float32 a_ )
+int float32_is_quiet_nan(float32 a_, float_status *status)
{
uint32_t a = float32_val(a_);
-#if SNAN_BIT_IS_ONE
- return ( ( ( a>>22 ) & 0x1FF ) == 0x1FE ) && ( a & 0x003FFFFF );
-#else
- return ( 0xFF800000 <= (uint32_t) ( a<<1 ) );
-#endif
+ if (status->snan_bit_is_one) {
+ return (((a >> 22) & 0x1FF) == 0x1FE) && (a & 0x003FFFFF);
+ } else {
+ return ((uint32_t)(a << 1) >= 0xFF800000);
+ }
}
/*----------------------------------------------------------------------------
| NaN; otherwise returns 0.
*----------------------------------------------------------------------------*/
-int float32_is_signaling_nan( float32 a_ )
+int float32_is_signaling_nan(float32 a_, float_status *status)
{
uint32_t a = float32_val(a_);
-#if SNAN_BIT_IS_ONE
- return ( 0xFF800000 <= (uint32_t) ( a<<1 ) );
-#else
- return ( ( ( a>>22 ) & 0x1FF ) == 0x1FE ) && ( a & 0x003FFFFF );
-#endif
+ if (status->snan_bit_is_one) {
+ return ((uint32_t)(a << 1) >= 0xFF800000);
+ } else {
+ return (((a >> 22) & 0x1FF) == 0x1FE) && (a & 0x003FFFFF);
+ }
}
#endif
| signaling NaN; otherwise returns `a'.
*----------------------------------------------------------------------------*/
-float32 float32_maybe_silence_nan( float32 a_ )
+float32 float32_maybe_silence_nan(float32 a_, float_status *status)
{
- if (float32_is_signaling_nan(a_)) {
-#if SNAN_BIT_IS_ONE
-# if defined(TARGET_MIPS) || defined(TARGET_SH4) || defined(TARGET_UNICORE32)
- return float32_default_nan;
-# else
-# error Rules for silencing a signaling NaN are target-specific
-# endif
+ if (float32_is_signaling_nan(a_, status)) {
+ if (status->snan_bit_is_one) {
+#ifdef TARGET_HPPA
+ uint32_t a = float32_val(a_);
+ a &= ~0x00400000;
+ a |= 0x00200000;
+ return make_float32(a);
#else
- uint32_t a = float32_val(a_);
- a |= (1 << 22);
- return make_float32(a);
+ return float32_default_nan(status);
#endif
+ } else {
+ uint32_t a = float32_val(a_);
+ a |= (1 << 22);
+ return make_float32(a);
+ }
}
return a_;
}
| exception is raised.
*----------------------------------------------------------------------------*/
-static commonNaNT float32ToCommonNaN( float32 a STATUS_PARAM )
+static commonNaNT float32ToCommonNaN(float32 a, float_status *status)
{
commonNaNT z;
- if ( float32_is_signaling_nan( a ) ) float_raise( float_flag_invalid STATUS_VAR );
- z.sign = float32_val(a)>>31;
+ if (float32_is_signaling_nan(a, status)) {
+ float_raise(float_flag_invalid, status);
+ }
+ z.sign = float32_val(a) >> 31;
z.low = 0;
- z.high = ( (uint64_t) float32_val(a) )<<41;
+ z.high = ((uint64_t)float32_val(a)) << 41;
return z;
}
| precision floating-point format.
*----------------------------------------------------------------------------*/
-static float32 commonNaNToFloat32( commonNaNT a STATUS_PARAM)
+static float32 commonNaNToFloat32(commonNaNT a, float_status *status)
{
- uint32_t mantissa = a.high>>41;
+ uint32_t mantissa = a.high >> 41;
- if ( STATUS(default_nan_mode) ) {
- return float32_default_nan;
+ if (status->default_nan_mode) {
+ return float32_default_nan(status);
}
- if ( mantissa )
+ if (mantissa) {
return make_float32(
- ( ( (uint32_t) a.sign )<<31 ) | 0x7F800000 | ( a.high>>41 ) );
- else
- return float32_default_nan;
+ (((uint32_t)a.sign) << 31) | 0x7F800000 | (a.high >> 41));
+ } else {
+ return float32_default_nan(status);
+ }
}
/*----------------------------------------------------------------------------
return 1;
}
}
-#elif defined(TARGET_MIPS)
+#elif defined(TARGET_MIPS) || defined(TARGET_HPPA)
static int pickNaN(flag aIsQNaN, flag aIsSNaN, flag bIsQNaN, flag bIsSNaN,
flag aIsLargerSignificand)
{
return aIsLargerSignificand ? 0 : 1;
}
return bIsQNaN ? 1 : 0;
- }
- else if (aIsQNaN) {
- if (bIsSNaN || !bIsQNaN)
+ } else if (aIsQNaN) {
+ if (bIsSNaN || !bIsQNaN) {
return 0;
- else {
+ } else {
return aIsLargerSignificand ? 0 : 1;
}
} else {
*----------------------------------------------------------------------------*/
#if defined(TARGET_ARM)
static int pickNaNMulAdd(flag aIsQNaN, flag aIsSNaN, flag bIsQNaN, flag bIsSNaN,
- flag cIsQNaN, flag cIsSNaN, flag infzero STATUS_PARAM)
+ flag cIsQNaN, flag cIsSNaN, flag infzero,
+ float_status *status)
{
/* For ARM, the (inf,zero,qnan) case sets InvalidOp and returns
* the default NaN
*/
if (infzero && cIsQNaN) {
- float_raise(float_flag_invalid STATUS_VAR);
+ float_raise(float_flag_invalid, status);
return 3;
}
}
#elif defined(TARGET_MIPS)
static int pickNaNMulAdd(flag aIsQNaN, flag aIsSNaN, flag bIsQNaN, flag bIsSNaN,
- flag cIsQNaN, flag cIsSNaN, flag infzero STATUS_PARAM)
+ flag cIsQNaN, flag cIsSNaN, flag infzero,
+ float_status *status)
{
/* For MIPS, the (inf,zero,qnan) case sets InvalidOp and returns
* the default NaN
*/
if (infzero) {
- float_raise(float_flag_invalid STATUS_VAR);
+ float_raise(float_flag_invalid, status);
return 3;
}
- /* Prefer sNaN over qNaN, in the a, b, c order. */
- if (aIsSNaN) {
- return 0;
- } else if (bIsSNaN) {
- return 1;
- } else if (cIsSNaN) {
- return 2;
- } else if (aIsQNaN) {
- return 0;
- } else if (bIsQNaN) {
- return 1;
+ if (status->snan_bit_is_one) {
+ /* Prefer sNaN over qNaN, in the a, b, c order. */
+ if (aIsSNaN) {
+ return 0;
+ } else if (bIsSNaN) {
+ return 1;
+ } else if (cIsSNaN) {
+ return 2;
+ } else if (aIsQNaN) {
+ return 0;
+ } else if (bIsQNaN) {
+ return 1;
+ } else {
+ return 2;
+ }
} else {
- return 2;
+ /* Prefer sNaN over qNaN, in the c, a, b order. */
+ if (cIsSNaN) {
+ return 2;
+ } else if (aIsSNaN) {
+ return 0;
+ } else if (bIsSNaN) {
+ return 1;
+ } else if (cIsQNaN) {
+ return 2;
+ } else if (aIsQNaN) {
+ return 0;
+ } else {
+ return 1;
+ }
}
}
#elif defined(TARGET_PPC)
static int pickNaNMulAdd(flag aIsQNaN, flag aIsSNaN, flag bIsQNaN, flag bIsSNaN,
- flag cIsQNaN, flag cIsSNaN, flag infzero STATUS_PARAM)
+ flag cIsQNaN, flag cIsSNaN, flag infzero,
+ float_status *status)
{
/* For PPC, the (inf,zero,qnan) case sets InvalidOp, but we prefer
* to return an input NaN if we have one (ie c) rather than generating
* a default NaN
*/
if (infzero) {
- float_raise(float_flag_invalid STATUS_VAR);
+ float_raise(float_flag_invalid, status);
return 2;
}
* This is unlikely to actually match any real implementation.
*/
static int pickNaNMulAdd(flag aIsQNaN, flag aIsSNaN, flag bIsQNaN, flag bIsSNaN,
- flag cIsQNaN, flag cIsSNaN, flag infzero STATUS_PARAM)
+ flag cIsQNaN, flag cIsSNaN, flag infzero,
+ float_status *status)
{
if (aIsSNaN || aIsQNaN) {
return 0;
| signaling NaN, the invalid exception is raised.
*----------------------------------------------------------------------------*/
-static float32 propagateFloat32NaN( float32 a, float32 b STATUS_PARAM)
+static float32 propagateFloat32NaN(float32 a, float32 b, float_status *status)
{
flag aIsQuietNaN, aIsSignalingNaN, bIsQuietNaN, bIsSignalingNaN;
flag aIsLargerSignificand;
uint32_t av, bv;
- aIsQuietNaN = float32_is_quiet_nan( a );
- aIsSignalingNaN = float32_is_signaling_nan( a );
- bIsQuietNaN = float32_is_quiet_nan( b );
- bIsSignalingNaN = float32_is_signaling_nan( b );
+ aIsQuietNaN = float32_is_quiet_nan(a, status);
+ aIsSignalingNaN = float32_is_signaling_nan(a, status);
+ bIsQuietNaN = float32_is_quiet_nan(b, status);
+ bIsSignalingNaN = float32_is_signaling_nan(b, status);
av = float32_val(a);
bv = float32_val(b);
- if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid STATUS_VAR);
+ if (aIsSignalingNaN | bIsSignalingNaN) {
+ float_raise(float_flag_invalid, status);
+ }
- if ( STATUS(default_nan_mode) )
- return float32_default_nan;
+ if (status->default_nan_mode) {
+ return float32_default_nan(status);
+ }
- if ((uint32_t)(av<<1) < (uint32_t)(bv<<1)) {
+ if ((uint32_t)(av << 1) < (uint32_t)(bv << 1)) {
aIsLargerSignificand = 0;
- } else if ((uint32_t)(bv<<1) < (uint32_t)(av<<1)) {
+ } else if ((uint32_t)(bv << 1) < (uint32_t)(av << 1)) {
aIsLargerSignificand = 1;
} else {
aIsLargerSignificand = (av < bv) ? 1 : 0;
if (pickNaN(aIsQuietNaN, aIsSignalingNaN, bIsQuietNaN, bIsSignalingNaN,
aIsLargerSignificand)) {
- return float32_maybe_silence_nan(b);
+ return float32_maybe_silence_nan(b, status);
} else {
- return float32_maybe_silence_nan(a);
+ return float32_maybe_silence_nan(a, status);
}
}
*----------------------------------------------------------------------------*/
static float32 propagateFloat32MulAddNaN(float32 a, float32 b,
- float32 c, flag infzero STATUS_PARAM)
+ float32 c, flag infzero,
+ float_status *status)
{
flag aIsQuietNaN, aIsSignalingNaN, bIsQuietNaN, bIsSignalingNaN,
cIsQuietNaN, cIsSignalingNaN;
int which;
- aIsQuietNaN = float32_is_quiet_nan(a);
- aIsSignalingNaN = float32_is_signaling_nan(a);
- bIsQuietNaN = float32_is_quiet_nan(b);
- bIsSignalingNaN = float32_is_signaling_nan(b);
- cIsQuietNaN = float32_is_quiet_nan(c);
- cIsSignalingNaN = float32_is_signaling_nan(c);
+ aIsQuietNaN = float32_is_quiet_nan(a, status);
+ aIsSignalingNaN = float32_is_signaling_nan(a, status);
+ bIsQuietNaN = float32_is_quiet_nan(b, status);
+ bIsSignalingNaN = float32_is_signaling_nan(b, status);
+ cIsQuietNaN = float32_is_quiet_nan(c, status);
+ cIsSignalingNaN = float32_is_signaling_nan(c, status);
if (aIsSignalingNaN | bIsSignalingNaN | cIsSignalingNaN) {
- float_raise(float_flag_invalid STATUS_VAR);
+ float_raise(float_flag_invalid, status);
}
which = pickNaNMulAdd(aIsQuietNaN, aIsSignalingNaN,
bIsQuietNaN, bIsSignalingNaN,
- cIsQuietNaN, cIsSignalingNaN, infzero STATUS_VAR);
+ cIsQuietNaN, cIsSignalingNaN, infzero, status);
- if (STATUS(default_nan_mode)) {
+ if (status->default_nan_mode) {
/* Note that this check is after pickNaNMulAdd so that function
* has an opportunity to set the Invalid flag.
*/
- return float32_default_nan;
+ return float32_default_nan(status);
}
switch (which) {
case 0:
- return float32_maybe_silence_nan(a);
+ return float32_maybe_silence_nan(a, status);
case 1:
- return float32_maybe_silence_nan(b);
+ return float32_maybe_silence_nan(b, status);
case 2:
- return float32_maybe_silence_nan(c);
+ return float32_maybe_silence_nan(c, status);
case 3:
default:
- return float32_default_nan;
+ return float32_default_nan(status);
}
}
#ifdef NO_SIGNALING_NANS
-int float64_is_quiet_nan(float64 a_)
+int float64_is_quiet_nan(float64 a_, float_status *status)
{
return float64_is_any_nan(a_);
}
-int float64_is_signaling_nan(float64 a_)
+int float64_is_signaling_nan(float64 a_, float_status *status)
{
return 0;
}
| NaN; otherwise returns 0.
*----------------------------------------------------------------------------*/
-int float64_is_quiet_nan( float64 a_ )
+int float64_is_quiet_nan(float64 a_, float_status *status)
{
uint64_t a = float64_val(a_);
-#if SNAN_BIT_IS_ONE
- return
- ( ( ( a>>51 ) & 0xFFF ) == 0xFFE )
- && ( a & LIT64( 0x0007FFFFFFFFFFFF ) );
-#else
- return ( LIT64( 0xFFF0000000000000 ) <= (uint64_t) ( a<<1 ) );
-#endif
+ if (status->snan_bit_is_one) {
+ return (((a >> 51) & 0xFFF) == 0xFFE)
+ && (a & 0x0007FFFFFFFFFFFFULL);
+ } else {
+ return ((a << 1) >= 0xFFF0000000000000ULL);
+ }
}
/*----------------------------------------------------------------------------
| NaN; otherwise returns 0.
*----------------------------------------------------------------------------*/
-int float64_is_signaling_nan( float64 a_ )
+int float64_is_signaling_nan(float64 a_, float_status *status)
{
uint64_t a = float64_val(a_);
-#if SNAN_BIT_IS_ONE
- return ( LIT64( 0xFFF0000000000000 ) <= (uint64_t) ( a<<1 ) );
-#else
- return
- ( ( ( a>>51 ) & 0xFFF ) == 0xFFE )
- && ( a & LIT64( 0x0007FFFFFFFFFFFF ) );
-#endif
+ if (status->snan_bit_is_one) {
+ return ((a << 1) >= 0xFFF0000000000000ULL);
+ } else {
+ return (((a >> 51) & 0xFFF) == 0xFFE)
+ && (a & LIT64(0x0007FFFFFFFFFFFF));
+ }
}
#endif
| signaling NaN; otherwise returns `a'.
*----------------------------------------------------------------------------*/
-float64 float64_maybe_silence_nan( float64 a_ )
+float64 float64_maybe_silence_nan(float64 a_, float_status *status)
{
- if (float64_is_signaling_nan(a_)) {
-#if SNAN_BIT_IS_ONE
-# if defined(TARGET_MIPS) || defined(TARGET_SH4) || defined(TARGET_UNICORE32)
- return float64_default_nan;
-# else
-# error Rules for silencing a signaling NaN are target-specific
-# endif
+ if (float64_is_signaling_nan(a_, status)) {
+ if (status->snan_bit_is_one) {
+#ifdef TARGET_HPPA
+ uint64_t a = float64_val(a_);
+ a &= ~0x0008000000000000ULL;
+ a |= 0x0004000000000000ULL;
+ return make_float64(a);
#else
- uint64_t a = float64_val(a_);
- a |= LIT64( 0x0008000000000000 );
- return make_float64(a);
+ return float64_default_nan(status);
#endif
+ } else {
+ uint64_t a = float64_val(a_);
+ a |= LIT64(0x0008000000000000);
+ return make_float64(a);
+ }
}
return a_;
}
| exception is raised.
*----------------------------------------------------------------------------*/
-static commonNaNT float64ToCommonNaN( float64 a STATUS_PARAM)
+static commonNaNT float64ToCommonNaN(float64 a, float_status *status)
{
commonNaNT z;
- if ( float64_is_signaling_nan( a ) ) float_raise( float_flag_invalid STATUS_VAR);
- z.sign = float64_val(a)>>63;
+ if (float64_is_signaling_nan(a, status)) {
+ float_raise(float_flag_invalid, status);
+ }
+ z.sign = float64_val(a) >> 63;
z.low = 0;
- z.high = float64_val(a)<<12;
+ z.high = float64_val(a) << 12;
return z;
}
| precision floating-point format.
*----------------------------------------------------------------------------*/
-static float64 commonNaNToFloat64( commonNaNT a STATUS_PARAM)
+static float64 commonNaNToFloat64(commonNaNT a, float_status *status)
{
- uint64_t mantissa = a.high>>12;
+ uint64_t mantissa = a.high >> 12;
- if ( STATUS(default_nan_mode) ) {
- return float64_default_nan;
+ if (status->default_nan_mode) {
+ return float64_default_nan(status);
}
- if ( mantissa )
+ if (mantissa) {
return make_float64(
- ( ( (uint64_t) a.sign )<<63 )
- | LIT64( 0x7FF0000000000000 )
- | ( a.high>>12 ));
- else
- return float64_default_nan;
+ (((uint64_t) a.sign) << 63)
+ | LIT64(0x7FF0000000000000)
+ | (a.high >> 12));
+ } else {
+ return float64_default_nan(status);
+ }
}
/*----------------------------------------------------------------------------
| signaling NaN, the invalid exception is raised.
*----------------------------------------------------------------------------*/
-static float64 propagateFloat64NaN( float64 a, float64 b STATUS_PARAM)
+static float64 propagateFloat64NaN(float64 a, float64 b, float_status *status)
{
flag aIsQuietNaN, aIsSignalingNaN, bIsQuietNaN, bIsSignalingNaN;
flag aIsLargerSignificand;
uint64_t av, bv;
- aIsQuietNaN = float64_is_quiet_nan( a );
- aIsSignalingNaN = float64_is_signaling_nan( a );
- bIsQuietNaN = float64_is_quiet_nan( b );
- bIsSignalingNaN = float64_is_signaling_nan( b );
+ aIsQuietNaN = float64_is_quiet_nan(a, status);
+ aIsSignalingNaN = float64_is_signaling_nan(a, status);
+ bIsQuietNaN = float64_is_quiet_nan(b, status);
+ bIsSignalingNaN = float64_is_signaling_nan(b, status);
av = float64_val(a);
bv = float64_val(b);
- if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid STATUS_VAR);
+ if (aIsSignalingNaN | bIsSignalingNaN) {
+ float_raise(float_flag_invalid, status);
+ }
- if ( STATUS(default_nan_mode) )
- return float64_default_nan;
+ if (status->default_nan_mode) {
+ return float64_default_nan(status);
+ }
- if ((uint64_t)(av<<1) < (uint64_t)(bv<<1)) {
+ if ((uint64_t)(av << 1) < (uint64_t)(bv << 1)) {
aIsLargerSignificand = 0;
- } else if ((uint64_t)(bv<<1) < (uint64_t)(av<<1)) {
+ } else if ((uint64_t)(bv << 1) < (uint64_t)(av << 1)) {
aIsLargerSignificand = 1;
} else {
aIsLargerSignificand = (av < bv) ? 1 : 0;
if (pickNaN(aIsQuietNaN, aIsSignalingNaN, bIsQuietNaN, bIsSignalingNaN,
aIsLargerSignificand)) {
- return float64_maybe_silence_nan(b);
+ return float64_maybe_silence_nan(b, status);
} else {
- return float64_maybe_silence_nan(a);
+ return float64_maybe_silence_nan(a, status);
}
}
*----------------------------------------------------------------------------*/
static float64 propagateFloat64MulAddNaN(float64 a, float64 b,
- float64 c, flag infzero STATUS_PARAM)
+ float64 c, flag infzero,
+ float_status *status)
{
flag aIsQuietNaN, aIsSignalingNaN, bIsQuietNaN, bIsSignalingNaN,
cIsQuietNaN, cIsSignalingNaN;
int which;
- aIsQuietNaN = float64_is_quiet_nan(a);
- aIsSignalingNaN = float64_is_signaling_nan(a);
- bIsQuietNaN = float64_is_quiet_nan(b);
- bIsSignalingNaN = float64_is_signaling_nan(b);
- cIsQuietNaN = float64_is_quiet_nan(c);
- cIsSignalingNaN = float64_is_signaling_nan(c);
+ aIsQuietNaN = float64_is_quiet_nan(a, status);
+ aIsSignalingNaN = float64_is_signaling_nan(a, status);
+ bIsQuietNaN = float64_is_quiet_nan(b, status);
+ bIsSignalingNaN = float64_is_signaling_nan(b, status);
+ cIsQuietNaN = float64_is_quiet_nan(c, status);
+ cIsSignalingNaN = float64_is_signaling_nan(c, status);
if (aIsSignalingNaN | bIsSignalingNaN | cIsSignalingNaN) {
- float_raise(float_flag_invalid STATUS_VAR);
+ float_raise(float_flag_invalid, status);
}
which = pickNaNMulAdd(aIsQuietNaN, aIsSignalingNaN,
bIsQuietNaN, bIsSignalingNaN,
- cIsQuietNaN, cIsSignalingNaN, infzero STATUS_VAR);
+ cIsQuietNaN, cIsSignalingNaN, infzero, status);
- if (STATUS(default_nan_mode)) {
+ if (status->default_nan_mode) {
/* Note that this check is after pickNaNMulAdd so that function
* has an opportunity to set the Invalid flag.
*/
- return float64_default_nan;
+ return float64_default_nan(status);
}
switch (which) {
case 0:
- return float64_maybe_silence_nan(a);
+ return float64_maybe_silence_nan(a, status);
case 1:
- return float64_maybe_silence_nan(b);
+ return float64_maybe_silence_nan(b, status);
case 2:
- return float64_maybe_silence_nan(c);
+ return float64_maybe_silence_nan(c, status);
case 3:
default:
- return float64_default_nan;
+ return float64_default_nan(status);
}
}
#ifdef NO_SIGNALING_NANS
-int floatx80_is_quiet_nan(floatx80 a_)
+int floatx80_is_quiet_nan(floatx80 a_, float_status *status)
{
return floatx80_is_any_nan(a_);
}
-int floatx80_is_signaling_nan(floatx80 a_)
+int floatx80_is_signaling_nan(floatx80 a_, float_status *status)
{
return 0;
}
| function for other types as floatx80 has an explicit bit.
*----------------------------------------------------------------------------*/
-int floatx80_is_quiet_nan( floatx80 a )
+int floatx80_is_quiet_nan(floatx80 a, float_status *status)
{
-#if SNAN_BIT_IS_ONE
- uint64_t aLow;
-
- aLow = a.low & ~ LIT64( 0x4000000000000000 );
- return
- ( ( a.high & 0x7FFF ) == 0x7FFF )
- && (uint64_t) ( aLow<<1 )
- && ( a.low == aLow );
-#else
- return ( ( a.high & 0x7FFF ) == 0x7FFF )
- && (LIT64( 0x8000000000000000 ) <= ((uint64_t) ( a.low<<1 )));
-#endif
+ if (status->snan_bit_is_one) {
+ uint64_t aLow;
+
+ aLow = a.low & ~0x4000000000000000ULL;
+ return ((a.high & 0x7FFF) == 0x7FFF)
+ && (aLow << 1)
+ && (a.low == aLow);
+ } else {
+ return ((a.high & 0x7FFF) == 0x7FFF)
+ && (LIT64(0x8000000000000000) <= ((uint64_t)(a.low << 1)));
+ }
}
/*----------------------------------------------------------------------------
| function for other types as floatx80 has an explicit bit.
*----------------------------------------------------------------------------*/
-int floatx80_is_signaling_nan( floatx80 a )
+int floatx80_is_signaling_nan(floatx80 a, float_status *status)
{
-#if SNAN_BIT_IS_ONE
- return ( ( a.high & 0x7FFF ) == 0x7FFF )
- && (LIT64( 0x8000000000000000 ) <= ((uint64_t) ( a.low<<1 )));
-#else
- uint64_t aLow;
+ if (status->snan_bit_is_one) {
+ return ((a.high & 0x7FFF) == 0x7FFF)
+ && ((a.low << 1) >= 0x8000000000000000ULL);
+ } else {
+ uint64_t aLow;
- aLow = a.low & ~ LIT64( 0x4000000000000000 );
- return
- ( ( a.high & 0x7FFF ) == 0x7FFF )
- && (uint64_t) ( aLow<<1 )
- && ( a.low == aLow );
-#endif
+ aLow = a.low & ~LIT64(0x4000000000000000);
+ return ((a.high & 0x7FFF) == 0x7FFF)
+ && (uint64_t)(aLow << 1)
+ && (a.low == aLow);
+ }
}
#endif
| `a' is a signaling NaN; otherwise returns `a'.
*----------------------------------------------------------------------------*/
-floatx80 floatx80_maybe_silence_nan( floatx80 a )
+floatx80 floatx80_maybe_silence_nan(floatx80 a, float_status *status)
{
- if (floatx80_is_signaling_nan(a)) {
-#if SNAN_BIT_IS_ONE
-# if defined(TARGET_MIPS) || defined(TARGET_SH4) || defined(TARGET_UNICORE32)
- a.low = floatx80_default_nan_low;
- a.high = floatx80_default_nan_high;
-# else
-# error Rules for silencing a signaling NaN are target-specific
-# endif
-#else
- a.low |= LIT64( 0xC000000000000000 );
- return a;
-#endif
+ if (floatx80_is_signaling_nan(a, status)) {
+ if (status->snan_bit_is_one) {
+ a = floatx80_default_nan(status);
+ } else {
+ a.low |= LIT64(0xC000000000000000);
+ return a;
+ }
}
return a;
}
| invalid exception is raised.
*----------------------------------------------------------------------------*/
-static commonNaNT floatx80ToCommonNaN( floatx80 a STATUS_PARAM)
+static commonNaNT floatx80ToCommonNaN(floatx80 a, float_status *status)
{
+ floatx80 dflt;
commonNaNT z;
- if ( floatx80_is_signaling_nan( a ) ) float_raise( float_flag_invalid STATUS_VAR);
- if ( a.low >> 63 ) {
+ if (floatx80_is_signaling_nan(a, status)) {
+ float_raise(float_flag_invalid, status);
+ }
+ if (a.low >> 63) {
z.sign = a.high >> 15;
z.low = 0;
z.high = a.low << 1;
} else {
- z.sign = floatx80_default_nan_high >> 15;
+ dflt = floatx80_default_nan(status);
+ z.sign = dflt.high >> 15;
z.low = 0;
- z.high = floatx80_default_nan_low << 1;
+ z.high = dflt.low << 1;
}
return z;
}
| double-precision floating-point format.
*----------------------------------------------------------------------------*/
-static floatx80 commonNaNToFloatx80( commonNaNT a STATUS_PARAM)
+static floatx80 commonNaNToFloatx80(commonNaNT a, float_status *status)
{
floatx80 z;
- if ( STATUS(default_nan_mode) ) {
- z.low = floatx80_default_nan_low;
- z.high = floatx80_default_nan_high;
- return z;
+ if (status->default_nan_mode) {
+ return floatx80_default_nan(status);
}
if (a.high >> 1) {
- z.low = LIT64( 0x8000000000000000 ) | a.high >> 1;
- z.high = ( ( (uint16_t) a.sign )<<15 ) | 0x7FFF;
+ z.low = LIT64(0x8000000000000000) | a.high >> 1;
+ z.high = (((uint16_t)a.sign) << 15) | 0x7FFF;
} else {
- z.low = floatx80_default_nan_low;
- z.high = floatx80_default_nan_high;
+ z = floatx80_default_nan(status);
}
-
return z;
}
| `b' is a signaling NaN, the invalid exception is raised.
*----------------------------------------------------------------------------*/
-static floatx80 propagateFloatx80NaN( floatx80 a, floatx80 b STATUS_PARAM)
+static floatx80 propagateFloatx80NaN(floatx80 a, floatx80 b,
+ float_status *status)
{
flag aIsQuietNaN, aIsSignalingNaN, bIsQuietNaN, bIsSignalingNaN;
flag aIsLargerSignificand;
- aIsQuietNaN = floatx80_is_quiet_nan( a );
- aIsSignalingNaN = floatx80_is_signaling_nan( a );
- bIsQuietNaN = floatx80_is_quiet_nan( b );
- bIsSignalingNaN = floatx80_is_signaling_nan( b );
+ aIsQuietNaN = floatx80_is_quiet_nan(a, status);
+ aIsSignalingNaN = floatx80_is_signaling_nan(a, status);
+ bIsQuietNaN = floatx80_is_quiet_nan(b, status);
+ bIsSignalingNaN = floatx80_is_signaling_nan(b, status);
- if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid STATUS_VAR);
+ if (aIsSignalingNaN | bIsSignalingNaN) {
+ float_raise(float_flag_invalid, status);
+ }
- if ( STATUS(default_nan_mode) ) {
- a.low = floatx80_default_nan_low;
- a.high = floatx80_default_nan_high;
- return a;
+ if (status->default_nan_mode) {
+ return floatx80_default_nan(status);
}
if (a.low < b.low) {
if (pickNaN(aIsQuietNaN, aIsSignalingNaN, bIsQuietNaN, bIsSignalingNaN,
aIsLargerSignificand)) {
- return floatx80_maybe_silence_nan(b);
+ return floatx80_maybe_silence_nan(b, status);
} else {
- return floatx80_maybe_silence_nan(a);
+ return floatx80_maybe_silence_nan(a, status);
}
}
#ifdef NO_SIGNALING_NANS
-int float128_is_quiet_nan(float128 a_)
+int float128_is_quiet_nan(float128 a_, float_status *status)
{
return float128_is_any_nan(a_);
}
-int float128_is_signaling_nan(float128 a_)
+int float128_is_signaling_nan(float128 a_, float_status *status)
{
return 0;
}
| NaN; otherwise returns 0.
*----------------------------------------------------------------------------*/
-int float128_is_quiet_nan( float128 a )
+int float128_is_quiet_nan(float128 a, float_status *status)
{
-#if SNAN_BIT_IS_ONE
- return
- ( ( ( a.high>>47 ) & 0xFFFF ) == 0xFFFE )
- && ( a.low || ( a.high & LIT64( 0x00007FFFFFFFFFFF ) ) );
-#else
- return
- ( LIT64( 0xFFFE000000000000 ) <= (uint64_t) ( a.high<<1 ) )
- && ( a.low || ( a.high & LIT64( 0x0000FFFFFFFFFFFF ) ) );
-#endif
+ if (status->snan_bit_is_one) {
+ return (((a.high >> 47) & 0xFFFF) == 0xFFFE)
+ && (a.low || (a.high & 0x00007FFFFFFFFFFFULL));
+ } else {
+ return ((a.high << 1) >= 0xFFFF000000000000ULL)
+ && (a.low || (a.high & 0x0000FFFFFFFFFFFFULL));
+ }
}
/*----------------------------------------------------------------------------
| signaling NaN; otherwise returns 0.
*----------------------------------------------------------------------------*/
-int float128_is_signaling_nan( float128 a )
+int float128_is_signaling_nan(float128 a, float_status *status)
{
-#if SNAN_BIT_IS_ONE
- return
- ( LIT64( 0xFFFE000000000000 ) <= (uint64_t) ( a.high<<1 ) )
- && ( a.low || ( a.high & LIT64( 0x0000FFFFFFFFFFFF ) ) );
-#else
- return
- ( ( ( a.high>>47 ) & 0xFFFF ) == 0xFFFE )
- && ( a.low || ( a.high & LIT64( 0x00007FFFFFFFFFFF ) ) );
-#endif
+ if (status->snan_bit_is_one) {
+ return ((a.high << 1) >= 0xFFFF000000000000ULL)
+ && (a.low || (a.high & 0x0000FFFFFFFFFFFFULL));
+ } else {
+ return (((a.high >> 47) & 0xFFFF) == 0xFFFE)
+ && (a.low || (a.high & LIT64(0x00007FFFFFFFFFFF)));
+ }
}
#endif
| a signaling NaN; otherwise returns `a'.
*----------------------------------------------------------------------------*/
-float128 float128_maybe_silence_nan( float128 a )
+float128 float128_maybe_silence_nan(float128 a, float_status *status)
{
- if (float128_is_signaling_nan(a)) {
-#if SNAN_BIT_IS_ONE
-# if defined(TARGET_MIPS) || defined(TARGET_SH4) || defined(TARGET_UNICORE32)
- a.low = float128_default_nan_low;
- a.high = float128_default_nan_high;
-# else
-# error Rules for silencing a signaling NaN are target-specific
-# endif
-#else
- a.high |= LIT64( 0x0000800000000000 );
- return a;
-#endif
+ if (float128_is_signaling_nan(a, status)) {
+ if (status->snan_bit_is_one) {
+ a = float128_default_nan(status);
+ } else {
+ a.high |= LIT64(0x0000800000000000);
+ return a;
+ }
}
return a;
}
| exception is raised.
*----------------------------------------------------------------------------*/
-static commonNaNT float128ToCommonNaN( float128 a STATUS_PARAM)
+static commonNaNT float128ToCommonNaN(float128 a, float_status *status)
{
commonNaNT z;
- if ( float128_is_signaling_nan( a ) ) float_raise( float_flag_invalid STATUS_VAR);
- z.sign = a.high>>63;
- shortShift128Left( a.high, a.low, 16, &z.high, &z.low );
+ if (float128_is_signaling_nan(a, status)) {
+ float_raise(float_flag_invalid, status);
+ }
+ z.sign = a.high >> 63;
+ shortShift128Left(a.high, a.low, 16, &z.high, &z.low);
return z;
}
| precision floating-point format.
*----------------------------------------------------------------------------*/
-static float128 commonNaNToFloat128( commonNaNT a STATUS_PARAM)
+static float128 commonNaNToFloat128(commonNaNT a, float_status *status)
{
float128 z;
- if ( STATUS(default_nan_mode) ) {
- z.low = float128_default_nan_low;
- z.high = float128_default_nan_high;
- return z;
+ if (status->default_nan_mode) {
+ return float128_default_nan(status);
}
- shift128Right( a.high, a.low, 16, &z.high, &z.low );
- z.high |= ( ( (uint64_t) a.sign )<<63 ) | LIT64( 0x7FFF000000000000 );
+ shift128Right(a.high, a.low, 16, &z.high, &z.low);
+ z.high |= (((uint64_t)a.sign) << 63) | LIT64(0x7FFF000000000000);
return z;
}
| `b' is a signaling NaN, the invalid exception is raised.
*----------------------------------------------------------------------------*/
-static float128 propagateFloat128NaN( float128 a, float128 b STATUS_PARAM)
+static float128 propagateFloat128NaN(float128 a, float128 b,
+ float_status *status)
{
flag aIsQuietNaN, aIsSignalingNaN, bIsQuietNaN, bIsSignalingNaN;
flag aIsLargerSignificand;
- aIsQuietNaN = float128_is_quiet_nan( a );
- aIsSignalingNaN = float128_is_signaling_nan( a );
- bIsQuietNaN = float128_is_quiet_nan( b );
- bIsSignalingNaN = float128_is_signaling_nan( b );
+ aIsQuietNaN = float128_is_quiet_nan(a, status);
+ aIsSignalingNaN = float128_is_signaling_nan(a, status);
+ bIsQuietNaN = float128_is_quiet_nan(b, status);
+ bIsSignalingNaN = float128_is_signaling_nan(b, status);
- if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid STATUS_VAR);
+ if (aIsSignalingNaN | bIsSignalingNaN) {
+ float_raise(float_flag_invalid, status);
+ }
- if ( STATUS(default_nan_mode) ) {
- a.low = float128_default_nan_low;
- a.high = float128_default_nan_high;
- return a;
+ if (status->default_nan_mode) {
+ return float128_default_nan(status);
}
- if (lt128(a.high<<1, a.low, b.high<<1, b.low)) {
+ if (lt128(a.high << 1, a.low, b.high << 1, b.low)) {
aIsLargerSignificand = 0;
- } else if (lt128(b.high<<1, b.low, a.high<<1, a.low)) {
+ } else if (lt128(b.high << 1, b.low, a.high << 1, a.low)) {
aIsLargerSignificand = 1;
} else {
aIsLargerSignificand = (a.high < b.high) ? 1 : 0;
if (pickNaN(aIsQuietNaN, aIsSignalingNaN, bIsQuietNaN, bIsSignalingNaN,
aIsLargerSignificand)) {
- return float128_maybe_silence_nan(b);
+ return float128_maybe_silence_nan(b, status);
} else {
- return float128_maybe_silence_nan(a);
+ return float128_maybe_silence_nan(a, status);
}
}
-