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
19typedef 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
31typedef 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
48typedef 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
57static inline fp_except
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
75static inline int
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
93static inline fp_rnd
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
111static inline int
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