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 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