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