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

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since a35b458 was a35b458, checked in by Jiří Zárevúcky <zarevucky.jiri@…>, 7 years ago

style: Remove trailing whitespace on _all_ lines, including empty ones, for particular file types.

Command used: tools/srepl '\s\+$' '' -- *.c *.h *.py *.sh *.s *.S *.ag

Currently, whitespace on empty lines is very inconsistent.
There are two basic choices: Either remove the whitespace, or keep empty lines
indented to the level of surrounding code. The former is AFAICT more common,
and also much easier to do automatically.

Alternatively, we could write script for automatic indentation, and use that
instead. However, if such a script exists, it's possible to use the indented
style locally, by having the editor apply relevant conversions on load/save,
without affecting remote repository. IMO, it makes more sense to adopt
the simpler rule.

  • 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 <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.