testsoftfloat.c revision 207151
1174782Smarcel
2174782Smarcel/*
3174782Smarcel===============================================================================
4174782Smarcel
5174782SmarcelThis C source file is part of TestFloat, Release 2a, a package of programs
6174782Smarcelfor testing the correctness of floating-point arithmetic complying to the
7174782SmarcelIEC/IEEE Standard for Floating-Point.
8174782Smarcel
9174782SmarcelWritten by John R. Hauser.  More information is available through the Web
10174782Smarcelpage `http://HTTP.CS.Berkeley.EDU/~jhauser/arithmetic/TestFloat.html'.
11174782Smarcel
12174782SmarcelTHIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE.  Although reasonable effort
13174782Smarcelhas been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT
14174782SmarcelTIMES RESULT IN INCORRECT BEHAVIOR.  USE OF THIS SOFTWARE IS RESTRICTED TO
15174782SmarcelPERSONS AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ANY
16174782SmarcelAND ALL LOSSES, COSTS, OR OTHER PROBLEMS ARISING FROM ITS USE.
17174782Smarcel
18174782SmarcelDerivative works are acceptable, even for commercial purposes, so long as
19174782Smarcel(1) they include prominent notice that the work is derivative, and (2) they
20174782Smarcelinclude prominent notice akin to these four paragraphs for those parts of
21174782Smarcelthis code that are retained.
22174782Smarcel
23174782Smarcel===============================================================================
24174782Smarcel*/
25174782Smarcel
26174782Smarcel#include <sys/cdefs.h>
27174782Smarcel__FBSDID("$FreeBSD: head/tools/test/testfloat/testsoftfloat.c 207151 2010-04-24 12:11:41Z marius $");
28174782Smarcel
29174782Smarcel#include <stdlib.h>
30174782Smarcel#include <signal.h>
31174782Smarcel#include <string.h>
32174782Smarcel#include "milieu.h"
33174782Smarcel#include "fail.h"
34174782Smarcel#include "softfloat.h"
35191447Smarcel#include "slowfloat.h"
36191447Smarcel#include "testCases.h"
37191447Smarcel#include "testLoops.h"
38174782Smarcel
39174782Smarcelstatic void catchSIGINT( int signalCode )
40174782Smarcel{
41191447Smarcel
42190681Snwhitehorn    if ( stop ) exit( EXIT_FAILURE );
43190681Snwhitehorn    stop = TRUE;
44174782Smarcel
45174782Smarcel}
46174782Smarcel
47190681Snwhitehornint8 clearFlags( void )
48174782Smarcel{
49174782Smarcel    int8 flags;
50174782Smarcel
51190681Snwhitehorn    flags = float_exception_flags;
52190681Snwhitehorn    float_exception_flags = 0;
53190681Snwhitehorn    return flags;
54257178Snwhitehorn
55190681Snwhitehorn}
56190681Snwhitehorn
57213307Snwhitehornenum {
58190681Snwhitehorn    INT32_TO_FLOAT32 = 1,
59190681Snwhitehorn    INT32_TO_FLOAT64,
60190681Snwhitehorn#ifdef FLOATX80
61190681Snwhitehorn    INT32_TO_FLOATX80,
62190681Snwhitehorn#endif
63174782Smarcel#ifdef FLOAT128
64174782Smarcel    INT32_TO_FLOAT128,
65174782Smarcel#endif
66174782Smarcel#ifdef BITS64
67174782Smarcel    INT64_TO_FLOAT32,
68174782Smarcel    INT64_TO_FLOAT64,
69174782Smarcel#ifdef FLOATX80
70213307Snwhitehorn    INT64_TO_FLOATX80,
71174782Smarcel#endif
72174782Smarcel#ifdef FLOAT128
73213307Snwhitehorn    INT64_TO_FLOAT128,
74213307Snwhitehorn#endif
75190681Snwhitehorn#endif
76190681Snwhitehorn    FLOAT32_TO_INT32,
77190681Snwhitehorn    FLOAT32_TO_INT32_ROUND_TO_ZERO,
78190681Snwhitehorn#ifdef BITS64
79190681Snwhitehorn    FLOAT32_TO_INT64,
80190681Snwhitehorn    FLOAT32_TO_INT64_ROUND_TO_ZERO,
81190681Snwhitehorn#endif
82190681Snwhitehorn    FLOAT32_TO_FLOAT64,
83257178Snwhitehorn#ifdef FLOATX80
84257178Snwhitehorn    FLOAT32_TO_FLOATX80,
85190681Snwhitehorn#endif
86213307Snwhitehorn#ifdef FLOAT128
87257178Snwhitehorn    FLOAT32_TO_FLOAT128,
88190681Snwhitehorn#endif
89190681Snwhitehorn    FLOAT32_ROUND_TO_INT,
90213307Snwhitehorn    FLOAT32_ADD,
91213307Snwhitehorn    FLOAT32_SUB,
92213307Snwhitehorn    FLOAT32_MUL,
93213307Snwhitehorn    FLOAT32_DIV,
94213307Snwhitehorn    FLOAT32_REM,
95213307Snwhitehorn    FLOAT32_SQRT,
96213307Snwhitehorn    FLOAT32_EQ,
97213307Snwhitehorn    FLOAT32_LE,
98213307Snwhitehorn    FLOAT32_LT,
99213307Snwhitehorn    FLOAT32_EQ_SIGNALING,
100190681Snwhitehorn    FLOAT32_LE_QUIET,
101190681Snwhitehorn    FLOAT32_LT_QUIET,
102174782Smarcel    FLOAT64_TO_INT32,
103174782Smarcel    FLOAT64_TO_INT32_ROUND_TO_ZERO,
104174782Smarcel#ifdef BITS64
105190681Snwhitehorn    FLOAT64_TO_INT64,
106190681Snwhitehorn    FLOAT64_TO_INT64_ROUND_TO_ZERO,
107190681Snwhitehorn#endif
108190681Snwhitehorn    FLOAT64_TO_FLOAT32,
109257178Snwhitehorn#ifdef FLOATX80
110213307Snwhitehorn    FLOAT64_TO_FLOATX80,
111190681Snwhitehorn#endif
112190681Snwhitehorn#ifdef FLOAT128
113190681Snwhitehorn    FLOAT64_TO_FLOAT128,
114257178Snwhitehorn#endif
115257178Snwhitehorn    FLOAT64_ROUND_TO_INT,
116209849Snwhitehorn    FLOAT64_ADD,
117190681Snwhitehorn    FLOAT64_SUB,
118213307Snwhitehorn    FLOAT64_MUL,
119213307Snwhitehorn    FLOAT64_DIV,
120213307Snwhitehorn    FLOAT64_REM,
121213307Snwhitehorn    FLOAT64_SQRT,
122213307Snwhitehorn    FLOAT64_EQ,
123213307Snwhitehorn    FLOAT64_LE,
124213307Snwhitehorn    FLOAT64_LT,
125213307Snwhitehorn    FLOAT64_EQ_SIGNALING,
126213307Snwhitehorn    FLOAT64_LE_QUIET,
127213307Snwhitehorn    FLOAT64_LT_QUIET,
128190681Snwhitehorn#ifdef FLOATX80
129257178Snwhitehorn    FLOATX80_TO_INT32,
130190681Snwhitehorn    FLOATX80_TO_INT32_ROUND_TO_ZERO,
131257178Snwhitehorn#ifdef BITS64
132257178Snwhitehorn    FLOATX80_TO_INT64,
133190681Snwhitehorn    FLOATX80_TO_INT64_ROUND_TO_ZERO,
134190681Snwhitehorn#endif
135190681Snwhitehorn    FLOATX80_TO_FLOAT32,
136190681Snwhitehorn    FLOATX80_TO_FLOAT64,
137190681Snwhitehorn#ifdef FLOAT128
138174782Smarcel    FLOATX80_TO_FLOAT128,
139174782Smarcel#endif
140174782Smarcel    FLOATX80_ROUND_TO_INT,
141174782Smarcel    FLOATX80_ADD,
142174782Smarcel    FLOATX80_SUB,
143174782Smarcel    FLOATX80_MUL,
144174782Smarcel    FLOATX80_DIV,
145174782Smarcel    FLOATX80_REM,
146174782Smarcel    FLOATX80_SQRT,
147174782Smarcel    FLOATX80_EQ,
148174782Smarcel    FLOATX80_LE,
149174782Smarcel    FLOATX80_LT,
150174782Smarcel    FLOATX80_EQ_SIGNALING,
151174782Smarcel    FLOATX80_LE_QUIET,
152174782Smarcel    FLOATX80_LT_QUIET,
153174782Smarcel#endif
154174782Smarcel#ifdef FLOAT128
155174782Smarcel    FLOAT128_TO_INT32,
156174782Smarcel    FLOAT128_TO_INT32_ROUND_TO_ZERO,
157174782Smarcel#ifdef BITS64
158174782Smarcel    FLOAT128_TO_INT64,
159174782Smarcel    FLOAT128_TO_INT64_ROUND_TO_ZERO,
160174782Smarcel#endif
161174782Smarcel    FLOAT128_TO_FLOAT32,
162174782Smarcel    FLOAT128_TO_FLOAT64,
163174782Smarcel#ifdef FLOATX80
164174782Smarcel    FLOAT128_TO_FLOATX80,
165174782Smarcel#endif
166174782Smarcel    FLOAT128_ROUND_TO_INT,
167174782Smarcel    FLOAT128_ADD,
168174782Smarcel    FLOAT128_SUB,
169174782Smarcel    FLOAT128_MUL,
170234579Snwhitehorn    FLOAT128_DIV,
171234579Snwhitehorn    FLOAT128_REM,
172174782Smarcel    FLOAT128_SQRT,
173174782Smarcel    FLOAT128_EQ,
174174782Smarcel    FLOAT128_LE,
175174782Smarcel    FLOAT128_LT,
176174782Smarcel    FLOAT128_EQ_SIGNALING,
177174782Smarcel    FLOAT128_LE_QUIET,
178174782Smarcel    FLOAT128_LT_QUIET,
179174782Smarcel#endif
180191447Smarcel    NUM_FUNCTIONS
181191447Smarcel};
182191447Smarcelstatic struct {
183191447Smarcel    char *name;
184191447Smarcel    int8 numInputs;
185234579Snwhitehorn    flag roundingPrecision, roundingMode;
186191447Smarcel    flag tininessMode, tininessModeAtReducedPrecision;
187191447Smarcel} functions[ NUM_FUNCTIONS ] = {
188174782Smarcel    { 0, 0, 0, 0, 0, 0 },
189174782Smarcel    { "int32_to_float32",                1, FALSE, TRUE,  FALSE, FALSE },
190174782Smarcel    { "int32_to_float64",                1, FALSE, FALSE, FALSE, FALSE },
191174782Smarcel#ifdef FLOATX80
192174782Smarcel    { "int32_to_floatx80",               1, FALSE, FALSE, FALSE, FALSE },
193191447Smarcel#endif
194191447Smarcel#ifdef FLOAT128
195191447Smarcel    { "int32_to_float128",               1, FALSE, FALSE, FALSE, FALSE },
196191447Smarcel#endif
197191447Smarcel#ifdef BITS64
198234579Snwhitehorn    { "int64_to_float32",                1, FALSE, TRUE,  FALSE, FALSE },
199191447Smarcel    { "int64_to_float64",                1, FALSE, TRUE,  FALSE, FALSE },
200191447Smarcel#ifdef FLOATX80
201174782Smarcel    { "int64_to_floatx80",               1, FALSE, FALSE, FALSE, FALSE },
202174782Smarcel#endif
203174782Smarcel#ifdef FLOAT128
204174782Smarcel    { "int64_to_float128",               1, FALSE, FALSE, FALSE, FALSE },
205174782Smarcel#endif
206191447Smarcel#endif
207191447Smarcel    { "float32_to_int32",                1, FALSE, TRUE,  FALSE, FALSE },
208191447Smarcel    { "float32_to_int32_round_to_zero",  1, FALSE, FALSE, FALSE, FALSE },
209191447Smarcel#ifdef BITS64
210191447Smarcel    { "float32_to_int64",                1, FALSE, TRUE,  FALSE, FALSE },
211234579Snwhitehorn    { "float32_to_int64_round_to_zero",  1, FALSE, FALSE, FALSE, FALSE },
212191447Smarcel#endif
213191447Smarcel    { "float32_to_float64",              1, FALSE, FALSE, FALSE, FALSE },
214174782Smarcel#ifdef FLOATX80
215174782Smarcel    { "float32_to_floatx80",             1, FALSE, FALSE, FALSE, FALSE },
216174782Smarcel#endif
217174782Smarcel#ifdef FLOAT128
218174782Smarcel    { "float32_to_float128",             1, FALSE, FALSE, FALSE, FALSE },
219193578Sraj#endif
220193578Sraj    { "float32_round_to_int",            1, FALSE, TRUE,  FALSE, FALSE },
221193578Sraj    { "float32_add",                     2, FALSE, TRUE,  FALSE, FALSE },
222193578Sraj    { "float32_sub",                     2, FALSE, TRUE,  FALSE, FALSE },
223193578Sraj    { "float32_mul",                     2, FALSE, TRUE,  TRUE,  FALSE },
224234579Snwhitehorn    { "float32_div",                     2, FALSE, TRUE,  FALSE, FALSE },
225193578Sraj    { "float32_rem",                     2, FALSE, FALSE, FALSE, FALSE },
226174782Smarcel    { "float32_sqrt",                    1, FALSE, TRUE,  FALSE, FALSE },
227174782Smarcel    { "float32_eq",                      2, FALSE, FALSE, FALSE, FALSE },
228174782Smarcel    { "float32_le",                      2, FALSE, FALSE, FALSE, FALSE },
229174782Smarcel    { "float32_lt",                      2, FALSE, FALSE, FALSE, FALSE },
230174782Smarcel    { "float32_eq_signaling",            2, FALSE, FALSE, FALSE, FALSE },
231174782Smarcel    { "float32_le_quiet",                2, FALSE, FALSE, FALSE, FALSE },
232174782Smarcel    { "float32_lt_quiet",                2, FALSE, FALSE, FALSE, FALSE },
233174782Smarcel    { "float64_to_int32",                1, FALSE, TRUE,  FALSE, FALSE },
234174782Smarcel    { "float64_to_int32_round_to_zero",  1, FALSE, FALSE, FALSE, FALSE },
235174782Smarcel#ifdef BITS64
236174782Smarcel    { "float64_to_int64",                1, FALSE, TRUE,  FALSE, FALSE },
237174782Smarcel    { "float64_to_int64_round_to_zero",  1, FALSE, FALSE, FALSE, FALSE },
238174782Smarcel#endif
239174782Smarcel    { "float64_to_float32",              1, FALSE, TRUE,  TRUE,  FALSE },
240174782Smarcel#ifdef FLOATX80
241174782Smarcel    { "float64_to_floatx80",             1, FALSE, FALSE, FALSE, FALSE },
242174782Smarcel#endif
243174782Smarcel#ifdef FLOAT128
244174782Smarcel    { "float64_to_float128",             1, FALSE, FALSE, FALSE, FALSE },
245174782Smarcel#endif
246174782Smarcel    { "float64_round_to_int",            1, FALSE, TRUE,  FALSE, FALSE },
247193578Sraj    { "float64_add",                     2, FALSE, TRUE,  FALSE, FALSE },
248174782Smarcel    { "float64_sub",                     2, FALSE, TRUE,  FALSE, FALSE },
249193578Sraj    { "float64_mul",                     2, FALSE, TRUE,  TRUE,  FALSE },
250174782Smarcel    { "float64_div",                     2, FALSE, TRUE,  FALSE, FALSE },
251174782Smarcel    { "float64_rem",                     2, FALSE, FALSE, FALSE, FALSE },
252174782Smarcel    { "float64_sqrt",                    1, FALSE, TRUE,  FALSE, FALSE },
253174782Smarcel    { "float64_eq",                      2, FALSE, FALSE, FALSE, FALSE },
254174782Smarcel    { "float64_le",                      2, FALSE, FALSE, FALSE, FALSE },
255174782Smarcel    { "float64_lt",                      2, FALSE, FALSE, FALSE, FALSE },
256174782Smarcel    { "float64_eq_signaling",            2, FALSE, FALSE, FALSE, FALSE },
257174782Smarcel    { "float64_le_quiet",                2, FALSE, FALSE, FALSE, FALSE },
258174782Smarcel    { "float64_lt_quiet",                2, FALSE, FALSE, FALSE, FALSE },
259234579Snwhitehorn#ifdef FLOATX80
260174782Smarcel    { "floatx80_to_int32",               1, FALSE, TRUE,  FALSE, FALSE },
261174782Smarcel    { "floatx80_to_int32_round_to_zero", 1, FALSE, FALSE, FALSE, FALSE },
262174782Smarcel#ifdef BITS64
263174782Smarcel    { "floatx80_to_int64",               1, FALSE, TRUE,  FALSE, FALSE },
264174782Smarcel    { "floatx80_to_int64_round_to_zero", 1, FALSE, FALSE, FALSE, FALSE },
265174782Smarcel#endif
266174782Smarcel    { "floatx80_to_float32",             1, FALSE, TRUE,  TRUE,  FALSE },
267174782Smarcel    { "floatx80_to_float64",             1, FALSE, TRUE,  TRUE,  FALSE },
268174782Smarcel#ifdef FLOAT128
269234579Snwhitehorn    { "floatx80_to_float128",            1, FALSE, FALSE, FALSE, FALSE },
270174782Smarcel#endif
271174782Smarcel    { "floatx80_round_to_int",           1, FALSE, TRUE,  FALSE, FALSE },
272174782Smarcel    { "floatx80_add",                    2, TRUE,  TRUE,  FALSE, TRUE  },
273174782Smarcel    { "floatx80_sub",                    2, TRUE,  TRUE,  FALSE, TRUE  },
274174782Smarcel    { "floatx80_mul",                    2, TRUE,  TRUE,  TRUE,  TRUE  },
275174782Smarcel    { "floatx80_div",                    2, TRUE,  TRUE,  FALSE, TRUE  },
276174782Smarcel    { "floatx80_rem",                    2, FALSE, FALSE, FALSE, FALSE },
277174782Smarcel    { "floatx80_sqrt",                   1, TRUE,  TRUE,  FALSE, FALSE },
278174782Smarcel    { "floatx80_eq",                     2, FALSE, FALSE, FALSE, FALSE },
279234579Snwhitehorn    { "floatx80_le",                     2, FALSE, FALSE, FALSE, FALSE },
280174782Smarcel    { "floatx80_lt",                     2, FALSE, FALSE, FALSE, FALSE },
281174782Smarcel    { "floatx80_eq_signaling",           2, FALSE, FALSE, FALSE, FALSE },
282174782Smarcel    { "floatx80_le_quiet",               2, FALSE, FALSE, FALSE, FALSE },
283174782Smarcel    { "floatx80_lt_quiet",               2, FALSE, FALSE, FALSE, FALSE },
284174782Smarcel#endif
285193578Sraj#ifdef FLOAT128
286193578Sraj    { "float128_to_int32",               1, FALSE, TRUE,  FALSE, FALSE },
287193578Sraj    { "float128_to_int32_round_to_zero", 1, FALSE, FALSE, FALSE, FALSE },
288193578Sraj#ifdef BITS64
289234579Snwhitehorn    { "float128_to_int64",               1, FALSE, TRUE,  FALSE, FALSE },
290174782Smarcel    { "float128_to_int64_round_to_zero", 1, FALSE, FALSE, FALSE, FALSE },
291174782Smarcel#endif
292174782Smarcel    { "float128_to_float32",             1, FALSE, TRUE,  TRUE,  FALSE },
293174782Smarcel    { "float128_to_float64",             1, FALSE, TRUE,  TRUE,  FALSE },
294174782Smarcel#ifdef FLOATX80
295191447Smarcel    { "float128_to_floatx80",            1, FALSE, TRUE,  TRUE,  FALSE },
296191447Smarcel#endif
297191447Smarcel    { "float128_round_to_int",           1, FALSE, TRUE,  FALSE, FALSE },
298191447Smarcel    { "float128_add",                    2, FALSE, TRUE,  FALSE, FALSE },
299234579Snwhitehorn    { "float128_sub",                    2, FALSE, TRUE,  FALSE, FALSE },
300191447Smarcel    { "float128_mul",                    2, FALSE, TRUE,  TRUE,  FALSE },
301174782Smarcel    { "float128_div",                    2, FALSE, TRUE,  FALSE, FALSE },
302174782Smarcel    { "float128_rem",                    2, FALSE, FALSE, FALSE, FALSE },
303174782Smarcel    { "float128_sqrt",                   1, FALSE, TRUE,  FALSE, FALSE },
304174782Smarcel    { "float128_eq",                     2, FALSE, FALSE, FALSE, FALSE },
305174782Smarcel    { "float128_le",                     2, FALSE, FALSE, FALSE, FALSE },
306191447Smarcel    { "float128_lt",                     2, FALSE, FALSE, FALSE, FALSE },
307191447Smarcel    { "float128_eq_signaling",           2, FALSE, FALSE, FALSE, FALSE },
308191447Smarcel    { "float128_le_quiet",               2, FALSE, FALSE, FALSE, FALSE },
309191447Smarcel    { "float128_lt_quiet",               2, FALSE, FALSE, FALSE, FALSE },
310234579Snwhitehorn#endif
311191447Smarcel};
312174782Smarcel
313174782Smarcelenum {
314174782Smarcel    ROUND_NEAREST_EVEN = 1,
315174782Smarcel    ROUND_TO_ZERO,
316174782Smarcel    ROUND_DOWN,
317191447Smarcel    ROUND_UP,
318191447Smarcel    NUM_ROUNDINGMODES
319191447Smarcel};
320191447Smarcelenum {
321234579Snwhitehorn    TININESS_BEFORE_ROUNDING = 1,
322191447Smarcel    TININESS_AFTER_ROUNDING,
323174782Smarcel    NUM_TININESSMODES
324174782Smarcel};
325174782Smarcel
326174782Smarcelstatic void
327174782Smarcel testFunctionVariety(
328193578Sraj     uint8 functionCode,
329193578Sraj     int8 roundingPrecision,
330193578Sraj     int8 roundingMode,
331193578Sraj     int8 tininessMode
332234579Snwhitehorn )
333174782Smarcel{
334174782Smarcel    uint8 roundingCode;
335174782Smarcel    int8 tininessCode;
336174782Smarcel
337174782Smarcel    functionName = functions[ functionCode ].name;
338174782Smarcel    if ( roundingPrecision == 32 ) {
339174782Smarcel        roundingPrecisionName = "32";
340174782Smarcel    }
341174782Smarcel    else if ( roundingPrecision == 64 ) {
342174782Smarcel        roundingPrecisionName = "64";
343174782Smarcel    }
344174782Smarcel    else if ( roundingPrecision == 80 ) {
345174782Smarcel        roundingPrecisionName = "80";
346174782Smarcel    }
347174782Smarcel    else {
348174782Smarcel        roundingPrecisionName = 0;
349174782Smarcel    }
350174782Smarcel#ifdef FLOATX80
351174782Smarcel    floatx80_rounding_precision = roundingPrecision;
352174782Smarcel    slow_floatx80_rounding_precision = roundingPrecision;
353174782Smarcel#endif
354174782Smarcel    switch ( roundingMode ) {
355174782Smarcel     default:
356174782Smarcel        roundingModeName = 0;
357174782Smarcel        roundingCode = float_round_nearest_even;
358174782Smarcel        break;
359174782Smarcel     case ROUND_NEAREST_EVEN:
360193578Sraj        roundingModeName = "nearest_even";
361174782Smarcel        roundingCode = float_round_nearest_even;
362174782Smarcel        break;
363174782Smarcel     case ROUND_TO_ZERO:
364174782Smarcel        roundingModeName = "to_zero";
365174782Smarcel        roundingCode = float_round_to_zero;
366174782Smarcel        break;
367174782Smarcel     case ROUND_DOWN:
368174782Smarcel        roundingModeName = "down";
369174782Smarcel        roundingCode = float_round_down;
370174782Smarcel        break;
371234579Snwhitehorn     case ROUND_UP:
372174782Smarcel        roundingModeName = "up";
373174782Smarcel        roundingCode = float_round_up;
374174782Smarcel        break;
375174782Smarcel    }
376174782Smarcel    float_rounding_mode = roundingCode;
377174782Smarcel    slow_float_rounding_mode = roundingCode;
378174782Smarcel    switch ( tininessMode ) {
379174782Smarcel     default:
380174782Smarcel        tininessModeName = 0;
381174782Smarcel        tininessCode = float_tininess_after_rounding;
382234579Snwhitehorn        break;
383174782Smarcel     case TININESS_BEFORE_ROUNDING:
384174782Smarcel        tininessModeName = "before";
385174782Smarcel        tininessCode = float_tininess_before_rounding;
386174782Smarcel        break;
387174782Smarcel     case TININESS_AFTER_ROUNDING:
388174782Smarcel        tininessModeName = "after";
389174782Smarcel        tininessCode = float_tininess_after_rounding;
390174782Smarcel        break;
391174782Smarcel    }
392174782Smarcel    float_detect_tininess = tininessCode;
393234579Snwhitehorn    slow_float_detect_tininess = tininessCode;
394174782Smarcel    fputs( "Testing ", stderr );
395174782Smarcel    writeFunctionName( stderr );
396174782Smarcel    fputs( ".\n", stderr );
397174782Smarcel    switch ( functionCode ) {
398174782Smarcel     case INT32_TO_FLOAT32:
399174782Smarcel        test_a_int32_z_float32( slow_int32_to_float32, int32_to_float32 );
400193578Sraj        break;
401193578Sraj     case INT32_TO_FLOAT64:
402193578Sraj        test_a_int32_z_float64( slow_int32_to_float64, int32_to_float64 );
403193578Sraj        break;
404234579Snwhitehorn#ifdef FLOATX80
405174782Smarcel     case INT32_TO_FLOATX80:
406174782Smarcel        test_a_int32_z_floatx80( slow_int32_to_floatx80, int32_to_floatx80 );
407174782Smarcel        break;
408174782Smarcel#endif
409174782Smarcel#ifdef FLOAT128
410174782Smarcel     case INT32_TO_FLOAT128:
411174782Smarcel        test_a_int32_z_float128( slow_int32_to_float128, int32_to_float128 );
412174782Smarcel        break;
413174782Smarcel#endif
414234579Snwhitehorn#ifdef BITS64
415174782Smarcel     case INT64_TO_FLOAT32:
416174782Smarcel        test_a_int64_z_float32( slow_int64_to_float32, int64_to_float32 );
417174782Smarcel        break;
418174782Smarcel     case INT64_TO_FLOAT64:
419174782Smarcel        test_a_int64_z_float64( slow_int64_to_float64, int64_to_float64 );
420174782Smarcel        break;
421174782Smarcel#ifdef FLOATX80
422174782Smarcel     case INT64_TO_FLOATX80:
423174782Smarcel        test_a_int64_z_floatx80( slow_int64_to_floatx80, int64_to_floatx80 );
424234579Snwhitehorn        break;
425174782Smarcel#endif
426174782Smarcel#ifdef FLOAT128
427174782Smarcel     case INT64_TO_FLOAT128:
428174782Smarcel        test_a_int64_z_float128( slow_int64_to_float128, int64_to_float128 );
429174782Smarcel        break;
430174782Smarcel#endif
431174782Smarcel#endif
432174782Smarcel     case FLOAT32_TO_INT32:
433174782Smarcel        test_a_float32_z_int32( slow_float32_to_int32, float32_to_int32 );
434234579Snwhitehorn        break;
435174782Smarcel     case FLOAT32_TO_INT32_ROUND_TO_ZERO:
436174782Smarcel        test_a_float32_z_int32(
437174782Smarcel            slow_float32_to_int32_round_to_zero,
438174782Smarcel            float32_to_int32_round_to_zero
439174782Smarcel        );
440193578Sraj        break;
441193578Sraj#ifdef BITS64
442193578Sraj     case FLOAT32_TO_INT64:
443193578Sraj        test_a_float32_z_int64( slow_float32_to_int64, float32_to_int64 );
444234579Snwhitehorn        break;
445174782Smarcel     case FLOAT32_TO_INT64_ROUND_TO_ZERO:
446174782Smarcel        test_a_float32_z_int64(
447174782Smarcel            slow_float32_to_int64_round_to_zero,
448174782Smarcel            float32_to_int64_round_to_zero
449174782Smarcel        );
450174782Smarcel        break;
451174782Smarcel#endif
452174782Smarcel     case FLOAT32_TO_FLOAT64:
453174782Smarcel        test_a_float32_z_float64(
454234579Snwhitehorn            slow_float32_to_float64, float32_to_float64 );
455174782Smarcel        break;
456174782Smarcel#ifdef FLOATX80
457174782Smarcel     case FLOAT32_TO_FLOATX80:
458174782Smarcel        test_a_float32_z_floatx80(
459174782Smarcel            slow_float32_to_floatx80, float32_to_floatx80 );
460174782Smarcel        break;
461174782Smarcel#endif
462174782Smarcel#ifdef FLOAT128
463174782Smarcel     case FLOAT32_TO_FLOAT128:
464234579Snwhitehorn        test_a_float32_z_float128(
465174782Smarcel            slow_float32_to_float128, float32_to_float128 );
466174782Smarcel        break;
467174782Smarcel#endif
468174782Smarcel     case FLOAT32_ROUND_TO_INT:
469174782Smarcel        test_az_float32( slow_float32_round_to_int, float32_round_to_int );
470174782Smarcel        break;
471174782Smarcel     case FLOAT32_ADD:
472174782Smarcel        test_abz_float32( slow_float32_add, float32_add );
473174782Smarcel        break;
474234579Snwhitehorn     case FLOAT32_SUB:
475174782Smarcel        test_abz_float32( slow_float32_sub, float32_sub );
476174782Smarcel        break;
477174782Smarcel     case FLOAT32_MUL:
478174782Smarcel        test_abz_float32( slow_float32_mul, float32_mul );
479174782Smarcel        break;
480193578Sraj     case FLOAT32_DIV:
481193578Sraj        test_abz_float32( slow_float32_div, float32_div );
482193578Sraj        break;
483193578Sraj     case FLOAT32_REM:
484234579Snwhitehorn        test_abz_float32( slow_float32_rem, float32_rem );
485174782Smarcel        break;
486174782Smarcel     case FLOAT32_SQRT:
487174782Smarcel        test_az_float32( slow_float32_sqrt, float32_sqrt );
488174782Smarcel        break;
489174782Smarcel     case FLOAT32_EQ:
490174782Smarcel        test_ab_float32_z_flag( slow_float32_eq, float32_eq );
491174782Smarcel        break;
492174782Smarcel     case FLOAT32_LE:
493191447Smarcel        test_ab_float32_z_flag( slow_float32_le, float32_le );
494191447Smarcel        break;
495191447Smarcel     case FLOAT32_LT:
496191447Smarcel        test_ab_float32_z_flag( slow_float32_lt, float32_lt );
497191447Smarcel        break;
498234579Snwhitehorn     case FLOAT32_EQ_SIGNALING:
499191447Smarcel        test_ab_float32_z_flag(
500191447Smarcel            slow_float32_eq_signaling, float32_eq_signaling );
501174782Smarcel        break;
502174782Smarcel     case FLOAT32_LE_QUIET:
503174782Smarcel        test_ab_float32_z_flag( slow_float32_le_quiet, float32_le_quiet );
504174782Smarcel        break;
505174782Smarcel     case FLOAT32_LT_QUIET:
506191447Smarcel        test_ab_float32_z_flag( slow_float32_lt_quiet, float32_lt_quiet );
507191447Smarcel        break;
508191447Smarcel     case FLOAT64_TO_INT32:
509191447Smarcel        test_a_float64_z_int32( slow_float64_to_int32, float64_to_int32 );
510191447Smarcel        break;
511234579Snwhitehorn     case FLOAT64_TO_INT32_ROUND_TO_ZERO:
512191447Smarcel        test_a_float64_z_int32(
513191447Smarcel            slow_float64_to_int32_round_to_zero,
514174782Smarcel            float64_to_int32_round_to_zero
515174782Smarcel        );
516174782Smarcel        break;
517174782Smarcel#ifdef BITS64
518174782Smarcel     case FLOAT64_TO_INT64:
519191447Smarcel        test_a_float64_z_int64( slow_float64_to_int64, float64_to_int64 );
520191447Smarcel        break;
521191447Smarcel     case FLOAT64_TO_INT64_ROUND_TO_ZERO:
522191447Smarcel        test_a_float64_z_int64(
523191447Smarcel            slow_float64_to_int64_round_to_zero,
524234579Snwhitehorn            float64_to_int64_round_to_zero
525191447Smarcel        );
526191447Smarcel        break;
527174782Smarcel#endif
528174782Smarcel     case FLOAT64_TO_FLOAT32:
529174782Smarcel        test_a_float64_z_float32(
530174782Smarcel            slow_float64_to_float32, float64_to_float32 );
531174782Smarcel        break;
532174782Smarcel#ifdef FLOATX80
533174782Smarcel     case FLOAT64_TO_FLOATX80:
534174782Smarcel        test_a_float64_z_floatx80(
535174782Smarcel            slow_float64_to_floatx80, float64_to_floatx80 );
536174782Smarcel        break;
537174782Smarcel#endif
538174782Smarcel#ifdef FLOAT128
539174782Smarcel     case FLOAT64_TO_FLOAT128:
540174782Smarcel        test_a_float64_z_float128(
541174782Smarcel            slow_float64_to_float128, float64_to_float128 );
542174782Smarcel        break;
543174782Smarcel#endif
544174782Smarcel     case FLOAT64_ROUND_TO_INT:
545174782Smarcel        test_az_float64( slow_float64_round_to_int, float64_round_to_int );
546174782Smarcel        break;
547174782Smarcel     case FLOAT64_ADD:
548174782Smarcel        test_abz_float64( slow_float64_add, float64_add );
549174782Smarcel        break;
550174782Smarcel     case FLOAT64_SUB:
551174782Smarcel        test_abz_float64( slow_float64_sub, float64_sub );
552174782Smarcel        break;
553174782Smarcel     case FLOAT64_MUL:
554174782Smarcel        test_abz_float64( slow_float64_mul, float64_mul );
555174782Smarcel        break;
556174782Smarcel     case FLOAT64_DIV:
557174782Smarcel        test_abz_float64( slow_float64_div, float64_div );
558174782Smarcel        break;
559174782Smarcel     case FLOAT64_REM:
560174782Smarcel        test_abz_float64( slow_float64_rem, float64_rem );
561174782Smarcel        break;
562174782Smarcel     case FLOAT64_SQRT:
563174782Smarcel        test_az_float64( slow_float64_sqrt, float64_sqrt );
564174782Smarcel        break;
565174782Smarcel     case FLOAT64_EQ:
566234579Snwhitehorn        test_ab_float64_z_flag( slow_float64_eq, float64_eq );
567174782Smarcel        break;
568174782Smarcel     case FLOAT64_LE:
569174782Smarcel        test_ab_float64_z_flag( slow_float64_le, float64_le );
570174782Smarcel        break;
571174782Smarcel     case FLOAT64_LT:
572174782Smarcel        test_ab_float64_z_flag( slow_float64_lt, float64_lt );
573174782Smarcel        break;
574174782Smarcel     case FLOAT64_EQ_SIGNALING:
575174782Smarcel        test_ab_float64_z_flag(
576234579Snwhitehorn            slow_float64_eq_signaling, float64_eq_signaling );
577174782Smarcel        break;
578174782Smarcel     case FLOAT64_LE_QUIET:
579174782Smarcel        test_ab_float64_z_flag( slow_float64_le_quiet, float64_le_quiet );
580174782Smarcel        break;
581174782Smarcel     case FLOAT64_LT_QUIET:
582174782Smarcel        test_ab_float64_z_flag( slow_float64_lt_quiet, float64_lt_quiet );
583174782Smarcel        break;
584174782Smarcel#ifdef FLOATX80
585174782Smarcel     case FLOATX80_TO_INT32:
586234579Snwhitehorn        test_a_floatx80_z_int32( slow_floatx80_to_int32, floatx80_to_int32 );
587174782Smarcel        break;
588174782Smarcel     case FLOATX80_TO_INT32_ROUND_TO_ZERO:
589174782Smarcel        test_a_floatx80_z_int32(
590174782Smarcel            slow_floatx80_to_int32_round_to_zero,
591174782Smarcel            floatx80_to_int32_round_to_zero
592174782Smarcel        );
593174782Smarcel        break;
594174782Smarcel#ifdef BITS64
595174782Smarcel     case FLOATX80_TO_INT64:
596174782Smarcel        test_a_floatx80_z_int64( slow_floatx80_to_int64, floatx80_to_int64 );
597174782Smarcel        break;
598191447Smarcel     case FLOATX80_TO_INT64_ROUND_TO_ZERO:
599191447Smarcel        test_a_floatx80_z_int64(
600191447Smarcel            slow_floatx80_to_int64_round_to_zero,
601191447Smarcel            floatx80_to_int64_round_to_zero
602234579Snwhitehorn        );
603191447Smarcel        break;
604174782Smarcel#endif
605174782Smarcel     case FLOATX80_TO_FLOAT32:
606174782Smarcel        test_a_floatx80_z_float32(
607174782Smarcel            slow_floatx80_to_float32, floatx80_to_float32 );
608174782Smarcel        break;
609191447Smarcel     case FLOATX80_TO_FLOAT64:
610191447Smarcel        test_a_floatx80_z_float64(
611191447Smarcel            slow_floatx80_to_float64, floatx80_to_float64 );
612191447Smarcel        break;
613234579Snwhitehorn#ifdef FLOAT128
614191447Smarcel     case FLOATX80_TO_FLOAT128:
615174782Smarcel        test_a_floatx80_z_float128(
616174782Smarcel            slow_floatx80_to_float128, floatx80_to_float128 );
617174782Smarcel        break;
618174782Smarcel#endif
619174782Smarcel     case FLOATX80_ROUND_TO_INT:
620191447Smarcel        test_az_floatx80( slow_floatx80_round_to_int, floatx80_round_to_int );
621191447Smarcel        break;
622191447Smarcel     case FLOATX80_ADD:
623191447Smarcel        test_abz_floatx80( slow_floatx80_add, floatx80_add );
624234579Snwhitehorn        break;
625191447Smarcel     case FLOATX80_SUB:
626174782Smarcel        test_abz_floatx80( slow_floatx80_sub, floatx80_sub );
627174782Smarcel        break;
628174782Smarcel     case FLOATX80_MUL:
629174782Smarcel        test_abz_floatx80( slow_floatx80_mul, floatx80_mul );
630174782Smarcel        break;
631174782Smarcel     case FLOATX80_DIV:
632174782Smarcel        test_abz_floatx80( slow_floatx80_div, floatx80_div );
633174782Smarcel        break;
634174782Smarcel     case FLOATX80_REM:
635174782Smarcel        test_abz_floatx80( slow_floatx80_rem, floatx80_rem );
636174782Smarcel        break;
637174782Smarcel     case FLOATX80_SQRT:
638174782Smarcel        test_az_floatx80( slow_floatx80_sqrt, floatx80_sqrt );
639174782Smarcel        break;
640174782Smarcel     case FLOATX80_EQ:
641174782Smarcel        test_ab_floatx80_z_flag( slow_floatx80_eq, floatx80_eq );
642174782Smarcel        break;
643174782Smarcel     case FLOATX80_LE:
644174782Smarcel        test_ab_floatx80_z_flag( slow_floatx80_le, floatx80_le );
645174782Smarcel        break;
646174782Smarcel     case FLOATX80_LT:
647174782Smarcel        test_ab_floatx80_z_flag( slow_floatx80_lt, floatx80_lt );
648174782Smarcel        break;
649174782Smarcel     case FLOATX80_EQ_SIGNALING:
650174782Smarcel        test_ab_floatx80_z_flag(
651174782Smarcel            slow_floatx80_eq_signaling, floatx80_eq_signaling );
652174782Smarcel        break;
653174782Smarcel     case FLOATX80_LE_QUIET:
654174782Smarcel        test_ab_floatx80_z_flag( slow_floatx80_le_quiet, floatx80_le_quiet );
655174782Smarcel        break;
656174782Smarcel     case FLOATX80_LT_QUIET:
657174782Smarcel        test_ab_floatx80_z_flag( slow_floatx80_lt_quiet, floatx80_lt_quiet );
658174782Smarcel        break;
659174782Smarcel#endif
660174782Smarcel#ifdef FLOAT128
661174782Smarcel     case FLOAT128_TO_INT32:
662174782Smarcel        test_a_float128_z_int32( slow_float128_to_int32, float128_to_int32 );
663174782Smarcel        break;
664174782Smarcel     case FLOAT128_TO_INT32_ROUND_TO_ZERO:
665174782Smarcel        test_a_float128_z_int32(
666174782Smarcel            slow_float128_to_int32_round_to_zero,
667174782Smarcel            float128_to_int32_round_to_zero
668174782Smarcel        );
669174782Smarcel        break;
670234579Snwhitehorn#ifdef BITS64
671174782Smarcel     case FLOAT128_TO_INT64:
672174782Smarcel        test_a_float128_z_int64( slow_float128_to_int64, float128_to_int64 );
673174782Smarcel        break;
674174782Smarcel     case FLOAT128_TO_INT64_ROUND_TO_ZERO:
675174782Smarcel        test_a_float128_z_int64(
676174782Smarcel            slow_float128_to_int64_round_to_zero,
677174782Smarcel            float128_to_int64_round_to_zero
678174782Smarcel        );
679174782Smarcel        break;
680174782Smarcel#endif
681234579Snwhitehorn     case FLOAT128_TO_FLOAT32:
682174782Smarcel        test_a_float128_z_float32(
683174782Smarcel            slow_float128_to_float32, float128_to_float32 );
684174782Smarcel        break;
685174782Smarcel     case FLOAT128_TO_FLOAT64:
686174782Smarcel        test_a_float128_z_float64(
687174782Smarcel            slow_float128_to_float64, float128_to_float64 );
688174782Smarcel        break;
689174782Smarcel#ifdef FLOATX80
690174782Smarcel     case FLOAT128_TO_FLOATX80:
691174782Smarcel        test_a_float128_z_floatx80(
692234579Snwhitehorn            slow_float128_to_floatx80, float128_to_floatx80 );
693174782Smarcel        break;
694174782Smarcel#endif
695174782Smarcel     case FLOAT128_ROUND_TO_INT:
696174782Smarcel        test_az_float128( slow_float128_round_to_int, float128_round_to_int );
697174782Smarcel        break;
698174782Smarcel     case FLOAT128_ADD:
699174782Smarcel        test_abz_float128( slow_float128_add, float128_add );
700174782Smarcel        break;
701174782Smarcel     case FLOAT128_SUB:
702174782Smarcel        test_abz_float128( slow_float128_sub, float128_sub );
703174782Smarcel        break;
704174782Smarcel     case FLOAT128_MUL:
705174782Smarcel        test_abz_float128( slow_float128_mul, float128_mul );
706174782Smarcel        break;
707174782Smarcel     case FLOAT128_DIV:
708174782Smarcel        test_abz_float128( slow_float128_div, float128_div );
709234579Snwhitehorn        break;
710174782Smarcel     case FLOAT128_REM:
711174782Smarcel        test_abz_float128( slow_float128_rem, float128_rem );
712174782Smarcel        break;
713174782Smarcel     case FLOAT128_SQRT:
714174782Smarcel        test_az_float128( slow_float128_sqrt, float128_sqrt );
715174782Smarcel        break;
716174782Smarcel     case FLOAT128_EQ:
717174782Smarcel        test_ab_float128_z_flag( slow_float128_eq, float128_eq );
718174782Smarcel        break;
719234579Snwhitehorn     case FLOAT128_LE:
720174782Smarcel        test_ab_float128_z_flag( slow_float128_le, float128_le );
721174782Smarcel        break;
722174782Smarcel     case FLOAT128_LT:
723174782Smarcel        test_ab_float128_z_flag( slow_float128_lt, float128_lt );
724174782Smarcel        break;
725174782Smarcel     case FLOAT128_EQ_SIGNALING:
726174782Smarcel        test_ab_float128_z_flag(
727174782Smarcel            slow_float128_eq_signaling, float128_eq_signaling );
728174782Smarcel        break;
729234579Snwhitehorn     case FLOAT128_LE_QUIET:
730174782Smarcel        test_ab_float128_z_flag( slow_float128_le_quiet, float128_le_quiet );
731174782Smarcel        break;
732174782Smarcel     case FLOAT128_LT_QUIET:
733174782Smarcel        test_ab_float128_z_flag( slow_float128_lt_quiet, float128_lt_quiet );
734174782Smarcel        break;
735174782Smarcel#endif
736174782Smarcel    }
737174782Smarcel    if ( ( errorStop && anyErrors ) || stop ) exitWithStatus();
738174782Smarcel
739174782Smarcel}
740174782Smarcel
741174782Smarcelstatic void
742174782Smarcel testFunction(
743174782Smarcel     uint8 functionCode,
744174782Smarcel     int8 roundingPrecisionIn,
745234579Snwhitehorn     int8 roundingModeIn,
746174782Smarcel     int8 tininessModeIn
747174782Smarcel )
748174782Smarcel{
749174782Smarcel    int8 roundingPrecision, roundingMode, tininessMode;
750174782Smarcel
751174782Smarcel    roundingPrecision = 32;
752174782Smarcel    for (;;) {
753174782Smarcel        if ( ! functions[ functionCode ].roundingPrecision ) {
754174782Smarcel            roundingPrecision = 0;
755234579Snwhitehorn        }
756174782Smarcel        else if ( roundingPrecisionIn ) {
757174782Smarcel            roundingPrecision = roundingPrecisionIn;
758174782Smarcel        }
759174782Smarcel        for ( roundingMode = 1;
760174782Smarcel              roundingMode < NUM_ROUNDINGMODES;
761174782Smarcel              ++roundingMode
762174782Smarcel            ) {
763174782Smarcel            if ( ! functions[ functionCode ].roundingMode ) {
764174782Smarcel                roundingMode = 0;
765234579Snwhitehorn            }
766174782Smarcel            else if ( roundingModeIn ) {
767174782Smarcel                roundingMode = roundingModeIn;
768174782Smarcel            }
769174782Smarcel            for ( tininessMode = 1;
770174782Smarcel                  tininessMode < NUM_TININESSMODES;
771174782Smarcel                  ++tininessMode
772174782Smarcel                ) {
773174782Smarcel                if (    ( roundingPrecision == 32 )
774174782Smarcel                     || ( roundingPrecision == 64 ) ) {
775174782Smarcel                    if ( ! functions[ functionCode ]
776174782Smarcel                               .tininessModeAtReducedPrecision
777174782Smarcel                       ) {
778174782Smarcel                        tininessMode = 0;
779174782Smarcel                    }
780174782Smarcel                    else if ( tininessModeIn ) {
781174782Smarcel                        tininessMode = tininessModeIn;
782174782Smarcel                    }
783174782Smarcel                }
784174782Smarcel                else {
785174782Smarcel                    if ( ! functions[ functionCode ].tininessMode ) {
786174782Smarcel                        tininessMode = 0;
787174782Smarcel                    }
788174782Smarcel                    else if ( tininessModeIn ) {
789174782Smarcel                        tininessMode = tininessModeIn;
790174782Smarcel                    }
791174782Smarcel                }
792174782Smarcel                testFunctionVariety(
793174782Smarcel                    functionCode, roundingPrecision, roundingMode, tininessMode
794174782Smarcel                );
795174782Smarcel                if ( tininessModeIn || ! tininessMode ) break;
796174782Smarcel            }
797174782Smarcel            if ( roundingModeIn || ! roundingMode ) break;
798174782Smarcel        }
799174782Smarcel        if ( roundingPrecisionIn || ! roundingPrecision ) break;
800174782Smarcel        if ( roundingPrecision == 80 ) {
801174782Smarcel            break;
802174782Smarcel        }
803174782Smarcel        else if ( roundingPrecision == 64 ) {
804174782Smarcel            roundingPrecision = 80;
805174782Smarcel        }
806174782Smarcel        else if ( roundingPrecision == 32 ) {
807174782Smarcel            roundingPrecision = 64;
808174782Smarcel        }
809174782Smarcel    }
810174782Smarcel
811174782Smarcel}
812174782Smarcel
813174782Smarcelint
814174782Smarcelmain( int argc, char **argv )
815174782Smarcel{
816174782Smarcel    char *argPtr;
817174782Smarcel    flag functionArgument;
818174782Smarcel    uint8 functionCode;
819174782Smarcel    int8 operands, roundingPrecision, roundingMode, tininessMode;
820174782Smarcel
821174782Smarcel    fail_programName = "testsoftfloat";
822174782Smarcel    if ( argc <= 1 ) goto writeHelpMessage;
823174782Smarcel    testCases_setLevel( 1 );
824174782Smarcel    trueName = "true";
825174782Smarcel    testName = "soft";
826174782Smarcel    errorStop = FALSE;
827174782Smarcel    forever = FALSE;
828174782Smarcel    maxErrorCount = 20;
829174782Smarcel    trueFlagsPtr = &slow_float_exception_flags;
830174782Smarcel    testFlagsFunctionPtr = clearFlags;
831174782Smarcel    functionArgument = FALSE;
832174782Smarcel    functionCode = 0;
833174782Smarcel    operands = 0;
834174782Smarcel    roundingPrecision = 0;
835174782Smarcel    roundingMode = 0;
836174782Smarcel    tininessMode = 0;
837174782Smarcel    --argc;
838174782Smarcel    ++argv;
839174782Smarcel    while ( argc && ( argPtr = argv[ 0 ] ) ) {
840174782Smarcel        if ( argPtr[ 0 ] == '-' ) ++argPtr;
841174782Smarcel        if ( strcmp( argPtr, "help" ) == 0 ) {
842174782Smarcel writeHelpMessage:
843174782Smarcel            fputs(
844174782Smarcel"testsoftfloat [<option>...] <function>\n"
845174782Smarcel"  <option>:  (* is default)\n"
846174782Smarcel"    -help            --Write this message and exit.\n"
847174782Smarcel"    -level <num>     --Testing level <num> (1 or 2).\n"
848174782Smarcel" *  -level 1\n"
849174782Smarcel"    -errors <num>    --Stop each function test after <num> errors.\n"
850174782Smarcel" *  -errors 20\n"
851174782Smarcel"    -errorstop       --Exit after first function with any error.\n"
852174782Smarcel"    -forever         --Test one function repeatedly (implies `-level 2').\n"
853174782Smarcel#ifdef FLOATX80
854174782Smarcel"    -precision32     --Only test rounding precision equivalent to float32.\n"
855174782Smarcel"    -precision64     --Only test rounding precision equivalent to float64.\n"
856174782Smarcel"    -precision80     --Only test maximum rounding precision.\n"
857174782Smarcel#endif
858174782Smarcel"    -nearesteven     --Only test rounding to nearest/even.\n"
859174782Smarcel"    -tozero          --Only test rounding to zero.\n"
860174782Smarcel"    -down            --Only test rounding down.\n"
861174782Smarcel"    -up              --Only test rounding up.\n"
862174782Smarcel"    -tininessbefore  --Only test underflow tininess before rounding.\n"
863174782Smarcel"    -tininessafter   --Only test underflow tininess after rounding.\n"
864174782Smarcel"  <function>:\n"
865174782Smarcel"    int32_to_<float>                 <float>_add   <float>_eq\n"
866174782Smarcel"    <float>_to_int32                 <float>_sub   <float>_le\n"
867174782Smarcel"    <float>_to_int32_round_to_zero   <float>_mul   <float>_lt\n"
868174782Smarcel#ifdef BITS64
869174782Smarcel"    int64_to_<float>                 <float>_div   <float>_eq_signaling\n"
870174782Smarcel"    <float>_to_int64                 <float>_rem   <float>_le_quiet\n"
871174782Smarcel"    <float>_to_int64_round_to_zero                 <float>_lt_quiet\n"
872174782Smarcel"    <float>_to_<float>\n"
873174782Smarcel"    <float>_round_to_int\n"
874174782Smarcel"    <float>_sqrt\n"
875174782Smarcel#else
876174782Smarcel"    <float>_to_<float>               <float>_div   <float>_eq_signaling\n"
877174782Smarcel"    <float>_round_to_int             <float>_rem   <float>_le_quiet\n"
878174782Smarcel"    <float>_sqrt                                   <float>_lt_quiet\n"
879174782Smarcel#endif
880174782Smarcel"    -all1            --All 1-operand functions.\n"
881174782Smarcel"    -all2            --All 2-operand functions.\n"
882174782Smarcel"    -all             --All functions.\n"
883174782Smarcel"  <float>:\n"
884174782Smarcel"    float32          --Single precision.\n"
885174782Smarcel"    float64          --Double precision.\n"
886174782Smarcel#ifdef FLOATX80
887174782Smarcel"    floatx80         --Extended double precision.\n"
888174782Smarcel#endif
889174782Smarcel#ifdef FLOAT128
890174782Smarcel"    float128         --Quadruple precision.\n"
891174782Smarcel#endif
892174782Smarcel                ,
893174782Smarcel                stdout
894174782Smarcel            );
895174782Smarcel            return EXIT_SUCCESS;
896174782Smarcel        }
897174782Smarcel        else if ( strcmp( argPtr, "level" ) == 0 ) {
898174782Smarcel            if ( argc < 2 ) goto optionError;
899174782Smarcel            testCases_setLevel( atoi( argv[ 1 ] ) );
900174782Smarcel            --argc;
901174782Smarcel            ++argv;
902174782Smarcel        }
903174782Smarcel        else if ( strcmp( argPtr, "level1" ) == 0 ) {
904174782Smarcel            testCases_setLevel( 1 );
905174782Smarcel        }
906174782Smarcel        else if ( strcmp( argPtr, "level2" ) == 0 ) {
907174782Smarcel            testCases_setLevel( 2 );
908174782Smarcel        }
909174782Smarcel        else if ( strcmp( argPtr, "errors" ) == 0 ) {
910174782Smarcel            if ( argc < 2 ) {
911174782Smarcel     optionError:
912174782Smarcel                fail( "`%s' option requires numeric argument", argv[ 0 ] );
913174782Smarcel            }
914174782Smarcel            maxErrorCount = atoi( argv[ 1 ] );
915174782Smarcel            --argc;
916174782Smarcel            ++argv;
917174782Smarcel        }
918174782Smarcel        else if ( strcmp( argPtr, "errorstop" ) == 0 ) {
919174782Smarcel            errorStop = TRUE;
920174782Smarcel        }
921174782Smarcel        else if ( strcmp( argPtr, "forever" ) == 0 ) {
922174782Smarcel            testCases_setLevel( 2 );
923174782Smarcel            forever = TRUE;
924174782Smarcel        }
925174782Smarcel#ifdef FLOATX80
926174782Smarcel        else if ( strcmp( argPtr, "precision32" ) == 0 ) {
927174782Smarcel            roundingPrecision = 32;
928174782Smarcel        }
929174782Smarcel        else if ( strcmp( argPtr, "precision64" ) == 0 ) {
930174782Smarcel            roundingPrecision = 64;
931174782Smarcel        }
932174782Smarcel        else if ( strcmp( argPtr, "precision80" ) == 0 ) {
933174782Smarcel            roundingPrecision = 80;
934174782Smarcel        }
935174782Smarcel#endif
936174782Smarcel        else if (    ( strcmp( argPtr, "nearesteven" ) == 0 )
937174782Smarcel                  || ( strcmp( argPtr, "nearest_even" ) == 0 ) ) {
938174782Smarcel            roundingMode = ROUND_NEAREST_EVEN;
939174782Smarcel        }
940174782Smarcel        else if (    ( strcmp( argPtr, "tozero" ) == 0 )
941174782Smarcel                  || ( strcmp( argPtr, "to_zero" ) == 0 ) ) {
942174782Smarcel            roundingMode = ROUND_TO_ZERO;
943174782Smarcel        }
944174782Smarcel        else if ( strcmp( argPtr, "down" ) == 0 ) {
945174782Smarcel            roundingMode = ROUND_DOWN;
946174782Smarcel        }
947174782Smarcel        else if ( strcmp( argPtr, "up" ) == 0 ) {
948174782Smarcel            roundingMode = ROUND_UP;
949174782Smarcel        }
950174782Smarcel        else if ( strcmp( argPtr, "tininessbefore" ) == 0 ) {
951174782Smarcel            tininessMode = TININESS_BEFORE_ROUNDING;
952174782Smarcel        }
953174782Smarcel        else if ( strcmp( argPtr, "tininessafter" ) == 0 ) {
954174782Smarcel            tininessMode = TININESS_AFTER_ROUNDING;
955174782Smarcel        }
956174782Smarcel        else if ( strcmp( argPtr, "all1" ) == 0 ) {
957174782Smarcel            functionArgument = TRUE;
958174782Smarcel            functionCode = 0;
959174782Smarcel            operands = 1;
960174782Smarcel        }
961        else if ( strcmp( argPtr, "all2" ) == 0 ) {
962            functionArgument = TRUE;
963            functionCode = 0;
964            operands = 2;
965        }
966        else if ( strcmp( argPtr, "all" ) == 0 ) {
967            functionArgument = TRUE;
968            functionCode = 0;
969            operands = 0;
970        }
971        else {
972            for ( functionCode = 1;
973                  functionCode < NUM_FUNCTIONS;
974                  ++functionCode
975                ) {
976                if ( strcmp( argPtr, functions[ functionCode ].name ) == 0 ) {
977                    break;
978                }
979            }
980            if ( functionCode == NUM_FUNCTIONS ) {
981                fail( "Invalid option or function `%s'", argv[ 0 ] );
982            }
983            functionArgument = TRUE;
984        }
985        --argc;
986        ++argv;
987    }
988    if ( ! functionArgument ) fail( "Function argument required" );
989    (void) signal( SIGINT, catchSIGINT );
990    (void) signal( SIGTERM, catchSIGINT );
991    if ( functionCode ) {
992        if ( forever ) {
993            if ( ! roundingPrecision ) roundingPrecision = 80;
994            if ( ! roundingMode ) roundingMode = ROUND_NEAREST_EVEN;
995        }
996        testFunction(
997            functionCode, roundingPrecision, roundingMode, tininessMode );
998    }
999    else {
1000        if ( operands == 1 ) {
1001            for ( functionCode = 1;
1002                  functionCode < NUM_FUNCTIONS;
1003                  ++functionCode
1004                ) {
1005                if ( functions[ functionCode ].numInputs == 1 ) {
1006                    testFunction(
1007                        functionCode,
1008                        roundingPrecision,
1009                        roundingMode,
1010                        tininessMode
1011                    );
1012                }
1013            }
1014        }
1015        else if ( operands == 2 ) {
1016            for ( functionCode = 1;
1017                  functionCode < NUM_FUNCTIONS;
1018                  ++functionCode
1019                ) {
1020                if ( functions[ functionCode ].numInputs == 2 ) {
1021                    testFunction(
1022                        functionCode,
1023                        roundingPrecision,
1024                        roundingMode,
1025                        tininessMode
1026                    );
1027                }
1028            }
1029        }
1030        else {
1031            for ( functionCode = 1;
1032                  functionCode < NUM_FUNCTIONS;
1033                  ++functionCode
1034                ) {
1035                testFunction(
1036                    functionCode, roundingPrecision, roundingMode, tininessMode
1037                );
1038            }
1039        }
1040    }
1041    exitWithStatus();
1042
1043}
1044
1045