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 #include "lint.h" 28 #include <sys/isa_defs.h> 29 #include <floatingpoint.h> 30 #include <limits.h> 31 #include "libc.h" 32 33 /* 34 * Ensure that this "portable" code is only used on big-endian ISAs 35 */ 36 #if !defined(_BIG_ENDIAN) || defined(_LITTLE_ENDIAN) 37 #error "big-endian only!" 38 #endif 39 40 /* 41 * Convert a double precision floating point # into a 64-bit unsigned int. 42 * 43 * For compatibility with Sun's other conversion routines, pretend result 44 * is signed if input is negative. 45 */ 46 unsigned long long 47 __dtoull(double dval) 48 { 49 int i0; /* bitslam */ 50 unsigned i1; /* bitslam */ 51 int exp; /* exponent */ 52 unsigned int m0; /* most significant word of mantissa */ 53 unsigned int m1; /* least sig. word of mantissa */ 54 unsigned int _fp_current_exceptions = 0; 55 union { 56 int i[2]; 57 double d; 58 } u; 59 60 /* 61 * Extract the exponent and check boundary conditions. 62 * Notice that the exponent is equal to the bit number where 63 * we want the most significant bit to live. 64 */ 65 u.d = dval; 66 i0 = u.i[0]; 67 i1 = u.i[1]; 68 69 exp = ((i0 >> 20) & 0x7ff) - 0x3ff; 70 if (exp < 0) { 71 /* abs(x) < 1.0, so round to 0 */ 72 return ((unsigned long long)0); 73 } else if (exp > 63) { 74 /* 75 * abs(x) > MAXLLONG; return {MIN,MAX}ULLONG and as 76 * overflow, Inf, NaN set fp_invalid exception 77 */ 78 _fp_current_exceptions |= (1 << (int)fp_invalid); 79 (void) _Q_set_exception(_fp_current_exceptions); 80 if (i0 < 0) 81 return ((unsigned long long)LLONG_MIN); 82 else 83 return (ULLONG_MAX); /* MAXLONG */ 84 } 85 86 /* Extract the mantissa. */ 87 88 m0 = 0x80000000 | ((i0 << 11) & 0x7ffff800) | ((i1 >> 21) & 0x7ff); 89 m1 = i1 << 11; 90 91 /* 92 * The most significant bit of the mantissa is now in bit 63 of m0:m1. 93 * Shift right by (63 - exp) bits. 94 */ 95 switch (exp) { 96 case 63: 97 break; 98 case 31: 99 m1 = m0; 100 m0 = 0; 101 break; 102 default: 103 if (exp > 31) { 104 m1 = (m0 << (exp - 31)) | (m1 >> (63 - exp)); 105 m0 = (m0 >> (63 - exp)); 106 } else { 107 m1 = (m0 >> (31 - exp)); 108 m0 = 0; 109 } 110 break; 111 } 112 113 if (i0 < 0) { 114 if ((int)m0 < 0) { /* x < MINLLONG; return MINLLONG */ 115 m0 = 0x80000000; 116 m1 = 0; 117 } else { 118 m0 = ~m0; 119 m1 = ~m1; 120 if (++m1 == 0) 121 m0++; 122 } 123 } 124 125 (void) _Q_set_exception(_fp_current_exceptions); 126 return (((unsigned long long)m0 << 32) | m1); 127 } 128 129 /* 130 * Convert a floating point number into a 64-bit unsigned int. 131 * 132 * For compatibility with Sun's other conversion routines, pretend result 133 * is signed if input is negative. 134 */ 135 unsigned long long 136 __ftoull(float fval) 137 { 138 int i0; /* bitslam */ 139 int exp; /* exponent */ 140 unsigned int m0; /* most significant word of mantissa */ 141 unsigned int m1; /* least sig. word of mantissa */ 142 unsigned int _fp_current_exceptions = 0; 143 union { 144 int i; 145 float f; 146 } u; 147 148 /* 149 * Extract the exponent and check boundary conditions. 150 * Notice that the exponent is equal to the bit number where 151 * we want the most significant bit to live. 152 */ 153 u.f = fval; 154 i0 = u.i; 155 156 exp = ((i0 >> 23) & 0xff) - 0x7f; 157 if (exp < 0) { 158 /* abs(x) < 1.0, so round to 0 */ 159 return ((unsigned long long)0); 160 } else if (exp > 63) { 161 /* 162 * abs(x) > MAXLLONG; return {MIN,MAX}ULLONG and as 163 * overflow, Inf, NaN set fp_invalid exception 164 */ 165 _fp_current_exceptions |= (1 << (int)fp_invalid); 166 (void) _Q_set_exception(_fp_current_exceptions); 167 if (i0 < 0) 168 return ((unsigned long long)LLONG_MIN); 169 else 170 return (ULLONG_MAX); /* MAXLONG */ 171 } 172 173 /* Extract the mantissa. */ 174 175 m0 = 0x80000000 | (i0 << 8) & 0x7fffff00; 176 m1 = 0; 177 178 /* 179 * The most significant bit of the mantissa is now in bit 63 of m0:m1. 180 * Shift right by (63 - exp) bits. 181 */ 182 switch (exp) { 183 case 63: 184 break; 185 case 31: 186 m1 = m0; 187 m0 = 0; 188 break; 189 default: 190 if (exp > 31) { 191 m1 = m0 << (exp - 31); 192 m0 = (m0 >> (63 - exp)); 193 } else { 194 m1 = (m0 >> (31 - exp)); 195 m0 = 0; 196 } 197 break; 198 } 199 200 if (i0 < 0) { 201 if ((int)m0 < 0) { /* x < MINLLONG; return MINLLONG */ 202 m0 = 0x80000000; 203 m1 = 0; 204 } else { 205 m0 = ~m0; 206 m1 = ~m1; 207 if (++m1 == 0) 208 m0++; 209 } 210 } 211 212 (void) _Q_set_exception(_fp_current_exceptions); 213 return (((unsigned long long)m0 << 32) | m1); 214 } 215 216 /* 217 * Convert an extended precision floating point # into a 64-bit unsigned int. 218 * 219 * For compatibility with Sun's other conversion routines, pretend result 220 * is signed if input is negative. 221 */ 222 unsigned long long 223 _Q_qtoull(long double ld) 224 { 225 int i0; 226 unsigned int i1, i2; /* a long double is 128-bit in length */ 227 int exp; /* exponent */ 228 unsigned int m0; /* most significant word of mantissa */ 229 unsigned int m1; /* least sig. word of mantissa */ 230 unsigned int _fp_current_exceptions = 0; 231 int *plngdbl = (int *)&ld; 232 233 /* Only 96-bits of precision used */ 234 i0 = plngdbl[0]; 235 i1 = plngdbl[1]; 236 i2 = plngdbl[2]; 237 238 /* 239 * Extract the exponent and check boundary conditions. 240 * Notice that the exponent is equal to the bit number where 241 * we want the most significant bit to live. 242 */ 243 exp = ((i0 >> 16) & 0x7fff) - 0x3fff; 244 if (exp < 0) { 245 return ((long long)0); /* abs(x) < 1.0, so round to 0 */ 246 } else if (exp > 63) { 247 /* 248 * abs(x) > MAXLLONG; return {MIN,MAX}ULLONG and as 249 * overflow, Inf, NaN set fp_invalid exception 250 */ 251 _fp_current_exceptions |= (1 << (int)fp_invalid); 252 (void) _Q_set_exception(_fp_current_exceptions); 253 if (i0 < 0) 254 return ((unsigned long long)LLONG_MIN); 255 else 256 return (ULLONG_MAX); /* MAXLONG */ 257 } 258 259 /* Extract the mantissa. */ 260 261 m0 = 0x80000000 | ((i0<<15) & 0x7fff8000) | ((i1>>17) & 0x7fff); 262 m1 = (i1 << 15) | ((i2 >> 17) & 0x7fff); 263 264 /* 265 * The most significant bit of the mantissa is now in bit 63 of m0:m1. 266 * Shift right by (63 - exp) bits. 267 */ 268 switch (exp) { 269 case 63: 270 break; 271 case 31: 272 m1 = m0; 273 m0 = 0; 274 break; 275 default: 276 if (exp > 31) { 277 m1 = (m0 << (exp - 31)) | (m1 >> (63 - exp)); 278 m0 = (m0 >> (63 - exp)); 279 } else { 280 m1 = (m0 >> (31 - exp)); 281 m0 = 0; 282 } 283 break; 284 } 285 286 if (i0 < 0) { 287 if ((int)m0 < 0) { /* x < MINLLONG; return MINLLONG */ 288 m0 = 0x80000000; 289 m1 = 0; 290 } else { 291 m0 = ~m0; 292 m1 = ~m1; 293 if (++m1 == 0) 294 m0++; 295 } 296 } 297 298 (void) _Q_set_exception(_fp_current_exceptions); 299 return (((unsigned long long)m0 << 32) | m1); 300 } 301