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

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

Add softfloat1 tests for (unsigned) int to double conversions.

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