xref: /illumos-gate/usr/src/lib/libc/sparc/fp/quad.h (revision ddb365bfc9e868ad24ccdcb0dc91af18b10df082)
1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License, Version 1.0 only
6  * (the "License").  You may not use this file except in compliance
7  * with the License.
8  *
9  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10  * or http://www.opensolaris.org/os/licensing.
11  * See the License for the specific language governing permissions
12  * and limitations under the License.
13  *
14  * When distributing Covered Code, include this CDDL HEADER in each
15  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16  * If applicable, add the following below this CDDL HEADER, with the
17  * fields enclosed by brackets "[]" replaced with your own identifying
18  * information: Portions Copyright [yyyy] [name of copyright owner]
19  *
20  * CDDL HEADER END
21  */
22 /*
23  * Copyright (c) 1994-1997, by Sun Microsystems, Inc.
24  * All rights reserved.
25  */
26 
27 #ifndef _QUAD_H
28 #define	_QUAD_H
29 
30 #ifdef __cplusplus
31 extern "C" {
32 #endif
33 
34 /*
35  * Common definitions for quadruple precision emulation routines
36  * (SPARC only)
37  */
38 
39 /* macros to simplify dealing with the diferences between V8 and V9 */
40 #ifdef __sparcv9
41 
42 #define	Z		(*pz)
43 #define	QUAD_RETURN(x)	return
44 
45 #else
46 
47 #define	Z		z
48 #define	QUAD_RETURN(x)	return (x)
49 
50 #endif
51 
52 /* fsr definitions */
53 
54 /* current exception bits */
55 #define	FSR_NXC		0x1
56 #define	FSR_DZC		0x2
57 #define	FSR_UFC		0x4
58 #define	FSR_OFC		0x8
59 #define	FSR_NVC		0x10
60 #define	FSR_CEXC	0x1f	/* mask for all cexc bits */
61 
62 /* accrued exception bits */
63 #define	FSR_NXA		0x20
64 #define	FSR_DZA		0x40
65 #define	FSR_UFA		0x80
66 #define	FSR_OFA		0x100
67 #define	FSR_NVA		0x200
68 
69 /* trap enable bits */
70 #define	FSR_NXM		0x00800000
71 #define	FSR_DZM		0x01000000
72 #define	FSR_UFM		0x02000000
73 #define	FSR_OFM		0x04000000
74 #define	FSR_NVM		0x08000000
75 
76 /* rounding directions (shifted) */
77 #define	FSR_RN		0
78 #define	FSR_RZ		1
79 #define	FSR_RP		2
80 #define	FSR_RM		3
81 
82 /*
83  * in struct longdouble, msw implicitly consists of
84  *	unsigned short	sign:1;
85  *	unsigned short	exponent:15;
86  *	unsigned short	frac1:16;
87  */
88 
89 /* structure used to access words within a quad */
90 union longdouble {
91 	struct {
92 		unsigned int	msw;
93 		unsigned int	frac2;
94 		unsigned int	frac3;
95 		unsigned int	frac4;
96 	} l;
97 	long double	d;	/* unused; just guarantees correct alignment */
98 };
99 
100 /* macros used internally for readability */
101 #define	QUAD_ISNAN(x) \
102 	(((x).l.msw & 0x7fff0000) == 0x7fff0000 && \
103 	(((x).l.msw & 0xffff) | (x).l.frac2 | (x).l.frac3 | (x).l.frac4))
104 
105 #define	QUAD_ISZERO(x) \
106 	(!(((x).l.msw & 0x7fffffff) | (x).l.frac2 | (x).l.frac3 | (x).l.frac4))
107 
108 /* structure used to access words within a double */
109 union xdouble {
110 	struct {
111 		unsigned int	hi;
112 		unsigned int	lo;
113 	} l;
114 	double			d;
115 };
116 
117 /* relationships returned by _Q_cmp and _Q_cmpe */
118 enum fcc_type {
119 	fcc_equal	= 0,
120 	fcc_less	= 1,
121 	fcc_greater	= 2,
122 	fcc_unordered	= 3
123 };
124 
125 /* internal routines */
126 extern void __quad_mag_add(const union longdouble *,
127 	const union longdouble *, union longdouble *, unsigned int *);
128 extern void __quad_mag_sub(const union longdouble *,
129 	const union longdouble *, union longdouble *, unsigned int *);
130 
131 /* inline templates */
132 extern void __quad_getfsrp(unsigned int *);
133 extern void __quad_setfsrp(const unsigned int *);
134 extern double __quad_dp_sqrt(double *);
135 extern void __quad_faddq(const union longdouble *, const union longdouble *,
136 	union longdouble *);
137 extern void __quad_fsubq(const union longdouble *, const union longdouble *,
138 	union longdouble *);
139 extern void __quad_fmulq(const union longdouble *, const union longdouble *,
140 	union longdouble *);
141 extern void __quad_fdivq(const union longdouble *, const union longdouble *,
142 	union longdouble *);
143 extern void __quad_fsqrtq(const union longdouble *, union longdouble *);
144 extern void __quad_fcmpq(const union longdouble *, const union longdouble *,
145 	unsigned int *);
146 extern void __quad_fcmpeq(const union longdouble *, const union longdouble *,
147 	unsigned int *);
148 extern void __quad_fstoq(const float *, union longdouble *);
149 extern void __quad_fdtoq(const double *, union longdouble *);
150 extern void __quad_fqtoi(const union longdouble *, int *);
151 extern void __quad_fqtos(const union longdouble *, float *);
152 extern void __quad_fqtod(const union longdouble *, double *);
153 #ifdef __sparcv9
154 extern void __quad_fqtox(const union longdouble *, long *);
155 #endif
156 
157 #ifdef __cplusplus
158 }
159 #endif
160 
161 #endif	/* _QUAD_H */
162