xref: /netbsd-src/sys/arch/sh3/include/ieeefp.h (revision 7e30e94394d0994ab9534f68a8f91665045c91ce)
1*7e30e943Schs /* $NetBSD: ieeefp.h,v 1.7 2017/03/22 23:11:10 chs Exp $ */
265363da2Sitojun 
365363da2Sitojun /*
465363da2Sitojun  * Written by J.T. Conklin, Apr 6, 1995
565363da2Sitojun  * Public domain.
665363da2Sitojun  */
765363da2Sitojun 
865363da2Sitojun #ifndef _SH3_IEEEFP_H_
965363da2Sitojun #define	_SH3_IEEEFP_H_
1065363da2Sitojun 
1191d4704cSmatt #include <sys/featuretest.h>
1291d4704cSmatt 
1391d4704cSmatt #if defined(_NETBSD_SOURCE) || defined(_ISOC99_SOURCE)
1491d4704cSmatt 
1585902696Schristos #include <fenv.h>
1691d4704cSmatt 
1791d4704cSmatt #if defined(_NETBSD_SOURCE)
1891d4704cSmatt 
1983df8f87Schristos typedef int fp_except;
2083df8f87Schristos 
21*7e30e943Schs #ifdef	__SH_FPU_ANY__
22*7e30e943Schs 
23*7e30e943Schs /* hardfloat */
24*7e30e943Schs 
2591d4704cSmatt #define	FP_X_INV	FE_INVALID	/* invalid operation exception */
2691d4704cSmatt #define	FP_X_DZ		FE_DIVBYZERO	/* divide-by-zero exception */
2791d4704cSmatt #define	FP_X_OFL	FE_OVERFLOW	/* overflow exception */
2891d4704cSmatt #define	FP_X_UFL	FE_UNDERFLOW	/* underflow exception */
2991d4704cSmatt #define	FP_X_IMP	FE_INEXACT	/* imprecise (loss of precision) */
3065363da2Sitojun 
3165363da2Sitojun typedef enum {
3291d4704cSmatt 	FP_RN=FE_TONEAREST,	/* round to nearest representable number */
3383df8f87Schristos 	FP_RM=FE_DOWNWARD,      /* round toward negative infinity */
3483df8f87Schristos 	FP_RP=FE_UPWARD,        /* round toward positive infinity */
3591d4704cSmatt 	FP_RZ=FE_TOWARDZERO	/* round to zero (truncate) */
3665363da2Sitojun } fp_rnd;
3765363da2Sitojun 
38*7e30e943Schs #else /* __SH_FPU_ANY__ */
39*7e30e943Schs 
40*7e30e943Schs /* softfloat */
41*7e30e943Schs 
42*7e30e943Schs #define	FP_X_INV	0x01	/* invalid operation exception */
43*7e30e943Schs #define	FP_X_DZ		0x04	/* divide-by-zero exception */
44*7e30e943Schs #define	FP_X_OFL	0x08	/* overflow exception */
45*7e30e943Schs #define	FP_X_UFL	0x10	/* underflow exception */
46*7e30e943Schs #define	FP_X_IMP	0x20	/* imprecise (loss of precision) */
47*7e30e943Schs 
48*7e30e943Schs typedef enum {
49*7e30e943Schs 	FP_RN=0,		/* round to nearest representable number */
50*7e30e943Schs 	FP_RM=1,		/* round toward negative infinity */
51*7e30e943Schs 	FP_RP=2,        	/* round toward positive infinity */
52*7e30e943Schs 	FP_RZ=3			/* round to zero (truncate) */
53*7e30e943Schs } fp_rnd;
54*7e30e943Schs 
55*7e30e943Schs /* adjust for FP_* and FE_* value differences */
56*7e30e943Schs 
57*7e30e943Schs static inline fp_except
__FPE(int __fe)58*7e30e943Schs __FPE(int __fe)
59*7e30e943Schs {
60*7e30e943Schs 	int __fp = 0;
61*7e30e943Schs 
62*7e30e943Schs 	if (__fe & FE_DIVBYZERO)
63*7e30e943Schs 		__fp |= FP_X_DZ;
64*7e30e943Schs 	if (__fe & FE_INEXACT)
65*7e30e943Schs 		__fp |= FP_X_IMP;
66*7e30e943Schs 	if (__fe & FE_INVALID)
67*7e30e943Schs 		__fp |= FP_X_INV;
68*7e30e943Schs 	if (__fe & FE_OVERFLOW)
69*7e30e943Schs 		__fp |= FP_X_OFL;
70*7e30e943Schs 	if (__fe & FE_UNDERFLOW)
71*7e30e943Schs 		__fp |= FP_X_UFL;
72*7e30e943Schs 	return __fp;
73*7e30e943Schs }
74*7e30e943Schs 
75*7e30e943Schs static inline int
__FEE(fp_except __fp)76*7e30e943Schs __FEE(fp_except __fp)
77*7e30e943Schs {
78*7e30e943Schs 	int __fe = 0;
79*7e30e943Schs 
80*7e30e943Schs 	if (__fp & FP_X_DZ)
81*7e30e943Schs 		__fe |= FE_DIVBYZERO;
82*7e30e943Schs 	if (__fp & FP_X_IMP)
83*7e30e943Schs 		__fe |= FE_INEXACT;
84*7e30e943Schs 	if (__fp & FP_X_INV)
85*7e30e943Schs 		__fe |= FE_INVALID;
86*7e30e943Schs 	if (__fp & FP_X_OFL)
87*7e30e943Schs 		__fe |= FE_OVERFLOW;
88*7e30e943Schs 	if (__fp & FP_X_UFL)
89*7e30e943Schs 		__fe |= FE_UNDERFLOW;
90*7e30e943Schs 	return __fe;
91*7e30e943Schs }
92*7e30e943Schs 
93*7e30e943Schs static inline fp_rnd
__FPR(int __fe)94*7e30e943Schs __FPR(int __fe)
95*7e30e943Schs {
96*7e30e943Schs 
97*7e30e943Schs 	switch (__fe) {
98*7e30e943Schs 	case FE_TONEAREST:
99*7e30e943Schs 		return FP_RN;
100*7e30e943Schs 	case FE_DOWNWARD:
101*7e30e943Schs 		return FP_RM;
102*7e30e943Schs 	case FE_UPWARD:
103*7e30e943Schs 		return FP_RP;
104*7e30e943Schs 	case FE_TOWARDZERO:
105*7e30e943Schs 		return FP_RZ;
106*7e30e943Schs 	default:
107*7e30e943Schs 		return FP_RN;
108*7e30e943Schs 	}
109*7e30e943Schs }
110*7e30e943Schs 
111*7e30e943Schs static inline int
__FER(fp_rnd __fp)112*7e30e943Schs __FER(fp_rnd __fp)
113*7e30e943Schs {
114*7e30e943Schs 
115*7e30e943Schs 	switch (__fp) {
116*7e30e943Schs 	case FP_RN:
117*7e30e943Schs 		return FE_TONEAREST;
118*7e30e943Schs 	case FP_RM:
119*7e30e943Schs 		return FE_DOWNWARD;
120*7e30e943Schs 	case FP_RP:
121*7e30e943Schs 		return FE_UPWARD;
122*7e30e943Schs 	case FP_RZ:
123*7e30e943Schs 		return FE_TOWARDZERO;
124*7e30e943Schs 	default:
125*7e30e943Schs 		return FE_TONEAREST;
126*7e30e943Schs 	}
127*7e30e943Schs }
128*7e30e943Schs 
129*7e30e943Schs #endif /* __SH_FPU_ANY__ */
130*7e30e943Schs 
13191d4704cSmatt #endif /* !_ISOC99_SOURCE */
13291d4704cSmatt 
13391d4704cSmatt #endif /* _NETBSD_SOURCE || _ISOC99_SOURCE */
13491d4704cSmatt 
13593da9db9Such #endif /* !_SH3_IEEEFP_H_ */
136