xref: /netbsd-src/sys/arch/sh3/include/ieeefp.h (revision 7e30e94394d0994ab9534f68a8f91665045c91ce)
1 /* $NetBSD: ieeefp.h,v 1.7 2017/03/22 23:11:10 chs Exp $ */
2 
3 /*
4  * Written by J.T. Conklin, Apr 6, 1995
5  * Public domain.
6  */
7 
8 #ifndef _SH3_IEEEFP_H_
9 #define	_SH3_IEEEFP_H_
10 
11 #include <sys/featuretest.h>
12 
13 #if defined(_NETBSD_SOURCE) || defined(_ISOC99_SOURCE)
14 
15 #include <fenv.h>
16 
17 #if defined(_NETBSD_SOURCE)
18 
19 typedef int fp_except;
20 
21 #ifdef	__SH_FPU_ANY__
22 
23 /* hardfloat */
24 
25 #define	FP_X_INV	FE_INVALID	/* invalid operation exception */
26 #define	FP_X_DZ		FE_DIVBYZERO	/* divide-by-zero exception */
27 #define	FP_X_OFL	FE_OVERFLOW	/* overflow exception */
28 #define	FP_X_UFL	FE_UNDERFLOW	/* underflow exception */
29 #define	FP_X_IMP	FE_INEXACT	/* imprecise (loss of precision) */
30 
31 typedef enum {
32 	FP_RN=FE_TONEAREST,	/* round to nearest representable number */
33 	FP_RM=FE_DOWNWARD,      /* round toward negative infinity */
34 	FP_RP=FE_UPWARD,        /* round toward positive infinity */
35 	FP_RZ=FE_TOWARDZERO	/* round to zero (truncate) */
36 } fp_rnd;
37 
38 #else /* __SH_FPU_ANY__ */
39 
40 /* softfloat */
41 
42 #define	FP_X_INV	0x01	/* invalid operation exception */
43 #define	FP_X_DZ		0x04	/* divide-by-zero exception */
44 #define	FP_X_OFL	0x08	/* overflow exception */
45 #define	FP_X_UFL	0x10	/* underflow exception */
46 #define	FP_X_IMP	0x20	/* imprecise (loss of precision) */
47 
48 typedef enum {
49 	FP_RN=0,		/* round to nearest representable number */
50 	FP_RM=1,		/* round toward negative infinity */
51 	FP_RP=2,        	/* round toward positive infinity */
52 	FP_RZ=3			/* round to zero (truncate) */
53 } fp_rnd;
54 
55 /* adjust for FP_* and FE_* value differences */
56 
57 static inline fp_except
__FPE(int __fe)58 __FPE(int __fe)
59 {
60 	int __fp = 0;
61 
62 	if (__fe & FE_DIVBYZERO)
63 		__fp |= FP_X_DZ;
64 	if (__fe & FE_INEXACT)
65 		__fp |= FP_X_IMP;
66 	if (__fe & FE_INVALID)
67 		__fp |= FP_X_INV;
68 	if (__fe & FE_OVERFLOW)
69 		__fp |= FP_X_OFL;
70 	if (__fe & FE_UNDERFLOW)
71 		__fp |= FP_X_UFL;
72 	return __fp;
73 }
74 
75 static inline int
__FEE(fp_except __fp)76 __FEE(fp_except __fp)
77 {
78 	int __fe = 0;
79 
80 	if (__fp & FP_X_DZ)
81 		__fe |= FE_DIVBYZERO;
82 	if (__fp & FP_X_IMP)
83 		__fe |= FE_INEXACT;
84 	if (__fp & FP_X_INV)
85 		__fe |= FE_INVALID;
86 	if (__fp & FP_X_OFL)
87 		__fe |= FE_OVERFLOW;
88 	if (__fp & FP_X_UFL)
89 		__fe |= FE_UNDERFLOW;
90 	return __fe;
91 }
92 
93 static inline fp_rnd
__FPR(int __fe)94 __FPR(int __fe)
95 {
96 
97 	switch (__fe) {
98 	case FE_TONEAREST:
99 		return FP_RN;
100 	case FE_DOWNWARD:
101 		return FP_RM;
102 	case FE_UPWARD:
103 		return FP_RP;
104 	case FE_TOWARDZERO:
105 		return FP_RZ;
106 	default:
107 		return FP_RN;
108 	}
109 }
110 
111 static inline int
__FER(fp_rnd __fp)112 __FER(fp_rnd __fp)
113 {
114 
115 	switch (__fp) {
116 	case FP_RN:
117 		return FE_TONEAREST;
118 	case FP_RM:
119 		return FE_DOWNWARD;
120 	case FP_RP:
121 		return FE_UPWARD;
122 	case FP_RZ:
123 		return FE_TOWARDZERO;
124 	default:
125 		return FE_TONEAREST;
126 	}
127 }
128 
129 #endif /* __SH_FPU_ANY__ */
130 
131 #endif /* !_ISOC99_SOURCE */
132 
133 #endif /* _NETBSD_SOURCE || _ISOC99_SOURCE */
134 
135 #endif /* !_SH3_IEEEFP_H_ */
136