move the debug folder to the top level
[AROS.git] / test / misc / mathtest.c
blobe27a8bdf9956bad10d5fc1403cd727061657b91d
1 /*
2 Copyright © 1995-2014, The AROS Development Team. All rights reserved.
3 $Id$
4 */
6 #include <string.h>
8 #include <aros/asmcall.h>
10 #include <proto/alib.h>
12 #include <proto/exec.h>
13 #include <proto/aros.h>
14 #include <proto/dos.h>
16 double X_Mul(double x, double y)
18 if (x==x) return x*y;
19 return x*y;
22 /* to avoid casts these two lines are absolutely necessary!! */
23 #define float LONG
25 #include <proto/mathffp.h>
26 #include <proto/mathtrans.h>
27 #include <proto/mathieeesingbas.h>
28 #include <proto/mathieeesingtrans.h>
29 #include <proto/mathieeedoubbas.h>
30 #include <proto/mathieeedoubtrans.h>
32 #include <exec/types.h>
34 struct Library * MathBase;
35 struct Library * MathTransBase;
36 struct Library * MathIeeeSingBasBase;
37 struct Library * MathIeeeSingTransBase;
38 struct Library * MathIeeeDoubBasBase;
39 struct Library * MathIeeeDoubTransBase;
41 #ifdef __mc68000
42 /* For compatability with AOS, our test reference,
43 * use this SPrintf()
45 static AROS_UFH2(VOID, _SPutC,
46 AROS_UFHA(BYTE, c, D0),
47 AROS_UFHA(BYTE **, ptr, A3))
49 AROS_USERFUNC_INIT
51 if (c != 0)
52 Write(Output(),&c,1);
54 AROS_USERFUNC_EXIT
57 #undef Printf
58 VOID Printf( const char *format, ...)
60 RawDoFmt( format, (APTR)&(((ULONG *)&format)[1]), _SPutC, NULL);
62 #endif
64 int main(int argc, char **argv)
66 LONG tested = 0, passed = 0;
67 float FFPOne, FFPTwo, FFPOnehalf, FFPMinusOne, FFPNull;
68 float SPOne, SPTwo, SPOnehalf;
69 float float_res;
70 LONG * float_resptr = (LONG *)&float_res;
71 LONG * ptr;
72 LONG wanted;
73 double double_res, double_res2;
74 double * Darg1;
75 QUAD * double_resptr = (QUAD *)&double_res;
76 QUAD * double_resptr2 = (QUAD *)&double_res2;
77 QUAD QArg1;
79 Printf("---- Testing Started ----\n");
81 Darg1 = (double *)&QArg1;
83 #define DEF_FFPOne 0x80000041UL
84 #define DEF_FFPTwo 0x80000042UL
85 #define DEF_FFPMinusOne 0x800000C1UL
86 #define DEF_FFPOnehalf 0x80000040UL
87 #define DEF_FFPNull 0x00000000UL
89 #define DEF_SPOne 0x3f800000UL
90 #define DEF_SPTwo 0x40000000UL
91 #define DEF_SPOnehalf 0x3f000000UL
93 #define DEF_DPOne 0x3ff0000000000000ULL
94 #define DEF_DPMinusOne 0xbff0000000000000ULL
95 #define DEF_DPTwo 0x4000000000000000ULL
96 #define DEF_DPThree 0x4008000000000000ULL
97 #define DEF_DPFour 0x4010000000000000ULL
98 #define DEF_DPTwenty 0x4034000000000000ULL
100 ptr = (LONG *)&FFPOne; *ptr = DEF_FFPOne;
101 ptr = (LONG *)&FFPTwo; *ptr = DEF_FFPTwo;
102 ptr = (LONG *)&FFPMinusOne; *ptr = DEF_FFPMinusOne;
103 ptr = (LONG *)&FFPOnehalf; *ptr = DEF_FFPOnehalf;
104 ptr = (LONG *)&FFPNull; *ptr = DEF_FFPNull;
106 ptr = (LONG *)&SPOne; *ptr = DEF_SPOne;
107 ptr = (LONG *)&SPOnehalf; *ptr = DEF_SPOnehalf;
108 ptr = (LONG *)&SPTwo; *ptr = DEF_SPTwo;
110 /* if you deactivate #define float LONG something very funny happens here:
111 Printf("two: %x <-> %x \n",*ptr,SPTwo);
112 Printf("two: %x <-> %x \n",SPTwo,*ptr);
115 #define CHECK(func, args, cres) \
116 float_res = func args; \
117 tested++; \
118 if (*float_resptr != cres) \
119 Printf ("FAIL: " #func " " #args " in line %ld " \
120 "(got=0x%08lx expected=0x%08lx)\n", \
121 __LINE__, (unsigned long)*float_resptr, (unsigned long)cres); \
122 else \
124 passed++; \
125 Printf ("OK : " #func " " #args "\n"); \
129 When using doubles or QUADs it is important to pay attention to the
130 Endianess of the processor, otherwise you'll never see what you want to see.
133 #define CHECK_DOUBLE1A(func, arg1, cres) \
134 double_res = func (arg1); \
135 tested++; \
136 if (*double_resptr != cres) \
138 if (0 != AROS_BIG_ENDIAN) \
140 Printf ("FAIL: " #func " " #arg1 " in line %ld " \
141 "(got=0x%08lx%08lx expected=0x%08lx%08lx)\n", \
142 __LINE__, \
143 (unsigned long)(((QUAD)*double_resptr) >> 32), \
144 (unsigned long)*(((LONG *)double_resptr) + 1), \
145 (unsigned long)(((QUAD)cres)>>32), (unsigned long)cres); \
147 else \
149 Printf ("(little endian) FAIL: " #func " " #arg1 " in line %ld " \
150 "(got=0x%08lx%08lx expected=0x%08lx%08lx)\n", \
151 __LINE__, \
152 (unsigned long)*(((LONG *)double_resptr) + 1), \
153 (unsigned long)*(((LONG *)double_resptr)), \
154 (unsigned long)(((QUAD)cres) >> 32), (unsigned long)cres); \
157 else \
159 passed++; \
160 Printf ("OK : " #func " " #arg1 "\n"); \
163 #define CHECK_DOUBLE1AF(func, cres) \
164 tested++; \
165 if (*double_resptr != cres) \
167 if (0 != AROS_BIG_ENDIAN) \
169 Printf ("FAIL: " #func " in line %ld " \
170 "(got=0x%08lx%08lx expected=0x%08lx%08lx)\n", \
171 __LINE__, \
172 (unsigned long)(((QUAD)*double_resptr) >> 32), \
173 (unsigned long)*(((LONG *)double_resptr) + 1), \
174 (unsigned long)(((QUAD)cres) >> 32), (unsigned long)cres); \
176 else \
178 Printf ("(little endian) FAIL: " #func " in line %ld " \
179 "(got=0x%08lx%08lx expected=0x%08lx%08lx)\n", \
180 __LINE__, \
181 (unsigned long)*(((LONG *)double_resptr) + 1), \
182 (unsigned long)*(((LONG *)double_resptr)), \
183 (unsigned long)(((QUAD)cres) >> 32), \
184 (unsigned long)cres); \
187 else { \
188 passed++; \
189 Printf ("OK : " #func "\n"); \
192 #define CHECK_DOUBLE1B(func, arg1, cres) \
193 QArg1 = arg1; \
194 double_res = func (*Darg1); \
195 tested++; \
196 if (*double_resptr != cres) \
198 if (0 != AROS_BIG_ENDIAN) \
200 Printf ("FAIL: " #func " " #arg1 " in line %ld " \
201 "(got=0x%08lx%08lx expected=0x%08lx%08lx)\n", \
202 __LINE__, \
203 (unsigned long)(((QUAD)*double_resptr) >> 32), \
204 (unsigned long)*(((LONG *)double_resptr) + 1), \
205 (unsigned long)(((QUAD)cres) >> 32), (unsigned long)cres); \
207 else \
209 Printf ("(little endian) FAIL: " #func " " #arg1 " in line %ld " \
210 "(got=0x%08lx%08lx expected=0x%08lx%08lx)\n", \
211 __LINE__, \
212 (unsigned long)*(((LONG *)double_resptr) + 1), \
213 (unsigned long)*(((LONG *)double_resptr)), \
214 (unsigned long)(((QUAD)cres) >> 32), (unsigned long)cres); \
217 else { \
218 passed++; \
219 Printf ("OK : " #func " " #arg1 "\n"); \
222 #define CHECK_DOUBLE2A(func, arg1, arg2, cres) \
223 double_res = func (arg1, arg2);\
224 double_res2 = cres; \
225 tested++; \
226 if (double_res != double_res2) \
228 if (0 != AROS_BIG_ENDIAN) \
230 Printf ("FAIL: " #func " (" #arg1 "," #arg2 ") in line %ld " \
231 "(got=0x%08lx%08lx expected=0x%08lx%08lx)\n", \
232 __LINE__, \
233 (unsigned long)(((QUAD)*double_resptr ) >> 32), \
234 (unsigned long)*(((LONG *)double_resptr ) + 1), \
235 (unsigned long)(((QUAD)*double_resptr2) >> 32), \
236 (unsigned long)*(((LONG *)double_resptr2) + 1) ); \
238 else \
240 Printf ("(little endian) FAIL: " #func " (" #arg1 "," #arg2 ") " \
241 "in line %ld (got=0x%08lx%08lx expected=0x%08lx%08lx)\n", \
242 __LINE__, \
243 (unsigned long)*(((LONG *)double_resptr ) + 1), \
244 (unsigned long)*(((LONG *)double_resptr)), \
245 (unsigned long)*(((LONG *)double_resptr2) + 1), \
246 (unsigned long)*(((LONG *)double_resptr2))); \
249 else { \
250 passed++; \
251 Printf ("OK : " #func " ( " #arg1 "," #arg2 " ) \n"); \
255 if (!(MathBase = OpenLibrary("mathffp.library", 0L)))
257 Printf ("Couldn't open mathffp.library\n");
258 return RETURN_FAIL;
261 Printf("\nValidating 'mathffp' functionality...\n");
263 /* this should set the zero-bit*/
264 wanted = DEF_FFPNull; CHECK(SPAbs,(0),wanted);
266 wanted = DEF_FFPNull; CHECK(SPFlt,(0),wanted);
267 wanted = DEF_FFPOne; CHECK(SPFlt,(1),wanted);
268 wanted = DEF_FFPTwo; CHECK(SPFlt,(2),wanted);
269 wanted = DEF_FFPMinusOne; CHECK(SPFlt,(-1),wanted);
270 wanted = DEF_FFPTwo; CHECK(SPAdd,(FFPOne, FFPOne),wanted);
271 wanted = DEF_FFPOnehalf; CHECK(SPDiv,(FFPTwo, FFPOne),wanted);
272 wanted = DEF_FFPTwo; CHECK(SPMul,(FFPOne, FFPTwo),wanted);
274 CHECK(SPMul, (SPFlt(-1000), SPFlt(-10)), 0x9c40004e);
275 CHECK(SPDiv, (SPFlt(-10), SPFlt(-1000)), 0xc8000047);
276 CHECK(SPDiv, (SPFlt(0), SPFlt(1000)), 0);
278 /* Should also check condition codes but impossible without assembly */
279 CHECK(SPCmp, (SPFlt(10),SPFlt(15)), -1);
280 CHECK(SPCmp, (SPFlt(10),SPFlt(-15)), 1);
281 CHECK(SPCmp, (SPFlt(-10),SPFlt(-15)), 1);
282 CHECK(SPCmp, (SPFlt(-15),SPFlt(-10)), -1);
283 CHECK(SPCmp, (SPFlt(10),SPFlt(10)), 0);
284 CHECK(SPCmp, (SPFlt(-100), SPFlt(-7)), -1);
285 CHECK(SPCmp, (SPFlt(100), SPFlt(7)), 1);
286 CHECK(SPTst, (SPFlt(-1)), -1);
287 CHECK(SPTst, (SPFlt(0)), 0);
288 CHECK(SPTst, (SPFlt(1)), 1);
290 CloseLibrary(MathBase);
292 if (!(MathTransBase = OpenLibrary("mathtrans.library", 0L)))
294 Printf ("Couldn't open mathtrans.library\n");
295 return RETURN_FAIL;
298 Printf("\nValidating 'mathtrans' functionality...\n");
300 CHECK (SPLog, (FFPTwo), 0xb1721840UL);
301 CHECK (SPLog10, (FFPTwo), 0x9a209b3fUL);
302 CHECK (SPSin, (FFPOne), 0xd76aa440UL);
303 CHECK (SPCos, (FFPOne), 0x8a514040UL);
304 CHECK (SPTan, (FFPOne), 0xc7592341UL);
305 CHECK (SPSinh, (FFPOne), 0x966cfe41UL);
306 CHECK (SPCosh, (FFPOne), 0xc583aa41UL);
307 CHECK (SPTanh, (FFPOne), 0xc2f7d640UL);
308 CHECK (SPExp, (FFPTwo), 0xec732543UL);
309 CHECK (SPAsin, (FFPOnehalf), 0x860a9240UL);
310 CHECK (SPAcos, (FFPOnehalf), 0x860a9241UL);
312 CloseLibrary(MathTransBase);
314 if (!(MathIeeeSingBasBase = OpenLibrary("mathieeesingbas.library", 0L)))
316 Printf ("Couldn't open mathieeesingbas.library\n");
317 return RETURN_FAIL;
320 Printf("\nValidating 'mathieeesingbas' functionality...\n");
321 #if (1)
322 Printf(" TODO!\n");
323 #else
324 #endif
326 if (!(MathIeeeSingTransBase = OpenLibrary("mathieeesingtrans.library", 0L)))
328 Printf ("Couldn't open mathieeesingtrans.library\n");
329 return RETURN_FAIL;
332 Printf("\nValidating 'mathieeesingtrans' functionality...\n");
334 CHECK (IEEESPLog, (SPTwo), 0x3f317218UL);
335 CHECK (IEEESPLog10, (SPTwo), 0x3e9a209aUL);
336 CHECK (IEEESPSin, (SPOne), 0x3f576aa4UL);
337 CHECK (IEEESPCos, (SPOne), 0x3f0a5140UL);
338 CHECK (IEEESPTan, (SPOne), 0x3fc75923UL);
339 CHECK (IEEESPSinh, (SPTwo), 0x40681e7bUL);
340 CHECK (IEEESPCosh, (SPTwo), 0x4070c7d1UL);
341 CHECK (IEEESPTanh, (SPOne), 0x3f42f7d6UL);
342 CHECK (IEEESPExp, (SPTwo), 0x40ec7325UL);
343 CHECK (IEEESPAsin, (SPOnehalf), 0x3f060a92UL);
344 CHECK (IEEESPAcos, (SPOnehalf), 0x3f860a92UL);
346 CloseLibrary(MathIeeeSingTransBase);
348 if (!(MathIeeeDoubBasBase = OpenLibrary("mathieeedoubbas.library", 0L)))
350 Printf ("Couldn't open mathieeedoubbas.library\n");
351 return RETURN_FAIL;
354 Printf("\nValidating 'mathieeedoubbas' functionality...\n");
356 CHECK_DOUBLE1A(IEEEDPFlt, ((LONG)1), DEF_DPOne);
357 CHECK_DOUBLE1A(IEEEDPFlt, ((LONG)2), DEF_DPTwo);
358 CHECK_DOUBLE1A(IEEEDPFlt, ((LONG)3), DEF_DPThree);
359 CHECK_DOUBLE1A(IEEEDPFlt, ((LONG)20), DEF_DPTwenty);
360 CHECK_DOUBLE1B(IEEEDPAbs, ((QUAD)DEF_DPMinusOne), (QUAD)DEF_DPOne);
361 CHECK_DOUBLE1B(IEEEDPNeg, ((QUAD)DEF_DPMinusOne), (QUAD)DEF_DPOne);
362 CHECK_DOUBLE2A(IEEEDPAdd, IEEEDPFlt(1), IEEEDPFlt(1), IEEEDPFlt(2));
363 CHECK_DOUBLE2A(IEEEDPAdd, IEEEDPFlt(123456), IEEEDPFlt(654321), IEEEDPFlt(777777));
364 CHECK_DOUBLE2A(IEEEDPSub, IEEEDPFlt(123456), IEEEDPFlt(654321), IEEEDPFlt(-530865));
365 CHECK_DOUBLE2A(IEEEDPMul, IEEEDPFlt(321), IEEEDPFlt(123456), IEEEDPFlt(39629376));
366 CHECK_DOUBLE2A(IEEEDPMul, IEEEDPFlt(2), IEEEDPFlt(2), IEEEDPFlt(4));
367 CHECK_DOUBLE2A(IEEEDPMul, IEEEDPFlt(20), IEEEDPFlt(20), IEEEDPFlt(400));
368 CHECK_DOUBLE2A(IEEEDPDiv, IEEEDPFlt(39629376),IEEEDPFlt(123456),IEEEDPFlt(321));
369 CHECK_DOUBLE2A(IEEEDPDiv, IEEEDPFlt(4), IEEEDPFlt(2), IEEEDPFlt(2));
370 CHECK_DOUBLE2A(IEEEDPDiv, IEEEDPFlt(400), IEEEDPFlt(20), IEEEDPFlt(20));
372 if (!(MathIeeeDoubTransBase = OpenLibrary("mathieeedoubtrans.library", 0L)))
374 Printf ("Couldn't open mathieeedoubtrans.library\n");
375 return RETURN_FAIL;
378 Printf("\nValidating 'mathieeedoubtrans' functionality...\n");
380 CHECK_DOUBLE1A(IEEEDPSqrt, ((double)IEEEDPFlt(4)), DEF_DPTwo);
381 CHECK_DOUBLE1A(IEEEDPSqrt, ((double)IEEEDPFlt(9)), DEF_DPThree);
382 CHECK_DOUBLE1A(IEEEDPCos, ((double)IEEEDPFlt(1)), 0x3fe14a280fb5068bULL);
383 CHECK_DOUBLE1A(IEEEDPSin, ((double)IEEEDPFlt(1)), 0x3feaed548f090ceeULL);
385 double_res = IEEEDPSincos(&double_res2, (double)IEEEDPFlt(1));
386 CHECK_DOUBLE1AF(IEEEDPSincos, 0x3feaed548f090ceeULL);
387 double_res = double_res2;
388 CHECK_DOUBLE1AF(IEEEDPSincos, 0x3fe14a280fb5068bULL);
390 wanted = IEEEDPTieee(IEEEDPFlt(2));
391 Printf("IEEEDPTieee(2) = %08lx\n", (LONG)wanted);
393 double_res = IEEEDPFieee(SPFlt(2));
394 CHECK_DOUBLE1AF(IEEEDPFieee, DEF_DPTwo);
396 CloseLibrary(MathIeeeDoubTransBase);
397 CloseLibrary(MathIeeeDoubBasBase);
399 Printf("---- Testing Completed ----\n");
401 Printf("Passed %ld of %ld tests\n", passed, tested);
402 return (tested == passed) ? RETURN_OK : RETURN_FAIL;