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