/*============================================================================ This C source file is part of TestFloat, Release 3, a package of programs for testing the correctness of floating-point arithmetic complying with the IEEE Standard for Floating-Point, 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 #include #include #include #include #include #include "platform.h" #include "fail.h" #include "softfloat.h" #include "slowfloat.h" #include "functions.h" #include "genCases.h" #include "verCases.h" #include "writeCase.h" #include "testLoops.h" static void catchSIGINT( int signalCode ) { if ( verCases_stop ) exit( EXIT_FAILURE ); verCases_stop = true; } static uint_fast8_t softfloat_clearExceptionFlags( void ) { uint_fast8_t prevFlags; prevFlags = softfloat_exceptionFlags; softfloat_exceptionFlags = 0; return prevFlags; } static void testFunctionInstance( int functionCode, uint_fast8_t roundingMode, bool exact ) { float32_t (*trueFunction_abz_f32)( float32_t, float32_t ); float32_t (*subjFunction_abz_f32)( float32_t, float32_t ); bool (*trueFunction_ab_f32_z_bool)( float32_t, float32_t ); bool (*subjFunction_ab_f32_z_bool)( float32_t, float32_t ); float64_t (*trueFunction_abz_f64)( float64_t, float64_t ); float64_t (*subjFunction_abz_f64)( float64_t, float64_t ); bool (*trueFunction_ab_f64_z_bool)( float64_t, float64_t ); bool (*subjFunction_ab_f64_z_bool)( float64_t, float64_t ); #ifdef EXTFLOAT80 void (*trueFunction_abz_extF80M)( const extFloat80_t *, const extFloat80_t *, extFloat80_t * ); void (*subjFunction_abz_extF80M)( const extFloat80_t *, const extFloat80_t *, extFloat80_t * ); bool (*trueFunction_ab_extF80M_z_bool)( const extFloat80_t *, const extFloat80_t * ); bool (*subjFunction_ab_extF80M_z_bool)( const extFloat80_t *, const extFloat80_t * ); #endif #ifdef FLOAT128 void (*trueFunction_abz_f128M)( const float128_t *, const float128_t *, float128_t * ); void (*subjFunction_abz_f128M)( const float128_t *, const float128_t *, float128_t * ); bool (*trueFunction_ab_f128M_z_bool)( const float128_t *, const float128_t * ); bool (*subjFunction_ab_f128M_z_bool)( const float128_t *, const float128_t * ); #endif fputs( "Testing ", stderr ); verCases_writeFunctionName( stderr ); fputs( ".\n", stderr ); switch ( functionCode ) { /*-------------------------------------------------------------------- *--------------------------------------------------------------------*/ case UI32_TO_F32: test_a_ui32_z_f32( slow_ui32_to_f32, ui32_to_f32 ); break; case UI32_TO_F64: test_a_ui32_z_f64( slow_ui32_to_f64, ui32_to_f64 ); break; #ifdef EXTFLOAT80 case UI32_TO_EXTF80: test_a_ui32_z_extF80( slow_ui32_to_extF80M, ui32_to_extF80M ); break; #endif #ifdef FLOAT128 case UI32_TO_F128: test_a_ui32_z_f128( slow_ui32_to_f128M, ui32_to_f128M ); break; #endif case UI64_TO_F32: test_a_ui64_z_f32( slow_ui64_to_f32, ui64_to_f32 ); break; case UI64_TO_F64: test_a_ui64_z_f64( slow_ui64_to_f64, ui64_to_f64 ); break; #ifdef EXTFLOAT80 case UI64_TO_EXTF80: test_a_ui64_z_extF80( slow_ui64_to_extF80M, ui64_to_extF80M ); break; #endif #ifdef FLOAT128 case UI64_TO_F128: test_a_ui64_z_f128( slow_ui64_to_f128M, ui64_to_f128M ); break; #endif case I32_TO_F32: test_a_i32_z_f32( slow_i32_to_f32, i32_to_f32 ); break; case I32_TO_F64: test_a_i32_z_f64( slow_i32_to_f64, i32_to_f64 ); break; #ifdef EXTFLOAT80 case I32_TO_EXTF80: test_a_i32_z_extF80( slow_i32_to_extF80M, i32_to_extF80M ); break; #endif #ifdef FLOAT128 case I32_TO_F128: test_a_i32_z_f128( slow_i32_to_f128M, i32_to_f128M ); break; #endif case I64_TO_F32: test_a_i64_z_f32( slow_i64_to_f32, i64_to_f32 ); break; case I64_TO_F64: test_a_i64_z_f64( slow_i64_to_f64, i64_to_f64 ); break; #ifdef EXTFLOAT80 case I64_TO_EXTF80: test_a_i64_z_extF80( slow_i64_to_extF80M, i64_to_extF80M ); break; #endif #ifdef FLOAT128 case I64_TO_F128: test_a_i64_z_f128( slow_i64_to_f128M, i64_to_f128M ); break; #endif /*-------------------------------------------------------------------- *--------------------------------------------------------------------*/ case F32_TO_UI32: test_a_f32_z_ui32_rx( slow_f32_to_ui32, f32_to_ui32, roundingMode, exact ); break; case F32_TO_UI64: test_a_f32_z_ui64_rx( slow_f32_to_ui64, f32_to_ui64, roundingMode, exact ); break; case F32_TO_I32: test_a_f32_z_i32_rx( slow_f32_to_i32, f32_to_i32, roundingMode, exact ); break; case F32_TO_I64: test_a_f32_z_i64_rx( slow_f32_to_i64, f32_to_i64, roundingMode, exact ); break; case F32_TO_UI32_R_MINMAG: test_a_f32_z_ui32_x( slow_f32_to_ui32_r_minMag, f32_to_ui32_r_minMag, exact ); break; case F32_TO_UI64_R_MINMAG: test_a_f32_z_ui64_x( slow_f32_to_ui64_r_minMag, f32_to_ui64_r_minMag, exact ); break; case F32_TO_I32_R_MINMAG: test_a_f32_z_i32_x( slow_f32_to_i32_r_minMag, f32_to_i32_r_minMag, exact ); break; case F32_TO_I64_R_MINMAG: test_a_f32_z_i64_x( slow_f32_to_i64_r_minMag, f32_to_i64_r_minMag, exact ); break; case F32_TO_F64: test_a_f32_z_f64( slow_f32_to_f64, f32_to_f64 ); break; #ifdef EXTFLOAT80 case F32_TO_EXTF80: test_a_f32_z_extF80( slow_f32_to_extF80M, f32_to_extF80M ); break; #endif #ifdef FLOAT128 case F32_TO_F128: test_a_f32_z_f128( slow_f32_to_f128M, f32_to_f128M ); break; #endif case F32_ROUNDTOINT: test_az_f32_rx( slow_f32_roundToInt, f32_roundToInt, roundingMode, exact ); break; case F32_ADD: trueFunction_abz_f32 = slow_f32_add; subjFunction_abz_f32 = f32_add; goto test_abz_f32; case F32_SUB: trueFunction_abz_f32 = slow_f32_sub; subjFunction_abz_f32 = f32_sub; goto test_abz_f32; case F32_MUL: trueFunction_abz_f32 = slow_f32_mul; subjFunction_abz_f32 = f32_mul; goto test_abz_f32; case F32_DIV: trueFunction_abz_f32 = slow_f32_div; subjFunction_abz_f32 = f32_div; goto test_abz_f32; case F32_REM: trueFunction_abz_f32 = slow_f32_rem; subjFunction_abz_f32 = f32_rem; test_abz_f32: test_abz_f32( trueFunction_abz_f32, subjFunction_abz_f32 ); break; case F32_MULADD: test_abcz_f32( slow_f32_mulAdd, f32_mulAdd ); break; case F32_SQRT: test_az_f32( slow_f32_sqrt, f32_sqrt ); break; case F32_EQ: trueFunction_ab_f32_z_bool = slow_f32_eq; subjFunction_ab_f32_z_bool = f32_eq; goto test_ab_f32_z_bool; case F32_LE: trueFunction_ab_f32_z_bool = slow_f32_le; subjFunction_ab_f32_z_bool = f32_le; goto test_ab_f32_z_bool; case F32_LT: trueFunction_ab_f32_z_bool = slow_f32_lt; subjFunction_ab_f32_z_bool = f32_lt; goto test_ab_f32_z_bool; case F32_EQ_SIGNALING: trueFunction_ab_f32_z_bool = slow_f32_eq_signaling; subjFunction_ab_f32_z_bool = f32_eq_signaling; goto test_ab_f32_z_bool; case F32_LE_QUIET: trueFunction_ab_f32_z_bool = slow_f32_le_quiet; subjFunction_ab_f32_z_bool = f32_le_quiet; goto test_ab_f32_z_bool; case F32_LT_QUIET: trueFunction_ab_f32_z_bool = slow_f32_lt_quiet; subjFunction_ab_f32_z_bool = f32_lt_quiet; test_ab_f32_z_bool: test_ab_f32_z_bool( trueFunction_ab_f32_z_bool, subjFunction_ab_f32_z_bool ); break; /*-------------------------------------------------------------------- *--------------------------------------------------------------------*/ case F64_TO_UI32: test_a_f64_z_ui32_rx( slow_f64_to_ui32, f64_to_ui32, roundingMode, exact ); break; case F64_TO_UI64: test_a_f64_z_ui64_rx( slow_f64_to_ui64, f64_to_ui64, roundingMode, exact ); break; case F64_TO_I32: test_a_f64_z_i32_rx( slow_f64_to_i32, f64_to_i32, roundingMode, exact ); break; case F64_TO_I64: test_a_f64_z_i64_rx( slow_f64_to_i64, f64_to_i64, roundingMode, exact ); break; case F64_TO_UI32_R_MINMAG: test_a_f64_z_ui32_x( slow_f64_to_ui32_r_minMag, f64_to_ui32_r_minMag, exact ); break; case F64_TO_UI64_R_MINMAG: test_a_f64_z_ui64_x( slow_f64_to_ui64_r_minMag, f64_to_ui64_r_minMag, exact ); break; case F64_TO_I32_R_MINMAG: test_a_f64_z_i32_x( slow_f64_to_i32_r_minMag, f64_to_i32_r_minMag, exact ); break; case F64_TO_I64_R_MINMAG: test_a_f64_z_i64_x( slow_f64_to_i64_r_minMag, f64_to_i64_r_minMag, exact ); break; case F64_TO_F32: test_a_f64_z_f32( slow_f64_to_f32, f64_to_f32 ); break; #ifdef EXTFLOAT80 case F64_TO_EXTF80: test_a_f64_z_extF80( slow_f64_to_extF80M, f64_to_extF80M ); break; #endif #ifdef FLOAT128 case F64_TO_F128: test_a_f64_z_f128( slow_f64_to_f128M, f64_to_f128M ); break; #endif case F64_ROUNDTOINT: test_az_f64_rx( slow_f64_roundToInt, f64_roundToInt, roundingMode, exact ); break; case F64_ADD: trueFunction_abz_f64 = slow_f64_add; subjFunction_abz_f64 = f64_add; goto test_abz_f64; case F64_SUB: trueFunction_abz_f64 = slow_f64_sub; subjFunction_abz_f64 = f64_sub; goto test_abz_f64; case F64_MUL: trueFunction_abz_f64 = slow_f64_mul; subjFunction_abz_f64 = f64_mul; goto test_abz_f64; case F64_DIV: trueFunction_abz_f64 = slow_f64_div; subjFunction_abz_f64 = f64_div; goto test_abz_f64; case F64_REM: trueFunction_abz_f64 = slow_f64_rem; subjFunction_abz_f64 = f64_rem; test_abz_f64: test_abz_f64( trueFunction_abz_f64, subjFunction_abz_f64 ); break; case F64_MULADD: test_abcz_f64( slow_f64_mulAdd, f64_mulAdd ); break; case F64_SQRT: test_az_f64( slow_f64_sqrt, f64_sqrt ); break; case F64_EQ: trueFunction_ab_f64_z_bool = slow_f64_eq; subjFunction_ab_f64_z_bool = f64_eq; goto test_ab_f64_z_bool; case F64_LE: trueFunction_ab_f64_z_bool = slow_f64_le; subjFunction_ab_f64_z_bool = f64_le; goto test_ab_f64_z_bool; case F64_LT: trueFunction_ab_f64_z_bool = slow_f64_lt; subjFunction_ab_f64_z_bool = f64_lt; goto test_ab_f64_z_bool; case F64_EQ_SIGNALING: trueFunction_ab_f64_z_bool = slow_f64_eq_signaling; subjFunction_ab_f64_z_bool = f64_eq_signaling; goto test_ab_f64_z_bool; case F64_LE_QUIET: trueFunction_ab_f64_z_bool = slow_f64_le_quiet; subjFunction_ab_f64_z_bool = f64_le_quiet; goto test_ab_f64_z_bool; case F64_LT_QUIET: trueFunction_ab_f64_z_bool = slow_f64_lt_quiet; subjFunction_ab_f64_z_bool = f64_lt_quiet; test_ab_f64_z_bool: test_ab_f64_z_bool( trueFunction_ab_f64_z_bool, subjFunction_ab_f64_z_bool ); break; /*-------------------------------------------------------------------- *--------------------------------------------------------------------*/ #ifdef EXTFLOAT80 case EXTF80_TO_UI32: test_a_extF80_z_ui32_rx( slow_extF80M_to_ui32, extF80M_to_ui32, roundingMode, exact ); break; case EXTF80_TO_UI64: test_a_extF80_z_ui64_rx( slow_extF80M_to_ui64, extF80M_to_ui64, roundingMode, exact ); break; case EXTF80_TO_I32: test_a_extF80_z_i32_rx( slow_extF80M_to_i32, extF80M_to_i32, roundingMode, exact ); break; case EXTF80_TO_I64: test_a_extF80_z_i64_rx( slow_extF80M_to_i64, extF80M_to_i64, roundingMode, exact ); break; case EXTF80_TO_UI32_R_MINMAG: test_a_extF80_z_ui32_x( slow_extF80M_to_ui32_r_minMag, extF80M_to_ui32_r_minMag, exact ); break; case EXTF80_TO_UI64_R_MINMAG: test_a_extF80_z_ui64_x( slow_extF80M_to_ui64_r_minMag, extF80M_to_ui64_r_minMag, exact ); break; case EXTF80_TO_I32_R_MINMAG: test_a_extF80_z_i32_x( slow_extF80M_to_i32_r_minMag, extF80M_to_i32_r_minMag, exact ); break; case EXTF80_TO_I64_R_MINMAG: test_a_extF80_z_i64_x( slow_extF80M_to_i64_r_minMag, extF80M_to_i64_r_minMag, exact ); break; case EXTF80_TO_F32: test_a_extF80_z_f32( slow_extF80M_to_f32, extF80M_to_f32 ); break; case EXTF80_TO_F64: test_a_extF80_z_f64( slow_extF80M_to_f64, extF80M_to_f64 ); break; #ifdef FLOAT128 case EXTF80_TO_F128: test_a_extF80_z_f128( slow_extF80M_to_f128M, extF80M_to_f128M ); break; #endif case EXTF80_ROUNDTOINT: test_az_extF80_rx( slow_extF80M_roundToInt, extF80M_roundToInt, roundingMode, exact ); break; case EXTF80_ADD: trueFunction_abz_extF80M = slow_extF80M_add; subjFunction_abz_extF80M = extF80M_add; goto test_abz_extF80; case EXTF80_SUB: trueFunction_abz_extF80M = slow_extF80M_sub; subjFunction_abz_extF80M = extF80M_sub; goto test_abz_extF80; case EXTF80_MUL: trueFunction_abz_extF80M = slow_extF80M_mul; subjFunction_abz_extF80M = extF80M_mul; goto test_abz_extF80; case EXTF80_DIV: trueFunction_abz_extF80M = slow_extF80M_div; subjFunction_abz_extF80M = extF80M_div; goto test_abz_extF80; case EXTF80_REM: trueFunction_abz_extF80M = slow_extF80M_rem; subjFunction_abz_extF80M = extF80M_rem; test_abz_extF80: test_abz_extF80( trueFunction_abz_extF80M, subjFunction_abz_extF80M ); break; case EXTF80_SQRT: test_az_extF80( slow_extF80M_sqrt, extF80M_sqrt ); break; case EXTF80_EQ: trueFunction_ab_extF80M_z_bool = slow_extF80M_eq; subjFunction_ab_extF80M_z_bool = extF80M_eq; goto test_ab_extF80_z_bool; case EXTF80_LE: trueFunction_ab_extF80M_z_bool = slow_extF80M_le; subjFunction_ab_extF80M_z_bool = extF80M_le; goto test_ab_extF80_z_bool; case EXTF80_LT: trueFunction_ab_extF80M_z_bool = slow_extF80M_lt; subjFunction_ab_extF80M_z_bool = extF80M_lt; goto test_ab_extF80_z_bool; case EXTF80_EQ_SIGNALING: trueFunction_ab_extF80M_z_bool = slow_extF80M_eq_signaling; subjFunction_ab_extF80M_z_bool = extF80M_eq_signaling; goto test_ab_extF80_z_bool; case EXTF80_LE_QUIET: trueFunction_ab_extF80M_z_bool = slow_extF80M_le_quiet; subjFunction_ab_extF80M_z_bool = extF80M_le_quiet; goto test_ab_extF80_z_bool; case EXTF80_LT_QUIET: trueFunction_ab_extF80M_z_bool = slow_extF80M_lt_quiet; subjFunction_ab_extF80M_z_bool = extF80M_lt_quiet; test_ab_extF80_z_bool: test_ab_extF80_z_bool( trueFunction_ab_extF80M_z_bool, subjFunction_ab_extF80M_z_bool ); break; #endif /*-------------------------------------------------------------------- *--------------------------------------------------------------------*/ #ifdef FLOAT128 case F128_TO_UI32: test_a_f128_z_ui32_rx( slow_f128M_to_ui32, f128M_to_ui32, roundingMode, exact ); break; case F128_TO_UI64: test_a_f128_z_ui64_rx( slow_f128M_to_ui64, f128M_to_ui64, roundingMode, exact ); break; case F128_TO_I32: test_a_f128_z_i32_rx( slow_f128M_to_i32, f128M_to_i32, roundingMode, exact ); break; case F128_TO_I64: test_a_f128_z_i64_rx( slow_f128M_to_i64, f128M_to_i64, roundingMode, exact ); break; case F128_TO_UI32_R_MINMAG: test_a_f128_z_ui32_x( slow_f128M_to_ui32_r_minMag, f128M_to_ui32_r_minMag, exact ); break; case F128_TO_UI64_R_MINMAG: test_a_f128_z_ui64_x( slow_f128M_to_ui64_r_minMag, f128M_to_ui64_r_minMag, exact ); break; case F128_TO_I32_R_MINMAG: test_a_f128_z_i32_x( slow_f128M_to_i32_r_minMag, f128M_to_i32_r_minMag, exact ); break; case F128_TO_I64_R_MINMAG: test_a_f128_z_i64_x( slow_f128M_to_i64_r_minMag, f128M_to_i64_r_minMag, exact ); break; case F128_TO_F32: test_a_f128_z_f32( slow_f128M_to_f32, f128M_to_f32 ); break; case F128_TO_F64: test_a_f128_z_f64( slow_f128M_to_f64, f128M_to_f64 ); break; #ifdef EXTFLOAT80 case F128_TO_EXTF80: test_a_f128_z_extF80( slow_f128M_to_extF80M, f128M_to_extF80M ); break; #endif case F128_ROUNDTOINT: test_az_f128_rx( slow_f128M_roundToInt, f128M_roundToInt, roundingMode, exact ); break; case F128_ADD: trueFunction_abz_f128M = slow_f128M_add; subjFunction_abz_f128M = f128M_add; goto test_abz_f128; case F128_SUB: trueFunction_abz_f128M = slow_f128M_sub; subjFunction_abz_f128M = f128M_sub; goto test_abz_f128; case F128_MUL: trueFunction_abz_f128M = slow_f128M_mul; subjFunction_abz_f128M = f128M_mul; goto test_abz_f128; case F128_DIV: trueFunction_abz_f128M = slow_f128M_div; subjFunction_abz_f128M = f128M_div; goto test_abz_f128; case F128_REM: trueFunction_abz_f128M = slow_f128M_rem; subjFunction_abz_f128M = f128M_rem; test_abz_f128: test_abz_f128( trueFunction_abz_f128M, subjFunction_abz_f128M ); break; case F128_MULADD: test_abcz_f128( slow_f128M_mulAdd, f128M_mulAdd ); break; case F128_SQRT: test_az_f128( slow_f128M_sqrt, f128M_sqrt ); break; case F128_EQ: trueFunction_ab_f128M_z_bool = slow_f128M_eq; subjFunction_ab_f128M_z_bool = f128M_eq; goto test_ab_f128_z_bool; case F128_LE: trueFunction_ab_f128M_z_bool = slow_f128M_le; subjFunction_ab_f128M_z_bool = f128M_le; goto test_ab_f128_z_bool; case F128_LT: trueFunction_ab_f128M_z_bool = slow_f128M_lt; subjFunction_ab_f128M_z_bool = f128M_lt; goto test_ab_f128_z_bool; case F128_EQ_SIGNALING: trueFunction_ab_f128M_z_bool = slow_f128M_eq_signaling; subjFunction_ab_f128M_z_bool = f128M_eq_signaling; goto test_ab_f128_z_bool; case F128_LE_QUIET: trueFunction_ab_f128M_z_bool = slow_f128M_le_quiet; subjFunction_ab_f128M_z_bool = f128M_le_quiet; goto test_ab_f128_z_bool; case F128_LT_QUIET: trueFunction_ab_f128M_z_bool = slow_f128M_lt_quiet; subjFunction_ab_f128M_z_bool = f128M_lt_quiet; test_ab_f128_z_bool: test_ab_f128_z_bool( trueFunction_ab_f128M_z_bool, subjFunction_ab_f128M_z_bool ); break; #endif } if ( (verCases_errorStop && verCases_anyErrors) || verCases_stop ) { verCases_exitWithStatus(); } } enum { EXACT_FALSE = 1, EXACT_TRUE }; static void testFunction( int functionCode, uint_fast8_t roundingPrecisionIn, int roundingCodeIn, int tininessCodeIn, int exactCodeIn ) { int functionAttribs; uint_fast8_t roundingPrecision; int roundingCode; uint_fast8_t roundingMode; int exactCode; bool exact; int tininessCode; uint_fast8_t tininessMode; functionAttribs = functionInfos[functionCode].attribs; verCases_functionNamePtr = functionInfos[functionCode].namePtr; roundingPrecision = 32; for (;;) { if ( ! (functionAttribs & FUNC_EFF_ROUNDINGPRECISION) ) { roundingPrecision = 0; } else if ( roundingPrecisionIn ) { roundingPrecision = roundingPrecisionIn; } #ifdef EXTFLOAT80 verCases_roundingPrecision = roundingPrecision; if ( roundingPrecision ) { slow_extF80_roundingPrecision = roundingPrecision; extF80_roundingPrecision = roundingPrecision; } #endif for ( roundingCode = 1; roundingCode < NUM_ROUNDINGMODES; ++roundingCode ) { if ( ! (functionAttribs & (FUNC_ARG_ROUNDINGMODE | FUNC_EFF_ROUNDINGMODE)) ) { roundingCode = 0; } else if ( roundingCodeIn ) { roundingCode = roundingCodeIn; } verCases_roundingCode = roundingCode; if ( roundingCode ) { roundingMode = roundingModes[roundingCode]; if ( functionAttribs & FUNC_EFF_ROUNDINGMODE ) { slowfloat_roundingMode = roundingMode; softfloat_roundingMode = roundingMode; } } for ( exactCode = EXACT_FALSE; exactCode <= EXACT_TRUE; ++exactCode ) { if ( ! (functionAttribs & FUNC_ARG_EXACT) ) { exactCode = 0; } else if ( exactCodeIn ) { exactCode = exactCodeIn; } exact = (exactCode == EXACT_TRUE); verCases_usesExact = (exactCode != 0); verCases_exact = exact; for ( tininessCode = 1; tininessCode < NUM_TININESSMODES; ++tininessCode ) { if ( ! (functionAttribs & (roundingPrecision && (roundingPrecision < 80) ? FUNC_EFF_TININESSMODE_REDUCEDPREC : FUNC_EFF_TININESSMODE)) ) { tininessCode = 0; } else if ( tininessCodeIn ) { tininessCode = tininessCodeIn; } verCases_tininessCode = tininessCode; if ( tininessCode ) { tininessMode = tininessModes[tininessCode]; slowfloat_detectTininess = tininessMode; softfloat_detectTininess = tininessMode; } testFunctionInstance( functionCode, roundingMode, exact ); if ( tininessCodeIn || ! tininessCode ) break; } if ( exactCodeIn || ! exactCode ) break; } if ( roundingCodeIn || ! roundingCode ) break; } if ( roundingPrecisionIn || ! roundingPrecision ) break; if ( roundingPrecision == 80 ) { break; } else if ( roundingPrecision == 64 ) { roundingPrecision = 80; } else if ( roundingPrecision == 32 ) { roundingPrecision = 64; } } } int main( int argc, char *argv[] ) { bool haveFunctionArg; int functionCode, numOperands; uint_fast8_t roundingPrecision; int roundingCode, tininessCode, exactCode; const char *argPtr; long i; /*------------------------------------------------------------------------ *------------------------------------------------------------------------*/ fail_programName = "testsoftfloat"; if ( argc <= 1 ) goto writeHelpMessage; genCases_setLevel( 1 ); verCases_maxErrorCount = 20; testLoops_trueFlagsPtr = &slowfloat_exceptionFlags; testLoops_subjFlagsFunction = softfloat_clearExceptionFlags; haveFunctionArg = false; functionCode = 0; numOperands = 0; roundingPrecision = 0; roundingCode = 0; tininessCode = 0; exactCode = 0; for (;;) { --argc; if ( ! argc ) break; argPtr = *++argv; if ( ! argPtr ) break; if ( argPtr[0] == '-' ) ++argPtr; if ( ! strcmp( argPtr, "help" ) || ! strcmp( argPtr, "-help" ) || ! strcmp( argPtr, "h" ) ) { writeHelpMessage: fputs( "testsoftfloat [