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 2011 Nexenta Systems, Inc. All rights reserved. 24 */ 25 /* 26 * Copyright 2006 Sun Microsystems, Inc. All rights reserved. 27 * Use is subject to license terms. 28 */ 29 30 #pragma weak frexpl = __frexpl 31 32 #include "libm.h" 33 34 #if defined(__sparc) 35 36 long double 37 __frexpl(long double x, int *exp) { 38 union { 39 unsigned i[4]; 40 long double q; 41 } xx; 42 unsigned hx; 43 int e, s; 44 45 xx.q = x; 46 hx = xx.i[0] & ~0x80000000; 47 48 if (hx >= 0x7fff0000) { /* x is infinite or NaN */ 49 *exp = 0; 50 return (x); 51 } 52 53 e = 0; 54 if (hx < 0x00010000) { /* x is subnormal or zero */ 55 if ((hx | xx.i[1] | xx.i[2] | xx.i[3]) == 0) { 56 *exp = 0; 57 return (x); 58 } 59 60 /* normalize x */ 61 s = xx.i[0] & 0x80000000; 62 while ((hx | (xx.i[1] & 0xffff0000)) == 0) { 63 hx = xx.i[1]; 64 xx.i[1] = xx.i[2]; 65 xx.i[2] = xx.i[3]; 66 xx.i[3] = 0; 67 e -= 32; 68 } 69 while (hx < 0x10000) { 70 hx = (hx << 1) | (xx.i[1] >> 31); 71 xx.i[1] = (xx.i[1] << 1) | (xx.i[2] >> 31); 72 xx.i[2] = (xx.i[2] << 1) | (xx.i[3] >> 31); 73 xx.i[3] <<= 1; 74 e--; 75 } 76 xx.i[0] = s | hx; 77 } 78 79 /* now xx.q is normal */ 80 xx.i[0] = (xx.i[0] & ~0x7fff0000) | 0x3ffe0000; 81 *exp = e + (hx >> 16) - 0x3ffe; 82 return (xx.q); 83 } 84 85 #elif defined(__x86) 86 87 long double 88 __frexpl(long double x, int *exp) { 89 union { 90 unsigned i[3]; 91 long double e; 92 } xx; 93 unsigned hx; 94 int e; 95 96 xx.e = x; 97 hx = xx.i[2] & 0x7fff; 98 99 if (hx >= 0x7fff) { /* x is infinite or NaN */ 100 *exp = 0; 101 return (x); 102 } 103 104 e = 0; 105 if (hx < 0x0001) { /* x is subnormal or zero */ 106 if ((xx.i[0] | xx.i[1]) == 0) { 107 *exp = 0; 108 return (x); 109 } 110 111 /* normalize x */ 112 xx.e *= 18446744073709551616.0L; /* 2^64 */ 113 hx = xx.i[2] & 0x7fff; 114 e = -64; 115 } 116 117 /* now xx.e is normal */ 118 xx.i[2] = (xx.i[2] & 0x8000) | 0x3ffe; 119 *exp = e + hx - 0x3ffe; 120 return (xx.e); 121 } 122 123 #else 124 #error Unknown architecture 125 #endif 126