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 number into a 64-bit int. 42 */ 43 long long 44 __dtoll(double dval) 45 { 46 int i0, i1; /* bitslam */ 47 int exp; /* exponent */ 48 int m0; /* most significant word of mantissa */ 49 unsigned int m1; /* least sig. word of mantissa */ 50 unsigned int _fp_current_exceptions = 0; 51 union { 52 int i[2]; 53 double d; 54 } u; 55 56 /* 57 * Extract the exponent and check boundary conditions. 58 * Notice that the exponent is equal to the bit number where 59 * we want the most significant bit to live. 60 */ 61 u.d = dval; 62 i0 = u.i[0]; 63 i1 = u.i[1]; 64 65 exp = ((i0 >> 20) & 0x7ff) - 0x3ff; 66 if (exp < 0) { 67 return ((long long)0); /* abs(x) < 1.0, so round to 0 */ 68 } else if (exp > 62) { 69 /* 70 * fp_invalid NOT raised if <i0,i1> == LLONG_MIN 71 */ 72 if (i0 >= 0 || exp != 63 || (i0 & 0xfffff) != 0 || i1 != 0) { 73 /* 74 * abs(x) > MAXLLONG; return {MIN,MAX}LLONG and as 75 * overflow, Inf, NaN set fp_invalid exception 76 */ 77 _fp_current_exceptions |= (1 << (int)fp_invalid); 78 (void) _Q_set_exception(_fp_current_exceptions); 79 } 80 if (i0 < 0) 81 return (LLONG_MIN); 82 else 83 return (LLONG_MAX); /* MAXLONG */ 84 } 85 86 /* Extract the mantissa. */ 87 88 m0 = 0x40000000 | ((i0 << 10) & 0x3ffffc00) | ((i1 >> 22) & 0x3ff); 89 m1 = i1 << 10; 90 91 /* 92 * The most significant bit of the mantissa is now in bit 62 of m0:m1. 93 * Shift right by (62 - exp) bits. 94 */ 95 switch (exp) { 96 case 62: 97 break; 98 case 30: 99 m1 = m0; 100 m0 = 0; 101 break; 102 default: 103 if (exp > 30) { 104 m1 = (m0 << (exp - 30)) | 105 (m1 >> (62 - exp)) & ~(UINT_MAX << (exp - 30)); 106 m0 >>= 62 - exp; 107 } else { 108 m1 = m0 >> (30 - exp); 109 m0 = 0; 110 } 111 break; 112 } 113 114 if (i0 < 0) { 115 m0 = ~m0; 116 m1 = ~m1; 117 if (++m1 == 0) 118 m0++; 119 } 120 121 (void) _Q_set_exception(_fp_current_exceptions); 122 return ((long long)(((unsigned long long)m0 << 32) | m1)); 123 } 124 125 /* 126 * Convert a floating point number into a 64-bit int. 127 */ 128 long long 129 __ftoll(float fval) 130 { 131 int i0; 132 int exp; /* exponent */ 133 int m0; /* most significant word of mantissa */ 134 unsigned int m1; /* least sig. word of mantissa */ 135 unsigned int _fp_current_exceptions = 0; 136 union { 137 int i; 138 float f; 139 } u; 140 141 /* 142 * Extract the exponent and check boundary conditions. 143 * Notice that the exponent is equal to the bit number where 144 * we want the most significant bit to live. 145 */ 146 u.f = fval; 147 i0 = u.i; 148 149 exp = ((i0 >> 23) & 0xff) - 0x7f; 150 if (exp < 0) { 151 return ((long long) 0); /* abs(x) < 1.0, so round to 0 */ 152 } else if (exp > 62) { 153 /* 154 * fp_invalid NOT raised if <i0> == LLONG_MIN 155 */ 156 if (i0 >= 0 || exp != 63 || (i0 & 0x7fffff) != 0) { 157 /* 158 * abs(x) > MAXLLONG; return {MIN,MAX}LLONG and as 159 * overflow, Inf, NaN set fp_invalid exception 160 */ 161 _fp_current_exceptions |= (1 << (int)fp_invalid); 162 (void) _Q_set_exception(_fp_current_exceptions); 163 } 164 if (i0 < 0) 165 return (LLONG_MIN); 166 else 167 return (LLONG_MAX); /* MAXLONG */ 168 } 169 170 /* Extract the mantissa. */ 171 172 m0 = 0x40000000 | (i0 << 7) & 0x3fffff80; 173 m1 = 0; 174 175 /* 176 * The most significant bit of the mantissa is now in bit 62 of m0:m1. 177 * Shift right by (62 - exp) bits. 178 */ 179 switch (exp) { 180 case 62: 181 break; 182 case 30: 183 m1 = m0; 184 m0 = 0; 185 break; 186 default: 187 if (exp > 30) { 188 m1 = m0 << (exp - 30); 189 m0 >>= 62 - exp; 190 } else { 191 m1 = m0 >> (30 - exp); 192 m0 = 0; 193 } 194 break; 195 } 196 197 if (i0 < 0) { 198 m0 = ~m0; 199 m1 = ~m1; 200 if (++m1 == 0) 201 m0++; 202 } 203 204 (void) _Q_set_exception(_fp_current_exceptions); 205 return ((long long)(((unsigned long long)m0 << 32) | m1)); 206 } 207 208 /* 209 * Convert an extended precision floating point number into a 64-bit int. 210 */ 211 long long 212 _Q_qtoll(long double longdbl) 213 { 214 int i0; 215 unsigned int i1, i2; /* a long double is 128-bit in length */ 216 int *plngdbl = (int *)&longdbl; 217 int exp; /* exponent */ 218 int m0; /* most significant word of mantissa */ 219 unsigned int m1; /* least sig. word of mantissa */ 220 unsigned int _fp_current_exceptions = 0; 221 222 /* 223 * Only 96-bits of precision used 224 */ 225 i0 = plngdbl[0]; 226 i1 = plngdbl[1]; 227 i2 = plngdbl[2]; 228 229 /* 230 * Extract the exponent and check boundary conditions. 231 * Notice that the exponent is equal to the bit number where 232 * we want the most significant bit to live. 233 */ 234 exp = ((i0 >> 16) & 0x7fff) - 0x3fff; 235 if (exp < 0) { 236 return ((long long)0); /* abs(x) < 1.0, so round to 0 */ 237 } else if (exp > 62) { 238 /* 239 * fp_invalid NOT raised if <i0,i1,i2,i3> when chopped to 240 * 64 bits == LLONG_MIN 241 */ 242 if (i0 >= 0 || exp != 63 || (i0 & 0xffff) != 0 || i1 != 0 || 243 (i2 & 0xfffe0000) != 0) { 244 /* 245 * abs(x) > MAXLLONG; return {MIN,MAX}LLONG and as 246 * overflow, Inf, NaN set fp_invalid exception 247 */ 248 _fp_current_exceptions |= (1 << (int)fp_invalid); 249 (void) _Q_set_exception(_fp_current_exceptions); 250 } 251 if (i0 < 0) 252 return (LLONG_MIN); 253 else 254 return (LLONG_MAX); /* MAXLONG */ 255 } 256 257 /* Extract the mantissa. */ 258 259 m0 = 0x40000000 | ((i0 << 14) & 0x3fffc000) | ((i1 >> 18) & 0x3fff); 260 m1 = (i1 << 14) | ((i2 >> 18) & 0x3fff); 261 262 /* 263 * The most significant bit of the mantissa is now in bit 62 of m0:m1. 264 * Shift right by (62 - exp) bits. 265 */ 266 switch (exp) { 267 case 62: 268 break; 269 case 30: 270 m1 = m0; 271 m0 = 0; 272 break; 273 default: 274 if (exp > 30) { 275 m1 = (m0 << (exp - 30)) | 276 (m1 >> (62 - exp)) & ~(UINT_MAX << (exp - 30)); 277 m0 >>= 62 - exp; 278 } else { 279 m1 = m0 >> (30 - exp); 280 m0 = 0; 281 } 282 break; 283 } 284 285 if (i0 < 0) { 286 m0 = ~m0; 287 m1 = ~m1; 288 if (++m1 == 0) 289 m0++; 290 } 291 292 (void) _Q_set_exception(_fp_current_exceptions); 293 return ((long long)(((unsigned long long)m0 << 32) | m1)); 294 } 295