Remove unistd.h
[helenos.git] / uspace / app / tester / float / softfloat1.c
blob7981cf5ecbcb65389d789ef9a00e56292b38bb4a
1 /*
2 * Copyright (c) 2012 Martin Decky
3 * All rights reserved.
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
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.
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.
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"
42 #define add_float __addsf3
43 #define sub_float __subsf3
44 #define mul_float __mulsf3
45 #define div_float __divsf3
47 #define is_float_lt __ltsf2
48 #define is_float_gt __gtsf2
49 #define is_float_eq __eqsf2
51 #define add_double __adddf3
52 #define sub_double __subdf3
53 #define mul_double __muldf3
54 #define div_double __divdf3
56 #define is_double_lt __ltdf2
57 #define is_double_gt __gtdf2
58 #define is_double_eq __eqdf2
60 #define uint_to_double __floatsidf
61 #define double_to_uint __fixunsdfsi
62 #define double_to_int __fixdfsi
64 #define OPERANDS 10
65 #define PRECISION 1000
67 #define PRIdCMPTYPE PRId32
69 typedef int32_t cmptype_t;
71 typedef void (* uint_to_double_op_t)(unsigned int, double *, double *);
72 typedef void (* double_to_uint_op_t)(double, unsigned int *, unsigned int *);
73 typedef void (* float_binary_op_t)(float, float, float *, float *);
74 typedef void (* float_cmp_op_t)(float, float, cmptype_t *, cmptype_t *);
75 typedef void (* double_binary_op_t)(double, double, double *, double *);
76 typedef void (* double_cmp_op_t)(double, double, cmptype_t *, cmptype_t *);
78 typedef void (* template_unary_t)(void *, unsigned, cmptype_t *, cmptype_t *);
79 typedef void (* template_binary_t)(void *, unsigned, unsigned, cmptype_t *,
80 cmptype_t *);
82 #define NUMBERS \
83 3.5, -2.1, 100.0, 50.0, -1024.0, 0.0, 768.3156, 1080.499999, -600.0, 1.0
85 static float fop_a[OPERANDS] = {
86 NUMBERS
89 static double dop_a[OPERANDS] = {
90 NUMBERS
93 static unsigned int uop_a[OPERANDS] = {
94 4, 2, 100, 50, 1024, 0, 1000000, 1, 0x8000000, 500
97 static int fcmp(float a, float b)
99 if (a < b)
100 return -1;
102 if (a > b)
103 return 1;
105 return 0;
108 static int dcmp(double a, double b)
110 if (a < b)
111 return -1;
113 if (a > b)
114 return 1;
116 return 0;
119 static void uint_to_double_template(void *f, unsigned i, cmptype_t *pic,
120 cmptype_t *pisc)
122 uint_to_double_op_t op = (uint_to_double_op_t) f;
124 double c;
125 double sc;
126 op(uop_a[i], &c, &sc);
128 *pic = (cmptype_t) (c * PRECISION);
129 *pisc = (cmptype_t) (sc * PRECISION);
132 static void double_to_uint_template(void *f, unsigned i, cmptype_t *pic,
133 cmptype_t *pisc)
135 double_to_uint_op_t op = (double_to_uint_op_t) f;
137 unsigned int c;
138 unsigned int sc;
139 op(dop_a[i], &c, &sc);
141 *pic = (cmptype_t) c;
142 *pisc = (cmptype_t) sc;
145 static void float_template_binary(void *f, unsigned i, unsigned j,
146 cmptype_t *pic, cmptype_t *pisc)
148 float_binary_op_t op = (float_binary_op_t) f;
150 float c;
151 float sc;
152 op(fop_a[i], fop_a[j], &c, &sc);
154 *pic = (cmptype_t) (c * PRECISION);
155 *pisc = (cmptype_t) (sc * PRECISION);
158 static void float_compare_template(void *f, unsigned i, unsigned j,
159 cmptype_t *pis, cmptype_t *piss)
161 float_cmp_op_t op = (float_cmp_op_t) f;
163 op(dop_a[i], dop_a[j], pis, piss);
166 static void double_template_binary(void *f, unsigned i, unsigned j,
167 cmptype_t *pic, cmptype_t *pisc)
169 double_binary_op_t op = (double_binary_op_t) f;
171 double c;
172 double sc;
173 op(dop_a[i], dop_a[j], &c, &sc);
175 *pic = (cmptype_t) (c * PRECISION);
176 *pisc = (cmptype_t) (sc * PRECISION);
179 static void double_compare_template(void *f, unsigned i, unsigned j,
180 cmptype_t *pis, cmptype_t *piss)
182 double_cmp_op_t op = (double_cmp_op_t) f;
184 op(dop_a[i], dop_a[j], pis, piss);
187 static bool test_template_unary(template_unary_t template, void *f)
189 bool correct = true;
191 for (unsigned int i = 0; i < OPERANDS; i++) {
192 cmptype_t ic;
193 cmptype_t isc;
195 template(f, i, &ic, &isc);
196 cmptype_t diff = ic - isc;
198 if (diff != 0) {
199 TPRINTF("i=%u ic=%" PRIdCMPTYPE " isc=%" PRIdCMPTYPE "\n",
200 i, ic, isc);
201 correct = false;
205 return correct;
208 static bool test_template_binary(template_binary_t template, void *f)
210 bool correct = true;
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;
217 template(f, i, j, &ic, &isc);
218 cmptype_t diff = ic - isc;
220 if (diff != 0) {
221 TPRINTF("i=%u, j=%u ic=%" PRIdCMPTYPE
222 " isc=%" PRIdCMPTYPE "\n", i, j, ic, isc);
223 correct = false;
228 return correct;
231 static void uint_to_double_operator(unsigned int a, double *pc, double *psc)
233 *pc = (double) a;
234 *psc = uint_to_double(a);
237 static void double_to_uint_operator(double a, unsigned int *pc,
238 unsigned int *psc)
240 *pc = (unsigned int) a;
241 *psc = double_to_uint(a);
244 static void double_to_int_operator(double a, unsigned int *pc,
245 unsigned int *psc)
247 *pc = (int) a;
248 *psc = double_to_int(a);
251 static void float_add_operator(float a, float b, float *pc, float *psc)
253 *pc = a + b;
254 *psc = add_float(a, b);
257 static void float_sub_operator(float a, float b, float *pc, float *psc)
259 *pc = a - b;
260 *psc = sub_float(a, b);
263 static void float_mul_operator(float a, float b, float *pc, float *psc)
265 *pc = a * b;
266 *psc = mul_float(a, b);
269 static void float_div_operator(float a, float b, float *pc, float *psc)
271 if ((cmptype_t) b == 0) {
272 *pc = 0.0;
273 *psc = 0.0;
274 return;
277 *pc = a / b;
278 *psc = div_float(a, b);
281 static void float_cmp_operator(float a, float b, cmptype_t *pis,
282 cmptype_t *piss)
284 *pis = fcmp(a, b);
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;
296 static void double_add_operator(double a, double b, double *pc, double *psc)
298 *pc = a + b;
299 *psc = add_double(a, b);
302 static void double_sub_operator(double a, double b, double *pc, double *psc)
304 *pc = a - b;
305 *psc = sub_double(a, b);
308 static void double_mul_operator(double a, double b, double *pc, double *psc)
310 *pc = a * b;
311 *psc = mul_double(a, b);
314 static void double_div_operator(double a, double b, double *pc, double *psc)
316 if ((cmptype_t) b == 0) {
317 *pc = 0.0;
318 *psc = 0.0;
319 return;
322 *pc = a / b;
323 *psc = div_double(a, b);
326 static void double_cmp_operator(double a, double b, cmptype_t *pis,
327 cmptype_t *piss)
329 *pis = dcmp(a, b);
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;
341 const char *test_softfloat1(void)
343 bool err = false;
345 if (!test_template_binary(float_template_binary, float_add_operator)) {
346 err = true;
347 TPRINTF("%s\n", "Float addition failed");
350 if (!test_template_binary(float_template_binary, float_sub_operator)) {
351 err = true;
352 TPRINTF("%s\n", "Float addition failed");
355 if (!test_template_binary(float_template_binary, float_mul_operator)) {
356 err = true;
357 TPRINTF("%s\n", "Float multiplication failed");
360 if (!test_template_binary(float_template_binary, float_div_operator)) {
361 err = true;
362 TPRINTF("%s\n", "Float division failed");
365 if (!test_template_binary(float_compare_template, float_cmp_operator)) {
366 err = true;
367 TPRINTF("%s\n", "Float comparison failed");
370 if (!test_template_binary(double_template_binary, double_add_operator)) {
371 err = true;
372 TPRINTF("%s\n", "Double addition failed");
375 if (!test_template_binary(double_template_binary, double_sub_operator)) {
376 err = true;
377 TPRINTF("%s\n", "Double addition failed");
380 if (!test_template_binary(double_template_binary, double_mul_operator)) {
381 err = true;
382 TPRINTF("%s\n", "Double multiplication failed");
385 if (!test_template_binary(double_template_binary, double_div_operator)) {
386 err = true;
387 TPRINTF("%s\n", "Double division failed");
390 if (!test_template_binary(double_compare_template, double_cmp_operator)) {
391 err = true;
392 TPRINTF("%s\n", "Double comparison failed");
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");
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");
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");
413 if (err)
414 return "Software floating point imprecision";
416 return NULL;