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

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

Remove unistd.h

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