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 (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21
22/*
23 * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
24 * Use is subject to license terms.
25 */
26
27#ifndef	BASE_CONVERSION_H
28#define	BASE_CONVERSION_H
29
30#pragma ident	"%Z%%M%	%I%	%E% SMI"
31
32#include <errno.h>
33#include <floatingpoint.h>
34#include <sys/isa_defs.h>
35
36/*
37 * Common constants, types, and declarations for floating point
38 * base conversion
39 */
40
41/* PRIVATE CONSTANTS	 */
42
43/* exponent bias */
44#define	SINGLE_BIAS	  127
45#define	DOUBLE_BIAS	 1023
46#define	EXTENDED_BIAS	16383
47#define	QUAD_BIAS	16383
48
49
50/* PRIVATE TYPES */
51
52/*
53 * Unpacked binary floating point format.  The binary point lies
54 * to the right of the most significant bit in significand[0].
55 * The exponent is unbiased.  The significand array is long enough
56 * that the last word never contains any bits we need to keep,
57 * just rounding information.
58 */
59
60#define	UNPACKED_SIZE	5
61
62typedef struct {
63	int		sign;
64	enum fp_class_type fpclass;
65	int		exponent;
66	unsigned	significand[UNPACKED_SIZE];
67} unpacked;
68
69/*
70 * Packed binary floating point formats.  The *_msw structure
71 * corresponds to the most significant word.
72 */
73
74#ifdef _LITTLE_ENDIAN
75
76typedef struct {
77	unsigned	significand:23;
78	unsigned	exponent:8;
79	unsigned	sign:1;
80} single_msw;
81
82typedef struct {
83	unsigned	significand:20;
84	unsigned	exponent:11;
85	unsigned	sign:1;
86} double_msw;
87
88typedef struct {
89	unsigned	exponent:15;
90	unsigned	sign:1;
91	unsigned	unused:16;
92} extended_msw;
93
94typedef struct {
95	unsigned	significand:16;
96	unsigned	exponent:15;
97	unsigned	sign:1;
98} quadruple_msw;
99
100typedef struct {
101	single_msw	msw;
102} single_formatted;
103
104typedef struct {
105	unsigned	significand2;
106	double_msw	msw;
107} double_formatted;
108
109typedef struct {
110	unsigned	significand2;
111	unsigned	significand;
112	extended_msw	msw;
113} extended_formatted;
114
115typedef struct {
116	unsigned	significand4;
117	unsigned	significand3;
118	unsigned	significand2;
119	quadruple_msw	msw;
120} quadruple_formatted;
121
122#else
123
124typedef struct {
125	unsigned	sign:1;
126	unsigned	exponent:8;
127	unsigned	significand:23;
128} single_msw;
129
130typedef struct {
131	unsigned	sign:1;
132	unsigned	exponent:11;
133	unsigned	significand:20;
134} double_msw;
135
136typedef struct {
137	unsigned	sign:1;
138	unsigned	exponent:15;
139	unsigned	unused:16;
140} extended_msw;
141
142typedef struct {
143	unsigned	sign:1;
144	unsigned	exponent:15;
145	unsigned	significand:16;
146} quadruple_msw;
147
148typedef struct {
149	single_msw	msw;
150} single_formatted;
151
152typedef struct {
153	double_msw	msw;
154	unsigned	significand2;
155} double_formatted;
156
157typedef struct {
158	extended_msw	msw;
159	unsigned	significand;
160	unsigned	significand2;
161} extended_formatted;
162
163typedef struct {
164	quadruple_msw   msw;
165	unsigned	significand2;
166	unsigned	significand3;
167	unsigned	significand4;
168} quadruple_formatted;
169
170#endif
171
172typedef union {
173	single_formatted f;
174	single		x;
175} single_equivalence;
176
177typedef union {
178	double_formatted f;
179	double		x;
180} double_equivalence;
181
182typedef union {
183	extended_formatted f;
184	extended	x;
185} extended_equivalence;
186
187typedef union {
188	quadruple_formatted f;
189	quadruple	x;
190} quadruple_equivalence;
191
192/*
193 * Multiple precision floating point type.  This type is suitable
194 * for representing positive floating point numbers of variable
195 * precision in either binary or decimal.  The bsignificand array
196 * holds the digits of a multi-word integer, stored least significant
197 * digit first, in either radix 2^16 or 10^4.  blength is the
198 * length of the significand array.  bexponent is a power of two
199 * or ten, so that the value represented is
200 *
201 *   2^(bexponent) * sum (bsignificand[i] * 2^(i*16))
202 *
203 * if binary, or
204 *
205 *   10^(bexponent) * sum (bsignificand[i] * 10^(i*4))
206 *
207 * if decimal, where the sum runs from i = 0 to blength - 1.
208 * (Whether the representation is binary or decimal is implied
209 * from context.)  bsize indicates the size of the significand
210 * array and may be larger than _BIG_FLOAT_SIZE if storage has
211 * been allocated at runtime.
212 */
213
214#define	_BIG_FLOAT_SIZE	(DECIMAL_STRING_LENGTH/2)
215
216typedef struct {
217	unsigned short  bsize;
218	unsigned short  blength;
219	short int	bexponent;
220	unsigned short	bsignificand[_BIG_FLOAT_SIZE];
221} _big_float;
222
223/* structure for storing IEEE modes and status flags */
224typedef struct {
225	int	status, mode;
226} __ieee_flags_type;
227
228
229/* PRIVATE GLOBAL VARIABLES */
230
231/*
232 * Thread-specific flags to indicate whether any NaNs or infinities
233 * have been read or written.
234 */
235extern int *_thrp_get_inf_read(void);
236extern int *_thrp_get_inf_written(void);
237extern int *_thrp_get_nan_read(void);
238extern int *_thrp_get_nan_written(void);
239
240#define	__inf_read		(*(int *)_thrp_get_inf_read())
241#define	__inf_written		(*(int *)_thrp_get_inf_written())
242#define	__nan_read		(*(int *)_thrp_get_nan_read())
243#define	__nan_written		(*(int *)_thrp_get_nan_written())
244
245/*
246 * Powers of 5 in base 2**16 and powers of 2 in base 10**4.
247 *
248 * __tbl_10_small_digits	contains
249 *	5**0,
250 *	5**1, ...
251 *	5**__TBL_10_SMALL_SIZE-1
252 * __tbl_10_big_digits		contains
253 *	5**0,
254 *	5**__TBL_10_SMALL_SIZE, ...
255 *	5**__TBL_10_SMALL_SIZE*(__TBL_10_BIG_SIZE-1)
256 * __tbl_10_huge_digits		contains
257 *	5**0,
258 *	5**__TBL_10_SMALL_SIZE*__TBL_10_BIG_SIZE, ...
259 *	5**__TBL_10_SMALL_SIZE*__TBL_10_BIG_SIZE*(__TBL_10_HUGE_SIZE-1)
260 *
261 * so that any power of 5 from 5**0 to
262 *	5**__TBL_10_SMALL_SIZE*__TBL_10_BIG_SIZE*__TBL_10_HUGE_SIZE
263 * can be represented as a product of at most three table entries.
264 *
265 * Similarly any power of 2 from 2**0 to
266 *	2**__TBL_2_SMALL_SIZE*__TBL_2_BIG_SIZE*__TBL_2_HUGE_SIZE
267 * can be represented as a product of at most three table entries.
268 *
269 * Since the powers vary greatly in size, the tables are condensed:
270 * entry i in table x is stored in
271 *	x_digits[x_start[i]] (least significant)
272 * through
273 *	x_digits[x_start[i+1]-1] (most significant)
274 */
275
276#define	__TBL_10_SMALL_SIZE	64
277#define	__TBL_10_BIG_SIZE	16
278#define	__TBL_10_HUGE_SIZE	6
279
280extern const unsigned short
281	__tbl_10_small_digits[], __tbl_10_small_start[],
282	__tbl_10_big_digits[], __tbl_10_big_start[],
283	__tbl_10_huge_digits[], __tbl_10_huge_start[];
284
285#define	__TBL_2_SMALL_SIZE	176
286#define	__TBL_2_BIG_SIZE	16
287#define	__TBL_2_HUGE_SIZE	6
288
289extern const unsigned short
290	__tbl_2_small_digits[], __tbl_2_small_start[],
291	__tbl_2_big_digits[], __tbl_2_big_start[],
292	__tbl_2_huge_digits[], __tbl_2_huge_start[];
293
294/*
295 * Powers of ten.  For i = 0, 1, ..., __TBL_TENS_MAX, __tbl_tens[i]
296 * = 10^i rounded to double precision.  (10^i is representable exactly
297 * in double precision for i <= __TBL_TENS_EXACT.)
298 */
299
300#define	__TBL_TENS_EXACT	22
301#define	__TBL_TENS_MAX		49
302
303extern const double __tbl_tens[];
304
305
306/* PRIVATE FUNCTIONS */
307
308extern void __base_conversion_set_exception(fp_exception_field_type);
309
310extern void __four_digits_quick(unsigned short, char *);
311
312extern int __fast_double_to_decimal(double *dd, decimal_mode *pm,
313		decimal_record *pd, fp_exception_field_type *ps);
314
315extern void __pack_single(unpacked *, single *, enum fp_direction_type,
316		fp_exception_field_type *);
317extern void __pack_double(unpacked *, double *, enum fp_direction_type,
318		fp_exception_field_type *);
319extern void __pack_extended(unpacked *, extended *, enum fp_direction_type,
320		fp_exception_field_type *);
321extern void __pack_quadruple(unpacked *, quadruple *,
322		enum fp_direction_type, fp_exception_field_type *);
323
324extern void __infnanstring(enum fp_class_type cl, int ndigits, char *buf);
325
326extern void __big_float_times_power(_big_float *pbf, int mult, int n,
327		int precision, _big_float **pnewbf);
328
329extern void __get_ieee_flags(__ieee_flags_type *);
330extern void __set_ieee_flags(__ieee_flags_type *);
331
332extern double __mul_set(double, double, int *);
333extern double __div_set(double, double, int *);
334extern double __dabs(double *);
335
336#if defined(sparc) || defined(__sparc)
337extern enum fp_direction_type _QgetRD(void);
338#endif
339
340#include "base_inlines.h"
341
342#endif	/* BASE_CONVERSION_H */
343