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 truncl = __truncl 32 #endif 33 34 #include "libm.h" 35 36 #if defined(__sparc) 37 long double 38 truncl(long double x) { 39 union { 40 unsigned i[4]; 41 long double q; 42 } xx; 43 unsigned hx, sx; 44 int j; 45 46 xx.q = x; 47 sx = xx.i[0] & 0x80000000; 48 hx = xx.i[0] & ~0x80000000; 49 50 /* handle trivial cases */ 51 if (hx >= 0x406f0000) /* |x| >= 2^112 + ... or x is nan */ 52 return (hx >= 0x7fff0000 ? x + x : x); 53 54 /* handle |x| < 1 */ 55 if (hx < 0x3fff0000) 56 return (sx ? -0.0L : 0.0L); 57 58 j = 0x406f - (hx >> 16); /* 1 <= j <= 112 */ 59 xx.i[0] = hx; 60 if (j >= 96) { /* 96 <= j <= 112 */ 61 xx.i[0] &= ~((1 << (j - 96)) - 1); 62 xx.i[1] = xx.i[2] = xx.i[3] = 0; 63 } else if (j >= 64) { /* 64 <= j <= 95 */ 64 xx.i[1] &= ~((1 << (j - 64)) - 1); 65 xx.i[2] = xx.i[3] = 0; 66 } else if (j >= 32) { /* 32 <= j <= 63 */ 67 xx.i[2] &= ~((1 << (j - 32)) - 1); 68 xx.i[3] = 0; 69 } else /* 1 <= j <= 31 */ 70 xx.i[3] &= ~((1 << j) - 1); 71 72 /* negate result if need be */ 73 if (sx) 74 xx.i[0] |= 0x80000000; 75 return (xx.q); 76 } 77 #elif defined(__x86) 78 long double 79 truncl(long double x) { 80 union { 81 unsigned i[3]; 82 long double e; 83 } xx; 84 int ex, sx, i; 85 86 xx.e = x; 87 ex = xx.i[2] & 0x7fff; 88 sx = xx.i[2] & 0x8000; 89 if (ex < 0x403e) { /* |x| < 2^63 */ 90 if (ex < 0x3fff) /* |x| < 1 */ 91 return (sx ? -0.0L : 0.0L); 92 93 /* chop x at the integer bit */ 94 if (ex < 0x401e) { 95 i = 1 << (0x401d - ex); 96 xx.i[1] &= ~(i | (i - 1)); 97 xx.i[0] = 0; 98 } else { 99 i = 1 << (0x403d - ex); 100 xx.i[0] &= ~(i | (i - 1)); 101 } 102 return (xx.e); 103 } else if (ex < 0x7fff) /* x is integral */ 104 return (x); 105 else /* inf or nan */ 106 return (x + x); 107 } 108 #else 109 #error Unknown architecture 110 #endif /* defined(__sparc) || defined(__x86) */ 111