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

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since c0c38c7c was c0c38c7c, checked in by Martin Decky <martin@…>, 10 years ago

software floating point overhaul
use proper type mapping
fix cosine calculation

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