6 typedef unsigned int UInt
;
7 typedef unsigned long long int ULong
;
18 static void set_NEAREST ( void ) {
19 __asm__
__volatile__("mtfsb0 30 ; mtfsb0 31");
21 static void set_ZERO ( void ) {
22 __asm__
__volatile__("mtfsb0 30 ; mtfsb1 31");
24 static void set_PosINF ( void ) {
25 __asm__
__volatile__("mtfsb1 30 ; mtfsb0 31");
27 static void set_NegINF ( void ) {
28 __asm__
__volatile__("mtfsb1 30 ; mtfsb1 31");
32 static ULong
double_as_ULong ( double d
)
34 union { double dd
; ULong ll
; } u
;
35 assert(sizeof(u
) == 8);
40 static ULong
round_with_mask ( ULong x
, ULong mask
)
99 static void showResult ( Result r
, ULong hideMask
)
101 /* hidemask should have 1 for every result bit we **don't**
102 want to show. viz should be all zeroes normally. */
104 printf("(%016llx cr1 0x%01x fprf 0x%02x)",
105 double_as_ULong(r
.fres
) & ~hidemask
,
106 (r
.cr
>> 24) & 0xF, (r
.fpscr
>> 12) & 0x1F);
108 printf("(%016llx cr1 ... fprf ...)",
109 (hideMask
== 0x1 || hideMask
== 0x3 || hideMask
== 0x7)
110 ? round_with_mask( double_as_ULong(r
.fres
), hideMask
)
111 : double_as_ULong(r
.fres
) & ~hideMask
117 /* Give an insn string such as "fmadd %%f4, %%f1,%%f2,%%f3". Args are
118 in f1, f2, f3, and result should go in f4. */
119 #define INSN(name,insn) \
121 static Result insn_##name ( double arg1, double arg2, double arg3 ) \
126 /* 16 */ double a3; \
127 /* 24 */ double res; \
128 /* 32 */ UInt fpscr_after; \
129 /* 36 */ UInt cr_after; \
131 assert(sizeof(foo) == 40); \
132 foo.a1 = foo.a2 = foo.a3 = foo.res = 0; \
133 foo.fpscr_after = foo.cr_after = 0; \
137 __asm__ __volatile__( \
138 "lfd %%f1, 0(%0)\n\t" /* a1 */ \
139 "lfd %%f2, 8(%0)\n\t" /* a2 */ \
140 "lfd %%f3, 16(%0)\n\t" /* a3 */ \
142 "stfd %%f4, 24(%0)\n\t" /* res */ \
144 "addi %0,%0,32\n\t" \
145 "stfiwx %%f4, %%r0,%0\n\t" /* fpscr_after. r0 reads as zero */ \
146 "addi %0,%0,-32\n\t" \
148 "stw %%r31, 36(%0)" /* cr_after */ \
150 : /*in*/ "b" (&foo.a1) \
151 : /*trash*/ "memory","cc", "fr1","fr2","fr3","fr4", "r31" \
154 result.fres = foo.res; \
155 result.cr = foo.cr_after; \
156 result.fpscr = foo.fpscr_after; \
161 INSN(fabs
, "fabs %%f4, %%f1");
162 INSN(fabs_
, "fabs. %%f4, %%f1");
164 INSN(fnabs
, "fnabs %%f4, %%f1");
165 INSN(fnabs_
, "fnabs. %%f4, %%f1");
167 INSN(fadd
, "fadd %%f4, %%f1,%%f2");
168 INSN(fadd_
, "fadd. %%f4, %%f1,%%f2");
170 INSN(fadds
, "fadds %%f4, %%f1,%%f2");
171 INSN(fadds_
, "fadds. %%f4, %%f1,%%f2");
173 INSN(fcfid
, "fcfid %%f4, %%f1");
174 INSN(fcfid_
, "fcfid. %%f4, %%f1");
176 INSN(fctid
, "fctid %%f4, %%f1");
177 INSN(fctid_
, "fctid. %%f4, %%f1");
179 INSN(fctidz
, "fctidz %%f4, %%f1");
180 INSN(fctidz_
, "fctidz. %%f4, %%f1");
182 INSN(fctiw
, "fctiw %%f4, %%f1");
183 INSN(fctiw_
, "fctiw. %%f4, %%f1");
185 INSN(fctiwz
, "fctiwz %%f4, %%f1");
186 INSN(fctiwz_
, "fctiwz. %%f4, %%f1");
188 INSN(fdiv
, "fdiv %%f4, %%f1,%%f2");
189 INSN(fdiv_
, "fdiv. %%f4, %%f1,%%f2");
191 INSN(fdivs
, "fdivs %%f4, %%f1,%%f2");
192 INSN(fdivs_
, "fdivs. %%f4, %%f1,%%f2");
194 INSN(fmadd
, "fmadd %%f4, %%f1,%%f2,%%f3");
195 INSN(fmadd_
, "fmadd. %%f4, %%f1,%%f2,%%f3");
197 INSN(fmadds
, "fmadds %%f4, %%f1,%%f2,%%f3");
198 INSN(fmadds_
, "fmadds. %%f4, %%f1,%%f2,%%f3");
200 INSN(fmr
, "fmr %%f4, %%f1");
201 INSN(fmr_
, "fmr. %%f4, %%f1");
203 INSN(fmsub
, "fmsub %%f4, %%f1,%%f2,%%f3");
204 INSN(fmsub_
, "fmsub. %%f4, %%f1,%%f2,%%f3");
206 INSN(fmsubs
, "fmsubs %%f4, %%f1,%%f2,%%f3");
207 INSN(fmsubs_
, "fmsubs. %%f4, %%f1,%%f2,%%f3");
209 INSN(fmul
, "fmul %%f4, %%f1,%%f2");
210 INSN(fmul_
, "fmul. %%f4, %%f1,%%f2");
212 INSN(fmuls
, "fmuls %%f4, %%f1,%%f2");
213 INSN(fmuls_
, "fmuls. %%f4, %%f1,%%f2");
215 INSN(fneg
, "fneg %%f4, %%f1");
216 INSN(fneg_
, "fneg. %%f4, %%f1");
218 INSN(fnmadd
, "fnmadd %%f4, %%f1,%%f2,%%f3");
219 INSN(fnmadd_
, "fnmadd. %%f4, %%f1,%%f2,%%f3");
221 INSN(fnmadds
, "fnmadds %%f4, %%f1,%%f2,%%f3");
222 INSN(fnmadds_
, "fnmadds. %%f4, %%f1,%%f2,%%f3");
224 INSN(fnmsub
, "fnmsub %%f4, %%f1,%%f2,%%f3");
225 INSN(fnmsub_
, "fnmsub. %%f4, %%f1,%%f2,%%f3");
227 INSN(fnmsubs
, "fnmsubs %%f4, %%f1,%%f2,%%f3");
228 INSN(fnmsubs_
, "fnmsubs. %%f4, %%f1,%%f2,%%f3");
230 INSN(fre
, "fre %%f4, %%f1");
231 INSN(fre_
, "fre. %%f4, %%f1");
233 INSN(fres
, "fres %%f4, %%f1");
234 INSN(fres_
, "fres. %%f4, %%f1");
236 INSN(frsqrte
, "frsqrte %%f4, %%f1");
237 INSN(frsqrte_
, "frsqrte. %%f4, %%f1");
239 //INSN(frsqrtes, "frsqrtes %%f4, %%f1");
240 //INSN(frsqrtes_, "frsqrtes. %%f4, %%f1");
242 INSN(frsp
, "frsp %%f4, %%f1");
243 INSN(frsp_
, "frsp. %%f4, %%f1");
245 INSN(fsel
, "fsel %%f4, %%f1,%%f2,%%f3");
246 INSN(fsel_
, "fsel. %%f4, %%f1,%%f2,%%f3");
248 INSN(fsqrt
, "fsqrt %%f4, %%f1");
249 INSN(fsqrt_
, "fsqrt. %%f4, %%f1");
251 INSN(fsqrts
, "fsqrts %%f4, %%f1");
252 INSN(fsqrts_
, "fsqrts. %%f4, %%f1");
254 INSN(fsub
, "fsub %%f4, %%f1,%%f2");
255 INSN(fsub_
, "fsub. %%f4, %%f1,%%f2");
257 INSN(fsubs
, "fsubs %%f4, %%f1,%%f2");
258 INSN(fsubs_
, "fsubs. %%f4, %%f1,%%f2");
262 void do_1_unary ( char* name
,
263 Result(*f
)(double,double,double),
268 printf("%8s: %016llx (%e)\n", name
, double_as_ULong(a1
), a1
);
271 printf(" near "); showResult(r
,hideMask
); printf("\n");
274 printf(" zero "); showResult(r
,hideMask
); printf("\n");
277 printf(" +inf "); showResult(r
,hideMask
); printf("\n");
280 printf(" -inf "); showResult(r
,hideMask
); printf("\n");
283 void do_1_binary ( char* name
,
284 Result(*f
)(double,double,double),
285 double a1
, double a2
,
289 printf("%8s: %016llx %016llx\n", name
, double_as_ULong(a1
),
290 double_as_ULong(a2
));
293 printf(" near "); showResult(r
,hideMask
); printf("\n");
296 printf(" zero "); showResult(r
,hideMask
); printf("\n");
299 printf(" +inf "); showResult(r
,hideMask
); printf("\n");
302 printf(" -inf "); showResult(r
,hideMask
); printf("\n");
305 void do_1_ternary ( char* name
,
306 Result(*f
)(double,double,double),
307 double a1
, double a2
, double a3
,
311 printf("%8s: %016llx %016llx %016llx\n",
312 name
, double_as_ULong(a1
),
313 double_as_ULong(a2
), double_as_ULong(a3
));
316 printf(" near "); showResult(r
,hideMask
); printf("\n");
319 printf(" zero "); showResult(r
,hideMask
); printf("\n");
322 printf(" +inf "); showResult(r
,hideMask
); printf("\n");
325 printf(" -inf "); showResult(r
,hideMask
); printf("\n");
328 void do_N_unary ( char* name
,
329 Result(*f
)(double,double,double),
335 for (i
= 0; i
< nargs
; i
++) {
336 do_1_unary( name
, f
, args
[i
], hideMask
);
340 void do_N_binary ( char* name
,
341 Result(*f
)(double,double,double),
347 for (i
= 0; i
< nargs
; i
++) {
348 for (j
= 0; j
< nargs
; j
++) {
349 do_1_binary( name
, f
, args
[i
], args
[j
], hideMask
);
354 void do_N_ternary ( char* name
,
355 Result(*f
)(double,double,double),
361 for (i
= 0; i
< nargs
; i
++) {
362 for (j
= 0; j
< nargs
; j
++) {
363 for (k
= 0; k
< nargs
; k
++) {
364 do_1_ternary( name
, f
, args
[i
], args
[j
], args
[k
], hideMask
);
372 const ULong SHOW_ALL
= 0;
377 double* args
= malloc(nargs
* sizeof(double));
378 double* macArgs
= malloc(nMacArgs
* sizeof(double));
381 args
[1] = 1.0 / 0.0; // inf
382 args
[2] = -args
[1]; // -inf
383 args
[3] = args
[2]/args
[2]; // nan
384 args
[4] = -args
[3]; // -nan
410 macArgs
[7] = -2e-200;
418 macArgs
[15] = 1.23e+5;
419 macArgs
[16] = 1.23e+14;
421 //macArgs[17] = args[3]; // nan
422 //macArgs[18] = -args[3]; // -nan
427 macArgs
[2] = 1.0 + (1.0/7.0);
430 macArgs
[5] = 31415927.0;
432 macArgs
[7] = - (1.0 + (1.0/7.0));
434 macArgs
[9] = - 501.0;
435 macArgs
[10] = - 31415927.0;
438 do_N_unary("fmr", insn_fmr
, args
, nargs
, SHOW_ALL
);
439 do_N_unary("fmr_", insn_fmr_
, args
, nargs
, SHOW_ALL
);
441 do_N_unary("fneg", insn_fneg
, args
, nargs
, SHOW_ALL
);
442 do_N_unary("fneg_", insn_fneg_
, args
, nargs
, SHOW_ALL
);
444 do_N_unary("fabs", insn_fabs
, args
, nargs
, SHOW_ALL
);
445 do_N_unary("fabs_", insn_fabs_
, args
, nargs
, SHOW_ALL
);
447 do_N_unary("fnabs", insn_fnabs
, args
, nargs
, SHOW_ALL
);
448 do_N_unary("fnabs_", insn_fnabs_
, args
, nargs
, SHOW_ALL
);
451 do_N_binary("fadd", insn_fadd
, args
, nargs
, SHOW_ALL
);
452 do_N_binary("fadd_", insn_fadd_
, args
, nargs
, SHOW_ALL
);
454 do_N_binary("fadds", insn_fadds
, args
, nargs
, SHOW_ALL
);
455 do_N_binary("fadds_", insn_fadds_
, args
, nargs
, SHOW_ALL
);
457 do_N_binary("fdiv", insn_fdiv
, args
, nargs
, SHOW_ALL
);
458 do_N_binary("fdiv_", insn_fdiv_
, args
, nargs
, SHOW_ALL
);
460 do_N_binary("fdivs", insn_fdivs
, args
, nargs
, SHOW_ALL
);
461 do_N_binary("fdivs_", insn_fdivs_
, args
, nargs
, SHOW_ALL
);
463 do_N_binary("fmul", insn_fmul
, args
, nargs
, SHOW_ALL
);
464 do_N_binary("fmul_", insn_fmul_
, args
, nargs
, SHOW_ALL
);
466 do_N_binary("fmuls", insn_fmuls
, args
, nargs
, SHOW_ALL
);
467 do_N_binary("fmuls_", insn_fmuls_
, args
, nargs
, SHOW_ALL
);
469 do_N_binary("fsub", insn_fsub
, args
, nargs
, SHOW_ALL
);
470 do_N_binary("fsub_", insn_fsub_
, args
, nargs
, SHOW_ALL
);
472 do_N_binary("fsubs", insn_fsubs
, args
, nargs
, SHOW_ALL
);
473 do_N_binary("fsubs_", insn_fsubs_
, args
, nargs
, SHOW_ALL
);
475 //do_N_unary(fcfid, SHOW_ALL);
476 //do_N_unary(fcfid_, SHOW_ALL);
478 //do_N_unary(fctid, SHOW_ALL);
479 //do_N_unary(fctid_, SHOW_ALL);
481 //do_N_unary(fctidz, SHOW_ALL);
482 //do_N_unary(fctidz_, SHOW_ALL);
484 do_N_unary("fctiw", insn_fctiw
, args
, nargs
, 0xFFFFFFFF00000000ULL
);
485 do_N_unary("fctiw_", insn_fctiw_
, args
, nargs
, 0xFFFFFFFF00000000ULL
);
487 do_N_unary("fctiwz", insn_fctiwz
, args
, nargs
, 0xFFFFFFFF00000000ULL
);
488 do_N_unary("fctiwz_", insn_fctiwz_
, args
, nargs
, 0xFFFFFFFF00000000ULL
);
490 do_N_ternary("fmadd", insn_fmadd
, macArgs
, nMacArgs
, SHOW_ALL
);
491 do_N_ternary("fmadd_", insn_fmadd_
, macArgs
, nMacArgs
, SHOW_ALL
);
493 do_N_ternary("fmadds", insn_fmadds
, macArgs
, nMacArgs
, SHOW_ALL
);
494 do_N_ternary("fmadds_", insn_fmadds_
, macArgs
, nMacArgs
, SHOW_ALL
);
496 do_N_ternary("fmsub", insn_fmsub
, macArgs
, nMacArgs
, SHOW_ALL
);
497 do_N_ternary("fmsub_", insn_fmsub_
, macArgs
, nMacArgs
, SHOW_ALL
);
499 do_N_ternary("fmsubs", insn_fmsubs
, macArgs
, nMacArgs
, SHOW_ALL
);
500 do_N_ternary("fmsubs_", insn_fmsubs_
, macArgs
, nMacArgs
, SHOW_ALL
);
502 do_N_ternary("fnmadd", insn_fnmadd
, macArgs
, nMacArgs
, SHOW_ALL
);
503 do_N_ternary("fnmadd_", insn_fnmadd_
, macArgs
, nMacArgs
, SHOW_ALL
);
505 do_N_ternary("fnmadds", insn_fnmadds
, macArgs
, nMacArgs
, SHOW_ALL
);
506 do_N_ternary("fnmadds_", insn_fnmadds_
, macArgs
, nMacArgs
, SHOW_ALL
);
508 do_N_ternary("fnmsub", insn_fnmsub
, macArgs
, nMacArgs
, SHOW_ALL
);
509 do_N_ternary("fnmsub_", insn_fnmsub_
, macArgs
, nMacArgs
, SHOW_ALL
);
511 do_N_ternary("fnmsubs", insn_fnmsubs
, macArgs
, nMacArgs
, SHOW_ALL
);
512 do_N_ternary("fnmsubs_", insn_fnmsubs_
, macArgs
, nMacArgs
, SHOW_ALL
);
514 //do_N_unary(fre, SHOW_ALL);
515 //do_N_unary(fre_, SHOW_ALL);
517 do_N_unary("fres", insn_fres
, args
, nargs
, 0x000001FFFFFFFFFFULL
);
518 do_N_unary("fres_", insn_fres_
, args
, nargs
, 0x000001FFFFFFFFFFULL
);
520 do_N_unary("frsqrte", insn_frsqrte
, args
, nargs
, SHOW_ALL
);
521 do_N_unary("frsqrte_", insn_frsqrte_
, args
, nargs
, SHOW_ALL
);
523 // do_N_unary("frsqrtes", insn_frsqrtes, args, nargs, SHOW_ALL);
524 // do_N_unary("frsqrtes_", insn_frsqrtes_, args, nargs, SHOW_ALL);
526 do_N_unary("frsp", insn_frsp
, args
, nargs
, SHOW_ALL
);
527 do_N_unary("frsp_", insn_frsp_
, args
, nargs
, SHOW_ALL
);
529 do_N_ternary("fsel", insn_fsel
, args
, nargs
, SHOW_ALL
);
530 do_N_ternary("fsel_", insn_fsel_
, args
, nargs
, SHOW_ALL
);
532 //do_N_unary(fsqrt, SHOW_ALL);
533 //do_N_unary(fsqrt_, SHOW_ALL);
535 //do_N_unary(fsqrts, SHOW_ALL);
536 //do_N_unary(fsqrts_, SHOW_ALL);