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, Version 1.0 only 6 * (the "License"). You may not use this file except in compliance 7 * with the License. 8 * 9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10 * or http://www.opensolaris.org/os/licensing. 11 * See the License for the specific language governing permissions 12 * and limitations under the License. 13 * 14 * When distributing Covered Code, include this CDDL HEADER in each 15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16 * If applicable, add the following below this CDDL HEADER, with the 17 * fields enclosed by brackets "[]" replaced with your own identifying 18 * information: Portions Copyright [yyyy] [name of copyright owner] 19 * 20 * CDDL HEADER END 21 */ 22 /* 23 * Copyright 2004 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 #pragma ident "%Z%%M% %I% %E% SMI" 28 29 #include "synonyms.h" 30 #include <sys/isa_defs.h> 31 #include <floatingpoint.h> 32 #include <limits.h> 33 #include "libc.h" 34 35 /* 36 * Ensure that this "portable" code is only used on big-endian ISAs 37 */ 38 #if !defined(_BIG_ENDIAN) || defined(_LITTLE_ENDIAN) 39 #error "big-endian only!" 40 #endif 41 42 /* 43 * Convert a double precision floating point number into a 64-bit int. 44 */ 45 long long 46 __dtoll(double dval) 47 { 48 int i0, i1; /* bitslam */ 49 int exp; /* exponent */ 50 int m0; /* most significant word of mantissa */ 51 unsigned int m1; /* least sig. word of mantissa */ 52 unsigned int _fp_current_exceptions = 0; 53 union { 54 int i[2]; 55 double d; 56 } u; 57 58 /* 59 * Extract the exponent and check boundary conditions. 60 * Notice that the exponent is equal to the bit number where 61 * we want the most significant bit to live. 62 */ 63 u.d = dval; 64 i0 = u.i[0]; 65 i1 = u.i[1]; 66 67 exp = ((i0 >> 20) & 0x7ff) - 0x3ff; 68 if (exp < 0) { 69 return ((long long)0); /* abs(x) < 1.0, so round to 0 */ 70 } else if (exp > 62) { 71 /* 72 * fp_invalid NOT raised if <i0,i1> == LLONG_MIN 73 */ 74 if (i0 >= 0 || exp != 63 || (i0 & 0xfffff) != 0 || i1 != 0) { 75 /* 76 * abs(x) > MAXLLONG; return {MIN,MAX}LLONG and as 77 * overflow, Inf, NaN set fp_invalid exception 78 */ 79 _fp_current_exceptions |= (1 << (int)fp_invalid); 80 (void) _Q_set_exception(_fp_current_exceptions); 81 } 82 if (i0 < 0) 83 return (LLONG_MIN); 84 else 85 return (LLONG_MAX); /* MAXLONG */ 86 } 87 88 /* Extract the mantissa. */ 89 90 m0 = 0x40000000 | ((i0 << 10) & 0x3ffffc00) | ((i1 >> 22) & 0x3ff); 91 m1 = i1 << 10; 92 93 /* 94 * The most significant bit of the mantissa is now in bit 62 of m0:m1. 95 * Shift right by (62 - exp) bits. 96 */ 97 switch (exp) { 98 case 62: 99 break; 100 case 30: 101 m1 = m0; 102 m0 = 0; 103 break; 104 default: 105 if (exp > 30) { 106 m1 = (m0 << (exp - 30)) | 107 (m1 >> (62 - exp)) & ~(-1 << (exp - 30)); 108 m0 >>= 62 - exp; 109 } else { 110 m1 = m0 >> (30 - exp); 111 m0 = 0; 112 } 113 break; 114 } 115 116 if (i0 < 0) { 117 m0 = ~m0; 118 m1 = ~m1; 119 if (++m1 == 0) 120 m0++; 121 } 122 123 (void) _Q_set_exception(_fp_current_exceptions); 124 return ((long long)(((unsigned long long)m0 << 32) | m1)); 125 } 126 127 /* 128 * Convert a floating point number into a 64-bit int. 129 */ 130 long long 131 __ftoll(float fval) 132 { 133 int i0; 134 int exp; /* exponent */ 135 int m0; /* most significant word of mantissa */ 136 unsigned int m1; /* least sig. word of mantissa */ 137 unsigned int _fp_current_exceptions = 0; 138 union { 139 int i; 140 float f; 141 } u; 142 143 /* 144 * Extract the exponent and check boundary conditions. 145 * Notice that the exponent is equal to the bit number where 146 * we want the most significant bit to live. 147 */ 148 u.f = fval; 149 i0 = u.i; 150 151 exp = ((i0 >> 23) & 0xff) - 0x7f; 152 if (exp < 0) { 153 return ((long long) 0); /* abs(x) < 1.0, so round to 0 */ 154 } else if (exp > 62) { 155 /* 156 * fp_invalid NOT raised if <i0> == LLONG_MIN 157 */ 158 if (i0 >= 0 || exp != 63 || (i0 & 0x7fffff) != 0) { 159 /* 160 * abs(x) > MAXLLONG; return {MIN,MAX}LLONG and as 161 * overflow, Inf, NaN set fp_invalid exception 162 */ 163 _fp_current_exceptions |= (1 << (int)fp_invalid); 164 (void) _Q_set_exception(_fp_current_exceptions); 165 } 166 if (i0 < 0) 167 return (LLONG_MIN); 168 else 169 return (LLONG_MAX); /* MAXLONG */ 170 } 171 172 /* Extract the mantissa. */ 173 174 m0 = 0x40000000 | (i0 << 7) & 0x3fffff80; 175 m1 = 0; 176 177 /* 178 * The most significant bit of the mantissa is now in bit 62 of m0:m1. 179 * Shift right by (62 - exp) bits. 180 */ 181 switch (exp) { 182 case 62: 183 break; 184 case 30: 185 m1 = m0; 186 m0 = 0; 187 break; 188 default: 189 if (exp > 30) { 190 m1 = m0 << (exp - 30); 191 m0 >>= 62 - exp; 192 } else { 193 m1 = m0 >> (30 - exp); 194 m0 = 0; 195 } 196 break; 197 } 198 199 if (i0 < 0) { 200 m0 = ~m0; 201 m1 = ~m1; 202 if (++m1 == 0) 203 m0++; 204 } 205 206 (void) _Q_set_exception(_fp_current_exceptions); 207 return ((long long)(((unsigned long long)m0 << 32) | m1)); 208 } 209 210 /* 211 * Convert an extended precision floating point number into a 64-bit int. 212 */ 213 long long 214 _Q_qtoll(long double longdbl) 215 { 216 int i0; 217 unsigned int i1, i2; /* a long double is 128-bit in length */ 218 int *plngdbl = (int *)&longdbl; 219 int exp; /* exponent */ 220 int m0; /* most significant word of mantissa */ 221 unsigned int m1; /* least sig. word of mantissa */ 222 unsigned int _fp_current_exceptions = 0; 223 224 /* 225 * Only 96-bits of precision used 226 */ 227 i0 = plngdbl[0]; 228 i1 = plngdbl[1]; 229 i2 = plngdbl[2]; 230 231 /* 232 * Extract the exponent and check boundary conditions. 233 * Notice that the exponent is equal to the bit number where 234 * we want the most significant bit to live. 235 */ 236 exp = ((i0 >> 16) & 0x7fff) - 0x3fff; 237 if (exp < 0) { 238 return ((long long)0); /* abs(x) < 1.0, so round to 0 */ 239 } else if (exp > 62) { 240 /* 241 * fp_invalid NOT raised if <i0,i1,i2,i3> when chopped to 242 * 64 bits == LLONG_MIN 243 */ 244 if (i0 >= 0 || exp != 63 || (i0 & 0xffff) != 0 || i1 != 0 || 245 (i2 & 0xfffe0000) != 0) { 246 /* 247 * abs(x) > MAXLLONG; return {MIN,MAX}LLONG and as 248 * overflow, Inf, NaN set fp_invalid exception 249 */ 250 _fp_current_exceptions |= (1 << (int)fp_invalid); 251 (void) _Q_set_exception(_fp_current_exceptions); 252 } 253 if (i0 < 0) 254 return (LLONG_MIN); 255 else 256 return (LLONG_MAX); /* MAXLONG */ 257 } 258 259 /* Extract the mantissa. */ 260 261 m0 = 0x40000000 | ((i0 << 14) & 0x3fffc000) | ((i1 >> 18) & 0x3fff); 262 m1 = (i1 << 14) | ((i2 >> 18) & 0x3fff); 263 264 /* 265 * The most significant bit of the mantissa is now in bit 62 of m0:m1. 266 * Shift right by (62 - exp) bits. 267 */ 268 switch (exp) { 269 case 62: 270 break; 271 case 30: 272 m1 = m0; 273 m0 = 0; 274 break; 275 default: 276 if (exp > 30) { 277 m1 = (m0 << (exp - 30)) | 278 (m1 >> (62 - exp)) & ~(-1 << (exp - 30)); 279 m0 >>= 62 - exp; 280 } else { 281 m1 = m0 >> (30 - exp); 282 m0 = 0; 283 } 284 break; 285 } 286 287 if (i0 < 0) { 288 m0 = ~m0; 289 m1 = ~m1; 290 if (++m1 == 0) 291 m0++; 292 } 293 294 (void) _Q_set_exception(_fp_current_exceptions); 295 return ((long long)(((unsigned long long)m0 << 32) | m1)); 296 } 297