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

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

Make it clear that the test templates are for binary operators.

  • Property mode set to 100644
File size: 6.8 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 <bool.h>
38#include "../tester.h"
39
40#define OPERANDS 6
41#define PRECISION 10000
42
43#define PRIdCMPTYPE PRId32
44
45typedef int32_t cmptype_t;
46typedef void (* float_binary_op_t)(float, float, float *, float_t *);
47typedef void (* double_binary_op_t)(double, double, double *, double_t *);
48typedef void (* double_cmp_op_t)(double, double, cmptype_t *, cmptype_t *);
49typedef void (* template_binary_t)(void *, unsigned, unsigned, cmptype_t *,
50 cmptype_t *);
51
52static float fop_a[OPERANDS] =
53 {3.5, -2.1, 100.0, 50.0, -1024.0, 0.0};
54
55static float fop_b[OPERANDS] =
56 {-2.1, 100.0, 50.0, -1024.0, 3.5, 0.0};
57
58static double dop_a[OPERANDS] =
59 {3.5, -2.1, 100.0, 50.0, -1024.0, 0.0};
60
61static double dop_b[OPERANDS] =
62 {-2.1, 100.0, 50.0, -1024.0, 3.5, 0.0};
63
64static cmptype_t cmpabs(cmptype_t a)
65{
66 if (a >= 0)
67 return a;
68
69 return -a;
70}
71
72static int dcmp(double a, double b)
73{
74 if (a < b)
75 return -1;
76 else if (a > b)
77 return 1;
78
79 return 0;
80}
81
82static void
83float_template_binary(void *f, unsigned i, unsigned j, cmptype_t *pic,
84 cmptype_t *pisc)
85{
86 float c;
87 float_t sc;
88
89 float_binary_op_t op = (float_binary_op_t) f;
90
91 op(fop_a[i], fop_b[j], &c, &sc);
92
93 *pic = (cmptype_t) (c * PRECISION);
94 *pisc = (cmptype_t) (sc.val * PRECISION);
95}
96
97static void
98double_template_binary(void *f, unsigned i, unsigned j, cmptype_t *pic,
99 cmptype_t *pisc)
100{
101 double c;
102 double_t sc;
103
104 double_binary_op_t op = (double_binary_op_t) f;
105
106 op(dop_a[i], dop_b[j], &c, &sc);
107
108 *pic = (cmptype_t) (c * PRECISION);
109 *pisc = (cmptype_t) (sc.val * PRECISION);
110}
111
112static void
113double_compare_template(void *f, unsigned i, unsigned j, cmptype_t *pis,
114 cmptype_t *piss)
115{
116 double_cmp_op_t op = (double_cmp_op_t) f;
117
118 op(dop_a[i], dop_b[j], pis, piss);
119}
120
121static bool test_template_binary(template_binary_t template, void *f)
122{
123 bool correct = true;
124
125 for (unsigned int i = 0; i < OPERANDS; i++) {
126 for (unsigned int j = 0; j < OPERANDS; j++) {
127 cmptype_t ic;
128 cmptype_t isc;
129
130 template(f, i, j, &ic, &isc);
131 cmptype_t diff = cmpabs(ic - isc);
132
133 if (diff != 0) {
134 TPRINTF("i=%u, j=%u diff=%" PRIdCMPTYPE "\n",
135 i, j, diff);
136 correct = false;
137 }
138 }
139 }
140
141 return correct;
142}
143
144static void float_add_operator(float a, float b, float *pc, float_t *psc)
145{
146 *pc = a + b;
147
148 float_t sa;
149 float_t sb;
150
151 sa.val = a;
152 sb.val = b;
153 if (sa.data.parts.sign == sb.data.parts.sign)
154 psc->data = add_float(sa.data, sb.data);
155 else if (sa.data.parts.sign) {
156 sa.data.parts.sign = 0;
157 psc->data = sub_float(sb.data, sa.data);
158 } else {
159 sb.data.parts.sign = 0;
160 psc->data = sub_float(sa.data, sb.data);
161 }
162}
163
164static void float_mul_operator(float a, float b, float *pc, float_t *psc)
165{
166 *pc = a * b;
167
168 float_t sa;
169 float_t sb;
170
171 sa.val = a;
172 sb.val = b;
173 psc->data = mul_float(sa.data, sb.data);
174}
175
176static void float_div_operator(float a, float b, float *pc, float_t *psc)
177{
178 if ((cmptype_t) b == 0) {
179 *pc = 0.0;
180 psc->val = 0.0;
181 return;
182 }
183
184 *pc = a / b;
185
186 float_t sa;
187 float_t sb;
188
189 sa.val = a;
190 sb.val = b;
191 psc->data = div_float(sa.data, sb.data);
192}
193
194static void double_add_operator(double a, double b, double *pc, double_t *psc)
195{
196 *pc = a + b;
197
198 double_t sa;
199 double_t sb;
200
201 sa.val = a;
202 sb.val = b;
203 if (sa.data.parts.sign == sb.data.parts.sign)
204 psc->data = add_double(sa.data, sb.data);
205 else if (sa.data.parts.sign) {
206 sa.data.parts.sign = 0;
207 psc->data = sub_double(sb.data, sa.data);
208 } else {
209 sb.data.parts.sign = 0;
210 psc->data = sub_double(sa.data, sb.data);
211 }
212}
213
214static void double_mul_operator(double a, double b, double *pc, double_t *psc)
215{
216 *pc = a * b;
217
218 double_t sa;
219 double_t sb;
220
221 sa.val = a;
222 sb.val = b;
223 psc->data = mul_double(sa.data, sb.data);
224}
225
226static void double_div_operator(double a, double b, double *pc, double_t *psc)
227{
228 if ((cmptype_t) b == 0) {
229 *pc = 0.0;
230 psc->val = 0.0;
231 return;
232 }
233
234 *pc = a / b;
235
236 double_t sa;
237 double_t sb;
238
239 sa.val = a;
240 sb.val = b;
241 psc->data = div_double(sa.data, sb.data);
242}
243
244static void
245double_cmp_operator(double a, double b, cmptype_t *pis, cmptype_t *piss)
246{
247 *pis = dcmp(a, b);
248
249 double_t sa;
250 double_t sb;
251
252 sa.val = a;
253 sb.val = b;
254
255 if (is_double_lt(sa.data, sb.data))
256 *piss = -1;
257 else if (is_double_gt(sa.data, sb.data))
258 *piss = 1;
259 else if (is_double_eq(sa.data, sb.data))
260 *piss = 0;
261 else
262 *piss = 42;
263}
264
265const char *test_softfloat1(void)
266{
267 const char *err = NULL;
268
269 if (!test_template_binary(float_template_binary, float_add_operator)) {
270 err = "Float addition failed";
271 TPRINTF("%s\n", err);
272 }
273 if (!test_template_binary(float_template_binary, float_mul_operator)) {
274 err = "Float multiplication failed";
275 TPRINTF("%s\n", err);
276 }
277 if (!test_template_binary(float_template_binary, float_div_operator)) {
278 err = "Float division failed";
279 TPRINTF("%s\n", err);
280 }
281 if (!test_template_binary(double_template_binary, double_add_operator)) {
282 err = "Double addition failed";
283 TPRINTF("%s\n", err);
284 }
285 if (!test_template_binary(double_template_binary, double_mul_operator)) {
286 err = "Double multiplication failed";
287 TPRINTF("%s\n", err);
288 }
289 if (!test_template_binary(double_template_binary, double_div_operator)) {
290 err = "Double division failed";
291 TPRINTF("%s\n", err);
292 }
293 if (!test_template_binary(double_compare_template, double_cmp_operator)) {
294 err = "Double comparison failed";
295 TPRINTF("%s\n", err);
296 }
297
298 return err;
299}
300
Note: See TracBrowser for help on using the repository browser.