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