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 2004 Sun Microsystems, Inc.  All rights reserved.
24  * Use is subject to license terms.
25  */
26 
27 /*	Copyright (c) 1988 AT&T	*/
28 /*	  All Rights Reserved  	*/
29 
30 /*
31  * Copyright 2017 John R. Marino <draco@marino.st>
32  *
33  * This was not part of the original libm release. The fpclass function
34  * has been reconstructed from Illumos sources as it is required for
35  * proper libm functionality (x86 only)
36  */
37 
38 /* double precision */
39 typedef  union {
40 	struct {
41 		unsigned  lo	:32;
42 		unsigned  hi	:20;
43 		unsigned  exp	:11;
44 		unsigned  sign	:1;
45 	} fparts;
46 	struct {
47 		unsigned  lo	:32;
48 		unsigned  hi	:19;
49 		unsigned  qnan_bit	:1;
50 		unsigned  exp	:11;
51 		unsigned  sign	:1;
52 	} nparts;
53 	struct {
54 		unsigned  lo	:32;
55 		unsigned  hi	:32;
56 	} fwords;
57 	double	d;
58 } _dval;
59 
60 /* single precision */
61 typedef  union {
62 	struct {
63 		unsigned fract	:23;
64 		unsigned exp	:8;
65 		unsigned sign	:1;
66 	} fparts;
67 	struct {
68 		unsigned fract	:22;
69 		unsigned qnan_bit	:1;
70 		unsigned exp	:8;
71 		unsigned sign	:1;
72 	} nparts;
73 	unsigned long	fword;
74 	float	f;
75 } _fval;
76 
77 #define	SIGNBIT(X)	(((_dval *)&(X))->fparts.sign)
78 #define	EXPONENT(X)	(((_dval *)&(X))->fparts.exp)
79 
80 #define	HIFRACTION(X)	(((_dval *)&(X))->fparts.hi)
81 #define	LOFRACTION(X)	(((_dval *)&(X))->fparts.lo)
82 #define	QNANBIT(X)	(((_dval *)&(X))->nparts.qnan_bit)
83 
84 #define	MAXEXP	0x7ff /* maximum exponent of double */
85 
86 #include <sys/ieeefp.h>
87 
88 /*
89  * FPCLASS(X)
90  * fpclass(x) returns the floating point class to which x belongs
91  *
92  * The original function distinguished between positive and negative
93  * versions of infinity, normal, denormal, and zero, but the
94  * fp_class_type enumeration doesn't make this distinguishment.
95  *
96 
97 fpclass_t
98 fpclass(double x)
99 {
100 	int	sign, exp;
101 
102 	exp = EXPONENT(x);
103 	sign = SIGNBIT(x);
104 	if (exp == 0) { * de-normal or zero *
105 		if (HIFRACTION(x) || LOFRACTION(x)) * de-normal *
106 			return (sign ? FP_NDENORM : FP_PDENORM);
107 		else
108 			return (sign ? FP_NZERO : FP_PZERO);
109 	}
110 	if (exp == MAXEXP) { * infinity or NaN *
111 		if ((HIFRACTION(x) == 0) && (LOFRACTION(x) == 0)) * infinity *
112 			return (sign ? FP_NINF : FP_PINF);
113 		else
114 			if (QNANBIT(x))
115 			* hi-bit of mantissa set - quiet nan *
116 				return (FP_QNAN);
117 			else	return (FP_SNAN);
118 	}
119 	* if we reach here we have non-zero normalized number *
120 	return (sign ? FP_NNORM : FP_PNORM);
121 }
122 */
123 
124 enum fp_class_type
fp_class(double x)125 fp_class(double x)
126 {
127 	int	exp;
128 	exp = EXPONENT(x);
129 	if (exp == 0) {
130 		if (HIFRACTION(x) || LOFRACTION(x))
131 			return fp_subnormal;
132 		else
133 			return fp_zero;
134 	}
135 	if (exp == MAXEXP) {
136 		/* infinity or NaN */
137 		if ((HIFRACTION(x) == 0) && (LOFRACTION(x) == 0))
138 			return fp_infinity;
139 		else {
140 			if (QNANBIT(x))
141 				return fp_quiet;
142 			else
143 				return fp_signaling;
144 		}
145 	}
146 	/* if we reach here we have non-zero normalized number */
147 	return fp_normal;
148 }
149