source: mainline/uspace/app/tester/float/softfloat1.c@ 673ea28

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since 673ea28 was 16bfcd3, checked in by jzr <zarevucky.jiri@…>, 8 years ago

Fix up headers.

  • Property mode set to 100644
File size: 9.7 KB
Line 
1/*
2 * Copyright (c) 2012 Martin Decky
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * - Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * - Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * - The name of the author may not be used to endorse or promote products
15 * derived from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29#include <stdio.h>
30#include <stdlib.h>
31#include <stdbool.h>
32#include <stddef.h>
33#include <inttypes.h>
34#include <mathtypes.h>
35#include <add.h>
36#include <sub.h>
37#include <mul.h>
38#include <div.h>
39#include <comparison.h>
40#include <conversion.h>
41#include "../tester.h"
42
43#define add_float __addsf3
44#define sub_float __subsf3
45#define mul_float __mulsf3
46#define div_float __divsf3
47
48#define is_float_lt __ltsf2
49#define is_float_gt __gtsf2
50#define is_float_eq __eqsf2
51
52#define add_double __adddf3
53#define sub_double __subdf3
54#define mul_double __muldf3
55#define div_double __divdf3
56
57#define is_double_lt __ltdf2
58#define is_double_gt __gtdf2
59#define is_double_eq __eqdf2
60
61#define uint_to_double __floatsidf
62#define double_to_uint __fixunsdfsi
63#define double_to_int __fixdfsi
64
65#define OPERANDS 10
66#define PRECISION 1000
67
68#define PRIdCMPTYPE PRId32
69
70typedef int32_t cmptype_t;
71
72typedef void (* uint_to_double_op_t)(unsigned int, double *, double *);
73typedef void (* double_to_uint_op_t)(double, unsigned int *, unsigned int *);
74typedef void (* float_binary_op_t)(float, float, float *, float *);
75typedef void (* float_cmp_op_t)(float, float, cmptype_t *, cmptype_t *);
76typedef void (* double_binary_op_t)(double, double, double *, double *);
77typedef void (* double_cmp_op_t)(double, double, cmptype_t *, cmptype_t *);
78
79typedef void (* template_unary_t)(void *, unsigned, cmptype_t *, cmptype_t *);
80typedef void (* template_binary_t)(void *, unsigned, unsigned, cmptype_t *,
81 cmptype_t *);
82
83#define NUMBERS \
84 3.5, -2.1, 100.0, 50.0, -1024.0, 0.0, 768.3156, 1080.499999, -600.0, 1.0
85
86static float fop_a[OPERANDS] = {
87 NUMBERS
88};
89
90static double dop_a[OPERANDS] = {
91 NUMBERS
92};
93
94static unsigned int uop_a[OPERANDS] = {
95 4, 2, 100, 50, 1024, 0, 1000000, 1, 0x8000000, 500
96};
97
98static int fcmp(float a, float b)
99{
100 if (a < b)
101 return -1;
102
103 if (a > b)
104 return 1;
105
106 return 0;
107}
108
109static int dcmp(double a, double b)
110{
111 if (a < b)
112 return -1;
113
114 if (a > b)
115 return 1;
116
117 return 0;
118}
119
120static void uint_to_double_template(void *f, unsigned i, cmptype_t *pic,
121 cmptype_t *pisc)
122{
123 uint_to_double_op_t op = (uint_to_double_op_t) f;
124
125 double c;
126 double sc;
127 op(uop_a[i], &c, &sc);
128
129 *pic = (cmptype_t) (c * PRECISION);
130 *pisc = (cmptype_t) (sc * PRECISION);
131}
132
133static void double_to_uint_template(void *f, unsigned i, cmptype_t *pic,
134 cmptype_t *pisc)
135{
136 double_to_uint_op_t op = (double_to_uint_op_t) f;
137
138 unsigned int c;
139 unsigned int sc;
140 op(dop_a[i], &c, &sc);
141
142 *pic = (cmptype_t) c;
143 *pisc = (cmptype_t) sc;
144}
145
146static void float_template_binary(void *f, unsigned i, unsigned j,
147 cmptype_t *pic, cmptype_t *pisc)
148{
149 float_binary_op_t op = (float_binary_op_t) f;
150
151 float c;
152 float sc;
153 op(fop_a[i], fop_a[j], &c, &sc);
154
155 *pic = (cmptype_t) (c * PRECISION);
156 *pisc = (cmptype_t) (sc * PRECISION);
157}
158
159static void float_compare_template(void *f, unsigned i, unsigned j,
160 cmptype_t *pis, cmptype_t *piss)
161{
162 float_cmp_op_t op = (float_cmp_op_t) f;
163
164 op(dop_a[i], dop_a[j], pis, piss);
165}
166
167static void double_template_binary(void *f, unsigned i, unsigned j,
168 cmptype_t *pic, cmptype_t *pisc)
169{
170 double_binary_op_t op = (double_binary_op_t) f;
171
172 double c;
173 double sc;
174 op(dop_a[i], dop_a[j], &c, &sc);
175
176 *pic = (cmptype_t) (c * PRECISION);
177 *pisc = (cmptype_t) (sc * PRECISION);
178}
179
180static void double_compare_template(void *f, unsigned i, unsigned j,
181 cmptype_t *pis, cmptype_t *piss)
182{
183 double_cmp_op_t op = (double_cmp_op_t) f;
184
185 op(dop_a[i], dop_a[j], pis, piss);
186}
187
188static bool test_template_unary(template_unary_t template, void *f)
189{
190 bool correct = true;
191
192 for (unsigned int i = 0; i < OPERANDS; i++) {
193 cmptype_t ic;
194 cmptype_t isc;
195
196 template(f, i, &ic, &isc);
197 cmptype_t diff = ic - isc;
198
199 if (diff != 0) {
200 TPRINTF("i=%u ic=%" PRIdCMPTYPE " isc=%" PRIdCMPTYPE "\n",
201 i, ic, isc);
202 correct = false;
203 }
204 }
205
206 return correct;
207}
208
209static bool test_template_binary(template_binary_t template, void *f)
210{
211 bool correct = true;
212
213 for (unsigned int i = 0; i < OPERANDS; i++) {
214 for (unsigned int j = 0; j < OPERANDS; j++) {
215 cmptype_t ic;
216 cmptype_t isc;
217
218 template(f, i, j, &ic, &isc);
219 cmptype_t diff = ic - isc;
220
221 if (diff != 0) {
222 TPRINTF("i=%u, j=%u ic=%" PRIdCMPTYPE
223 " isc=%" PRIdCMPTYPE "\n", i, j, ic, isc);
224 correct = false;
225 }
226 }
227 }
228
229 return correct;
230}
231
232static void uint_to_double_operator(unsigned int a, double *pc, double *psc)
233{
234 *pc = (double) a;
235 *psc = uint_to_double(a);
236}
237
238static void double_to_uint_operator(double a, unsigned int *pc,
239 unsigned int *psc)
240{
241 *pc = (unsigned int) a;
242 *psc = double_to_uint(a);
243}
244
245static void double_to_int_operator(double a, unsigned int *pc,
246 unsigned int *psc)
247{
248 *pc = (int) a;
249 *psc = double_to_int(a);
250}
251
252static void float_add_operator(float a, float b, float *pc, float *psc)
253{
254 *pc = a + b;
255 *psc = add_float(a, b);
256}
257
258static void float_sub_operator(float a, float b, float *pc, float *psc)
259{
260 *pc = a - b;
261 *psc = sub_float(a, b);
262}
263
264static void float_mul_operator(float a, float b, float *pc, float *psc)
265{
266 *pc = a * b;
267 *psc = mul_float(a, b);
268}
269
270static void float_div_operator(float a, float b, float *pc, float *psc)
271{
272 if ((cmptype_t) b == 0) {
273 *pc = 0.0;
274 *psc = 0.0;
275 return;
276 }
277
278 *pc = a / b;
279 *psc = div_float(a, b);
280}
281
282static void float_cmp_operator(float a, float b, cmptype_t *pis,
283 cmptype_t *piss)
284{
285 *pis = fcmp(a, b);
286
287 if (is_float_lt(a, b) == -1)
288 *piss = -1;
289 else if (is_float_gt(a, b) == 1)
290 *piss = 1;
291 else if (is_float_eq(a, b) == 0)
292 *piss = 0;
293 else
294 *piss = 42;
295}
296
297static void double_add_operator(double a, double b, double *pc, double *psc)
298{
299 *pc = a + b;
300 *psc = add_double(a, b);
301}
302
303static void double_sub_operator(double a, double b, double *pc, double *psc)
304{
305 *pc = a - b;
306 *psc = sub_double(a, b);
307}
308
309static void double_mul_operator(double a, double b, double *pc, double *psc)
310{
311 *pc = a * b;
312 *psc = mul_double(a, b);
313}
314
315static void double_div_operator(double a, double b, double *pc, double *psc)
316{
317 if ((cmptype_t) b == 0) {
318 *pc = 0.0;
319 *psc = 0.0;
320 return;
321 }
322
323 *pc = a / b;
324 *psc = div_double(a, b);
325}
326
327static void double_cmp_operator(double a, double b, cmptype_t *pis,
328 cmptype_t *piss)
329{
330 *pis = dcmp(a, b);
331
332 if (is_double_lt(a, b) == -1)
333 *piss = -1;
334 else if (is_double_gt(a, b) == 1)
335 *piss = 1;
336 else if (is_double_eq(a, b) == 0)
337 *piss = 0;
338 else
339 *piss = 42;
340}
341
342const char *test_softfloat1(void)
343{
344 bool err = false;
345
346 if (!test_template_binary(float_template_binary, float_add_operator)) {
347 err = true;
348 TPRINTF("%s\n", "Float addition failed");
349 }
350
351 if (!test_template_binary(float_template_binary, float_sub_operator)) {
352 err = true;
353 TPRINTF("%s\n", "Float addition failed");
354 }
355
356 if (!test_template_binary(float_template_binary, float_mul_operator)) {
357 err = true;
358 TPRINTF("%s\n", "Float multiplication failed");
359 }
360
361 if (!test_template_binary(float_template_binary, float_div_operator)) {
362 err = true;
363 TPRINTF("%s\n", "Float division failed");
364 }
365
366 if (!test_template_binary(float_compare_template, float_cmp_operator)) {
367 err = true;
368 TPRINTF("%s\n", "Float comparison failed");
369 }
370
371 if (!test_template_binary(double_template_binary, double_add_operator)) {
372 err = true;
373 TPRINTF("%s\n", "Double addition failed");
374 }
375
376 if (!test_template_binary(double_template_binary, double_sub_operator)) {
377 err = true;
378 TPRINTF("%s\n", "Double addition failed");
379 }
380
381 if (!test_template_binary(double_template_binary, double_mul_operator)) {
382 err = true;
383 TPRINTF("%s\n", "Double multiplication failed");
384 }
385
386 if (!test_template_binary(double_template_binary, double_div_operator)) {
387 err = true;
388 TPRINTF("%s\n", "Double division failed");
389 }
390
391 if (!test_template_binary(double_compare_template, double_cmp_operator)) {
392 err = true;
393 TPRINTF("%s\n", "Double comparison failed");
394 }
395
396 if (!test_template_unary(uint_to_double_template,
397 uint_to_double_operator)) {
398 err = true;
399 TPRINTF("%s\n", "Conversion from unsigned int to double failed");
400 }
401
402 if (!test_template_unary(double_to_uint_template,
403 double_to_uint_operator)) {
404 err = true;
405 TPRINTF("%s\n", "Conversion from double to unsigned int failed");
406 }
407
408 if (!test_template_unary(double_to_uint_template,
409 double_to_int_operator)) {
410 err = true;
411 TPRINTF("%s\n", "Conversion from double to signed int failed");
412 }
413
414 if (err)
415 return "Software floating point imprecision";
416
417 return NULL;
418}
Note: See TracBrowser for help on using the repository browser.