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

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

cstyle (no change in functionality)

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