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