xref: /inferno-os/libmath/FPcontrol-MacOSX.c (revision 37da2899f40661e3e9631e497da8dc59b971cbd0)
1 #include "lib9.h"
2 #include "fpuctl.h"
3 #include "mathi.h"
4 
5 #include<stdio.h>
6 
7 void PPC_PrintFPSCR()
8 {
9     ppc_fp_scr_t fpscr;
10 
11     fpscr = get_fp_scr();
12     fprintf(stderr, "FPSCR = 0x%08x : 0x%08x\n",
13             ((unsigned int *)&fpscr)[0],
14             ((unsigned int *)&fpscr)[1]);
15     fprintf(stderr, "FPSCR[ve] = %d\n", fpscr.ve);
16     fprintf(stderr, "FPSCR[ze] = %d\n", fpscr.ze);
17     fprintf(stderr, "FPSCR[ue] = %d\n", fpscr.ue);
18     fprintf(stderr, "FPSCR[oe] = %d\n", fpscr.oe);
19 }
20 
21 void
22 FPinit(void)
23 {
24 	ulong fcr9 = FPPDBL|FPRNR|FPINVAL|FPZDIV|FPUNFL|FPOVFL;
25 	setfsr(0);	/* Clear pending exceptions */
26 	setfcr(fcr9);
27 }
28 
29 ulong
30 getFPstatus(void)
31 {
32 	ulong fsr = 0, fsr9 = getfsr();
33 	/* on specific machines, could be table lookup */
34 	if(fsr9&FPAINEX) fsr |= INEX;
35 	if(fsr9&FPAOVFL) fsr |= OVFL;
36 	if(fsr9&FPAUNFL) fsr |= UNFL;
37 	if(fsr9&FPAZDIV) fsr |= ZDIV;
38 	if(fsr9&FPAINVAL) fsr |= INVAL;
39 	return fsr;
40 }
41 
42 ulong
43 FPstatus(ulong fsr, ulong mask)
44 {
45 	ulong fsr9 = 0;
46 	ulong old = getFPstatus();
47 	fsr = (fsr&mask) | (old&~mask);
48 	if(fsr&INEX) fsr9 |= FPAINEX;
49 	if(fsr&OVFL) fsr9 |= FPAOVFL;
50 	if(fsr&UNFL) fsr9 |= FPAUNFL;
51 	if(fsr&ZDIV) fsr9 |= FPAZDIV;
52 	if(fsr&INVAL) fsr9 |= FPAINVAL;
53 	setfsr(fsr9);
54 	return(old&mask);
55 }
56 
57 ulong
58 getFPcontrol(void)
59 {
60 	ulong fcr = 0, fcr9 = getfcr();
61 	switch(fcr9&FPRMASK){
62 		case FPRNR:	fcr = RND_NR; break;
63 		case FPRNINF:	fcr = RND_NINF; break;
64 		case FPRPINF:	fcr = RND_PINF; break;
65 		case FPRZ:	fcr = RND_Z; break;
66 	}
67 	if(fcr9&FPINEX) fcr |= INEX;
68 	if(fcr9&FPOVFL) fcr |= OVFL;
69 	if(fcr9&FPUNFL) fcr |= UNFL;
70 	if(fcr9&FPZDIV) fcr |= ZDIV;
71 	if(fcr9&FPINVAL) fcr |= INVAL;
72 	return fcr;
73 }
74 
75 ulong
76 FPcontrol(ulong fcr, ulong mask)
77 {
78 	ulong fcr9 = FPPDBL;
79 	ulong old = getFPcontrol();
80 	fcr = (fcr&mask) | (old&~mask);
81 	if(fcr&INEX) fcr9 |= FPINEX;
82 	if(fcr&OVFL) fcr9 |= FPOVFL;
83 	if(fcr&UNFL) fcr9 |= FPUNFL;
84 	if(fcr&ZDIV) fcr9 |= FPZDIV;
85 	if(fcr&INVAL) fcr9 |= FPINVAL;
86 	switch(fcr&RND_MASK){
87 		case RND_NR:	fcr9 |= FPRNR; break;
88 		case RND_NINF:	fcr9 |= FPRNINF; break;
89 		case RND_PINF:	fcr9 |= FPRPINF; break;
90 		case RND_Z:	fcr9 |= FPRZ; break;
91 	}
92 	setfcr(fcr9);
93 	return(old&mask);
94 }
95