source: mainline/uspace/app/tester/float/softfloat1.c@ 582a0b8

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since 582a0b8 was 582a0b8, checked in by Jakub Jermar <jakub@…>, 8 years ago

Remove unistd.h

  • Rename usleep() and sleep() to thread_usleep() and thread_sleep() and move to thread.[hc].
  • Include stddef.h in order to provide NULL.
  • Move getpagesize() to libposix.
  • Sync uspace/dist/src/c/demos with originals.
  • Property mode set to 100644
File size: 9.6 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 <mathtypes.h>
34#include <add.h>
35#include <sub.h>
36#include <mul.h>
37#include <div.h>
38#include <comparison.h>
39#include <conversion.h>
40#include "../tester.h"
41
42#define add_float __addsf3
43#define sub_float __subsf3
44#define mul_float __mulsf3
45#define div_float __divsf3
46
47#define is_float_lt __ltsf2
48#define is_float_gt __gtsf2
49#define is_float_eq __eqsf2
50
51#define add_double __adddf3
52#define sub_double __subdf3
53#define mul_double __muldf3
54#define div_double __divdf3
55
56#define is_double_lt __ltdf2
57#define is_double_gt __gtdf2
58#define is_double_eq __eqdf2
59
60#define uint_to_double __floatsidf
61#define double_to_uint __fixunsdfsi
62#define double_to_int __fixdfsi
63
64#define OPERANDS 10
65#define PRECISION 1000
66
67#define PRIdCMPTYPE PRId32
68
69typedef int32_t cmptype_t;
70
71typedef void (* uint_to_double_op_t)(unsigned int, double *, double *);
72typedef void (* double_to_uint_op_t)(double, unsigned int *, unsigned int *);
73typedef void (* float_binary_op_t)(float, float, float *, float *);
74typedef void (* float_cmp_op_t)(float, float, cmptype_t *, cmptype_t *);
75typedef void (* double_binary_op_t)(double, double, double *, double *);
76typedef void (* double_cmp_op_t)(double, double, cmptype_t *, cmptype_t *);
77
78typedef void (* template_unary_t)(void *, unsigned, cmptype_t *, cmptype_t *);
79typedef void (* template_binary_t)(void *, unsigned, unsigned, cmptype_t *,
80 cmptype_t *);
81
82#define NUMBERS \
83 3.5, -2.1, 100.0, 50.0, -1024.0, 0.0, 768.3156, 1080.499999, -600.0, 1.0
84
85static float fop_a[OPERANDS] = {
86 NUMBERS
87};
88
89static double dop_a[OPERANDS] = {
90 NUMBERS
91};
92
93static unsigned int uop_a[OPERANDS] = {
94 4, 2, 100, 50, 1024, 0, 1000000, 1, 0x8000000, 500
95};
96
97static int fcmp(float a, float b)
98{
99 if (a < b)
100 return -1;
101
102 if (a > b)
103 return 1;
104
105 return 0;
106}
107
108static int dcmp(double a, double b)
109{
110 if (a < b)
111 return -1;
112
113 if (a > b)
114 return 1;
115
116 return 0;
117}
118
119static void uint_to_double_template(void *f, unsigned i, cmptype_t *pic,
120 cmptype_t *pisc)
121{
122 uint_to_double_op_t op = (uint_to_double_op_t) f;
123
124 double c;
125 double sc;
126 op(uop_a[i], &c, &sc);
127
128 *pic = (cmptype_t) (c * PRECISION);
129 *pisc = (cmptype_t) (sc * PRECISION);
130}
131
132static void double_to_uint_template(void *f, unsigned i, cmptype_t *pic,
133 cmptype_t *pisc)
134{
135 double_to_uint_op_t op = (double_to_uint_op_t) f;
136
137 unsigned int c;
138 unsigned int sc;
139 op(dop_a[i], &c, &sc);
140
141 *pic = (cmptype_t) c;
142 *pisc = (cmptype_t) sc;
143}
144
145static void float_template_binary(void *f, unsigned i, unsigned j,
146 cmptype_t *pic, cmptype_t *pisc)
147{
148 float_binary_op_t op = (float_binary_op_t) f;
149
150 float c;
151 float sc;
152 op(fop_a[i], fop_a[j], &c, &sc);
153
154 *pic = (cmptype_t) (c * PRECISION);
155 *pisc = (cmptype_t) (sc * PRECISION);
156}
157
158static void float_compare_template(void *f, unsigned i, unsigned j,
159 cmptype_t *pis, cmptype_t *piss)
160{
161 float_cmp_op_t op = (float_cmp_op_t) f;
162
163 op(dop_a[i], dop_a[j], pis, piss);
164}
165
166static void double_template_binary(void *f, unsigned i, unsigned j,
167 cmptype_t *pic, cmptype_t *pisc)
168{
169 double_binary_op_t op = (double_binary_op_t) f;
170
171 double c;
172 double sc;
173 op(dop_a[i], dop_a[j], &c, &sc);
174
175 *pic = (cmptype_t) (c * PRECISION);
176 *pisc = (cmptype_t) (sc * PRECISION);
177}
178
179static void double_compare_template(void *f, unsigned i, unsigned j,
180 cmptype_t *pis, cmptype_t *piss)
181{
182 double_cmp_op_t op = (double_cmp_op_t) f;
183
184 op(dop_a[i], dop_a[j], pis, piss);
185}
186
187static bool test_template_unary(template_unary_t template, void *f)
188{
189 bool correct = true;
190
191 for (unsigned int i = 0; i < OPERANDS; i++) {
192 cmptype_t ic;
193 cmptype_t isc;
194
195 template(f, i, &ic, &isc);
196 cmptype_t diff = ic - isc;
197
198 if (diff != 0) {
199 TPRINTF("i=%u ic=%" PRIdCMPTYPE " isc=%" PRIdCMPTYPE "\n",
200 i, ic, isc);
201 correct = false;
202 }
203 }
204
205 return correct;
206}
207
208static bool test_template_binary(template_binary_t template, void *f)
209{
210 bool correct = true;
211
212 for (unsigned int i = 0; i < OPERANDS; i++) {
213 for (unsigned int j = 0; j < OPERANDS; j++) {
214 cmptype_t ic;
215 cmptype_t isc;
216
217 template(f, i, j, &ic, &isc);
218 cmptype_t diff = ic - isc;
219
220 if (diff != 0) {
221 TPRINTF("i=%u, j=%u ic=%" PRIdCMPTYPE
222 " isc=%" PRIdCMPTYPE "\n", i, j, ic, isc);
223 correct = false;
224 }
225 }
226 }
227
228 return correct;
229}
230
231static void uint_to_double_operator(unsigned int a, double *pc, double *psc)
232{
233 *pc = (double) a;
234 *psc = uint_to_double(a);
235}
236
237static void double_to_uint_operator(double a, unsigned int *pc,
238 unsigned int *psc)
239{
240 *pc = (unsigned int) a;
241 *psc = double_to_uint(a);
242}
243
244static void double_to_int_operator(double a, unsigned int *pc,
245 unsigned int *psc)
246{
247 *pc = (int) a;
248 *psc = double_to_int(a);
249}
250
251static void float_add_operator(float a, float b, float *pc, float *psc)
252{
253 *pc = a + b;
254 *psc = add_float(a, b);
255}
256
257static void float_sub_operator(float a, float b, float *pc, float *psc)
258{
259 *pc = a - b;
260 *psc = sub_float(a, b);
261}
262
263static void float_mul_operator(float a, float b, float *pc, float *psc)
264{
265 *pc = a * b;
266 *psc = mul_float(a, b);
267}
268
269static void float_div_operator(float a, float b, float *pc, float *psc)
270{
271 if ((cmptype_t) b == 0) {
272 *pc = 0.0;
273 *psc = 0.0;
274 return;
275 }
276
277 *pc = a / b;
278 *psc = div_float(a, b);
279}
280
281static void float_cmp_operator(float a, float b, cmptype_t *pis,
282 cmptype_t *piss)
283{
284 *pis = fcmp(a, b);
285
286 if (is_float_lt(a, b) == -1)
287 *piss = -1;
288 else if (is_float_gt(a, b) == 1)
289 *piss = 1;
290 else if (is_float_eq(a, b) == 0)
291 *piss = 0;
292 else
293 *piss = 42;
294}
295
296static void double_add_operator(double a, double b, double *pc, double *psc)
297{
298 *pc = a + b;
299 *psc = add_double(a, b);
300}
301
302static void double_sub_operator(double a, double b, double *pc, double *psc)
303{
304 *pc = a - b;
305 *psc = sub_double(a, b);
306}
307
308static void double_mul_operator(double a, double b, double *pc, double *psc)
309{
310 *pc = a * b;
311 *psc = mul_double(a, b);
312}
313
314static void double_div_operator(double a, double b, double *pc, double *psc)
315{
316 if ((cmptype_t) b == 0) {
317 *pc = 0.0;
318 *psc = 0.0;
319 return;
320 }
321
322 *pc = a / b;
323 *psc = div_double(a, b);
324}
325
326static void double_cmp_operator(double a, double b, cmptype_t *pis,
327 cmptype_t *piss)
328{
329 *pis = dcmp(a, b);
330
331 if (is_double_lt(a, b) == -1)
332 *piss = -1;
333 else if (is_double_gt(a, b) == 1)
334 *piss = 1;
335 else if (is_double_eq(a, b) == 0)
336 *piss = 0;
337 else
338 *piss = 42;
339}
340
341const char *test_softfloat1(void)
342{
343 bool err = false;
344
345 if (!test_template_binary(float_template_binary, float_add_operator)) {
346 err = true;
347 TPRINTF("%s\n", "Float addition failed");
348 }
349
350 if (!test_template_binary(float_template_binary, float_sub_operator)) {
351 err = true;
352 TPRINTF("%s\n", "Float addition failed");
353 }
354
355 if (!test_template_binary(float_template_binary, float_mul_operator)) {
356 err = true;
357 TPRINTF("%s\n", "Float multiplication failed");
358 }
359
360 if (!test_template_binary(float_template_binary, float_div_operator)) {
361 err = true;
362 TPRINTF("%s\n", "Float division failed");
363 }
364
365 if (!test_template_binary(float_compare_template, float_cmp_operator)) {
366 err = true;
367 TPRINTF("%s\n", "Float comparison failed");
368 }
369
370 if (!test_template_binary(double_template_binary, double_add_operator)) {
371 err = true;
372 TPRINTF("%s\n", "Double addition failed");
373 }
374
375 if (!test_template_binary(double_template_binary, double_sub_operator)) {
376 err = true;
377 TPRINTF("%s\n", "Double addition failed");
378 }
379
380 if (!test_template_binary(double_template_binary, double_mul_operator)) {
381 err = true;
382 TPRINTF("%s\n", "Double multiplication failed");
383 }
384
385 if (!test_template_binary(double_template_binary, double_div_operator)) {
386 err = true;
387 TPRINTF("%s\n", "Double division failed");
388 }
389
390 if (!test_template_binary(double_compare_template, double_cmp_operator)) {
391 err = true;
392 TPRINTF("%s\n", "Double comparison failed");
393 }
394
395 if (!test_template_unary(uint_to_double_template,
396 uint_to_double_operator)) {
397 err = true;
398 TPRINTF("%s\n", "Conversion from unsigned int to double failed");
399 }
400
401 if (!test_template_unary(double_to_uint_template,
402 double_to_uint_operator)) {
403 err = true;
404 TPRINTF("%s\n", "Conversion from double to unsigned int failed");
405 }
406
407 if (!test_template_unary(double_to_uint_template,
408 double_to_int_operator)) {
409 err = true;
410 TPRINTF("%s\n", "Conversion from double to signed int failed");
411 }
412
413 if (err)
414 return "Software floating point imprecision";
415
416 return NULL;
417}
Note: See TracBrowser for help on using the repository browser.