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 62 typedef 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 76 typedef struct { 77 unsigned significand:23; 78 unsigned exponent:8; 79 unsigned sign:1; 80 } single_msw; 81 82 typedef struct { 83 unsigned significand:20; 84 unsigned exponent:11; 85 unsigned sign:1; 86 } double_msw; 87 88 typedef struct { 89 unsigned exponent:15; 90 unsigned sign:1; 91 unsigned unused:16; 92 } extended_msw; 93 94 typedef struct { 95 unsigned significand:16; 96 unsigned exponent:15; 97 unsigned sign:1; 98 } quadruple_msw; 99 100 typedef struct { 101 single_msw msw; 102 } single_formatted; 103 104 typedef struct { 105 unsigned significand2; 106 double_msw msw; 107 } double_formatted; 108 109 typedef struct { 110 unsigned significand2; 111 unsigned significand; 112 extended_msw msw; 113 } extended_formatted; 114 115 typedef struct { 116 unsigned significand4; 117 unsigned significand3; 118 unsigned significand2; 119 quadruple_msw msw; 120 } quadruple_formatted; 121 122 #else 123 124 typedef struct { 125 unsigned sign:1; 126 unsigned exponent:8; 127 unsigned significand:23; 128 } single_msw; 129 130 typedef struct { 131 unsigned sign:1; 132 unsigned exponent:11; 133 unsigned significand:20; 134 } double_msw; 135 136 typedef struct { 137 unsigned sign:1; 138 unsigned exponent:15; 139 unsigned unused:16; 140 } extended_msw; 141 142 typedef struct { 143 unsigned sign:1; 144 unsigned exponent:15; 145 unsigned significand:16; 146 } quadruple_msw; 147 148 typedef struct { 149 single_msw msw; 150 } single_formatted; 151 152 typedef struct { 153 double_msw msw; 154 unsigned significand2; 155 } double_formatted; 156 157 typedef struct { 158 extended_msw msw; 159 unsigned significand; 160 unsigned significand2; 161 } extended_formatted; 162 163 typedef struct { 164 quadruple_msw msw; 165 unsigned significand2; 166 unsigned significand3; 167 unsigned significand4; 168 } quadruple_formatted; 169 170 #endif 171 172 typedef union { 173 single_formatted f; 174 single x; 175 } single_equivalence; 176 177 typedef union { 178 double_formatted f; 179 double x; 180 } double_equivalence; 181 182 typedef union { 183 extended_formatted f; 184 extended x; 185 } extended_equivalence; 186 187 typedef 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 216 typedef 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 */ 224 typedef 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 */ 235 extern int *_thrp_get_inf_read(void); 236 extern int *_thrp_get_inf_written(void); 237 extern int *_thrp_get_nan_read(void); 238 extern 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 280 extern 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 289 extern 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 303 extern const double __tbl_tens[]; 304 305 306 /* PRIVATE FUNCTIONS */ 307 308 extern void __base_conversion_set_exception(fp_exception_field_type); 309 310 extern void __four_digits_quick(unsigned short, char *); 311 312 extern int __fast_double_to_decimal(double *dd, decimal_mode *pm, 313 decimal_record *pd, fp_exception_field_type *ps); 314 315 extern void __pack_single(unpacked *, single *, enum fp_direction_type, 316 fp_exception_field_type *); 317 extern void __pack_double(unpacked *, double *, enum fp_direction_type, 318 fp_exception_field_type *); 319 extern void __pack_extended(unpacked *, extended *, enum fp_direction_type, 320 fp_exception_field_type *); 321 extern void __pack_quadruple(unpacked *, quadruple *, 322 enum fp_direction_type, fp_exception_field_type *); 323 324 extern void __infnanstring(enum fp_class_type cl, int ndigits, char *buf); 325 326 extern void __big_float_times_power(_big_float *pbf, int mult, int n, 327 int precision, _big_float **pnewbf); 328 329 extern void __get_ieee_flags(__ieee_flags_type *); 330 extern void __set_ieee_flags(__ieee_flags_type *); 331 332 extern double __mul_set(double, double, int *); 333 extern double __div_set(double, double, int *); 334 extern double __dabs(double *); 335 336 #if defined(sparc) || defined(__sparc) 337 extern enum fp_direction_type _QgetRD(void); 338 #endif 339 340 #include "base_inlines.h" 341 342 #endif /* BASE_CONVERSION_H */ 343