xref: /illumos-gate/usr/src/lib/libc/sparc/fp/quad.h (revision 7c478bd9)
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 #pragma ident	"%Z%%M%	%I%	%E% SMI"
31 
32 #ifdef __cplusplus
33 extern "C" {
34 #endif
35 
36 /*
37  * Common definitions for quadruple precision emulation routines
38  * (SPARC only)
39  */
40 
41 /* macros to simplify dealing with the diferences between V8 and V9 */
42 #ifdef __sparcv9
43 
44 #define	Z		(*pz)
45 #define	QUAD_RETURN(x)	return
46 
47 #else
48 
49 #define	Z		z
50 #define	QUAD_RETURN(x)	return (x)
51 
52 #endif
53 
54 /* fsr definitions */
55 
56 /* current exception bits */
57 #define	FSR_NXC		0x1
58 #define	FSR_DZC		0x2
59 #define	FSR_UFC		0x4
60 #define	FSR_OFC		0x8
61 #define	FSR_NVC		0x10
62 #define	FSR_CEXC	0x1f	/* mask for all cexc bits */
63 
64 /* accrued exception bits */
65 #define	FSR_NXA		0x20
66 #define	FSR_DZA		0x40
67 #define	FSR_UFA		0x80
68 #define	FSR_OFA		0x100
69 #define	FSR_NVA		0x200
70 
71 /* trap enable bits */
72 #define	FSR_NXM		0x00800000
73 #define	FSR_DZM		0x01000000
74 #define	FSR_UFM		0x02000000
75 #define	FSR_OFM		0x04000000
76 #define	FSR_NVM		0x08000000
77 
78 /* rounding directions (shifted) */
79 #define	FSR_RN		0
80 #define	FSR_RZ		1
81 #define	FSR_RP		2
82 #define	FSR_RM		3
83 
84 /*
85  * in struct longdouble, msw implicitly consists of
86  *	unsigned short	sign:1;
87  *	unsigned short	exponent:15;
88  *	unsigned short	frac1:16;
89  */
90 
91 /* structure used to access words within a quad */
92 union longdouble {
93 	struct {
94 		unsigned int	msw;
95 		unsigned int	frac2;
96 		unsigned int	frac3;
97 		unsigned int	frac4;
98 	} l;
99 	long double	d;	/* unused; just guarantees correct alignment */
100 };
101 
102 /* macros used internally for readability */
103 #define	QUAD_ISNAN(x) \
104 	(((x).l.msw & 0x7fff0000) == 0x7fff0000 && \
105 	(((x).l.msw & 0xffff) | (x).l.frac2 | (x).l.frac3 | (x).l.frac4))
106 
107 #define	QUAD_ISZERO(x) \
108 	(!(((x).l.msw & 0x7fffffff) | (x).l.frac2 | (x).l.frac3 | (x).l.frac4))
109 
110 /* structure used to access words within a double */
111 union xdouble {
112 	struct {
113 		unsigned int	hi;
114 		unsigned int	lo;
115 	} l;
116 	double			d;
117 };
118 
119 /* relationships returned by _Q_cmp and _Q_cmpe */
120 enum fcc_type {
121 	fcc_equal	= 0,
122 	fcc_less	= 1,
123 	fcc_greater	= 2,
124 	fcc_unordered	= 3
125 };
126 
127 /* internal routines */
128 extern void __quad_mag_add(const union longdouble *,
129 	const union longdouble *, union longdouble *, unsigned int *);
130 extern void __quad_mag_sub(const union longdouble *,
131 	const union longdouble *, union longdouble *, unsigned int *);
132 
133 /* inline templates */
134 extern void __quad_getfsrp(unsigned int *);
135 extern void __quad_setfsrp(const unsigned int *);
136 extern double __quad_dp_sqrt(double *);
137 extern void __quad_faddq(const union longdouble *, const union longdouble *,
138 	union longdouble *);
139 extern void __quad_fsubq(const union longdouble *, const union longdouble *,
140 	union longdouble *);
141 extern void __quad_fmulq(const union longdouble *, const union longdouble *,
142 	union longdouble *);
143 extern void __quad_fdivq(const union longdouble *, const union longdouble *,
144 	union longdouble *);
145 extern void __quad_fsqrtq(const union longdouble *, union longdouble *);
146 extern void __quad_fcmpq(const union longdouble *, const union longdouble *,
147 	unsigned int *);
148 extern void __quad_fcmpeq(const union longdouble *, const union longdouble *,
149 	unsigned int *);
150 extern void __quad_fstoq(const float *, union longdouble *);
151 extern void __quad_fdtoq(const double *, union longdouble *);
152 extern void __quad_fqtoi(const union longdouble *, int *);
153 extern void __quad_fqtos(const union longdouble *, float *);
154 extern void __quad_fqtod(const union longdouble *, double *);
155 #ifdef __sparcv9
156 extern void __quad_fqtox(const union longdouble *, long *);
157 #endif
158 
159 #ifdef __cplusplus
160 }
161 #endif
162 
163 #endif	/* _QUAD_H */
164