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