| |
| /*============================================================================ |
| |
| 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 <stdbool.h> |
| #include <stdint.h> |
| #include <string.h> |
| #include <stdlib.h> |
| #include <stdio.h> |
| #include <signal.h> |
| #include "platform.h" |
| #include "fail.h" |
| #include "softfloat.h" |
| #include "subjfloat_config.h" |
| #include "subjfloat.h" |
| #include "functions.h" |
| #include "genCases.h" |
| #include "verCases.h" |
| #include "testLoops.h" |
| |
| static void catchSIGINT( int signalCode ) |
| { |
| |
| if ( verCases_stop ) exit( EXIT_FAILURE ); |
| verCases_stop = true; |
| |
| } |
| |
| static void (*subjFunctionPtr)(); |
| |
| typedef float32_t funcType_a_ui32_z_f32( uint_fast32_t ); |
| typedef float64_t funcType_a_ui32_z_f64( uint_fast32_t ); |
| #ifdef EXTFLOAT80 |
| typedef void funcType_a_ui32_z_extF80( uint_fast32_t, extFloat80_t * ); |
| #endif |
| #ifdef FLOAT128 |
| typedef void funcType_a_ui32_z_f128( uint_fast32_t, float128_t * ); |
| #endif |
| typedef float32_t funcType_a_ui64_z_f32( uint_fast64_t ); |
| typedef float64_t funcType_a_ui64_z_f64( uint_fast64_t ); |
| #ifdef EXTFLOAT80 |
| typedef void funcType_a_ui64_z_extF80( uint_fast64_t, extFloat80_t * ); |
| #endif |
| #ifdef FLOAT128 |
| typedef void funcType_a_ui64_z_f128( uint_fast64_t, float128_t * ); |
| #endif |
| typedef float32_t funcType_a_i32_z_f32( int_fast32_t ); |
| typedef float64_t funcType_a_i32_z_f64( int_fast32_t ); |
| #ifdef EXTFLOAT80 |
| typedef void funcType_a_i32_z_extF80( int_fast32_t, extFloat80_t * ); |
| #endif |
| #ifdef FLOAT128 |
| typedef void funcType_a_i32_z_f128( int_fast32_t, float128_t * ); |
| #endif |
| typedef float32_t funcType_a_i64_z_f32( int_fast64_t ); |
| typedef float64_t funcType_a_i64_z_f64( int_fast64_t ); |
| #ifdef EXTFLOAT80 |
| typedef void funcType_a_i64_z_extF80( int_fast64_t, extFloat80_t * ); |
| #endif |
| #ifdef FLOAT128 |
| typedef void funcType_a_i64_z_f128( int_fast64_t, float128_t * ); |
| #endif |
| |
| typedef uint_fast32_t funcType_a_f32_z_ui32( float32_t ); |
| typedef uint_fast64_t funcType_a_f32_z_ui64( float32_t ); |
| typedef int_fast32_t funcType_a_f32_z_i32( float32_t ); |
| typedef int_fast64_t funcType_a_f32_z_i64( float32_t ); |
| typedef float64_t funcType_a_f32_z_f64( float32_t ); |
| #ifdef EXTFLOAT80 |
| typedef void funcType_a_f32_z_extF80( float32_t, extFloat80_t * ); |
| #endif |
| #ifdef FLOAT128 |
| typedef void funcType_a_f32_z_f128( float32_t, float128_t * ); |
| #endif |
| typedef float32_t funcType_az_f32( float32_t ); |
| typedef float32_t funcType_abz_f32( float32_t, float32_t ); |
| typedef float32_t funcType_abcz_f32( float32_t, float32_t, float32_t ); |
| typedef bool funcType_ab_f32_z_bool( float32_t, float32_t ); |
| |
| typedef uint_fast32_t funcType_a_f64_z_ui32( float64_t ); |
| typedef uint_fast64_t funcType_a_f64_z_ui64( float64_t ); |
| typedef int_fast32_t funcType_a_f64_z_i32( float64_t ); |
| typedef int_fast64_t funcType_a_f64_z_i64( float64_t ); |
| typedef float32_t funcType_a_f64_z_f32( float64_t ); |
| #ifdef EXTFLOAT80 |
| typedef void funcType_a_f64_z_extF80( float64_t, extFloat80_t * ); |
| #endif |
| #ifdef FLOAT128 |
| typedef void funcType_a_f64_z_f128( float64_t, float128_t * ); |
| #endif |
| typedef float64_t funcType_az_f64( float64_t ); |
| typedef float64_t funcType_abz_f64( float64_t, float64_t ); |
| typedef float64_t funcType_abcz_f64( float64_t, float64_t, float64_t ); |
| typedef bool funcType_ab_f64_z_bool( float64_t, float64_t ); |
| |
| #ifdef EXTFLOAT80 |
| typedef uint_fast32_t funcType_a_extF80_z_ui32( const extFloat80_t * ); |
| typedef uint_fast64_t funcType_a_extF80_z_ui64( const extFloat80_t * ); |
| typedef int_fast32_t funcType_a_extF80_z_i32( const extFloat80_t * ); |
| typedef int_fast64_t funcType_a_extF80_z_i64( const extFloat80_t * ); |
| typedef float32_t funcType_a_extF80_z_f32( const extFloat80_t * ); |
| typedef float64_t funcType_a_extF80_z_f64( const extFloat80_t * ); |
| #ifdef FLOAT128 |
| typedef void funcType_a_extF80_z_f128( const extFloat80_t *, float128_t * ); |
| #endif |
| typedef void funcType_az_extF80( const extFloat80_t *, extFloat80_t * ); |
| typedef |
| void |
| funcType_abz_extF80( |
| const extFloat80_t *, const extFloat80_t *, extFloat80_t * ); |
| typedef |
| bool funcType_ab_extF80_z_bool( const extFloat80_t *, const extFloat80_t * ); |
| #endif |
| |
| #ifdef FLOAT128 |
| typedef uint_fast32_t funcType_a_f128_z_ui32( const float128_t * ); |
| typedef uint_fast64_t funcType_a_f128_z_ui64( const float128_t * ); |
| typedef int_fast32_t funcType_a_f128_z_i32( const float128_t * ); |
| typedef int_fast64_t funcType_a_f128_z_i64( const float128_t * ); |
| typedef float32_t funcType_a_f128_z_f32( const float128_t * ); |
| typedef float64_t funcType_a_f128_z_f64( const float128_t * ); |
| #ifdef EXTFLOAT80 |
| typedef void funcType_a_f128_z_extF80( const float128_t *, extFloat80_t * ); |
| #endif |
| typedef void funcType_az_f128( const float128_t *, float128_t * ); |
| typedef |
| void |
| funcType_abz_f128( const float128_t *, const float128_t *, float128_t * ); |
| typedef |
| void |
| funcType_abcz_f128( |
| const float128_t *, const float128_t *, const float128_t *, float128_t * |
| ); |
| typedef bool funcType_ab_f128_z_bool( const float128_t *, const float128_t * ); |
| #endif |
| |
| static |
| uint_fast32_t |
| subjFunction_a_f32_z_ui32_rx( |
| float32_t a, uint_fast8_t roundingMode, bool exact ) |
| { |
| |
| return ((funcType_a_f32_z_ui32 *) subjFunctionPtr)( a ); |
| |
| } |
| |
| static |
| uint_fast64_t |
| subjFunction_a_f32_z_ui64_rx( |
| float32_t a, uint_fast8_t roundingMode, bool exact ) |
| { |
| |
| return ((funcType_a_f32_z_ui64 *) subjFunctionPtr)( a ); |
| |
| } |
| |
| static |
| int_fast32_t |
| subjFunction_a_f32_z_i32_rx( |
| float32_t a, uint_fast8_t roundingMode, bool exact ) |
| { |
| |
| return ((funcType_a_f32_z_i32 *) subjFunctionPtr)( a ); |
| |
| } |
| |
| static |
| int_fast64_t |
| subjFunction_a_f32_z_i64_rx( |
| float32_t a, uint_fast8_t roundingMode, bool exact ) |
| { |
| |
| return ((funcType_a_f32_z_i64 *) subjFunctionPtr)( a ); |
| |
| } |
| |
| static |
| float32_t |
| subjFunction_az_f32_rx( float32_t a, uint_fast8_t roundingMode, bool exact ) |
| { |
| |
| return ((funcType_az_f32 *) subjFunctionPtr)( a ); |
| |
| } |
| |
| static |
| uint_fast32_t |
| subjFunction_a_f64_z_ui32_rx( |
| float64_t a, uint_fast8_t roundingMode, bool exact ) |
| { |
| |
| return ((funcType_a_f64_z_ui32 *) subjFunctionPtr)( a ); |
| |
| } |
| |
| static |
| uint_fast64_t |
| subjFunction_a_f64_z_ui64_rx( |
| float64_t a, uint_fast8_t roundingMode, bool exact ) |
| { |
| |
| return ((funcType_a_f64_z_ui64 *) subjFunctionPtr)( a ); |
| |
| } |
| |
| static |
| int_fast32_t |
| subjFunction_a_f64_z_i32_rx( |
| float64_t a, uint_fast8_t roundingMode, bool exact ) |
| { |
| |
| return ((funcType_a_f64_z_i32 *) subjFunctionPtr)( a ); |
| |
| } |
| |
| static |
| int_fast64_t |
| subjFunction_a_f64_z_i64_rx( |
| float64_t a, uint_fast8_t roundingMode, bool exact ) |
| { |
| |
| return ((funcType_a_f64_z_i64 *) subjFunctionPtr)( a ); |
| |
| } |
| |
| static |
| float64_t |
| subjFunction_az_f64_rx( float64_t a, uint_fast8_t roundingMode, bool exact ) |
| { |
| |
| return ((funcType_az_f64 *) subjFunctionPtr)( a ); |
| |
| } |
| |
| #ifdef EXTFLOAT80 |
| |
| static |
| uint_fast32_t |
| subjFunction_a_extF80_z_ui32_rx( |
| const extFloat80_t *aPtr, uint_fast8_t roundingMode, bool exact ) |
| { |
| |
| return ((funcType_a_extF80_z_ui32 *) subjFunctionPtr)( aPtr ); |
| |
| } |
| |
| static |
| uint_fast64_t |
| subjFunction_a_extF80_z_ui64_rx( |
| const extFloat80_t *aPtr, uint_fast8_t roundingMode, bool exact ) |
| { |
| |
| return ((funcType_a_extF80_z_ui64 *) subjFunctionPtr)( aPtr ); |
| |
| } |
| |
| static |
| int_fast32_t |
| subjFunction_a_extF80_z_i32_rx( |
| const extFloat80_t *aPtr, uint_fast8_t roundingMode, bool exact ) |
| { |
| |
| return ((funcType_a_extF80_z_i32 *) subjFunctionPtr)( aPtr ); |
| |
| } |
| |
| static |
| int_fast64_t |
| subjFunction_a_extF80_z_i64_rx( |
| const extFloat80_t *aPtr, uint_fast8_t roundingMode, bool exact ) |
| { |
| |
| return ((funcType_a_extF80_z_i64 *) subjFunctionPtr)( aPtr ); |
| |
| } |
| |
| static |
| void |
| subjFunction_az_extF80_rx( |
| const extFloat80_t *aPtr, |
| uint_fast8_t roundingMode, |
| bool exact, |
| extFloat80_t *zPtr |
| ) |
| { |
| |
| return ((funcType_az_extF80 *) subjFunctionPtr)( aPtr, zPtr ); |
| |
| } |
| |
| #endif |
| |
| #ifdef FLOAT128 |
| |
| static |
| uint_fast32_t |
| subjFunction_a_f128_z_ui32_rx( |
| const float128_t *aPtr, uint_fast8_t roundingMode, bool exact ) |
| { |
| |
| return ((funcType_a_f128_z_ui32 *) subjFunctionPtr)( aPtr ); |
| |
| } |
| |
| static |
| uint_fast64_t |
| subjFunction_a_f128_z_ui64_rx( |
| const float128_t *aPtr, uint_fast8_t roundingMode, bool exact ) |
| { |
| |
| return ((funcType_a_f128_z_ui64 *) subjFunctionPtr)( aPtr ); |
| |
| } |
| |
| static |
| int_fast32_t |
| subjFunction_a_f128_z_i32_rx( |
| const float128_t *aPtr, uint_fast8_t roundingMode, bool exact ) |
| { |
| |
| return ((funcType_a_f128_z_i32 *) subjFunctionPtr)( aPtr ); |
| |
| } |
| |
| static |
| int_fast64_t |
| subjFunction_a_f128_z_i64_rx( |
| const float128_t *aPtr, uint_fast8_t roundingMode, bool exact ) |
| { |
| |
| return ((funcType_a_f128_z_i64 *) subjFunctionPtr)( aPtr ); |
| |
| } |
| |
| static |
| void |
| subjFunction_az_f128_rx( |
| const float128_t *aPtr, |
| uint_fast8_t roundingMode, |
| bool exact, |
| float128_t *zPtr |
| ) |
| { |
| |
| return ((funcType_az_f128 *) subjFunctionPtr)( aPtr, zPtr ); |
| |
| } |
| |
| #endif |
| |
| static |
| void |
| testFunctionInstance( |
| int functionCode, uint_fast8_t roundingMode, bool exact ) |
| { |
| funcType_abz_f32 *trueFunction_abz_f32; |
| funcType_ab_f32_z_bool *trueFunction_ab_f32_z_bool; |
| funcType_abz_f64 *trueFunction_abz_f64; |
| funcType_ab_f64_z_bool *trueFunction_ab_f64_z_bool; |
| funcType_abz_extF80 *trueFunction_abz_extF80; |
| funcType_ab_extF80_z_bool *trueFunction_ab_extF80_z_bool; |
| funcType_abz_f128 *trueFunction_abz_f128; |
| funcType_ab_f128_z_bool *trueFunction_ab_f128_z_bool; |
| |
| fputs( "Testing ", stderr ); |
| verCases_writeFunctionName( stderr ); |
| fputs( ".\n", stderr ); |
| switch ( functionCode ) { |
| /*-------------------------------------------------------------------- |
| *--------------------------------------------------------------------*/ |
| #ifdef SUBJ_UI32_TO_F32 |
| case UI32_TO_F32: |
| test_a_ui32_z_f32( |
| ui32_to_f32, (funcType_a_ui32_z_f32 *) subjFunctionPtr ); |
| break; |
| #endif |
| #ifdef SUBJ_UI32_TO_F64 |
| case UI32_TO_F64: |
| test_a_ui32_z_f64( |
| ui32_to_f64, (funcType_a_ui32_z_f64 *) subjFunctionPtr ); |
| break; |
| #endif |
| #ifdef EXTFLOAT80 |
| #ifdef SUBJ_UI32_TO_EXTF80 |
| case UI32_TO_EXTF80: |
| test_a_ui32_z_extF80( |
| ui32_to_extF80M, (funcType_a_ui32_z_extF80 *) subjFunctionPtr ); |
| break; |
| #endif |
| #endif |
| #ifdef FLOAT128 |
| #ifdef SUBJ_UI32_TO_F128 |
| case UI32_TO_F128: |
| test_a_ui32_z_f128( |
| ui32_to_f128M, (funcType_a_ui32_z_f128 *) subjFunctionPtr ); |
| break; |
| #endif |
| #endif |
| #ifdef SUBJ_UI64_TO_F32 |
| case UI64_TO_F32: |
| test_a_ui64_z_f32( |
| ui64_to_f32, (funcType_a_ui64_z_f32 *) subjFunctionPtr ); |
| break; |
| #endif |
| #ifdef SUBJ_UI64_TO_F64 |
| case UI64_TO_F64: |
| test_a_ui64_z_f64( |
| ui64_to_f64, (funcType_a_ui64_z_f64 *) subjFunctionPtr ); |
| break; |
| #endif |
| #ifdef EXTFLOAT80 |
| #ifdef SUBJ_UI64_TO_EXTF80 |
| case UI64_TO_EXTF80: |
| test_a_ui64_z_extF80( |
| ui64_to_extF80M, (funcType_a_ui64_z_extF80 *) subjFunctionPtr ); |
| break; |
| #endif |
| #endif |
| #ifdef FLOAT128 |
| #ifdef SUBJ_UI64_TO_F128 |
| case UI64_TO_F128: |
| test_a_ui64_z_f128( |
| ui64_to_f128M, (funcType_a_ui64_z_f128 *) subjFunctionPtr ); |
| break; |
| #endif |
| #endif |
| #ifdef SUBJ_I32_TO_F32 |
| case I32_TO_F32: |
| test_a_i32_z_f32( |
| i32_to_f32, (funcType_a_i32_z_f32 *) subjFunctionPtr ); |
| break; |
| #endif |
| #ifdef SUBJ_I32_TO_F64 |
| case I32_TO_F64: |
| test_a_i32_z_f64( |
| i32_to_f64, (funcType_a_i32_z_f64 *) subjFunctionPtr ); |
| break; |
| #endif |
| #ifdef EXTFLOAT80 |
| #ifdef SUBJ_I32_TO_EXTF80 |
| case I32_TO_EXTF80: |
| test_a_i32_z_extF80( |
| i32_to_extF80M, (funcType_a_i32_z_extF80 *) subjFunctionPtr ); |
| break; |
| #endif |
| #endif |
| #ifdef FLOAT128 |
| #ifdef SUBJ_I32_TO_F128 |
| case I32_TO_F128: |
| test_a_i32_z_f128( |
| i32_to_f128M, (funcType_a_i32_z_f128 *) subjFunctionPtr ); |
| break; |
| #endif |
| #endif |
| #ifdef SUBJ_I64_TO_F32 |
| case I64_TO_F32: |
| test_a_i64_z_f32( |
| i64_to_f32, (funcType_a_i64_z_f32 *) subjFunctionPtr ); |
| break; |
| #endif |
| #ifdef SUBJ_I64_TO_F64 |
| case I64_TO_F64: |
| test_a_i64_z_f64( |
| i64_to_f64, (funcType_a_i64_z_f64 *) subjFunctionPtr ); |
| break; |
| #endif |
| #ifdef EXTFLOAT80 |
| #ifdef SUBJ_I64_TO_EXTF80 |
| case I64_TO_EXTF80: |
| test_a_i64_z_extF80( |
| i64_to_extF80M, (funcType_a_i64_z_extF80 *) subjFunctionPtr ); |
| break; |
| #endif |
| #endif |
| #ifdef FLOAT128 |
| #ifdef SUBJ_I64_TO_F128 |
| case I64_TO_F128: |
| test_a_i64_z_f128( |
| i64_to_f128M, (funcType_a_i64_z_f128 *) subjFunctionPtr ); |
| break; |
| #endif |
| #endif |
| /*-------------------------------------------------------------------- |
| *--------------------------------------------------------------------*/ |
| case F32_TO_UI32: |
| test_a_f32_z_ui32_rx( |
| f32_to_ui32, subjFunction_a_f32_z_ui32_rx, roundingMode, exact ); |
| break; |
| case F32_TO_UI64: |
| test_a_f32_z_ui64_rx( |
| f32_to_ui64, subjFunction_a_f32_z_ui64_rx, roundingMode, exact ); |
| break; |
| case F32_TO_I32: |
| test_a_f32_z_i32_rx( |
| f32_to_i32, subjFunction_a_f32_z_i32_rx, roundingMode, exact ); |
| break; |
| case F32_TO_I64: |
| test_a_f32_z_i64_rx( |
| f32_to_i64, subjFunction_a_f32_z_i64_rx, roundingMode, exact ); |
| break; |
| #ifdef SUBJ_F32_TO_F64 |
| case F32_TO_F64: |
| test_a_f32_z_f64( |
| f32_to_f64, (funcType_a_f32_z_f64 *) subjFunctionPtr ); |
| break; |
| #endif |
| #ifdef EXTFLOAT80 |
| #ifdef SUBJ_F32_TO_EXTF80 |
| case F32_TO_EXTF80: |
| test_a_f32_z_extF80( |
| f32_to_extF80M, (funcType_a_f32_z_extF80 *) subjFunctionPtr ); |
| break; |
| #endif |
| #endif |
| #ifdef FLOAT128 |
| #ifdef SUBJ_F32_TO_F128 |
| case F32_TO_F128: |
| test_a_f32_z_f128( |
| f32_to_f128M, (funcType_a_f32_z_f128 *) subjFunctionPtr ); |
| break; |
| #endif |
| #endif |
| case F32_ROUNDTOINT: |
| test_az_f32_rx( |
| f32_roundToInt, subjFunction_az_f32_rx, roundingMode, exact ); |
| break; |
| #ifdef SUBJ_F32_ADD |
| case F32_ADD: |
| trueFunction_abz_f32 = f32_add; |
| goto test_abz_f32; |
| #endif |
| #ifdef SUBJ_F32_SUB |
| case F32_SUB: |
| trueFunction_abz_f32 = f32_sub; |
| goto test_abz_f32; |
| #endif |
| #ifdef SUBJ_F32_MUL |
| case F32_MUL: |
| trueFunction_abz_f32 = f32_mul; |
| goto test_abz_f32; |
| #endif |
| #ifdef SUBJ_F32_MULADD |
| case F32_MULADD: |
| test_abcz_f32( f32_mulAdd, (funcType_abcz_f32 *) subjFunctionPtr ); |
| break; |
| #endif |
| #ifdef SUBJ_F32_DIV |
| case F32_DIV: |
| trueFunction_abz_f32 = f32_div; |
| goto test_abz_f32; |
| #endif |
| #ifdef SUBJ_F32_REM |
| case F32_REM: |
| trueFunction_abz_f32 = f32_rem; |
| goto test_abz_f32; |
| #endif |
| test_abz_f32: |
| test_abz_f32( |
| trueFunction_abz_f32, (funcType_abz_f32 *) subjFunctionPtr ); |
| break; |
| #ifdef SUBJ_F32_SQRT |
| case F32_SQRT: |
| test_az_f32( f32_sqrt, (funcType_az_f32 *) subjFunctionPtr ); |
| break; |
| #endif |
| #ifdef SUBJ_F32_EQ |
| case F32_EQ: |
| trueFunction_ab_f32_z_bool = f32_eq; |
| goto test_ab_f32_z_bool; |
| #endif |
| #ifdef SUBJ_F32_LE |
| case F32_LE: |
| trueFunction_ab_f32_z_bool = f32_le; |
| goto test_ab_f32_z_bool; |
| #endif |
| #ifdef SUBJ_F32_LT |
| case F32_LT: |
| trueFunction_ab_f32_z_bool = f32_lt; |
| goto test_ab_f32_z_bool; |
| #endif |
| #ifdef SUBJ_F32_EQ_SIGNALING |
| case F32_EQ_SIGNALING: |
| trueFunction_ab_f32_z_bool = f32_eq_signaling; |
| goto test_ab_f32_z_bool; |
| #endif |
| #ifdef SUBJ_F32_LE_QUIET |
| case F32_LE_QUIET: |
| trueFunction_ab_f32_z_bool = f32_le_quiet; |
| goto test_ab_f32_z_bool; |
| #endif |
| #ifdef SUBJ_F32_LT_QUIET |
| case F32_LT_QUIET: |
| trueFunction_ab_f32_z_bool = f32_lt_quiet; |
| goto test_ab_f32_z_bool; |
| #endif |
| test_ab_f32_z_bool: |
| test_ab_f32_z_bool( |
| trueFunction_ab_f32_z_bool, |
| (funcType_ab_f32_z_bool *) subjFunctionPtr |
| ); |
| break; |
| /*-------------------------------------------------------------------- |
| *--------------------------------------------------------------------*/ |
| case F64_TO_UI32: |
| test_a_f64_z_ui32_rx( |
| f64_to_ui32, subjFunction_a_f64_z_ui32_rx, roundingMode, exact ); |
| break; |
| case F64_TO_UI64: |
| test_a_f64_z_ui64_rx( |
| f64_to_ui64, subjFunction_a_f64_z_ui64_rx, roundingMode, exact ); |
| break; |
| case F64_TO_I32: |
| test_a_f64_z_i32_rx( |
| f64_to_i32, subjFunction_a_f64_z_i32_rx, roundingMode, exact ); |
| break; |
| case F64_TO_I64: |
| test_a_f64_z_i64_rx( |
| f64_to_i64, subjFunction_a_f64_z_i64_rx, roundingMode, exact ); |
| break; |
| #ifdef SUBJ_F64_TO_F32 |
| case F64_TO_F32: |
| test_a_f64_z_f32( |
| f64_to_f32, (funcType_a_f64_z_f32 *) subjFunctionPtr ); |
| break; |
| #endif |
| #ifdef EXTFLOAT80 |
| #ifdef SUBJ_F64_TO_EXTF80 |
| case F64_TO_EXTF80: |
| test_a_f64_z_extF80( |
| f64_to_extF80M, (funcType_a_f64_z_extF80 *) subjFunctionPtr ); |
| break; |
| #endif |
| #endif |
| #ifdef FLOAT128 |
| #ifdef SUBJ_F64_TO_F128 |
| case F64_TO_F128: |
| test_a_f64_z_f128( |
| f64_to_f128M, (funcType_a_f64_z_f128 *) subjFunctionPtr ); |
| break; |
| #endif |
| #endif |
| case F64_ROUNDTOINT: |
| test_az_f64_rx( |
| f64_roundToInt, subjFunction_az_f64_rx, roundingMode, exact ); |
| break; |
| #ifdef SUBJ_F64_ADD |
| case F64_ADD: |
| trueFunction_abz_f64 = f64_add; |
| goto test_abz_f64; |
| #endif |
| #ifdef SUBJ_F64_SUB |
| case F64_SUB: |
| trueFunction_abz_f64 = f64_sub; |
| goto test_abz_f64; |
| #endif |
| #ifdef SUBJ_F64_MUL |
| case F64_MUL: |
| trueFunction_abz_f64 = f64_mul; |
| goto test_abz_f64; |
| #endif |
| #ifdef SUBJ_F64_MULADD |
| case F64_MULADD: |
| test_abcz_f64( f64_mulAdd, (funcType_abcz_f64 *) subjFunctionPtr ); |
| break; |
| #endif |
| #ifdef SUBJ_F64_DIV |
| case F64_DIV: |
| trueFunction_abz_f64 = f64_div; |
| goto test_abz_f64; |
| #endif |
| #ifdef SUBJ_F64_REM |
| case F64_REM: |
| trueFunction_abz_f64 = f64_rem; |
| goto test_abz_f64; |
| #endif |
| test_abz_f64: |
| test_abz_f64( |
| trueFunction_abz_f64, (funcType_abz_f64 *) subjFunctionPtr ); |
| break; |
| #ifdef SUBJ_F64_SQRT |
| case F64_SQRT: |
| test_az_f64( f64_sqrt, (funcType_az_f64 *) subjFunctionPtr ); |
| break; |
| #endif |
| #ifdef SUBJ_F64_EQ |
| case F64_EQ: |
| trueFunction_ab_f64_z_bool = f64_eq; |
| goto test_ab_f64_z_bool; |
| #endif |
| #ifdef SUBJ_F64_LE |
| case F64_LE: |
| trueFunction_ab_f64_z_bool = f64_le; |
| goto test_ab_f64_z_bool; |
| #endif |
| #ifdef SUBJ_F64_LT |
| case F64_LT: |
| trueFunction_ab_f64_z_bool = f64_lt; |
| goto test_ab_f64_z_bool; |
| #endif |
| #ifdef SUBJ_F64_EQ_SIGNALING |
| case F64_EQ_SIGNALING: |
| trueFunction_ab_f64_z_bool = f64_eq_signaling; |
| goto test_ab_f64_z_bool; |
| #endif |
| #ifdef SUBJ_F64_LE_QUIET |
| case F64_LE_QUIET: |
| trueFunction_ab_f64_z_bool = f64_le_quiet; |
| goto test_ab_f64_z_bool; |
| #endif |
| #ifdef SUBJ_F64_LT_QUIET |
| case F64_LT_QUIET: |
| trueFunction_ab_f64_z_bool = f64_lt_quiet; |
| goto test_ab_f64_z_bool; |
| #endif |
| test_ab_f64_z_bool: |
| test_ab_f64_z_bool( |
| trueFunction_ab_f64_z_bool, |
| (funcType_ab_f64_z_bool *) subjFunctionPtr |
| ); |
| break; |
| /*-------------------------------------------------------------------- |
| *--------------------------------------------------------------------*/ |
| #ifdef EXTFLOAT80 |
| case EXTF80_TO_UI32: |
| test_a_extF80_z_ui32_rx( |
| extF80M_to_ui32, |
| subjFunction_a_extF80_z_ui32_rx, |
| roundingMode, |
| exact |
| ); |
| break; |
| case EXTF80_TO_UI64: |
| test_a_extF80_z_ui64_rx( |
| extF80M_to_ui64, |
| subjFunction_a_extF80_z_ui64_rx, |
| roundingMode, |
| exact |
| ); |
| break; |
| case EXTF80_TO_I32: |
| test_a_extF80_z_i32_rx( |
| extF80M_to_i32, subjFunction_a_extF80_z_i32_rx, roundingMode, exact |
| ); |
| break; |
| case EXTF80_TO_I64: |
| test_a_extF80_z_i64_rx( |
| extF80M_to_i64, subjFunction_a_extF80_z_i64_rx, roundingMode, exact |
| ); |
| break; |
| #ifdef SUBJ_EXTF80_TO_F32 |
| case EXTF80_TO_F32: |
| test_a_extF80_z_f32( |
| extF80M_to_f32, (funcType_a_extF80_z_f32 *) subjFunctionPtr ); |
| break; |
| #endif |
| #ifdef SUBJ_EXTF80_TO_F64 |
| case EXTF80_TO_F64: |
| test_a_extF80_z_f64( |
| extF80M_to_f64, (funcType_a_extF80_z_f64 *) subjFunctionPtr ); |
| break; |
| #endif |
| #ifdef FLOAT128 |
| #ifdef SUBJ_EXTF80_TO_F128 |
| case EXTF80_TO_F128: |
| test_a_extF80_z_f128( |
| extF80M_to_f128M, (funcType_a_extF80_z_f128 *) subjFunctionPtr ); |
| break; |
| #endif |
| #endif |
| case EXTF80_ROUNDTOINT: |
| test_az_extF80_rx( |
| extF80M_roundToInt, subjFunction_az_extF80_rx, roundingMode, exact |
| ); |
| break; |
| #ifdef SUBJ_EXTF80_ADD |
| case EXTF80_ADD: |
| trueFunction_abz_extF80 = extF80M_add; |
| goto test_abz_extF80; |
| #endif |
| #ifdef SUBJ_EXTF80_SUB |
| case EXTF80_SUB: |
| trueFunction_abz_extF80 = extF80M_sub; |
| goto test_abz_extF80; |
| #endif |
| #ifdef SUBJ_EXTF80_MUL |
| case EXTF80_MUL: |
| trueFunction_abz_extF80 = extF80M_mul; |
| goto test_abz_extF80; |
| #endif |
| #ifdef SUBJ_EXTF80_DIV |
| case EXTF80_DIV: |
| trueFunction_abz_extF80 = extF80M_div; |
| goto test_abz_extF80; |
| #endif |
| #ifdef SUBJ_EXTF80_REM |
| case EXTF80_REM: |
| trueFunction_abz_extF80 = extF80M_rem; |
| goto test_abz_extF80; |
| #endif |
| test_abz_extF80: |
| test_abz_extF80( |
| trueFunction_abz_extF80, (funcType_abz_extF80 *) subjFunctionPtr ); |
| break; |
| #ifdef SUBJ_EXTF80_SQRT |
| case EXTF80_SQRT: |
| test_az_extF80( extF80M_sqrt, (funcType_az_extF80 *) subjFunctionPtr ); |
| break; |
| #endif |
| #ifdef SUBJ_EXTF80_EQ |
| case EXTF80_EQ: |
| trueFunction_ab_extF80_z_bool = extF80M_eq; |
| goto test_ab_extF80_z_bool; |
| #endif |
| #ifdef SUBJ_EXTF80_LE |
| case EXTF80_LE: |
| trueFunction_ab_extF80_z_bool = extF80M_le; |
| goto test_ab_extF80_z_bool; |
| #endif |
| #ifdef SUBJ_EXTF80_LT |
| case EXTF80_LT: |
| trueFunction_ab_extF80_z_bool = extF80M_lt; |
| goto test_ab_extF80_z_bool; |
| #endif |
| #ifdef SUBJ_EXTF80_EQ_SIGNALING |
| case EXTF80_EQ_SIGNALING: |
| trueFunction_ab_extF80_z_bool = extF80M_eq_signaling; |
| goto test_ab_extF80_z_bool; |
| #endif |
| #ifdef SUBJ_EXTF80_LE_QUIET |
| case EXTF80_LE_QUIET: |
| trueFunction_ab_extF80_z_bool = extF80M_le_quiet; |
| goto test_ab_extF80_z_bool; |
| #endif |
| #ifdef SUBJ_EXTF80_LT_QUIET |
| case EXTF80_LT_QUIET: |
| trueFunction_ab_extF80_z_bool = extF80M_lt_quiet; |
| goto test_ab_extF80_z_bool; |
| #endif |
| test_ab_extF80_z_bool: |
| test_ab_extF80_z_bool( |
| trueFunction_ab_extF80_z_bool, |
| (funcType_ab_extF80_z_bool *) subjFunctionPtr |
| ); |
| break; |
| #endif |
| /*-------------------------------------------------------------------- |
| *--------------------------------------------------------------------*/ |
| #ifdef FLOAT128 |
| case F128_TO_UI32: |
| test_a_f128_z_ui32_rx( |
| f128M_to_ui32, subjFunction_a_f128_z_ui32_rx, roundingMode, exact |
| ); |
| break; |
| case F128_TO_UI64: |
| test_a_f128_z_ui64_rx( |
| f128M_to_ui64, subjFunction_a_f128_z_ui64_rx, roundingMode, exact |
| ); |
| break; |
| case F128_TO_I32: |
| test_a_f128_z_i32_rx( |
| f128M_to_i32, subjFunction_a_f128_z_i32_rx, roundingMode, exact ); |
| break; |
| case F128_TO_I64: |
| test_a_f128_z_i64_rx( |
| f128M_to_i64, subjFunction_a_f128_z_i64_rx, roundingMode, exact ); |
| break; |
| #ifdef SUBJ_F128_TO_F32 |
| case F128_TO_F32: |
| test_a_f128_z_f32( |
| f128M_to_f32, (funcType_a_f128_z_f32 *) subjFunctionPtr ); |
| break; |
| #endif |
| #ifdef SUBJ_F128_TO_F64 |
| case F128_TO_F64: |
| test_a_f128_z_f64( |
| f128M_to_f64, (funcType_a_f128_z_f64 *) subjFunctionPtr ); |
| break; |
| #endif |
| #ifdef EXTFLOAT80 |
| #ifdef SUBJ_F128_TO_EXTF80 |
| case F128_TO_EXTF80: |
| test_a_f128_z_extF80( |
| f128M_to_extF80M, (funcType_a_f128_z_extF80 *) subjFunctionPtr ); |
| break; |
| #endif |
| #endif |
| case F128_ROUNDTOINT: |
| test_az_f128_rx( |
| f128M_roundToInt, subjFunction_az_f128_rx, roundingMode, exact ); |
| break; |
| #ifdef SUBJ_F128_ADD |
| case F128_ADD: |
| trueFunction_abz_f128 = f128M_add; |
| goto test_abz_f128; |
| #endif |
| #ifdef SUBJ_F128_SUB |
| case F128_SUB: |
| trueFunction_abz_f128 = f128M_sub; |
| goto test_abz_f128; |
| #endif |
| #ifdef SUBJ_F128_MUL |
| case F128_MUL: |
| trueFunction_abz_f128 = f128M_mul; |
| goto test_abz_f128; |
| #endif |
| #ifdef SUBJ_F128_MULADD |
| case F128_MULADD: |
| test_abcz_f128( f128M_mulAdd, (funcType_abcz_f128 *) subjFunctionPtr ); |
| break; |
| #endif |
| #ifdef SUBJ_F128_DIV |
| case F128_DIV: |
| trueFunction_abz_f128 = f128M_div; |
| goto test_abz_f128; |
| #endif |
| #ifdef SUBJ_F128_REM |
| case F128_REM: |
| trueFunction_abz_f128 = f128M_rem; |
| goto test_abz_f128; |
| #endif |
| test_abz_f128: |
| test_abz_f128( |
| trueFunction_abz_f128, (funcType_abz_f128 *) subjFunctionPtr ); |
| break; |
| #ifdef SUBJ_F128_SQRT |
| case F128_SQRT: |
| test_az_f128( f128M_sqrt, (funcType_az_f128 *) subjFunctionPtr ); |
| break; |
| #endif |
| #ifdef SUBJ_F128_EQ |
| case F128_EQ: |
| trueFunction_ab_f128_z_bool = f128M_eq; |
| goto test_ab_f128_z_bool; |
| #endif |
| #ifdef SUBJ_F128_LE |
| case F128_LE: |
| trueFunction_ab_f128_z_bool = f128M_le; |
| goto test_ab_f128_z_bool; |
| #endif |
| #ifdef SUBJ_F128_LT |
| case F128_LT: |
| trueFunction_ab_f128_z_bool = f128M_lt; |
| goto test_ab_f128_z_bool; |
| #endif |
| #ifdef SUBJ_F128_EQ_SIGNALING |
| case F128_EQ_SIGNALING: |
| trueFunction_ab_f128_z_bool = f128M_eq_signaling; |
| goto test_ab_f128_z_bool; |
| #endif |
| #ifdef SUBJ_F128_LE_QUIET |
| case F128_LE_QUIET: |
| trueFunction_ab_f128_z_bool = f128M_le_quiet; |
| goto test_ab_f128_z_bool; |
| #endif |
| #ifdef SUBJ_F128_LT_QUIET |
| case F128_LT_QUIET: |
| trueFunction_ab_f128_z_bool = f128M_lt_quiet; |
| goto test_ab_f128_z_bool; |
| #endif |
| test_ab_f128_z_bool: |
| test_ab_f128_z_bool( |
| trueFunction_ab_f128_z_bool, |
| (funcType_ab_f128_z_bool *) subjFunctionPtr |
| ); |
| break; |
| #endif |
| } |
| if ( (verCases_errorStop && verCases_anyErrors) || verCases_stop ) { |
| verCases_exitWithStatus(); |
| } |
| |
| } |
| |
| static |
| void |
| testFunction( |
| const struct standardFunctionInfo *standardFunctionInfoPtr, |
| uint_fast8_t roundingPrecisionIn, |
| int roundingCodeIn |
| ) |
| { |
| int functionCode, functionAttribs; |
| bool standardFunctionHasFixedRounding; |
| int roundingCode; |
| bool exact; |
| uint_fast8_t roundingPrecision, roundingMode; |
| |
| functionCode = standardFunctionInfoPtr->functionCode; |
| functionAttribs = functionInfos[functionCode].attribs; |
| standardFunctionHasFixedRounding = false; |
| if ( functionAttribs & FUNC_ARG_ROUNDINGMODE ) { |
| roundingCode = standardFunctionInfoPtr->roundingCode; |
| if ( roundingCode ) { |
| standardFunctionHasFixedRounding = true; |
| roundingCodeIn = roundingCode; |
| } |
| } |
| exact = standardFunctionInfoPtr->exact; |
| verCases_functionNamePtr = standardFunctionInfoPtr->namePtr; |
| roundingPrecision = 32; |
| for (;;) { |
| if ( ! (functionAttribs & FUNC_EFF_ROUNDINGPRECISION) ) { |
| roundingPrecision = 0; |
| } else if ( roundingPrecisionIn ) { |
| roundingPrecision = roundingPrecisionIn; |
| } |
| #ifdef EXTFLOAT80 |
| verCases_roundingPrecision = roundingPrecision; |
| if ( roundingPrecision ) { |
| extF80_roundingPrecision = roundingPrecision; |
| subjfloat_setExtF80RoundingPrecision( roundingPrecision ); |
| } |
| #endif |
| for ( |
| roundingCode = 1; roundingCode < NUM_ROUNDINGMODES; ++roundingCode |
| ) { |
| #ifndef SUBJFLOAT_ROUND_NEAR_MAXMAG |
| if ( roundingCode != ROUND_NEAR_MAXMAG ) { |
| #endif |
| if ( |
| ! (functionAttribs |
| & (FUNC_ARG_ROUNDINGMODE | FUNC_EFF_ROUNDINGMODE)) |
| ) { |
| roundingCode = 0; |
| } else if ( roundingCodeIn ) { |
| roundingCode = roundingCodeIn; |
| } |
| verCases_roundingCode = |
| standardFunctionHasFixedRounding ? 0 : roundingCode; |
| if ( roundingCode ) { |
| roundingMode = roundingModes[roundingCode]; |
| softfloat_roundingMode = roundingMode; |
| if ( ! standardFunctionHasFixedRounding ) { |
| subjfloat_setRoundingMode( roundingMode ); |
| } |
| } |
| testFunctionInstance( functionCode, roundingMode, exact ); |
| if ( roundingCodeIn || ! roundingCode ) break; |
| #ifndef SUBJFLOAT_ROUND_NEAR_MAXMAG |
| } |
| #endif |
| } |
| 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; |
| const struct standardFunctionInfo *standardFunctionInfoPtr; |
| int numOperands; |
| uint_fast8_t roundingPrecision; |
| int roundingCode; |
| const char *argPtr; |
| void (*const *subjFunctionPtrPtr)(); |
| const char *functionNamePtr; |
| long i; |
| |
| /*------------------------------------------------------------------------ |
| *------------------------------------------------------------------------*/ |
| fail_programName = "testfloat"; |
| if ( argc <= 1 ) goto writeHelpMessage; |
| genCases_setLevel( 1 ); |
| verCases_maxErrorCount = 20; |
| testLoops_trueFlagsPtr = &softfloat_exceptionFlags; |
| testLoops_subjFlagsFunction = subjfloat_clearExceptionFlags; |
| haveFunctionArg = false; |
| standardFunctionInfoPtr = 0; |
| numOperands = 0; |
| roundingPrecision = 0; |
| roundingCode = 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( |
| "testfloat [<option>...] <function>\n" |
| " <option>: (* is default)\n" |
| " -help --Write this message and exit.\n" |
| " -list --List all testable subject functions and exit.\n" |
| " -level <num> --Testing level <num> (1 or 2).\n" |
| " * -level 1\n" |
| " -errors <num> --Stop each function test after <num> errors.\n" |
| " * -errors 20\n" |
| " -errorstop --Exit after first function with any error.\n" |
| " -forever --Test one function repeatedly (implies `-level 2').\n" |
| " -checkNaNs --Check for bitwise correctness of NaN results.\n" |
| #ifdef EXTFLOAT80 |
| " -precision32 --For extF80, test only 32-bit rounding precision.\n" |
| " -precision64 --For extF80, test only 64-bit rounding precision.\n" |
| " -precision80 --For extF80, test only 80-bit rounding precision.\n" |
| #endif |
| " -r<round> --Test only specified rounding (if not inherent to\n" |
| " function).\n" |
| " -tininessbefore --Underflow tininess is detected before rounding.\n" |
| " -tininessafter --Underflow tininess is detected after rounding.\n" |
| " <function>:\n" |
| " <int>_to_<float> <float>_add <float>_eq\n" |
| " <float>_to_<int>_r_<round> <float>_sub <float>_le\n" |
| " <float>_to_<int>_rx_<round> <float>_mul <float>_lt\n" |
| " <float>_to_<float> <float>_mulAdd <float>_eq_signaling\n" |
| " <float>_roundToInt_r_<round> <float>_div <float>_le_quiet\n" |
| " <float>_roundToInt_x <float>_rem <float>_lt_quiet\n" |
| " <float>_sqrt\n" |
| " -all1 --All unary functions.\n" |
| " -all2 --All binary functions.\n" |
| " <int>:\n" |
| " ui32 --Unsigned 32-bit integer.\n" |
| " ui64 --Unsigned 64-bit integer.\n" |
| " i32 --Signed 32-bit integer.\n" |
| " i64 --Signed 64-bit integer.\n" |
| " <float>:\n" |
| " f32 --Binary 32-bit floating-point (single-precision).\n" |
| " f64 --Binary 64-bit floating-point (double-precision).\n" |
| #ifdef EXTFLOAT80 |
| " extF80 --Binary 80-bit extended floating-point.\n" |
| #endif |
| #ifdef FLOAT128 |
| " f128 --Binary 128-bit floating-point (quadruple-precision).\n" |
| #endif |
| " <round>:\n" |
| " near_even --Round to nearest/even.\n" |
| " minMag --Round to minimum magnitude (toward zero).\n" |
| " min --Round to minimum (down).\n" |
| " max --Round to maximum (up).\n" |
| " near_maxMag --Round to nearest/maximum magnitude (nearest/away).\n" |
| , |
| stdout |
| ); |
| return EXIT_SUCCESS; |
| } else if ( ! strcmp( argPtr, "list" ) ) { |
| standardFunctionInfoPtr = standardFunctionInfos; |
| subjFunctionPtrPtr = subjfloat_functions; |
| for (;;) { |
| functionNamePtr = standardFunctionInfoPtr->namePtr; |
| if ( ! functionNamePtr ) break; |
| if ( *subjFunctionPtrPtr ) puts( functionNamePtr ); |
| ++standardFunctionInfoPtr; |
| ++subjFunctionPtrPtr; |
| } |
| return EXIT_SUCCESS; |
| } else if ( ! strcmp( argPtr, "level" ) ) { |
| if ( argc < 2 ) goto optionError; |
| i = strtol( argv[1], (char **) &argPtr, 10 ); |
| if ( *argPtr ) goto optionError; |
| genCases_setLevel( i ); |
| --argc; |
| ++argv; |
| } else if ( ! strcmp( argPtr, "level1" ) ) { |
| genCases_setLevel( 1 ); |
| } else if ( ! strcmp( argPtr, "level2" ) ) { |
| genCases_setLevel( 2 ); |
| } else if ( ! strcmp( argPtr, "errors" ) ) { |
| if ( argc < 2 ) goto optionError; |
| i = strtol( argv[1], (char **) &argPtr, 10 ); |
| if ( *argPtr ) goto optionError; |
| verCases_maxErrorCount = i; |
| --argc; |
| ++argv; |
| } else if ( ! strcmp( argPtr, "errorstop" ) ) { |
| verCases_errorStop = true; |
| } else if ( ! strcmp( argPtr, "forever" ) ) { |
| genCases_setLevel( 2 ); |
| testLoops_forever = true; |
| } else if ( |
| ! strcmp( argPtr, "checkNaNs" ) || ! strcmp( argPtr, "checknans" ) |
| ) { |
| verCases_checkNaNs = true; |
| #ifdef EXTFLOAT80 |
| } else if ( ! strcmp( argPtr, "precision32" ) ) { |
| roundingPrecision = 32; |
| } else if ( ! strcmp( argPtr, "precision64" ) ) { |
| roundingPrecision = 64; |
| } else if ( ! strcmp( argPtr, "precision80" ) ) { |
| roundingPrecision = 80; |
| #endif |
| } else if ( |
| ! strcmp( argPtr, "rnear_even" ) |
| || ! strcmp( argPtr, "rneareven" ) |
| || ! strcmp( argPtr, "rnearest_even" ) |
| ) { |
| roundingCode = ROUND_NEAR_EVEN; |
| } else if ( |
| ! strcmp( argPtr, "rminmag" ) || ! strcmp( argPtr, "rminMag" ) |
| ) { |
| roundingCode = ROUND_MINMAG; |
| } else if ( ! strcmp( argPtr, "rmin" ) ) { |
| roundingCode = ROUND_MIN; |
| } else if ( ! strcmp( argPtr, "rmax" ) ) { |
| roundingCode = ROUND_MAX; |
| } else if ( |
| ! strcmp( argPtr, "rnear_maxmag" ) |
| || ! strcmp( argPtr, "rnear_maxMag" ) |
| || ! strcmp( argPtr, "rnearmaxmag" ) |
| || ! strcmp( argPtr, "rnearest_maxmag" ) |
| || ! strcmp( argPtr, "rnearest_maxMag" ) |
| ) { |
| #ifdef SUBJFLOAT_ROUND_NEAR_MAXMAG |
| roundingCode = ROUND_NEAR_MAXMAG; |
| #else |
| fail( |
| "Rounding mode near_maxMag is not supported or cannot be tested" |
| ); |
| #endif |
| } else if ( ! strcmp( argPtr, "tininessbefore" ) ) { |
| softfloat_detectTininess = softfloat_tininess_beforeRounding; |
| } else if ( ! strcmp( argPtr, "tininessafter" ) ) { |
| softfloat_detectTininess = softfloat_tininess_afterRounding; |
| } else if ( ! strcmp( argPtr, "all1" ) ) { |
| haveFunctionArg = true; |
| standardFunctionInfoPtr = 0; |
| numOperands = 1; |
| } else if ( ! strcmp( argPtr, "all2" ) ) { |
| haveFunctionArg = true; |
| standardFunctionInfoPtr = 0; |
| numOperands = 2; |
| } else { |
| standardFunctionInfoPtr = standardFunctionInfos; |
| for (;;) { |
| functionNamePtr = standardFunctionInfoPtr->namePtr; |
| if ( ! functionNamePtr ) { |
| fail( "Invalid argument `%s'", *argv ); |
| } |
| if ( ! strcmp( argPtr, functionNamePtr ) ) break; |
| ++standardFunctionInfoPtr; |
| } |
| subjFunctionPtr = |
| subjfloat_functions |
| [standardFunctionInfoPtr - standardFunctionInfos]; |
| if ( ! subjFunctionPtr ) { |
| fail( |
| "Function `%s' is not supported or cannot be tested", |
| argPtr |
| ); |
| } |
| haveFunctionArg = true; |
| } |
| } |
| if ( ! haveFunctionArg ) fail( "Function argument required" ); |
| /*------------------------------------------------------------------------ |
| *------------------------------------------------------------------------*/ |
| signal( SIGINT, catchSIGINT ); |
| signal( SIGTERM, catchSIGINT ); |
| if ( standardFunctionInfoPtr ) { |
| if ( testLoops_forever ) { |
| if ( ! roundingPrecision ) roundingPrecision = 80; |
| if ( ! roundingCode ) roundingCode = ROUND_NEAR_EVEN; |
| } |
| testFunction( |
| standardFunctionInfoPtr, roundingPrecision, roundingCode ); |
| } else { |
| if ( testLoops_forever ) { |
| fail( "Can test only one function with `-forever' option" ); |
| } |
| if ( numOperands == 1 ) { |
| standardFunctionInfoPtr = standardFunctionInfos; |
| subjFunctionPtrPtr = subjfloat_functions; |
| while ( standardFunctionInfoPtr->namePtr ) { |
| subjFunctionPtr = *subjFunctionPtrPtr; |
| if ( |
| subjFunctionPtr |
| && ! (functionInfos |
| [standardFunctionInfoPtr->functionCode] |
| .attribs |
| & FUNC_ARG_BINARY) |
| ) { |
| testFunction( |
| standardFunctionInfoPtr, |
| roundingPrecision, |
| roundingCode |
| ); |
| } |
| ++standardFunctionInfoPtr; |
| ++subjFunctionPtrPtr; |
| } |
| } else { |
| standardFunctionInfoPtr = standardFunctionInfos; |
| subjFunctionPtrPtr = subjfloat_functions; |
| while ( standardFunctionInfoPtr->namePtr ) { |
| subjFunctionPtr = *subjFunctionPtrPtr; |
| if ( |
| subjFunctionPtr |
| && (functionInfos |
| [standardFunctionInfoPtr->functionCode] |
| .attribs |
| & FUNC_ARG_BINARY) |
| ) { |
| testFunction( |
| standardFunctionInfoPtr, |
| roundingPrecision, |
| roundingCode |
| ); |
| } |
| ++standardFunctionInfoPtr; |
| ++subjFunctionPtrPtr; |
| } |
| } |
| } |
| verCases_exitWithStatus(); |
| /*------------------------------------------------------------------------ |
| *------------------------------------------------------------------------*/ |
| optionError: |
| fail( "`%s' option requires numeric argument", *argv ); |
| |
| } |
| |