2 Copyright © 1995-2014, The AROS Development Team. All rights reserved.
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
)
22 /* to avoid casts these two lines are absolutely necessary!! */
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
;
42 /* For compatability with AOS, our test reference,
45 static AROS_UFH2(VOID
, _SPutC
,
46 AROS_UFHA(BYTE
, c
, D0
),
47 AROS_UFHA(BYTE
**, ptr
, A3
))
58 VOID
Printf( const char *format
, ...)
60 RawDoFmt( format
, (APTR
)&(((ULONG
*)&format
)[1]), _SPutC
, NULL
);
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
;
70 LONG
* float_resptr
= (LONG
*)&float_res
;
73 double double_res
, double_res2
;
75 QUAD
* double_resptr
= (QUAD
*)&double_res
;
76 QUAD
* double_resptr2
= (QUAD
*)&double_res2
;
79 Darg1
= (double *)&QArg1
;
81 #define DEF_FFPOne 0x80000041UL
82 #define DEF_FFPTwo 0x80000042UL
83 #define DEF_FFPMinusOne 0x800000C1UL
84 #define DEF_FFPOnehalf 0x80000040UL
85 #define DEF_FFPNull 0x00000000UL
87 #define DEF_SPOne 0x3f800000UL
88 #define DEF_SPTwo 0x40000000UL
89 #define DEF_SPOnehalf 0x3f000000UL
91 #define DEF_DPOne 0x3ff0000000000000ULL
92 #define DEF_DPMinusOne 0xbff0000000000000ULL
93 #define DEF_DPTwo 0x4000000000000000ULL
94 #define DEF_DPThree 0x4008000000000000ULL
95 #define DEF_DPFour 0x4010000000000000ULL
96 #define DEF_DPTwenty 0x4034000000000000ULL
98 ptr
= (LONG
*)&FFPOne
; *ptr
= DEF_FFPOne
;
99 ptr
= (LONG
*)&FFPTwo
; *ptr
= DEF_FFPTwo
;
100 ptr
= (LONG
*)&FFPMinusOne
; *ptr
= DEF_FFPMinusOne
;
101 ptr
= (LONG
*)&FFPOnehalf
; *ptr
= DEF_FFPOnehalf
;
102 ptr
= (LONG
*)&FFPNull
; *ptr
= DEF_FFPNull
;
104 ptr
= (LONG
*)&SPOne
; *ptr
= DEF_SPOne
;
105 ptr
= (LONG
*)&SPOnehalf
; *ptr
= DEF_SPOnehalf
;
106 ptr
= (LONG
*)&SPTwo
; *ptr
= DEF_SPTwo
;
108 /* if you deactivate #define float LONG something very funny happens here:
109 Printf("two: %x <-> %x \n",*ptr,SPTwo);
110 Printf("two: %x <-> %x \n",SPTwo,*ptr);
113 #define CHECK(func, args, cres) \
114 float_res = func args; \
116 if (*float_resptr != cres) \
117 Printf ("FAIL: " #func " " #args " in line %ld " \
118 "(got=0x%08lx expected=0x%08lx)\n", \
119 __LINE__, (unsigned long)*float_resptr, (unsigned long)cres); \
123 Printf ("OK : " #func " " #args "\n"); \
127 When using doubles or QUADs it is important to pay attention to the
128 Endianess of the processor, otherwise you'll never see what you want to see.
131 #define CHECK_DOUBLE1A(func, arg1, cres) \
132 double_res = func (arg1); \
134 if (*double_resptr != cres) \
136 if (0 != AROS_BIG_ENDIAN) \
138 Printf ("FAIL: " #func " " #arg1 " in line %ld " \
139 "(got=0x%08lx%08lx expected=0x%08lx%08lx)\n", \
141 (unsigned long)(((QUAD)*double_resptr) >> 32), \
142 (unsigned long)*(((LONG *)double_resptr) + 1), \
143 (unsigned long)(((QUAD)cres)>>32), (unsigned long)cres); \
147 Printf ("(little endian) FAIL: " #func " " #arg1 " in line %ld " \
148 "(got=0x%08lx%08lx expected=0x%08lx%08lx)\n", \
150 (unsigned long)*(((LONG *)double_resptr) + 1), \
151 (unsigned long)*(((LONG *)double_resptr)), \
152 (unsigned long)(((QUAD)cres) >> 32), (unsigned long)cres); \
158 Printf ("OK : " #func " " #arg1 "\n"); \
161 #define CHECK_DOUBLE1AF(func, cres) \
163 if (*double_resptr != cres) \
165 if (0 != AROS_BIG_ENDIAN) \
167 Printf ("FAIL: " #func " in line %ld " \
168 "(got=0x%08lx%08lx expected=0x%08lx%08lx)\n", \
170 (unsigned long)(((QUAD)*double_resptr) >> 32), \
171 (unsigned long)*(((LONG *)double_resptr) + 1), \
172 (unsigned long)(((QUAD)cres) >> 32), (unsigned long)cres); \
176 Printf ("(little endian) FAIL: " #func " in line %ld " \
177 "(got=0x%08lx%08lx expected=0x%08lx%08lx)\n", \
179 (unsigned long)*(((LONG *)double_resptr) + 1), \
180 (unsigned long)*(((LONG *)double_resptr)), \
181 (unsigned long)(((QUAD)cres) >> 32), \
182 (unsigned long)cres); \
187 Printf ("OK : " #func "\n"); \
190 #define CHECK_DOUBLE1B(func, arg1, cres) \
192 double_res = func (*Darg1); \
194 if (*double_resptr != cres) \
196 if (0 != AROS_BIG_ENDIAN) \
198 Printf ("FAIL: " #func " " #arg1 " in line %ld " \
199 "(got=0x%08lx%08lx expected=0x%08lx%08lx)\n", \
201 (unsigned long)(((QUAD)*double_resptr) >> 32), \
202 (unsigned long)*(((LONG *)double_resptr) + 1), \
203 (unsigned long)(((QUAD)cres) >> 32), (unsigned long)cres); \
207 Printf ("(little endian) FAIL: " #func " " #arg1 " in line %ld " \
208 "(got=0x%08lx%08lx expected=0x%08lx%08lx)\n", \
210 (unsigned long)*(((LONG *)double_resptr) + 1), \
211 (unsigned long)*(((LONG *)double_resptr)), \
212 (unsigned long)(((QUAD)cres) >> 32), (unsigned long)cres); \
217 Printf ("OK : " #func " " #arg1 "\n"); \
220 #define CHECK_DOUBLE2A(func, arg1, arg2, cres) \
221 double_res = func (arg1, arg2);\
222 double_res2 = cres; \
224 if (double_res != double_res2) \
226 if (0 != AROS_BIG_ENDIAN) \
228 Printf ("FAIL: " #func " (" #arg1 "," #arg2 ") in line %ld " \
229 "(got=0x%08lx%08lx expected=0x%08lx%08lx)\n", \
231 (unsigned long)(((QUAD)*double_resptr ) >> 32), \
232 (unsigned long)*(((LONG *)double_resptr ) + 1), \
233 (unsigned long)(((QUAD)*double_resptr2) >> 32), \
234 (unsigned long)*(((LONG *)double_resptr2) + 1) ); \
238 Printf ("(little endian) FAIL: " #func " (" #arg1 "," #arg2 ") " \
239 "in line %ld (got=0x%08lx%08lx expected=0x%08lx%08lx)\n", \
241 (unsigned long)*(((LONG *)double_resptr ) + 1), \
242 (unsigned long)*(((LONG *)double_resptr)), \
243 (unsigned long)*(((LONG *)double_resptr2) + 1), \
244 (unsigned long)*(((LONG *)double_resptr2))); \
249 Printf ("OK : " #func " ( " #arg1 "," #arg2 " ) \n"); \
253 if (!(MathBase
= OpenLibrary("mathffp.library", 0L)))
255 Printf ("Couldn't open mathffp.library\n");
259 Printf("Very basic mathffp functionality test...\n");
261 /* this should set the zero-bit*/
262 wanted
= DEF_FFPNull
; CHECK(SPAbs
,(0),wanted
);
264 wanted
= DEF_FFPNull
; CHECK(SPFlt
,(0),wanted
);
265 wanted
= DEF_FFPOne
; CHECK(SPFlt
,(1),wanted
);
266 wanted
= DEF_FFPTwo
; CHECK(SPFlt
,(2),wanted
);
267 wanted
= DEF_FFPMinusOne
; CHECK(SPFlt
,(-1),wanted
);
268 wanted
= DEF_FFPTwo
; CHECK(SPAdd
,(FFPOne
, FFPOne
),wanted
);
269 wanted
= DEF_FFPOnehalf
; CHECK(SPDiv
,(FFPTwo
, FFPOne
),wanted
);
270 wanted
= DEF_FFPTwo
; CHECK(SPMul
,(FFPOne
, FFPTwo
),wanted
);
272 CHECK(SPMul
, (SPFlt(-1000), SPFlt(-10)), 0x9c40004e);
273 CHECK(SPDiv
, (SPFlt(-10), SPFlt(-1000)), 0xc8000047);
274 CHECK(SPDiv
, (SPFlt(0), SPFlt(1000)), 0);
276 /* Should also check condition codes but impossible without assembly */
277 CHECK(SPCmp
, (SPFlt(10),SPFlt(15)), -1);
278 CHECK(SPCmp
, (SPFlt(10),SPFlt(-15)), 1);
279 CHECK(SPCmp
, (SPFlt(-10),SPFlt(-15)), 1);
280 CHECK(SPCmp
, (SPFlt(-15),SPFlt(-10)), -1);
281 CHECK(SPCmp
, (SPFlt(10),SPFlt(10)), 0);
282 CHECK(SPCmp
, (SPFlt(-100), SPFlt(-7)), -1);
283 CHECK(SPCmp
, (SPFlt(100), SPFlt(7)), 1);
284 CHECK(SPTst
, (SPFlt(-1)), -1);
285 CHECK(SPTst
, (SPFlt(0)), 0);
286 CHECK(SPTst
, (SPFlt(1)), 1);
288 CloseLibrary(MathBase
);
290 if (!(MathTransBase
= OpenLibrary("mathtrans.library", 0L)))
292 Printf ("Couldn't open mathtrans.library\n");
296 Printf("Very basic mathtrans functionality test...\n");
298 CHECK (SPLog
, (FFPTwo
), 0xb1721840UL
);
299 CHECK (SPLog10
, (FFPTwo
), 0x9a209b3fUL
);
300 CHECK (SPSin
, (FFPOne
), 0xd76aa440UL
);
301 CHECK (SPCos
, (FFPOne
), 0x8a514040UL
);
302 CHECK (SPTan
, (FFPOne
), 0xc7592341UL
);
303 CHECK (SPSinh
, (FFPOne
), 0x966cfe41UL
);
304 CHECK (SPCosh
, (FFPOne
), 0xc583aa41UL
);
305 CHECK (SPTanh
, (FFPOne
), 0xc2f7d640UL
);
306 CHECK (SPExp
, (FFPTwo
), 0xec732543UL
);
307 CHECK (SPAsin
, (FFPOnehalf
), 0x860a9240UL
);
308 CHECK (SPAcos
, (FFPOnehalf
), 0x860a9241UL
);
310 CloseLibrary(MathTransBase
);
312 if (!(MathIeeeSingBasBase
= OpenLibrary("mathieeesingbas.library", 0L)))
314 Printf ("Couldn't open mathieeesingbas.library\n");
319 if (!(MathIeeeSingTransBase
= OpenLibrary("mathieeesingtrans.library", 0L)))
321 Printf ("Couldn't open mathieeesingtrans.library\n");
325 Printf("Very basic mathieeesingtrans functionality test...\n");
328 CHECK (IEEESPLog
, (SPTwo
), 0x3f317218UL
);
329 CHECK (IEEESPLog10
, (SPTwo
), 0x3e9a209aUL
);
330 CHECK (IEEESPSin
, (SPOne
), 0x3f576aa4UL
);
331 CHECK (IEEESPCos
, (SPOne
), 0x3f0a5140UL
);
332 CHECK (IEEESPTan
, (SPOne
), 0x3fc75923UL
);
333 CHECK (IEEESPSinh
, (SPTwo
), 0x40681e7bUL
);
334 CHECK (IEEESPCosh
, (SPTwo
), 0x4070c7d1UL
);
335 CHECK (IEEESPTanh
, (SPOne
), 0x3f42f7d6UL
);
336 CHECK (IEEESPExp
, (SPTwo
), 0x40ec7325UL
);
337 CHECK (IEEESPAsin
, (SPOnehalf
), 0x3f060a92UL
);
338 CHECK (IEEESPAcos
, (SPOnehalf
), 0x3f860a92UL
);
340 CloseLibrary(MathIeeeSingTransBase
);
342 if (!(MathIeeeDoubBasBase
= OpenLibrary("mathieeedoubbas.library", 0L)))
344 Printf ("Couldn't open mathieeedoubbas.library\n");
350 CHECK_DOUBLE1A(IEEEDPFlt
, ((LONG
)1), DEF_DPOne
);
351 CHECK_DOUBLE1A(IEEEDPFlt
, ((LONG
)2), DEF_DPTwo
);
352 CHECK_DOUBLE1A(IEEEDPFlt
, ((LONG
)3), DEF_DPThree
);
353 CHECK_DOUBLE1A(IEEEDPFlt
, ((LONG
)20), DEF_DPTwenty
);
354 CHECK_DOUBLE1B(IEEEDPAbs
, ((QUAD
)DEF_DPMinusOne
), (QUAD
)DEF_DPOne
);
355 CHECK_DOUBLE1B(IEEEDPNeg
, ((QUAD
)DEF_DPMinusOne
), (QUAD
)DEF_DPOne
);
356 CHECK_DOUBLE2A(IEEEDPAdd
, IEEEDPFlt(1), IEEEDPFlt(1), IEEEDPFlt(2));
357 CHECK_DOUBLE2A(IEEEDPAdd
, IEEEDPFlt(123456), IEEEDPFlt(654321), IEEEDPFlt(777777));
358 CHECK_DOUBLE2A(IEEEDPSub
, IEEEDPFlt(123456), IEEEDPFlt(654321), IEEEDPFlt(-530865));
359 CHECK_DOUBLE2A(IEEEDPMul
, IEEEDPFlt(321), IEEEDPFlt(123456), IEEEDPFlt(39629376));
360 CHECK_DOUBLE2A(IEEEDPMul
, IEEEDPFlt(2), IEEEDPFlt(2), IEEEDPFlt(4));
361 CHECK_DOUBLE2A(IEEEDPMul
, IEEEDPFlt(20), IEEEDPFlt(20), IEEEDPFlt(400));
362 CHECK_DOUBLE2A(IEEEDPDiv
, IEEEDPFlt(39629376),IEEEDPFlt(123456),IEEEDPFlt(321));
363 CHECK_DOUBLE2A(IEEEDPDiv
, IEEEDPFlt(4), IEEEDPFlt(2), IEEEDPFlt(2));
364 CHECK_DOUBLE2A(IEEEDPDiv
, IEEEDPFlt(400), IEEEDPFlt(20), IEEEDPFlt(20));
366 if (!(MathIeeeDoubTransBase
= OpenLibrary("mathieeedoubtrans.library", 0L)))
368 Printf ("Couldn't open mathieeedoubtrans.library\n");
372 CHECK_DOUBLE1A(IEEEDPSqrt
, ((double)IEEEDPFlt(4)), DEF_DPTwo
);
373 CHECK_DOUBLE1A(IEEEDPSqrt
, ((double)IEEEDPFlt(9)), DEF_DPThree
);
374 CHECK_DOUBLE1A(IEEEDPCos
, ((double)IEEEDPFlt(1)), 0x3fe14a280fb5068bULL
);
375 CHECK_DOUBLE1A(IEEEDPSin
, ((double)IEEEDPFlt(1)), 0x3feaed548f090ceeULL
);
377 double_res
= IEEEDPSincos(&double_res2
, (double)IEEEDPFlt(1));
378 CHECK_DOUBLE1AF(IEEEDPSincos
, 0x3feaed548f090ceeULL
);
379 double_res
= double_res2
;
380 CHECK_DOUBLE1AF(IEEEDPSincos
, 0x3fe14a280fb5068bULL
);
382 wanted
= IEEEDPTieee(IEEEDPFlt(2));
383 Printf("IEEEDPTieee(2) = %08lx\n", (LONG
)wanted
);
385 double_res
= IEEEDPFieee(SPFlt(2));
386 CHECK_DOUBLE1AF(IEEEDPFieee
, DEF_DPTwo
);
388 CloseLibrary(MathIeeeDoubTransBase
);
389 CloseLibrary(MathIeeeDoubBasBase
);
391 Printf("Passed %ld of %ld tests\n", passed
, tested
);
392 return (tested
== passed
) ? RETURN_OK
: RETURN_FAIL
;