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

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since a35b458 was a35b458, checked in by Jiří Zárevúcky <zarevucky.jiri@…>, 7 years ago

style: Remove trailing whitespace on _all_ lines, including empty ones, for particular file types.

Command used: tools/srepl '\s\+$' '' -- *.c *.h *.py *.sh *.s *.S *.ag

Currently, whitespace on empty lines is very inconsistent.
There are two basic choices: Either remove the whitespace, or keep empty lines
indented to the level of surrounding code. The former is AFAICT more common,
and also much easier to do automatically.

Alternatively, we could write script for automatic indentation, and use that
instead. However, if such a script exists, it's possible to use the indented
style locally, by having the editor apply relevant conversions on load/save,
without affecting remote repository. IMO, it makes more sense to adopt
the simpler rule.

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