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