3 ===============================================================================
5 This C source file is part of TestFloat, Release 2a, a package of programs
6 for testing the correctness of floating-point arithmetic complying to the
7 IEC/IEEE Standard for Floating-Point.
9 Written by John R. Hauser. More information is available through the Web
10 page `http://HTTP.CS.Berkeley.EDU/~jhauser/arithmetic/TestFloat.html'.
12 THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE. Although reasonable effort
13 has been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT
14 TIMES RESULT IN INCORRECT BEHAVIOR. USE OF THIS SOFTWARE IS RESTRICTED TO
15 PERSONS AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ANY
16 AND ALL LOSSES, COSTS, OR OTHER PROBLEMS ARISING FROM ITS USE.
18 Derivative works are acceptable, even for commercial purposes, so long as
19 (1) they include prominent notice that the work is derivative, and (2) they
20 include prominent notice akin to these four paragraphs for those parts of
21 this code that are retained.
23 ===============================================================================
26 #include <sys/cdefs.h>
27 __FBSDID("$FreeBSD$");
34 #include "softfloat.h"
35 #include "testCases.h"
36 #include "testLoops.h"
37 #include "systflags.h"
38 #include "testFunction.h"
40 static void catchSIGINT( int signalCode )
43 if ( stop ) exit( EXIT_FAILURE );
49 main( int argc, char **argv )
52 flag functionArgument;
54 int8 operands, roundingPrecision, roundingMode;
56 fail_programName = "testfloat";
57 if ( argc <= 1 ) goto writeHelpMessage;
58 testCases_setLevel( 1 );
64 trueFlagsPtr = &float_exception_flags;
65 testFlagsFunctionPtr = syst_float_flags_clear;
67 functionArgument = FALSE;
70 roundingPrecision = 0;
74 while ( argc && ( argPtr = argv[ 0 ] ) ) {
75 if ( argPtr[ 0 ] == '-' ) ++argPtr;
76 if ( strcmp( argPtr, "help" ) == 0 ) {
79 "testfloat [<option>...] <function>\n"
80 " <option>: (* is default)\n"
81 " -help --Write this message and exit.\n"
82 " -list --List all testable functions and exit.\n"
83 " -level <num> --Testing level <num> (1 or 2).\n"
85 " -errors <num> --Stop each function test after <num> errors.\n"
87 " -errorstop --Exit after first function with any error.\n"
88 " -forever --Test one function repeatedly (implies `-level 2').\n"
89 " -checkNaNs --Check for bitwise correctness of NaN results.\n"
91 " -precision32 --Only test rounding precision equivalent to float32.\n"
92 " -precision64 --Only test rounding precision equivalent to float64.\n"
93 " -precision80 --Only test maximum rounding precision.\n"
95 " -nearesteven --Only test rounding to nearest/even.\n"
96 " -tozero --Only test rounding to zero.\n"
97 " -down --Only test rounding down.\n"
98 " -up --Only test rounding up.\n"
99 " -tininessbefore --Underflow tininess detected before rounding.\n"
100 " -tininessafter --Underflow tininess detected after rounding.\n"
102 " int32_to_<float> <float>_add <float>_eq\n"
103 " <float>_to_int32 <float>_sub <float>_le\n"
104 " <float>_to_int32_round_to_zero <float>_mul <float>_lt\n"
106 " int64_to_<float> <float>_div <float>_eq_signaling\n"
107 " <float>_to_int64 <float>_rem <float>_le_quiet\n"
108 " <float>_to_int64_round_to_zero <float>_lt_quiet\n"
109 " <float>_to_<float>\n"
110 " <float>_round_to_int\n"
113 " <float>_to_<float> <float>_div <float>_eq_signaling\n"
114 " <float>_round_to_int <float>_rem <float>_le_quiet\n"
115 " <float>_sqrt <float>_lt_quiet\n"
117 " -all1 --All 1-operand functions.\n"
118 " -all2 --All 2-operand functions.\n"
119 " -all --All functions.\n"
121 " float32 --Single precision.\n"
122 " float64 --Double precision.\n"
124 " floatx80 --Extended double precision.\n"
127 " float128 --Quadruple precision.\n"
134 else if ( strcmp( argPtr, "list" ) == 0 ) {
135 for ( functionCode = 1;
136 functionCode < NUM_FUNCTIONS;
139 if ( functionExists[ functionCode ] ) {
140 puts( functions[ functionCode ].name );
145 else if ( strcmp( argPtr, "level" ) == 0 ) {
146 if ( argc < 2 ) goto optionError;
147 testCases_setLevel( atoi( argv[ 1 ] ) );
151 else if ( strcmp( argPtr, "level1" ) == 0 ) {
152 testCases_setLevel( 1 );
154 else if ( strcmp( argPtr, "level2" ) == 0 ) {
155 testCases_setLevel( 2 );
157 else if ( strcmp( argPtr, "errors" ) == 0 ) {
160 fail( "`%s' option requires numeric argument", argv[ 0 ] );
162 maxErrorCount = atoi( argv[ 1 ] );
166 else if ( strcmp( argPtr, "errorstop" ) == 0 ) {
169 else if ( strcmp( argPtr, "forever" ) == 0 ) {
170 testCases_setLevel( 2 );
173 else if ( ( strcmp( argPtr, "checkNaNs" ) == 0 )
174 || ( strcmp( argPtr, "checknans" ) == 0 ) ) {
178 else if ( strcmp( argPtr, "precision32" ) == 0 ) {
179 roundingPrecision = 32;
181 else if ( strcmp( argPtr, "precision64" ) == 0 ) {
182 roundingPrecision = 64;
184 else if ( strcmp( argPtr, "precision80" ) == 0 ) {
185 roundingPrecision = 80;
188 else if ( ( strcmp( argPtr, "nearesteven" ) == 0 )
189 || ( strcmp( argPtr, "nearest_even" ) == 0 ) ) {
190 roundingMode = ROUND_NEAREST_EVEN;
192 else if ( ( strcmp( argPtr, "tozero" ) == 0 )
193 || ( strcmp( argPtr, "to_zero" ) == 0 ) ) {
194 roundingMode = ROUND_TO_ZERO;
196 else if ( strcmp( argPtr, "down" ) == 0 ) {
197 roundingMode = ROUND_DOWN;
199 else if ( strcmp( argPtr, "up" ) == 0 ) {
200 roundingMode = ROUND_UP;
202 else if ( strcmp( argPtr, "tininessbefore" ) == 0 ) {
203 float_detect_tininess = float_tininess_before_rounding;
205 else if ( strcmp( argPtr, "tininessafter" ) == 0 ) {
206 float_detect_tininess = float_tininess_after_rounding;
208 else if ( strcmp( argPtr, "all1" ) == 0 ) {
209 functionArgument = TRUE;
213 else if ( strcmp( argPtr, "all2" ) == 0 ) {
214 functionArgument = TRUE;
218 else if ( strcmp( argPtr, "all" ) == 0 ) {
219 functionArgument = TRUE;
224 for ( functionCode = 1;
225 functionCode < NUM_FUNCTIONS;
228 if ( strcmp( argPtr, functions[ functionCode ].name ) == 0 ) {
232 if ( functionCode == NUM_FUNCTIONS ) {
233 fail( "Invalid option or function `%s'", argv[ 0 ] );
235 if ( ! functionExists[ functionCode ] ) {
237 "Function `%s' is not supported or cannot be tested",
241 functionArgument = TRUE;
246 if ( ! functionArgument ) fail( "Function argument required" );
247 (void) signal( SIGINT, catchSIGINT );
248 (void) signal( SIGTERM, catchSIGINT );
249 if ( functionCode ) {
251 if ( ! roundingPrecision ) roundingPrecision = 80;
252 if ( ! roundingMode ) roundingMode = ROUND_NEAREST_EVEN;
254 testFunction( functionCode, roundingPrecision, roundingMode );
258 fail( "Can only test one function with `-forever' option" );
260 if ( operands == 1 ) {
261 for ( functionCode = 1;
262 functionCode < NUM_FUNCTIONS;
265 if ( functionExists[ functionCode ]
266 && ( functions[ functionCode ].numInputs == 1 ) ) {
268 functionCode, roundingPrecision, roundingMode );
272 else if ( operands == 2 ) {
273 for ( functionCode = 1;
274 functionCode < NUM_FUNCTIONS;
277 if ( functionExists[ functionCode ]
278 && ( functions[ functionCode ].numInputs == 2 ) ) {
280 functionCode, roundingPrecision, roundingMode );
285 for ( functionCode = 1;
286 functionCode < NUM_FUNCTIONS;
289 if ( functionExists[ functionCode ] ) {
291 functionCode, roundingPrecision, roundingMode );