1206917Smarius
2206917Smarius/*
3206917Smarius===============================================================================
4206917Smarius
5206917SmariusThis C source file is part of TestFloat, Release 2a, a package of programs
6206917Smariusfor testing the correctness of floating-point arithmetic complying to the
7206917SmariusIEC/IEEE Standard for Floating-Point.
8206917Smarius
9206917SmariusWritten by John R. Hauser.  More information is available through the Web
10206917Smariuspage `http://HTTP.CS.Berkeley.EDU/~jhauser/arithmetic/TestFloat.html'.
11206917Smarius
12206917SmariusTHIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE.  Although reasonable effort
13206917Smariushas been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT
14206917SmariusTIMES RESULT IN INCORRECT BEHAVIOR.  USE OF THIS SOFTWARE IS RESTRICTED TO
15206917SmariusPERSONS AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ANY
16206917SmariusAND ALL LOSSES, COSTS, OR OTHER PROBLEMS ARISING FROM ITS USE.
17206917Smarius
18206917SmariusDerivative works are acceptable, even for commercial purposes, so long as
19206917Smarius(1) they include prominent notice that the work is derivative, and (2) they
20206917Smariusinclude prominent notice akin to these four paragraphs for those parts of
21206917Smariusthis code that are retained.
22206917Smarius
23206917Smarius===============================================================================
24206917Smarius*/
25206917Smarius
26207151Smarius#include <sys/cdefs.h>
27207151Smarius__FBSDID("$FreeBSD$");
28207151Smarius
29206917Smarius#include <stdlib.h>
30206917Smarius#include <signal.h>
31206917Smarius#include <string.h>
32206917Smarius#include "milieu.h"
33206917Smarius#include "fail.h"
34206917Smarius#include "softfloat.h"
35206917Smarius#include "slowfloat.h"
36206917Smarius#include "testCases.h"
37206917Smarius#include "testLoops.h"
38206917Smarius
39206917Smariusstatic void catchSIGINT( int signalCode )
40206917Smarius{
41206917Smarius
42206917Smarius    if ( stop ) exit( EXIT_FAILURE );
43206917Smarius    stop = TRUE;
44206917Smarius
45206917Smarius}
46206917Smarius
47206917Smariusint8 clearFlags( void )
48206917Smarius{
49206917Smarius    int8 flags;
50206917Smarius
51206917Smarius    flags = float_exception_flags;
52206917Smarius    float_exception_flags = 0;
53206917Smarius    return flags;
54206917Smarius
55206917Smarius}
56206917Smarius
57206917Smariusenum {
58206917Smarius    INT32_TO_FLOAT32 = 1,
59206917Smarius    INT32_TO_FLOAT64,
60206917Smarius#ifdef FLOATX80
61206917Smarius    INT32_TO_FLOATX80,
62206917Smarius#endif
63206917Smarius#ifdef FLOAT128
64206917Smarius    INT32_TO_FLOAT128,
65206917Smarius#endif
66206917Smarius#ifdef BITS64
67206917Smarius    INT64_TO_FLOAT32,
68206917Smarius    INT64_TO_FLOAT64,
69206917Smarius#ifdef FLOATX80
70206917Smarius    INT64_TO_FLOATX80,
71206917Smarius#endif
72206917Smarius#ifdef FLOAT128
73206917Smarius    INT64_TO_FLOAT128,
74206917Smarius#endif
75206917Smarius#endif
76206917Smarius    FLOAT32_TO_INT32,
77206917Smarius    FLOAT32_TO_INT32_ROUND_TO_ZERO,
78206917Smarius#ifdef BITS64
79206917Smarius    FLOAT32_TO_INT64,
80206917Smarius    FLOAT32_TO_INT64_ROUND_TO_ZERO,
81206917Smarius#endif
82206917Smarius    FLOAT32_TO_FLOAT64,
83206917Smarius#ifdef FLOATX80
84206917Smarius    FLOAT32_TO_FLOATX80,
85206917Smarius#endif
86206917Smarius#ifdef FLOAT128
87206917Smarius    FLOAT32_TO_FLOAT128,
88206917Smarius#endif
89206917Smarius    FLOAT32_ROUND_TO_INT,
90206917Smarius    FLOAT32_ADD,
91206917Smarius    FLOAT32_SUB,
92206917Smarius    FLOAT32_MUL,
93206917Smarius    FLOAT32_DIV,
94206917Smarius    FLOAT32_REM,
95206917Smarius    FLOAT32_SQRT,
96206917Smarius    FLOAT32_EQ,
97206917Smarius    FLOAT32_LE,
98206917Smarius    FLOAT32_LT,
99206917Smarius    FLOAT32_EQ_SIGNALING,
100206917Smarius    FLOAT32_LE_QUIET,
101206917Smarius    FLOAT32_LT_QUIET,
102206917Smarius    FLOAT64_TO_INT32,
103206917Smarius    FLOAT64_TO_INT32_ROUND_TO_ZERO,
104206917Smarius#ifdef BITS64
105206917Smarius    FLOAT64_TO_INT64,
106206917Smarius    FLOAT64_TO_INT64_ROUND_TO_ZERO,
107206917Smarius#endif
108206917Smarius    FLOAT64_TO_FLOAT32,
109206917Smarius#ifdef FLOATX80
110206917Smarius    FLOAT64_TO_FLOATX80,
111206917Smarius#endif
112206917Smarius#ifdef FLOAT128
113206917Smarius    FLOAT64_TO_FLOAT128,
114206917Smarius#endif
115206917Smarius    FLOAT64_ROUND_TO_INT,
116206917Smarius    FLOAT64_ADD,
117206917Smarius    FLOAT64_SUB,
118206917Smarius    FLOAT64_MUL,
119206917Smarius    FLOAT64_DIV,
120206917Smarius    FLOAT64_REM,
121206917Smarius    FLOAT64_SQRT,
122206917Smarius    FLOAT64_EQ,
123206917Smarius    FLOAT64_LE,
124206917Smarius    FLOAT64_LT,
125206917Smarius    FLOAT64_EQ_SIGNALING,
126206917Smarius    FLOAT64_LE_QUIET,
127206917Smarius    FLOAT64_LT_QUIET,
128206917Smarius#ifdef FLOATX80
129206917Smarius    FLOATX80_TO_INT32,
130206917Smarius    FLOATX80_TO_INT32_ROUND_TO_ZERO,
131206917Smarius#ifdef BITS64
132206917Smarius    FLOATX80_TO_INT64,
133206917Smarius    FLOATX80_TO_INT64_ROUND_TO_ZERO,
134206917Smarius#endif
135206917Smarius    FLOATX80_TO_FLOAT32,
136206917Smarius    FLOATX80_TO_FLOAT64,
137206917Smarius#ifdef FLOAT128
138206917Smarius    FLOATX80_TO_FLOAT128,
139206917Smarius#endif
140206917Smarius    FLOATX80_ROUND_TO_INT,
141206917Smarius    FLOATX80_ADD,
142206917Smarius    FLOATX80_SUB,
143206917Smarius    FLOATX80_MUL,
144206917Smarius    FLOATX80_DIV,
145206917Smarius    FLOATX80_REM,
146206917Smarius    FLOATX80_SQRT,
147206917Smarius    FLOATX80_EQ,
148206917Smarius    FLOATX80_LE,
149206917Smarius    FLOATX80_LT,
150206917Smarius    FLOATX80_EQ_SIGNALING,
151206917Smarius    FLOATX80_LE_QUIET,
152206917Smarius    FLOATX80_LT_QUIET,
153206917Smarius#endif
154206917Smarius#ifdef FLOAT128
155206917Smarius    FLOAT128_TO_INT32,
156206917Smarius    FLOAT128_TO_INT32_ROUND_TO_ZERO,
157206917Smarius#ifdef BITS64
158206917Smarius    FLOAT128_TO_INT64,
159206917Smarius    FLOAT128_TO_INT64_ROUND_TO_ZERO,
160206917Smarius#endif
161206917Smarius    FLOAT128_TO_FLOAT32,
162206917Smarius    FLOAT128_TO_FLOAT64,
163206917Smarius#ifdef FLOATX80
164206917Smarius    FLOAT128_TO_FLOATX80,
165206917Smarius#endif
166206917Smarius    FLOAT128_ROUND_TO_INT,
167206917Smarius    FLOAT128_ADD,
168206917Smarius    FLOAT128_SUB,
169206917Smarius    FLOAT128_MUL,
170206917Smarius    FLOAT128_DIV,
171206917Smarius    FLOAT128_REM,
172206917Smarius    FLOAT128_SQRT,
173206917Smarius    FLOAT128_EQ,
174206917Smarius    FLOAT128_LE,
175206917Smarius    FLOAT128_LT,
176206917Smarius    FLOAT128_EQ_SIGNALING,
177206917Smarius    FLOAT128_LE_QUIET,
178206917Smarius    FLOAT128_LT_QUIET,
179206917Smarius#endif
180206917Smarius    NUM_FUNCTIONS
181206917Smarius};
182206917Smariusstatic struct {
183206917Smarius    char *name;
184206917Smarius    int8 numInputs;
185206917Smarius    flag roundingPrecision, roundingMode;
186206917Smarius    flag tininessMode, tininessModeAtReducedPrecision;
187206917Smarius} functions[ NUM_FUNCTIONS ] = {
188206917Smarius    { 0, 0, 0, 0, 0, 0 },
189206917Smarius    { "int32_to_float32",                1, FALSE, TRUE,  FALSE, FALSE },
190206917Smarius    { "int32_to_float64",                1, FALSE, FALSE, FALSE, FALSE },
191206917Smarius#ifdef FLOATX80
192206917Smarius    { "int32_to_floatx80",               1, FALSE, FALSE, FALSE, FALSE },
193206917Smarius#endif
194206917Smarius#ifdef FLOAT128
195206917Smarius    { "int32_to_float128",               1, FALSE, FALSE, FALSE, FALSE },
196206917Smarius#endif
197206917Smarius#ifdef BITS64
198206917Smarius    { "int64_to_float32",                1, FALSE, TRUE,  FALSE, FALSE },
199206917Smarius    { "int64_to_float64",                1, FALSE, TRUE,  FALSE, FALSE },
200206917Smarius#ifdef FLOATX80
201206917Smarius    { "int64_to_floatx80",               1, FALSE, FALSE, FALSE, FALSE },
202206917Smarius#endif
203206917Smarius#ifdef FLOAT128
204206917Smarius    { "int64_to_float128",               1, FALSE, FALSE, FALSE, FALSE },
205206917Smarius#endif
206206917Smarius#endif
207206917Smarius    { "float32_to_int32",                1, FALSE, TRUE,  FALSE, FALSE },
208206917Smarius    { "float32_to_int32_round_to_zero",  1, FALSE, FALSE, FALSE, FALSE },
209206917Smarius#ifdef BITS64
210206917Smarius    { "float32_to_int64",                1, FALSE, TRUE,  FALSE, FALSE },
211206917Smarius    { "float32_to_int64_round_to_zero",  1, FALSE, FALSE, FALSE, FALSE },
212206917Smarius#endif
213206917Smarius    { "float32_to_float64",              1, FALSE, FALSE, FALSE, FALSE },
214206917Smarius#ifdef FLOATX80
215206917Smarius    { "float32_to_floatx80",             1, FALSE, FALSE, FALSE, FALSE },
216206917Smarius#endif
217206917Smarius#ifdef FLOAT128
218206917Smarius    { "float32_to_float128",             1, FALSE, FALSE, FALSE, FALSE },
219206917Smarius#endif
220206917Smarius    { "float32_round_to_int",            1, FALSE, TRUE,  FALSE, FALSE },
221206917Smarius    { "float32_add",                     2, FALSE, TRUE,  FALSE, FALSE },
222206917Smarius    { "float32_sub",                     2, FALSE, TRUE,  FALSE, FALSE },
223206917Smarius    { "float32_mul",                     2, FALSE, TRUE,  TRUE,  FALSE },
224206917Smarius    { "float32_div",                     2, FALSE, TRUE,  FALSE, FALSE },
225206917Smarius    { "float32_rem",                     2, FALSE, FALSE, FALSE, FALSE },
226206917Smarius    { "float32_sqrt",                    1, FALSE, TRUE,  FALSE, FALSE },
227206917Smarius    { "float32_eq",                      2, FALSE, FALSE, FALSE, FALSE },
228206917Smarius    { "float32_le",                      2, FALSE, FALSE, FALSE, FALSE },
229206917Smarius    { "float32_lt",                      2, FALSE, FALSE, FALSE, FALSE },
230206917Smarius    { "float32_eq_signaling",            2, FALSE, FALSE, FALSE, FALSE },
231206917Smarius    { "float32_le_quiet",                2, FALSE, FALSE, FALSE, FALSE },
232206917Smarius    { "float32_lt_quiet",                2, FALSE, FALSE, FALSE, FALSE },
233206917Smarius    { "float64_to_int32",                1, FALSE, TRUE,  FALSE, FALSE },
234206917Smarius    { "float64_to_int32_round_to_zero",  1, FALSE, FALSE, FALSE, FALSE },
235206917Smarius#ifdef BITS64
236206917Smarius    { "float64_to_int64",                1, FALSE, TRUE,  FALSE, FALSE },
237206917Smarius    { "float64_to_int64_round_to_zero",  1, FALSE, FALSE, FALSE, FALSE },
238206917Smarius#endif
239206917Smarius    { "float64_to_float32",              1, FALSE, TRUE,  TRUE,  FALSE },
240206917Smarius#ifdef FLOATX80
241206917Smarius    { "float64_to_floatx80",             1, FALSE, FALSE, FALSE, FALSE },
242206917Smarius#endif
243206917Smarius#ifdef FLOAT128
244206917Smarius    { "float64_to_float128",             1, FALSE, FALSE, FALSE, FALSE },
245206917Smarius#endif
246206917Smarius    { "float64_round_to_int",            1, FALSE, TRUE,  FALSE, FALSE },
247206917Smarius    { "float64_add",                     2, FALSE, TRUE,  FALSE, FALSE },
248206917Smarius    { "float64_sub",                     2, FALSE, TRUE,  FALSE, FALSE },
249206917Smarius    { "float64_mul",                     2, FALSE, TRUE,  TRUE,  FALSE },
250206917Smarius    { "float64_div",                     2, FALSE, TRUE,  FALSE, FALSE },
251206917Smarius    { "float64_rem",                     2, FALSE, FALSE, FALSE, FALSE },
252206917Smarius    { "float64_sqrt",                    1, FALSE, TRUE,  FALSE, FALSE },
253206917Smarius    { "float64_eq",                      2, FALSE, FALSE, FALSE, FALSE },
254206917Smarius    { "float64_le",                      2, FALSE, FALSE, FALSE, FALSE },
255206917Smarius    { "float64_lt",                      2, FALSE, FALSE, FALSE, FALSE },
256206917Smarius    { "float64_eq_signaling",            2, FALSE, FALSE, FALSE, FALSE },
257206917Smarius    { "float64_le_quiet",                2, FALSE, FALSE, FALSE, FALSE },
258206917Smarius    { "float64_lt_quiet",                2, FALSE, FALSE, FALSE, FALSE },
259206917Smarius#ifdef FLOATX80
260206917Smarius    { "floatx80_to_int32",               1, FALSE, TRUE,  FALSE, FALSE },
261206917Smarius    { "floatx80_to_int32_round_to_zero", 1, FALSE, FALSE, FALSE, FALSE },
262206917Smarius#ifdef BITS64
263206917Smarius    { "floatx80_to_int64",               1, FALSE, TRUE,  FALSE, FALSE },
264206917Smarius    { "floatx80_to_int64_round_to_zero", 1, FALSE, FALSE, FALSE, FALSE },
265206917Smarius#endif
266206917Smarius    { "floatx80_to_float32",             1, FALSE, TRUE,  TRUE,  FALSE },
267206917Smarius    { "floatx80_to_float64",             1, FALSE, TRUE,  TRUE,  FALSE },
268206917Smarius#ifdef FLOAT128
269206917Smarius    { "floatx80_to_float128",            1, FALSE, FALSE, FALSE, FALSE },
270206917Smarius#endif
271206917Smarius    { "floatx80_round_to_int",           1, FALSE, TRUE,  FALSE, FALSE },
272206917Smarius    { "floatx80_add",                    2, TRUE,  TRUE,  FALSE, TRUE  },
273206917Smarius    { "floatx80_sub",                    2, TRUE,  TRUE,  FALSE, TRUE  },
274206917Smarius    { "floatx80_mul",                    2, TRUE,  TRUE,  TRUE,  TRUE  },
275206917Smarius    { "floatx80_div",                    2, TRUE,  TRUE,  FALSE, TRUE  },
276206917Smarius    { "floatx80_rem",                    2, FALSE, FALSE, FALSE, FALSE },
277206917Smarius    { "floatx80_sqrt",                   1, TRUE,  TRUE,  FALSE, FALSE },
278206917Smarius    { "floatx80_eq",                     2, FALSE, FALSE, FALSE, FALSE },
279206917Smarius    { "floatx80_le",                     2, FALSE, FALSE, FALSE, FALSE },
280206917Smarius    { "floatx80_lt",                     2, FALSE, FALSE, FALSE, FALSE },
281206917Smarius    { "floatx80_eq_signaling",           2, FALSE, FALSE, FALSE, FALSE },
282206917Smarius    { "floatx80_le_quiet",               2, FALSE, FALSE, FALSE, FALSE },
283206917Smarius    { "floatx80_lt_quiet",               2, FALSE, FALSE, FALSE, FALSE },
284206917Smarius#endif
285206917Smarius#ifdef FLOAT128
286206917Smarius    { "float128_to_int32",               1, FALSE, TRUE,  FALSE, FALSE },
287206917Smarius    { "float128_to_int32_round_to_zero", 1, FALSE, FALSE, FALSE, FALSE },
288206917Smarius#ifdef BITS64
289206917Smarius    { "float128_to_int64",               1, FALSE, TRUE,  FALSE, FALSE },
290206917Smarius    { "float128_to_int64_round_to_zero", 1, FALSE, FALSE, FALSE, FALSE },
291206917Smarius#endif
292206917Smarius    { "float128_to_float32",             1, FALSE, TRUE,  TRUE,  FALSE },
293206917Smarius    { "float128_to_float64",             1, FALSE, TRUE,  TRUE,  FALSE },
294206917Smarius#ifdef FLOATX80
295206917Smarius    { "float128_to_floatx80",            1, FALSE, TRUE,  TRUE,  FALSE },
296206917Smarius#endif
297206917Smarius    { "float128_round_to_int",           1, FALSE, TRUE,  FALSE, FALSE },
298206917Smarius    { "float128_add",                    2, FALSE, TRUE,  FALSE, FALSE },
299206917Smarius    { "float128_sub",                    2, FALSE, TRUE,  FALSE, FALSE },
300206917Smarius    { "float128_mul",                    2, FALSE, TRUE,  TRUE,  FALSE },
301206917Smarius    { "float128_div",                    2, FALSE, TRUE,  FALSE, FALSE },
302206917Smarius    { "float128_rem",                    2, FALSE, FALSE, FALSE, FALSE },
303206917Smarius    { "float128_sqrt",                   1, FALSE, TRUE,  FALSE, FALSE },
304206917Smarius    { "float128_eq",                     2, FALSE, FALSE, FALSE, FALSE },
305206917Smarius    { "float128_le",                     2, FALSE, FALSE, FALSE, FALSE },
306206917Smarius    { "float128_lt",                     2, FALSE, FALSE, FALSE, FALSE },
307206917Smarius    { "float128_eq_signaling",           2, FALSE, FALSE, FALSE, FALSE },
308206917Smarius    { "float128_le_quiet",               2, FALSE, FALSE, FALSE, FALSE },
309206917Smarius    { "float128_lt_quiet",               2, FALSE, FALSE, FALSE, FALSE },
310206917Smarius#endif
311206917Smarius};
312206917Smarius
313206917Smariusenum {
314206917Smarius    ROUND_NEAREST_EVEN = 1,
315206917Smarius    ROUND_TO_ZERO,
316206917Smarius    ROUND_DOWN,
317206917Smarius    ROUND_UP,
318206917Smarius    NUM_ROUNDINGMODES
319206917Smarius};
320206917Smariusenum {
321206917Smarius    TININESS_BEFORE_ROUNDING = 1,
322206917Smarius    TININESS_AFTER_ROUNDING,
323206917Smarius    NUM_TININESSMODES
324206917Smarius};
325206917Smarius
326206917Smariusstatic void
327206917Smarius testFunctionVariety(
328206917Smarius     uint8 functionCode,
329206917Smarius     int8 roundingPrecision,
330206917Smarius     int8 roundingMode,
331206917Smarius     int8 tininessMode
332206917Smarius )
333206917Smarius{
334206917Smarius    uint8 roundingCode;
335206917Smarius    int8 tininessCode;
336206917Smarius
337206917Smarius    functionName = functions[ functionCode ].name;
338206917Smarius    if ( roundingPrecision == 32 ) {
339206917Smarius        roundingPrecisionName = "32";
340206917Smarius    }
341206917Smarius    else if ( roundingPrecision == 64 ) {
342206917Smarius        roundingPrecisionName = "64";
343206917Smarius    }
344206917Smarius    else if ( roundingPrecision == 80 ) {
345206917Smarius        roundingPrecisionName = "80";
346206917Smarius    }
347206917Smarius    else {
348206917Smarius        roundingPrecisionName = 0;
349206917Smarius    }
350206917Smarius#ifdef FLOATX80
351206917Smarius    floatx80_rounding_precision = roundingPrecision;
352206917Smarius    slow_floatx80_rounding_precision = roundingPrecision;
353206917Smarius#endif
354206917Smarius    switch ( roundingMode ) {
355207151Smarius     default:
356206917Smarius        roundingModeName = 0;
357206917Smarius        roundingCode = float_round_nearest_even;
358206917Smarius        break;
359206917Smarius     case ROUND_NEAREST_EVEN:
360206917Smarius        roundingModeName = "nearest_even";
361206917Smarius        roundingCode = float_round_nearest_even;
362206917Smarius        break;
363206917Smarius     case ROUND_TO_ZERO:
364206917Smarius        roundingModeName = "to_zero";
365206917Smarius        roundingCode = float_round_to_zero;
366206917Smarius        break;
367206917Smarius     case ROUND_DOWN:
368206917Smarius        roundingModeName = "down";
369206917Smarius        roundingCode = float_round_down;
370206917Smarius        break;
371206917Smarius     case ROUND_UP:
372206917Smarius        roundingModeName = "up";
373206917Smarius        roundingCode = float_round_up;
374206917Smarius        break;
375206917Smarius    }
376206917Smarius    float_rounding_mode = roundingCode;
377206917Smarius    slow_float_rounding_mode = roundingCode;
378206917Smarius    switch ( tininessMode ) {
379207151Smarius     default:
380206917Smarius        tininessModeName = 0;
381206917Smarius        tininessCode = float_tininess_after_rounding;
382206917Smarius        break;
383206917Smarius     case TININESS_BEFORE_ROUNDING:
384206917Smarius        tininessModeName = "before";
385206917Smarius        tininessCode = float_tininess_before_rounding;
386206917Smarius        break;
387206917Smarius     case TININESS_AFTER_ROUNDING:
388206917Smarius        tininessModeName = "after";
389206917Smarius        tininessCode = float_tininess_after_rounding;
390206917Smarius        break;
391206917Smarius    }
392206917Smarius    float_detect_tininess = tininessCode;
393206917Smarius    slow_float_detect_tininess = tininessCode;
394206917Smarius    fputs( "Testing ", stderr );
395206917Smarius    writeFunctionName( stderr );
396206917Smarius    fputs( ".\n", stderr );
397206917Smarius    switch ( functionCode ) {
398206917Smarius     case INT32_TO_FLOAT32:
399206917Smarius        test_a_int32_z_float32( slow_int32_to_float32, int32_to_float32 );
400206917Smarius        break;
401206917Smarius     case INT32_TO_FLOAT64:
402206917Smarius        test_a_int32_z_float64( slow_int32_to_float64, int32_to_float64 );
403206917Smarius        break;
404206917Smarius#ifdef FLOATX80
405206917Smarius     case INT32_TO_FLOATX80:
406206917Smarius        test_a_int32_z_floatx80( slow_int32_to_floatx80, int32_to_floatx80 );
407206917Smarius        break;
408206917Smarius#endif
409206917Smarius#ifdef FLOAT128
410206917Smarius     case INT32_TO_FLOAT128:
411206917Smarius        test_a_int32_z_float128( slow_int32_to_float128, int32_to_float128 );
412206917Smarius        break;
413206917Smarius#endif
414206917Smarius#ifdef BITS64
415206917Smarius     case INT64_TO_FLOAT32:
416206917Smarius        test_a_int64_z_float32( slow_int64_to_float32, int64_to_float32 );
417206917Smarius        break;
418206917Smarius     case INT64_TO_FLOAT64:
419206917Smarius        test_a_int64_z_float64( slow_int64_to_float64, int64_to_float64 );
420206917Smarius        break;
421206917Smarius#ifdef FLOATX80
422206917Smarius     case INT64_TO_FLOATX80:
423206917Smarius        test_a_int64_z_floatx80( slow_int64_to_floatx80, int64_to_floatx80 );
424206917Smarius        break;
425206917Smarius#endif
426206917Smarius#ifdef FLOAT128
427206917Smarius     case INT64_TO_FLOAT128:
428206917Smarius        test_a_int64_z_float128( slow_int64_to_float128, int64_to_float128 );
429206917Smarius        break;
430206917Smarius#endif
431206917Smarius#endif
432206917Smarius     case FLOAT32_TO_INT32:
433206917Smarius        test_a_float32_z_int32( slow_float32_to_int32, float32_to_int32 );
434206917Smarius        break;
435206917Smarius     case FLOAT32_TO_INT32_ROUND_TO_ZERO:
436206917Smarius        test_a_float32_z_int32(
437206917Smarius            slow_float32_to_int32_round_to_zero,
438206917Smarius            float32_to_int32_round_to_zero
439206917Smarius        );
440206917Smarius        break;
441206917Smarius#ifdef BITS64
442206917Smarius     case FLOAT32_TO_INT64:
443206917Smarius        test_a_float32_z_int64( slow_float32_to_int64, float32_to_int64 );
444206917Smarius        break;
445206917Smarius     case FLOAT32_TO_INT64_ROUND_TO_ZERO:
446206917Smarius        test_a_float32_z_int64(
447206917Smarius            slow_float32_to_int64_round_to_zero,
448206917Smarius            float32_to_int64_round_to_zero
449206917Smarius        );
450206917Smarius        break;
451206917Smarius#endif
452206917Smarius     case FLOAT32_TO_FLOAT64:
453206917Smarius        test_a_float32_z_float64(
454206917Smarius            slow_float32_to_float64, float32_to_float64 );
455206917Smarius        break;
456206917Smarius#ifdef FLOATX80
457206917Smarius     case FLOAT32_TO_FLOATX80:
458206917Smarius        test_a_float32_z_floatx80(
459206917Smarius            slow_float32_to_floatx80, float32_to_floatx80 );
460206917Smarius        break;
461206917Smarius#endif
462206917Smarius#ifdef FLOAT128
463206917Smarius     case FLOAT32_TO_FLOAT128:
464206917Smarius        test_a_float32_z_float128(
465206917Smarius            slow_float32_to_float128, float32_to_float128 );
466206917Smarius        break;
467206917Smarius#endif
468206917Smarius     case FLOAT32_ROUND_TO_INT:
469206917Smarius        test_az_float32( slow_float32_round_to_int, float32_round_to_int );
470206917Smarius        break;
471206917Smarius     case FLOAT32_ADD:
472206917Smarius        test_abz_float32( slow_float32_add, float32_add );
473206917Smarius        break;
474206917Smarius     case FLOAT32_SUB:
475206917Smarius        test_abz_float32( slow_float32_sub, float32_sub );
476206917Smarius        break;
477206917Smarius     case FLOAT32_MUL:
478206917Smarius        test_abz_float32( slow_float32_mul, float32_mul );
479206917Smarius        break;
480206917Smarius     case FLOAT32_DIV:
481206917Smarius        test_abz_float32( slow_float32_div, float32_div );
482206917Smarius        break;
483206917Smarius     case FLOAT32_REM:
484206917Smarius        test_abz_float32( slow_float32_rem, float32_rem );
485206917Smarius        break;
486206917Smarius     case FLOAT32_SQRT:
487206917Smarius        test_az_float32( slow_float32_sqrt, float32_sqrt );
488206917Smarius        break;
489206917Smarius     case FLOAT32_EQ:
490206917Smarius        test_ab_float32_z_flag( slow_float32_eq, float32_eq );
491206917Smarius        break;
492206917Smarius     case FLOAT32_LE:
493206917Smarius        test_ab_float32_z_flag( slow_float32_le, float32_le );
494206917Smarius        break;
495206917Smarius     case FLOAT32_LT:
496206917Smarius        test_ab_float32_z_flag( slow_float32_lt, float32_lt );
497206917Smarius        break;
498206917Smarius     case FLOAT32_EQ_SIGNALING:
499206917Smarius        test_ab_float32_z_flag(
500206917Smarius            slow_float32_eq_signaling, float32_eq_signaling );
501206917Smarius        break;
502206917Smarius     case FLOAT32_LE_QUIET:
503206917Smarius        test_ab_float32_z_flag( slow_float32_le_quiet, float32_le_quiet );
504206917Smarius        break;
505206917Smarius     case FLOAT32_LT_QUIET:
506206917Smarius        test_ab_float32_z_flag( slow_float32_lt_quiet, float32_lt_quiet );
507206917Smarius        break;
508206917Smarius     case FLOAT64_TO_INT32:
509206917Smarius        test_a_float64_z_int32( slow_float64_to_int32, float64_to_int32 );
510206917Smarius        break;
511206917Smarius     case FLOAT64_TO_INT32_ROUND_TO_ZERO:
512206917Smarius        test_a_float64_z_int32(
513206917Smarius            slow_float64_to_int32_round_to_zero,
514206917Smarius            float64_to_int32_round_to_zero
515206917Smarius        );
516206917Smarius        break;
517206917Smarius#ifdef BITS64
518206917Smarius     case FLOAT64_TO_INT64:
519206917Smarius        test_a_float64_z_int64( slow_float64_to_int64, float64_to_int64 );
520206917Smarius        break;
521206917Smarius     case FLOAT64_TO_INT64_ROUND_TO_ZERO:
522206917Smarius        test_a_float64_z_int64(
523206917Smarius            slow_float64_to_int64_round_to_zero,
524206917Smarius            float64_to_int64_round_to_zero
525206917Smarius        );
526206917Smarius        break;
527206917Smarius#endif
528206917Smarius     case FLOAT64_TO_FLOAT32:
529206917Smarius        test_a_float64_z_float32(
530206917Smarius            slow_float64_to_float32, float64_to_float32 );
531206917Smarius        break;
532206917Smarius#ifdef FLOATX80
533206917Smarius     case FLOAT64_TO_FLOATX80:
534206917Smarius        test_a_float64_z_floatx80(
535206917Smarius            slow_float64_to_floatx80, float64_to_floatx80 );
536206917Smarius        break;
537206917Smarius#endif
538206917Smarius#ifdef FLOAT128
539206917Smarius     case FLOAT64_TO_FLOAT128:
540206917Smarius        test_a_float64_z_float128(
541206917Smarius            slow_float64_to_float128, float64_to_float128 );
542206917Smarius        break;
543206917Smarius#endif
544206917Smarius     case FLOAT64_ROUND_TO_INT:
545206917Smarius        test_az_float64( slow_float64_round_to_int, float64_round_to_int );
546206917Smarius        break;
547206917Smarius     case FLOAT64_ADD:
548206917Smarius        test_abz_float64( slow_float64_add, float64_add );
549206917Smarius        break;
550206917Smarius     case FLOAT64_SUB:
551206917Smarius        test_abz_float64( slow_float64_sub, float64_sub );
552206917Smarius        break;
553206917Smarius     case FLOAT64_MUL:
554206917Smarius        test_abz_float64( slow_float64_mul, float64_mul );
555206917Smarius        break;
556206917Smarius     case FLOAT64_DIV:
557206917Smarius        test_abz_float64( slow_float64_div, float64_div );
558206917Smarius        break;
559206917Smarius     case FLOAT64_REM:
560206917Smarius        test_abz_float64( slow_float64_rem, float64_rem );
561206917Smarius        break;
562206917Smarius     case FLOAT64_SQRT:
563206917Smarius        test_az_float64( slow_float64_sqrt, float64_sqrt );
564206917Smarius        break;
565206917Smarius     case FLOAT64_EQ:
566206917Smarius        test_ab_float64_z_flag( slow_float64_eq, float64_eq );
567206917Smarius        break;
568206917Smarius     case FLOAT64_LE:
569206917Smarius        test_ab_float64_z_flag( slow_float64_le, float64_le );
570206917Smarius        break;
571206917Smarius     case FLOAT64_LT:
572206917Smarius        test_ab_float64_z_flag( slow_float64_lt, float64_lt );
573206917Smarius        break;
574206917Smarius     case FLOAT64_EQ_SIGNALING:
575206917Smarius        test_ab_float64_z_flag(
576206917Smarius            slow_float64_eq_signaling, float64_eq_signaling );
577206917Smarius        break;
578206917Smarius     case FLOAT64_LE_QUIET:
579206917Smarius        test_ab_float64_z_flag( slow_float64_le_quiet, float64_le_quiet );
580206917Smarius        break;
581206917Smarius     case FLOAT64_LT_QUIET:
582206917Smarius        test_ab_float64_z_flag( slow_float64_lt_quiet, float64_lt_quiet );
583206917Smarius        break;
584206917Smarius#ifdef FLOATX80
585206917Smarius     case FLOATX80_TO_INT32:
586206917Smarius        test_a_floatx80_z_int32( slow_floatx80_to_int32, floatx80_to_int32 );
587206917Smarius        break;
588206917Smarius     case FLOATX80_TO_INT32_ROUND_TO_ZERO:
589206917Smarius        test_a_floatx80_z_int32(
590206917Smarius            slow_floatx80_to_int32_round_to_zero,
591206917Smarius            floatx80_to_int32_round_to_zero
592206917Smarius        );
593206917Smarius        break;
594206917Smarius#ifdef BITS64
595206917Smarius     case FLOATX80_TO_INT64:
596206917Smarius        test_a_floatx80_z_int64( slow_floatx80_to_int64, floatx80_to_int64 );
597206917Smarius        break;
598206917Smarius     case FLOATX80_TO_INT64_ROUND_TO_ZERO:
599206917Smarius        test_a_floatx80_z_int64(
600206917Smarius            slow_floatx80_to_int64_round_to_zero,
601206917Smarius            floatx80_to_int64_round_to_zero
602206917Smarius        );
603206917Smarius        break;
604206917Smarius#endif
605206917Smarius     case FLOATX80_TO_FLOAT32:
606206917Smarius        test_a_floatx80_z_float32(
607206917Smarius            slow_floatx80_to_float32, floatx80_to_float32 );
608206917Smarius        break;
609206917Smarius     case FLOATX80_TO_FLOAT64:
610206917Smarius        test_a_floatx80_z_float64(
611206917Smarius            slow_floatx80_to_float64, floatx80_to_float64 );
612206917Smarius        break;
613206917Smarius#ifdef FLOAT128
614206917Smarius     case FLOATX80_TO_FLOAT128:
615206917Smarius        test_a_floatx80_z_float128(
616206917Smarius            slow_floatx80_to_float128, floatx80_to_float128 );
617206917Smarius        break;
618206917Smarius#endif
619206917Smarius     case FLOATX80_ROUND_TO_INT:
620206917Smarius        test_az_floatx80( slow_floatx80_round_to_int, floatx80_round_to_int );
621206917Smarius        break;
622206917Smarius     case FLOATX80_ADD:
623206917Smarius        test_abz_floatx80( slow_floatx80_add, floatx80_add );
624206917Smarius        break;
625206917Smarius     case FLOATX80_SUB:
626206917Smarius        test_abz_floatx80( slow_floatx80_sub, floatx80_sub );
627206917Smarius        break;
628206917Smarius     case FLOATX80_MUL:
629206917Smarius        test_abz_floatx80( slow_floatx80_mul, floatx80_mul );
630206917Smarius        break;
631206917Smarius     case FLOATX80_DIV:
632206917Smarius        test_abz_floatx80( slow_floatx80_div, floatx80_div );
633206917Smarius        break;
634206917Smarius     case FLOATX80_REM:
635206917Smarius        test_abz_floatx80( slow_floatx80_rem, floatx80_rem );
636206917Smarius        break;
637206917Smarius     case FLOATX80_SQRT:
638206917Smarius        test_az_floatx80( slow_floatx80_sqrt, floatx80_sqrt );
639206917Smarius        break;
640206917Smarius     case FLOATX80_EQ:
641206917Smarius        test_ab_floatx80_z_flag( slow_floatx80_eq, floatx80_eq );
642206917Smarius        break;
643206917Smarius     case FLOATX80_LE:
644206917Smarius        test_ab_floatx80_z_flag( slow_floatx80_le, floatx80_le );
645206917Smarius        break;
646206917Smarius     case FLOATX80_LT:
647206917Smarius        test_ab_floatx80_z_flag( slow_floatx80_lt, floatx80_lt );
648206917Smarius        break;
649206917Smarius     case FLOATX80_EQ_SIGNALING:
650206917Smarius        test_ab_floatx80_z_flag(
651206917Smarius            slow_floatx80_eq_signaling, floatx80_eq_signaling );
652206917Smarius        break;
653206917Smarius     case FLOATX80_LE_QUIET:
654206917Smarius        test_ab_floatx80_z_flag( slow_floatx80_le_quiet, floatx80_le_quiet );
655206917Smarius        break;
656206917Smarius     case FLOATX80_LT_QUIET:
657206917Smarius        test_ab_floatx80_z_flag( slow_floatx80_lt_quiet, floatx80_lt_quiet );
658206917Smarius        break;
659206917Smarius#endif
660206917Smarius#ifdef FLOAT128
661206917Smarius     case FLOAT128_TO_INT32:
662206917Smarius        test_a_float128_z_int32( slow_float128_to_int32, float128_to_int32 );
663206917Smarius        break;
664206917Smarius     case FLOAT128_TO_INT32_ROUND_TO_ZERO:
665206917Smarius        test_a_float128_z_int32(
666206917Smarius            slow_float128_to_int32_round_to_zero,
667206917Smarius            float128_to_int32_round_to_zero
668206917Smarius        );
669206917Smarius        break;
670206917Smarius#ifdef BITS64
671206917Smarius     case FLOAT128_TO_INT64:
672206917Smarius        test_a_float128_z_int64( slow_float128_to_int64, float128_to_int64 );
673206917Smarius        break;
674206917Smarius     case FLOAT128_TO_INT64_ROUND_TO_ZERO:
675206917Smarius        test_a_float128_z_int64(
676206917Smarius            slow_float128_to_int64_round_to_zero,
677206917Smarius            float128_to_int64_round_to_zero
678206917Smarius        );
679206917Smarius        break;
680206917Smarius#endif
681206917Smarius     case FLOAT128_TO_FLOAT32:
682206917Smarius        test_a_float128_z_float32(
683206917Smarius            slow_float128_to_float32, float128_to_float32 );
684206917Smarius        break;
685206917Smarius     case FLOAT128_TO_FLOAT64:
686206917Smarius        test_a_float128_z_float64(
687206917Smarius            slow_float128_to_float64, float128_to_float64 );
688206917Smarius        break;
689206917Smarius#ifdef FLOATX80
690206917Smarius     case FLOAT128_TO_FLOATX80:
691206917Smarius        test_a_float128_z_floatx80(
692206917Smarius            slow_float128_to_floatx80, float128_to_floatx80 );
693206917Smarius        break;
694206917Smarius#endif
695206917Smarius     case FLOAT128_ROUND_TO_INT:
696206917Smarius        test_az_float128( slow_float128_round_to_int, float128_round_to_int );
697206917Smarius        break;
698206917Smarius     case FLOAT128_ADD:
699206917Smarius        test_abz_float128( slow_float128_add, float128_add );
700206917Smarius        break;
701206917Smarius     case FLOAT128_SUB:
702206917Smarius        test_abz_float128( slow_float128_sub, float128_sub );
703206917Smarius        break;
704206917Smarius     case FLOAT128_MUL:
705206917Smarius        test_abz_float128( slow_float128_mul, float128_mul );
706206917Smarius        break;
707206917Smarius     case FLOAT128_DIV:
708206917Smarius        test_abz_float128( slow_float128_div, float128_div );
709206917Smarius        break;
710206917Smarius     case FLOAT128_REM:
711206917Smarius        test_abz_float128( slow_float128_rem, float128_rem );
712206917Smarius        break;
713206917Smarius     case FLOAT128_SQRT:
714206917Smarius        test_az_float128( slow_float128_sqrt, float128_sqrt );
715206917Smarius        break;
716206917Smarius     case FLOAT128_EQ:
717206917Smarius        test_ab_float128_z_flag( slow_float128_eq, float128_eq );
718206917Smarius        break;
719206917Smarius     case FLOAT128_LE:
720206917Smarius        test_ab_float128_z_flag( slow_float128_le, float128_le );
721206917Smarius        break;
722206917Smarius     case FLOAT128_LT:
723206917Smarius        test_ab_float128_z_flag( slow_float128_lt, float128_lt );
724206917Smarius        break;
725206917Smarius     case FLOAT128_EQ_SIGNALING:
726206917Smarius        test_ab_float128_z_flag(
727206917Smarius            slow_float128_eq_signaling, float128_eq_signaling );
728206917Smarius        break;
729206917Smarius     case FLOAT128_LE_QUIET:
730206917Smarius        test_ab_float128_z_flag( slow_float128_le_quiet, float128_le_quiet );
731206917Smarius        break;
732206917Smarius     case FLOAT128_LT_QUIET:
733206917Smarius        test_ab_float128_z_flag( slow_float128_lt_quiet, float128_lt_quiet );
734206917Smarius        break;
735206917Smarius#endif
736206917Smarius    }
737206917Smarius    if ( ( errorStop && anyErrors ) || stop ) exitWithStatus();
738206917Smarius
739206917Smarius}
740206917Smarius
741206917Smariusstatic void
742206917Smarius testFunction(
743206917Smarius     uint8 functionCode,
744206917Smarius     int8 roundingPrecisionIn,
745206917Smarius     int8 roundingModeIn,
746206917Smarius     int8 tininessModeIn
747206917Smarius )
748206917Smarius{
749206917Smarius    int8 roundingPrecision, roundingMode, tininessMode;
750206917Smarius
751206917Smarius    roundingPrecision = 32;
752206917Smarius    for (;;) {
753206917Smarius        if ( ! functions[ functionCode ].roundingPrecision ) {
754206917Smarius            roundingPrecision = 0;
755206917Smarius        }
756206917Smarius        else if ( roundingPrecisionIn ) {
757206917Smarius            roundingPrecision = roundingPrecisionIn;
758206917Smarius        }
759206917Smarius        for ( roundingMode = 1;
760206917Smarius              roundingMode < NUM_ROUNDINGMODES;
761206917Smarius              ++roundingMode
762206917Smarius            ) {
763206917Smarius            if ( ! functions[ functionCode ].roundingMode ) {
764206917Smarius                roundingMode = 0;
765206917Smarius            }
766206917Smarius            else if ( roundingModeIn ) {
767206917Smarius                roundingMode = roundingModeIn;
768206917Smarius            }
769206917Smarius            for ( tininessMode = 1;
770206917Smarius                  tininessMode < NUM_TININESSMODES;
771206917Smarius                  ++tininessMode
772206917Smarius                ) {
773206917Smarius                if (    ( roundingPrecision == 32 )
774206917Smarius                     || ( roundingPrecision == 64 ) ) {
775206917Smarius                    if ( ! functions[ functionCode ]
776206917Smarius                               .tininessModeAtReducedPrecision
777206917Smarius                       ) {
778206917Smarius                        tininessMode = 0;
779206917Smarius                    }
780206917Smarius                    else if ( tininessModeIn ) {
781206917Smarius                        tininessMode = tininessModeIn;
782206917Smarius                    }
783206917Smarius                }
784206917Smarius                else {
785206917Smarius                    if ( ! functions[ functionCode ].tininessMode ) {
786206917Smarius                        tininessMode = 0;
787206917Smarius                    }
788206917Smarius                    else if ( tininessModeIn ) {
789206917Smarius                        tininessMode = tininessModeIn;
790206917Smarius                    }
791206917Smarius                }
792206917Smarius                testFunctionVariety(
793206917Smarius                    functionCode, roundingPrecision, roundingMode, tininessMode
794206917Smarius                );
795206917Smarius                if ( tininessModeIn || ! tininessMode ) break;
796206917Smarius            }
797206917Smarius            if ( roundingModeIn || ! roundingMode ) break;
798206917Smarius        }
799206917Smarius        if ( roundingPrecisionIn || ! roundingPrecision ) break;
800206917Smarius        if ( roundingPrecision == 80 ) {
801206917Smarius            break;
802206917Smarius        }
803206917Smarius        else if ( roundingPrecision == 64 ) {
804206917Smarius            roundingPrecision = 80;
805206917Smarius        }
806206917Smarius        else if ( roundingPrecision == 32 ) {
807206917Smarius            roundingPrecision = 64;
808206917Smarius        }
809206917Smarius    }
810206917Smarius
811206917Smarius}
812206917Smarius
813207151Smariusint
814206917Smariusmain( int argc, char **argv )
815206917Smarius{
816206917Smarius    char *argPtr;
817206917Smarius    flag functionArgument;
818206917Smarius    uint8 functionCode;
819206917Smarius    int8 operands, roundingPrecision, roundingMode, tininessMode;
820206917Smarius
821206917Smarius    fail_programName = "testsoftfloat";
822206917Smarius    if ( argc <= 1 ) goto writeHelpMessage;
823206917Smarius    testCases_setLevel( 1 );
824206917Smarius    trueName = "true";
825206917Smarius    testName = "soft";
826206917Smarius    errorStop = FALSE;
827206917Smarius    forever = FALSE;
828206917Smarius    maxErrorCount = 20;
829206917Smarius    trueFlagsPtr = &slow_float_exception_flags;
830206917Smarius    testFlagsFunctionPtr = clearFlags;
831206917Smarius    functionArgument = FALSE;
832206917Smarius    functionCode = 0;
833206917Smarius    operands = 0;
834206917Smarius    roundingPrecision = 0;
835206917Smarius    roundingMode = 0;
836206917Smarius    tininessMode = 0;
837206917Smarius    --argc;
838206917Smarius    ++argv;
839206917Smarius    while ( argc && ( argPtr = argv[ 0 ] ) ) {
840206917Smarius        if ( argPtr[ 0 ] == '-' ) ++argPtr;
841206917Smarius        if ( strcmp( argPtr, "help" ) == 0 ) {
842206917Smarius writeHelpMessage:
843206917Smarius            fputs(
844206917Smarius"testsoftfloat [<option>...] <function>\n"
845206917Smarius"  <option>:  (* is default)\n"
846206917Smarius"    -help            --Write this message and exit.\n"
847206917Smarius"    -level <num>     --Testing level <num> (1 or 2).\n"
848206917Smarius" *  -level 1\n"
849206917Smarius"    -errors <num>    --Stop each function test after <num> errors.\n"
850206917Smarius" *  -errors 20\n"
851206917Smarius"    -errorstop       --Exit after first function with any error.\n"
852206917Smarius"    -forever         --Test one function repeatedly (implies `-level 2').\n"
853206917Smarius#ifdef FLOATX80
854206917Smarius"    -precision32     --Only test rounding precision equivalent to float32.\n"
855206917Smarius"    -precision64     --Only test rounding precision equivalent to float64.\n"
856206917Smarius"    -precision80     --Only test maximum rounding precision.\n"
857206917Smarius#endif
858206917Smarius"    -nearesteven     --Only test rounding to nearest/even.\n"
859206917Smarius"    -tozero          --Only test rounding to zero.\n"
860206917Smarius"    -down            --Only test rounding down.\n"
861206917Smarius"    -up              --Only test rounding up.\n"
862206917Smarius"    -tininessbefore  --Only test underflow tininess before rounding.\n"
863206917Smarius"    -tininessafter   --Only test underflow tininess after rounding.\n"
864206917Smarius"  <function>:\n"
865206917Smarius"    int32_to_<float>                 <float>_add   <float>_eq\n"
866206917Smarius"    <float>_to_int32                 <float>_sub   <float>_le\n"
867206917Smarius"    <float>_to_int32_round_to_zero   <float>_mul   <float>_lt\n"
868206917Smarius#ifdef BITS64
869206917Smarius"    int64_to_<float>                 <float>_div   <float>_eq_signaling\n"
870206917Smarius"    <float>_to_int64                 <float>_rem   <float>_le_quiet\n"
871206917Smarius"    <float>_to_int64_round_to_zero                 <float>_lt_quiet\n"
872206917Smarius"    <float>_to_<float>\n"
873206917Smarius"    <float>_round_to_int\n"
874206917Smarius"    <float>_sqrt\n"
875206917Smarius#else
876206917Smarius"    <float>_to_<float>               <float>_div   <float>_eq_signaling\n"
877206917Smarius"    <float>_round_to_int             <float>_rem   <float>_le_quiet\n"
878206917Smarius"    <float>_sqrt                                   <float>_lt_quiet\n"
879206917Smarius#endif
880206917Smarius"    -all1            --All 1-operand functions.\n"
881206917Smarius"    -all2            --All 2-operand functions.\n"
882206917Smarius"    -all             --All functions.\n"
883206917Smarius"  <float>:\n"
884206917Smarius"    float32          --Single precision.\n"
885206917Smarius"    float64          --Double precision.\n"
886206917Smarius#ifdef FLOATX80
887206917Smarius"    floatx80         --Extended double precision.\n"
888206917Smarius#endif
889206917Smarius#ifdef FLOAT128
890206917Smarius"    float128         --Quadruple precision.\n"
891206917Smarius#endif
892206917Smarius                ,
893206917Smarius                stdout
894206917Smarius            );
895206917Smarius            return EXIT_SUCCESS;
896206917Smarius        }
897206917Smarius        else if ( strcmp( argPtr, "level" ) == 0 ) {
898206917Smarius            if ( argc < 2 ) goto optionError;
899206917Smarius            testCases_setLevel( atoi( argv[ 1 ] ) );
900206917Smarius            --argc;
901206917Smarius            ++argv;
902206917Smarius        }
903206917Smarius        else if ( strcmp( argPtr, "level1" ) == 0 ) {
904206917Smarius            testCases_setLevel( 1 );
905206917Smarius        }
906206917Smarius        else if ( strcmp( argPtr, "level2" ) == 0 ) {
907206917Smarius            testCases_setLevel( 2 );
908206917Smarius        }
909206917Smarius        else if ( strcmp( argPtr, "errors" ) == 0 ) {
910206917Smarius            if ( argc < 2 ) {
911206917Smarius     optionError:
912206917Smarius                fail( "`%s' option requires numeric argument", argv[ 0 ] );
913206917Smarius            }
914206917Smarius            maxErrorCount = atoi( argv[ 1 ] );
915206917Smarius            --argc;
916206917Smarius            ++argv;
917206917Smarius        }
918206917Smarius        else if ( strcmp( argPtr, "errorstop" ) == 0 ) {
919206917Smarius            errorStop = TRUE;
920206917Smarius        }
921206917Smarius        else if ( strcmp( argPtr, "forever" ) == 0 ) {
922206917Smarius            testCases_setLevel( 2 );
923206917Smarius            forever = TRUE;
924206917Smarius        }
925206917Smarius#ifdef FLOATX80
926206917Smarius        else if ( strcmp( argPtr, "precision32" ) == 0 ) {
927206917Smarius            roundingPrecision = 32;
928206917Smarius        }
929206917Smarius        else if ( strcmp( argPtr, "precision64" ) == 0 ) {
930206917Smarius            roundingPrecision = 64;
931206917Smarius        }
932206917Smarius        else if ( strcmp( argPtr, "precision80" ) == 0 ) {
933206917Smarius            roundingPrecision = 80;
934206917Smarius        }
935206917Smarius#endif
936206917Smarius        else if (    ( strcmp( argPtr, "nearesteven" ) == 0 )
937206917Smarius                  || ( strcmp( argPtr, "nearest_even" ) == 0 ) ) {
938206917Smarius            roundingMode = ROUND_NEAREST_EVEN;
939206917Smarius        }
940206917Smarius        else if (    ( strcmp( argPtr, "tozero" ) == 0 )
941206917Smarius                  || ( strcmp( argPtr, "to_zero" ) == 0 ) ) {
942206917Smarius            roundingMode = ROUND_TO_ZERO;
943206917Smarius        }
944206917Smarius        else if ( strcmp( argPtr, "down" ) == 0 ) {
945206917Smarius            roundingMode = ROUND_DOWN;
946206917Smarius        }
947206917Smarius        else if ( strcmp( argPtr, "up" ) == 0 ) {
948206917Smarius            roundingMode = ROUND_UP;
949206917Smarius        }
950206917Smarius        else if ( strcmp( argPtr, "tininessbefore" ) == 0 ) {
951206917Smarius            tininessMode = TININESS_BEFORE_ROUNDING;
952206917Smarius        }
953206917Smarius        else if ( strcmp( argPtr, "tininessafter" ) == 0 ) {
954206917Smarius            tininessMode = TININESS_AFTER_ROUNDING;
955206917Smarius        }
956206917Smarius        else if ( strcmp( argPtr, "all1" ) == 0 ) {
957206917Smarius            functionArgument = TRUE;
958206917Smarius            functionCode = 0;
959206917Smarius            operands = 1;
960206917Smarius        }
961206917Smarius        else if ( strcmp( argPtr, "all2" ) == 0 ) {
962206917Smarius            functionArgument = TRUE;
963206917Smarius            functionCode = 0;
964206917Smarius            operands = 2;
965206917Smarius        }
966206917Smarius        else if ( strcmp( argPtr, "all" ) == 0 ) {
967206917Smarius            functionArgument = TRUE;
968206917Smarius            functionCode = 0;
969206917Smarius            operands = 0;
970206917Smarius        }
971206917Smarius        else {
972206917Smarius            for ( functionCode = 1;
973206917Smarius                  functionCode < NUM_FUNCTIONS;
974206917Smarius                  ++functionCode
975206917Smarius                ) {
976206917Smarius                if ( strcmp( argPtr, functions[ functionCode ].name ) == 0 ) {
977206917Smarius                    break;
978206917Smarius                }
979206917Smarius            }
980206917Smarius            if ( functionCode == NUM_FUNCTIONS ) {
981206917Smarius                fail( "Invalid option or function `%s'", argv[ 0 ] );
982206917Smarius            }
983206917Smarius            functionArgument = TRUE;
984206917Smarius        }
985206917Smarius        --argc;
986206917Smarius        ++argv;
987206917Smarius    }
988206917Smarius    if ( ! functionArgument ) fail( "Function argument required" );
989206917Smarius    (void) signal( SIGINT, catchSIGINT );
990206917Smarius    (void) signal( SIGTERM, catchSIGINT );
991206917Smarius    if ( functionCode ) {
992206917Smarius        if ( forever ) {
993206917Smarius            if ( ! roundingPrecision ) roundingPrecision = 80;
994206917Smarius            if ( ! roundingMode ) roundingMode = ROUND_NEAREST_EVEN;
995206917Smarius        }
996206917Smarius        testFunction(
997206917Smarius            functionCode, roundingPrecision, roundingMode, tininessMode );
998206917Smarius    }
999206917Smarius    else {
1000206917Smarius        if ( operands == 1 ) {
1001206917Smarius            for ( functionCode = 1;
1002206917Smarius                  functionCode < NUM_FUNCTIONS;
1003206917Smarius                  ++functionCode
1004206917Smarius                ) {
1005206917Smarius                if ( functions[ functionCode ].numInputs == 1 ) {
1006206917Smarius                    testFunction(
1007206917Smarius                        functionCode,
1008206917Smarius                        roundingPrecision,
1009206917Smarius                        roundingMode,
1010206917Smarius                        tininessMode
1011206917Smarius                    );
1012206917Smarius                }
1013206917Smarius            }
1014206917Smarius        }
1015206917Smarius        else if ( operands == 2 ) {
1016206917Smarius            for ( functionCode = 1;
1017206917Smarius                  functionCode < NUM_FUNCTIONS;
1018206917Smarius                  ++functionCode
1019206917Smarius                ) {
1020206917Smarius                if ( functions[ functionCode ].numInputs == 2 ) {
1021206917Smarius                    testFunction(
1022206917Smarius                        functionCode,
1023206917Smarius                        roundingPrecision,
1024206917Smarius                        roundingMode,
1025206917Smarius                        tininessMode
1026206917Smarius                    );
1027206917Smarius                }
1028206917Smarius            }
1029206917Smarius        }
1030206917Smarius        else {
1031206917Smarius            for ( functionCode = 1;
1032206917Smarius                  functionCode < NUM_FUNCTIONS;
1033206917Smarius                  ++functionCode
1034206917Smarius                ) {
1035206917Smarius                testFunction(
1036206917Smarius                    functionCode, roundingPrecision, roundingMode, tininessMode
1037206917Smarius                );
1038206917Smarius            }
1039206917Smarius        }
1040206917Smarius    }
1041206917Smarius    exitWithStatus();
1042206917Smarius
1043206917Smarius}
1044206917Smarius
1045