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