testfloat.c revision 1.4 1 1.4 ross /* $NetBSD: testfloat.c,v 1.4 2001/03/22 12:01:47 ross Exp $ */
2 1.3 ross
3 1.3 ross /* This is a derivative work. */
4 1.3 ross
5 1.3 ross /*-
6 1.3 ross * Copyright (c) 2001 The NetBSD Foundation, Inc.
7 1.3 ross * All rights reserved.
8 1.3 ross *
9 1.3 ross * This code is derived from software contributed to The NetBSD Foundation
10 1.3 ross * by Ross Harvey.
11 1.3 ross *
12 1.3 ross * Redistribution and use in source and binary forms, with or without
13 1.3 ross * modification, are permitted provided that the following conditions
14 1.3 ross * are met:
15 1.3 ross * 1. Redistributions of source code must retain the above copyright
16 1.3 ross * notice, this list of conditions and the following disclaimer.
17 1.3 ross * 2. Redistributions in binary form must reproduce the above copyright
18 1.3 ross * notice, this list of conditions and the following disclaimer in the
19 1.3 ross * documentation and/or other materials provided with the distribution.
20 1.3 ross * 3. All advertising materials mentioning features or use of this software
21 1.3 ross * must display the following acknowledgement:
22 1.3 ross * This product includes software developed by the NetBSD
23 1.3 ross * Foundation, Inc. and its contributors.
24 1.3 ross * 4. Neither the name of The NetBSD Foundation nor the names of its
25 1.3 ross * contributors may be used to endorse or promote products derived
26 1.3 ross * from this software without specific prior written permission.
27 1.3 ross *
28 1.3 ross * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
29 1.3 ross * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
30 1.3 ross * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
31 1.3 ross * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
32 1.3 ross * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
33 1.3 ross * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
34 1.3 ross * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
35 1.3 ross * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
36 1.3 ross * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
37 1.3 ross * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
38 1.3 ross * POSSIBILITY OF SUCH DAMAGE.
39 1.3 ross */
40 1.1 ross
41 1.1 ross /*
42 1.1 ross ===============================================================================
43 1.1 ross
44 1.1 ross This C source file is part of TestFloat, Release 2a, a package of programs
45 1.1 ross for testing the correctness of floating-point arithmetic complying to the
46 1.1 ross IEC/IEEE Standard for Floating-Point.
47 1.1 ross
48 1.1 ross Written by John R. Hauser. More information is available through the Web
49 1.1 ross page `http://HTTP.CS.Berkeley.EDU/~jhauser/arithmetic/TestFloat.html'.
50 1.1 ross
51 1.1 ross THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE. Although reasonable effort
52 1.1 ross has been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT
53 1.1 ross TIMES RESULT IN INCORRECT BEHAVIOR. USE OF THIS SOFTWARE IS RESTRICTED TO
54 1.1 ross PERSONS AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ANY
55 1.1 ross AND ALL LOSSES, COSTS, OR OTHER PROBLEMS ARISING FROM ITS USE.
56 1.1 ross
57 1.1 ross Derivative works are acceptable, even for commercial purposes, so long as
58 1.1 ross (1) they include prominent notice that the work is derivative, and (2) they
59 1.1 ross include prominent notice akin to these four paragraphs for those parts of
60 1.1 ross this code that are retained.
61 1.1 ross
62 1.1 ross ===============================================================================
63 1.1 ross */
64 1.4 ross
65 1.4 ross #include <sys/cdefs.h>
66 1.4 ross #ifndef __lint
67 1.4 ross __COPYRIGHT("@(#) Copyright (c) 2001\n\
68 1.4 ross The NetBSD Foundation, inc. All rights reserved.\n");
69 1.4 ross __RCSID("$NetBSD: testfloat.c,v 1.4 2001/03/22 12:01:47 ross Exp $");
70 1.4 ross #endif /* !__lint */
71 1.1 ross
72 1.1 ross #include <stdlib.h>
73 1.1 ross #include <signal.h>
74 1.1 ross #include <string.h>
75 1.1 ross #include "milieu.h"
76 1.1 ross #include "fail.h"
77 1.1 ross #include "softfloat.h"
78 1.1 ross #include "testCases.h"
79 1.1 ross #include "testLoops.h"
80 1.1 ross #include "systflags.h"
81 1.1 ross #include "testFunction.h"
82 1.1 ross
83 1.1 ross static void catchSIGINT( int signalCode )
84 1.1 ross {
85 1.1 ross
86 1.1 ross if ( stop ) exit( EXIT_FAILURE );
87 1.1 ross stop = TRUE;
88 1.1 ross
89 1.1 ross }
90 1.1 ross
91 1.2 ross int
92 1.1 ross main( int argc, char **argv )
93 1.1 ross {
94 1.1 ross char *argPtr;
95 1.1 ross flag functionArgument;
96 1.1 ross uint8 functionCode;
97 1.1 ross int8 operands, roundingPrecision, roundingMode;
98 1.1 ross
99 1.1 ross fail_programName = "testfloat";
100 1.1 ross if ( argc <= 1 ) goto writeHelpMessage;
101 1.1 ross testCases_setLevel( 1 );
102 1.1 ross trueName = "soft";
103 1.1 ross testName = "syst";
104 1.1 ross errorStop = FALSE;
105 1.1 ross forever = FALSE;
106 1.1 ross maxErrorCount = 20;
107 1.1 ross trueFlagsPtr = &float_exception_flags;
108 1.1 ross testFlagsFunctionPtr = syst_float_flags_clear;
109 1.1 ross tininessModeName = 0;
110 1.1 ross functionArgument = FALSE;
111 1.1 ross functionCode = 0;
112 1.1 ross operands = 0;
113 1.1 ross roundingPrecision = 0;
114 1.1 ross roundingMode = 0;
115 1.1 ross --argc;
116 1.1 ross ++argv;
117 1.1 ross while ( argc && ( argPtr = argv[ 0 ] ) ) {
118 1.1 ross if ( argPtr[ 0 ] == '-' ) ++argPtr;
119 1.1 ross if ( strcmp( argPtr, "help" ) == 0 ) {
120 1.1 ross writeHelpMessage:
121 1.1 ross fputs(
122 1.1 ross "testfloat [<option>...] <function>\n"
123 1.1 ross " <option>: (* is default)\n"
124 1.1 ross " -help --Write this message and exit.\n"
125 1.1 ross " -list --List all testable functions and exit.\n"
126 1.1 ross " -level <num> --Testing level <num> (1 or 2).\n"
127 1.1 ross " * -level 1\n"
128 1.1 ross " -errors <num> --Stop each function test after <num> errors.\n"
129 1.1 ross " * -errors 20\n"
130 1.1 ross " -errorstop --Exit after first function with any error.\n"
131 1.1 ross " -forever --Test one function repeatedly (implies `-level 2').\n"
132 1.1 ross " -checkNaNs --Check for bitwise correctness of NaN results.\n"
133 1.1 ross #ifdef FLOATX80
134 1.1 ross " -precision32 --Only test rounding precision equivalent to float32.\n"
135 1.1 ross " -precision64 --Only test rounding precision equivalent to float64.\n"
136 1.1 ross " -precision80 --Only test maximum rounding precision.\n"
137 1.1 ross #endif
138 1.1 ross " -nearesteven --Only test rounding to nearest/even.\n"
139 1.1 ross " -tozero --Only test rounding to zero.\n"
140 1.1 ross " -down --Only test rounding down.\n"
141 1.1 ross " -up --Only test rounding up.\n"
142 1.1 ross " -tininessbefore --Underflow tininess detected before rounding.\n"
143 1.1 ross " -tininessafter --Underflow tininess detected after rounding.\n"
144 1.1 ross " <function>:\n"
145 1.1 ross " int32_to_<float> <float>_add <float>_eq\n"
146 1.1 ross " <float>_to_int32 <float>_sub <float>_le\n"
147 1.1 ross " <float>_to_int32_round_to_zero <float>_mul <float>_lt\n"
148 1.1 ross #ifdef BITS64
149 1.1 ross " int64_to_<float> <float>_div <float>_eq_signaling\n"
150 1.1 ross " <float>_to_int64 <float>_rem <float>_le_quiet\n"
151 1.1 ross " <float>_to_int64_round_to_zero <float>_lt_quiet\n"
152 1.1 ross " <float>_to_<float>\n"
153 1.1 ross " <float>_round_to_int\n"
154 1.1 ross " <float>_sqrt\n"
155 1.1 ross #else
156 1.1 ross " <float>_to_<float> <float>_div <float>_eq_signaling\n"
157 1.1 ross " <float>_round_to_int <float>_rem <float>_le_quiet\n"
158 1.1 ross " <float>_sqrt <float>_lt_quiet\n"
159 1.1 ross #endif
160 1.1 ross " -all1 --All 1-operand functions.\n"
161 1.1 ross " -all2 --All 2-operand functions.\n"
162 1.1 ross " -all --All functions.\n"
163 1.1 ross " <float>:\n"
164 1.1 ross " float32 --Single precision.\n"
165 1.1 ross " float64 --Double precision.\n"
166 1.1 ross #ifdef FLOATX80
167 1.1 ross " floatx80 --Extended double precision.\n"
168 1.1 ross #endif
169 1.1 ross #ifdef FLOAT128
170 1.1 ross " float128 --Quadruple precision.\n"
171 1.1 ross #endif
172 1.1 ross ,
173 1.1 ross stdout
174 1.1 ross );
175 1.1 ross return EXIT_SUCCESS;
176 1.1 ross }
177 1.1 ross else if ( strcmp( argPtr, "list" ) == 0 ) {
178 1.1 ross for ( functionCode = 1;
179 1.1 ross functionCode < NUM_FUNCTIONS;
180 1.1 ross ++functionCode
181 1.1 ross ) {
182 1.1 ross if ( functionExists[ functionCode ] ) {
183 1.1 ross puts( functions[ functionCode ].name );
184 1.1 ross }
185 1.1 ross }
186 1.1 ross return EXIT_SUCCESS;
187 1.1 ross }
188 1.1 ross else if ( strcmp( argPtr, "level" ) == 0 ) {
189 1.1 ross if ( argc < 2 ) goto optionError;
190 1.1 ross testCases_setLevel( atoi( argv[ 1 ] ) );
191 1.1 ross --argc;
192 1.1 ross ++argv;
193 1.1 ross }
194 1.1 ross else if ( strcmp( argPtr, "level1" ) == 0 ) {
195 1.1 ross testCases_setLevel( 1 );
196 1.1 ross }
197 1.1 ross else if ( strcmp( argPtr, "level2" ) == 0 ) {
198 1.1 ross testCases_setLevel( 2 );
199 1.1 ross }
200 1.1 ross else if ( strcmp( argPtr, "errors" ) == 0 ) {
201 1.1 ross if ( argc < 2 ) {
202 1.1 ross optionError:
203 1.1 ross fail( "`%s' option requires numeric argument", argv[ 0 ] );
204 1.1 ross }
205 1.1 ross maxErrorCount = atoi( argv[ 1 ] );
206 1.1 ross --argc;
207 1.1 ross ++argv;
208 1.1 ross }
209 1.1 ross else if ( strcmp( argPtr, "errorstop" ) == 0 ) {
210 1.1 ross errorStop = TRUE;
211 1.1 ross }
212 1.1 ross else if ( strcmp( argPtr, "forever" ) == 0 ) {
213 1.1 ross testCases_setLevel( 2 );
214 1.1 ross forever = TRUE;
215 1.1 ross }
216 1.1 ross else if ( ( strcmp( argPtr, "checkNaNs" ) == 0 )
217 1.1 ross || ( strcmp( argPtr, "checknans" ) == 0 ) ) {
218 1.1 ross checkNaNs = TRUE;
219 1.1 ross }
220 1.1 ross #ifdef FLOATX80
221 1.1 ross else if ( strcmp( argPtr, "precision32" ) == 0 ) {
222 1.1 ross roundingPrecision = 32;
223 1.1 ross }
224 1.1 ross else if ( strcmp( argPtr, "precision64" ) == 0 ) {
225 1.1 ross roundingPrecision = 64;
226 1.1 ross }
227 1.1 ross else if ( strcmp( argPtr, "precision80" ) == 0 ) {
228 1.1 ross roundingPrecision = 80;
229 1.1 ross }
230 1.1 ross #endif
231 1.1 ross else if ( ( strcmp( argPtr, "nearesteven" ) == 0 )
232 1.1 ross || ( strcmp( argPtr, "nearest_even" ) == 0 ) ) {
233 1.1 ross roundingMode = ROUND_NEAREST_EVEN;
234 1.1 ross }
235 1.1 ross else if ( ( strcmp( argPtr, "tozero" ) == 0 )
236 1.1 ross || ( strcmp( argPtr, "to_zero" ) == 0 ) ) {
237 1.1 ross roundingMode = ROUND_TO_ZERO;
238 1.1 ross }
239 1.1 ross else if ( strcmp( argPtr, "down" ) == 0 ) {
240 1.1 ross roundingMode = ROUND_DOWN;
241 1.1 ross }
242 1.1 ross else if ( strcmp( argPtr, "up" ) == 0 ) {
243 1.1 ross roundingMode = ROUND_UP;
244 1.1 ross }
245 1.1 ross else if ( strcmp( argPtr, "tininessbefore" ) == 0 ) {
246 1.1 ross float_detect_tininess = float_tininess_before_rounding;
247 1.1 ross }
248 1.1 ross else if ( strcmp( argPtr, "tininessafter" ) == 0 ) {
249 1.1 ross float_detect_tininess = float_tininess_after_rounding;
250 1.1 ross }
251 1.1 ross else if ( strcmp( argPtr, "all1" ) == 0 ) {
252 1.1 ross functionArgument = TRUE;
253 1.1 ross functionCode = 0;
254 1.1 ross operands = 1;
255 1.1 ross }
256 1.1 ross else if ( strcmp( argPtr, "all2" ) == 0 ) {
257 1.1 ross functionArgument = TRUE;
258 1.1 ross functionCode = 0;
259 1.1 ross operands = 2;
260 1.1 ross }
261 1.1 ross else if ( strcmp( argPtr, "all" ) == 0 ) {
262 1.1 ross functionArgument = TRUE;
263 1.1 ross functionCode = 0;
264 1.1 ross operands = 0;
265 1.1 ross }
266 1.1 ross else {
267 1.1 ross for ( functionCode = 1;
268 1.1 ross functionCode < NUM_FUNCTIONS;
269 1.1 ross ++functionCode
270 1.1 ross ) {
271 1.1 ross if ( strcmp( argPtr, functions[ functionCode ].name ) == 0 ) {
272 1.1 ross break;
273 1.1 ross }
274 1.1 ross }
275 1.1 ross if ( functionCode == NUM_FUNCTIONS ) {
276 1.1 ross fail( "Invalid option or function `%s'", argv[ 0 ] );
277 1.1 ross }
278 1.1 ross if ( ! functionExists[ functionCode ] ) {
279 1.1 ross fail(
280 1.1 ross "Function `%s' is not supported or cannot be tested",
281 1.1 ross argPtr
282 1.1 ross );
283 1.1 ross }
284 1.1 ross functionArgument = TRUE;
285 1.1 ross }
286 1.1 ross --argc;
287 1.1 ross ++argv;
288 1.1 ross }
289 1.1 ross if ( ! functionArgument ) fail( "Function argument required" );
290 1.1 ross (void) signal( SIGINT, catchSIGINT );
291 1.1 ross (void) signal( SIGTERM, catchSIGINT );
292 1.1 ross if ( functionCode ) {
293 1.1 ross if ( forever ) {
294 1.1 ross if ( ! roundingPrecision ) roundingPrecision = 80;
295 1.1 ross if ( ! roundingMode ) roundingMode = ROUND_NEAREST_EVEN;
296 1.1 ross }
297 1.1 ross testFunction( functionCode, roundingPrecision, roundingMode );
298 1.1 ross }
299 1.1 ross else {
300 1.1 ross if ( forever ) {
301 1.1 ross fail( "Can only test one function with `-forever' option" );
302 1.1 ross }
303 1.1 ross if ( operands == 1 ) {
304 1.1 ross for ( functionCode = 1;
305 1.1 ross functionCode < NUM_FUNCTIONS;
306 1.1 ross ++functionCode
307 1.1 ross ) {
308 1.1 ross if ( functionExists[ functionCode ]
309 1.1 ross && ( functions[ functionCode ].numInputs == 1 ) ) {
310 1.1 ross testFunction(
311 1.1 ross functionCode, roundingPrecision, roundingMode );
312 1.1 ross }
313 1.1 ross }
314 1.1 ross }
315 1.1 ross else if ( operands == 2 ) {
316 1.1 ross for ( functionCode = 1;
317 1.1 ross functionCode < NUM_FUNCTIONS;
318 1.1 ross ++functionCode
319 1.1 ross ) {
320 1.1 ross if ( functionExists[ functionCode ]
321 1.1 ross && ( functions[ functionCode ].numInputs == 2 ) ) {
322 1.1 ross testFunction(
323 1.1 ross functionCode, roundingPrecision, roundingMode );
324 1.1 ross }
325 1.1 ross }
326 1.1 ross }
327 1.1 ross else {
328 1.1 ross for ( functionCode = 1;
329 1.1 ross functionCode < NUM_FUNCTIONS;
330 1.1 ross ++functionCode
331 1.1 ross ) {
332 1.1 ross if ( functionExists[ functionCode ] ) {
333 1.1 ross testFunction(
334 1.1 ross functionCode, roundingPrecision, roundingMode );
335 1.1 ross }
336 1.1 ross }
337 1.1 ross }
338 1.1 ross }
339 1.1 ross exitWithStatus();
340 1.2 ross return 0;
341 1.1 ross }
342 1.1 ross
343