xref: /titanic_41/usr/src/lib/libm/common/m9x/truncl.c (revision a9d3dcd5820128b4f34bf38f447e47aa95c004e8)
15b2ba9d3SPiotr Jasiukajtis /*
25b2ba9d3SPiotr Jasiukajtis  * CDDL HEADER START
35b2ba9d3SPiotr Jasiukajtis  *
45b2ba9d3SPiotr Jasiukajtis  * The contents of this file are subject to the terms of the
55b2ba9d3SPiotr Jasiukajtis  * Common Development and Distribution License (the "License").
65b2ba9d3SPiotr Jasiukajtis  * You may not use this file except in compliance with the License.
75b2ba9d3SPiotr Jasiukajtis  *
85b2ba9d3SPiotr Jasiukajtis  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
95b2ba9d3SPiotr Jasiukajtis  * or http://www.opensolaris.org/os/licensing.
105b2ba9d3SPiotr Jasiukajtis  * See the License for the specific language governing permissions
115b2ba9d3SPiotr Jasiukajtis  * and limitations under the License.
125b2ba9d3SPiotr Jasiukajtis  *
135b2ba9d3SPiotr Jasiukajtis  * When distributing Covered Code, include this CDDL HEADER in each
145b2ba9d3SPiotr Jasiukajtis  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
155b2ba9d3SPiotr Jasiukajtis  * If applicable, add the following below this CDDL HEADER, with the
165b2ba9d3SPiotr Jasiukajtis  * fields enclosed by brackets "[]" replaced with your own identifying
175b2ba9d3SPiotr Jasiukajtis  * information: Portions Copyright [yyyy] [name of copyright owner]
185b2ba9d3SPiotr Jasiukajtis  *
195b2ba9d3SPiotr Jasiukajtis  * CDDL HEADER END
205b2ba9d3SPiotr Jasiukajtis  */
215b2ba9d3SPiotr Jasiukajtis 
225b2ba9d3SPiotr Jasiukajtis /*
235b2ba9d3SPiotr Jasiukajtis  * Copyright 2011 Nexenta Systems, Inc.  All rights reserved.
245b2ba9d3SPiotr Jasiukajtis  */
255b2ba9d3SPiotr Jasiukajtis /*
265b2ba9d3SPiotr Jasiukajtis  * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
275b2ba9d3SPiotr Jasiukajtis  * Use is subject to license terms.
285b2ba9d3SPiotr Jasiukajtis  */
295b2ba9d3SPiotr Jasiukajtis 
30*a9d3dcd5SRichard Lowe #pragma weak __truncl = truncl
315b2ba9d3SPiotr Jasiukajtis 
325b2ba9d3SPiotr Jasiukajtis #include "libm.h"
335b2ba9d3SPiotr Jasiukajtis 
345b2ba9d3SPiotr Jasiukajtis #if defined(__sparc)
355b2ba9d3SPiotr Jasiukajtis long double
truncl(long double x)365b2ba9d3SPiotr Jasiukajtis truncl(long double x) {
375b2ba9d3SPiotr Jasiukajtis 	union {
385b2ba9d3SPiotr Jasiukajtis 		unsigned i[4];
395b2ba9d3SPiotr Jasiukajtis 		long double q;
405b2ba9d3SPiotr Jasiukajtis 	} xx;
415b2ba9d3SPiotr Jasiukajtis 	unsigned hx, sx;
425b2ba9d3SPiotr Jasiukajtis 	int j;
435b2ba9d3SPiotr Jasiukajtis 
445b2ba9d3SPiotr Jasiukajtis 	xx.q = x;
455b2ba9d3SPiotr Jasiukajtis 	sx = xx.i[0] & 0x80000000;
465b2ba9d3SPiotr Jasiukajtis 	hx = xx.i[0] & ~0x80000000;
475b2ba9d3SPiotr Jasiukajtis 
485b2ba9d3SPiotr Jasiukajtis 	/* handle trivial cases */
495b2ba9d3SPiotr Jasiukajtis 	if (hx >= 0x406f0000) /* |x| >= 2^112 + ... or x is nan */
505b2ba9d3SPiotr Jasiukajtis 		return (hx >= 0x7fff0000 ? x + x : x);
515b2ba9d3SPiotr Jasiukajtis 
525b2ba9d3SPiotr Jasiukajtis 	/* handle |x| < 1 */
535b2ba9d3SPiotr Jasiukajtis 	if (hx < 0x3fff0000)
545b2ba9d3SPiotr Jasiukajtis 		return (sx ? -0.0L : 0.0L);
555b2ba9d3SPiotr Jasiukajtis 
565b2ba9d3SPiotr Jasiukajtis 	j = 0x406f - (hx >> 16);		/* 1 <= j <= 112 */
575b2ba9d3SPiotr Jasiukajtis 	xx.i[0] = hx;
585b2ba9d3SPiotr Jasiukajtis 	if (j >= 96) {				/* 96 <= j <= 112 */
595b2ba9d3SPiotr Jasiukajtis 		xx.i[0] &= ~((1 << (j - 96)) - 1);
605b2ba9d3SPiotr Jasiukajtis 		xx.i[1] = xx.i[2] = xx.i[3] = 0;
615b2ba9d3SPiotr Jasiukajtis 	} else if (j >= 64) {			/* 64 <= j <= 95 */
625b2ba9d3SPiotr Jasiukajtis 		xx.i[1] &= ~((1 << (j - 64)) - 1);
635b2ba9d3SPiotr Jasiukajtis 		xx.i[2] = xx.i[3] = 0;
645b2ba9d3SPiotr Jasiukajtis 	} else if (j >= 32) {			/* 32 <= j <= 63 */
655b2ba9d3SPiotr Jasiukajtis 		xx.i[2] &= ~((1 << (j - 32)) - 1);
665b2ba9d3SPiotr Jasiukajtis 		xx.i[3] = 0;
675b2ba9d3SPiotr Jasiukajtis 	} else					/* 1 <= j <= 31 */
685b2ba9d3SPiotr Jasiukajtis 		xx.i[3] &= ~((1 << j) - 1);
695b2ba9d3SPiotr Jasiukajtis 
705b2ba9d3SPiotr Jasiukajtis 	/* negate result if need be */
715b2ba9d3SPiotr Jasiukajtis 	if (sx)
725b2ba9d3SPiotr Jasiukajtis 		xx.i[0] |= 0x80000000;
735b2ba9d3SPiotr Jasiukajtis 	return (xx.q);
745b2ba9d3SPiotr Jasiukajtis }
755b2ba9d3SPiotr Jasiukajtis #elif defined(__x86)
765b2ba9d3SPiotr Jasiukajtis long double
truncl(long double x)775b2ba9d3SPiotr Jasiukajtis truncl(long double x) {
785b2ba9d3SPiotr Jasiukajtis 	union {
795b2ba9d3SPiotr Jasiukajtis 		unsigned i[3];
805b2ba9d3SPiotr Jasiukajtis 		long double e;
815b2ba9d3SPiotr Jasiukajtis 	} xx;
825b2ba9d3SPiotr Jasiukajtis 	int ex, sx, i;
835b2ba9d3SPiotr Jasiukajtis 
845b2ba9d3SPiotr Jasiukajtis 	xx.e = x;
855b2ba9d3SPiotr Jasiukajtis 	ex = xx.i[2] & 0x7fff;
865b2ba9d3SPiotr Jasiukajtis 	sx = xx.i[2] & 0x8000;
875b2ba9d3SPiotr Jasiukajtis 	if (ex < 0x403e) {	/* |x| < 2^63 */
885b2ba9d3SPiotr Jasiukajtis 		if (ex < 0x3fff)	/* |x| < 1 */
895b2ba9d3SPiotr Jasiukajtis 			return (sx ? -0.0L : 0.0L);
905b2ba9d3SPiotr Jasiukajtis 
915b2ba9d3SPiotr Jasiukajtis 		/* chop x at the integer bit */
925b2ba9d3SPiotr Jasiukajtis 		if (ex < 0x401e) {
935b2ba9d3SPiotr Jasiukajtis 			i = 1 << (0x401d - ex);
945b2ba9d3SPiotr Jasiukajtis 			xx.i[1] &= ~(i | (i - 1));
955b2ba9d3SPiotr Jasiukajtis 			xx.i[0] = 0;
965b2ba9d3SPiotr Jasiukajtis 		} else {
975b2ba9d3SPiotr Jasiukajtis 			i = 1 << (0x403d - ex);
985b2ba9d3SPiotr Jasiukajtis 			xx.i[0] &= ~(i | (i - 1));
995b2ba9d3SPiotr Jasiukajtis 		}
1005b2ba9d3SPiotr Jasiukajtis 		return (xx.e);
1015b2ba9d3SPiotr Jasiukajtis 	} else if (ex < 0x7fff)	/* x is integral */
1025b2ba9d3SPiotr Jasiukajtis 		return (x);
1035b2ba9d3SPiotr Jasiukajtis 	else			/* inf or nan */
1045b2ba9d3SPiotr Jasiukajtis 		return (x + x);
1055b2ba9d3SPiotr Jasiukajtis }
1065b2ba9d3SPiotr Jasiukajtis #else
1075b2ba9d3SPiotr Jasiukajtis #error Unknown architecture
1085b2ba9d3SPiotr Jasiukajtis #endif	/* defined(__sparc) || defined(__x86) */
109