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 nexttowardl = __nexttowardl 32 #endif 33 34 #include "libm.h" 35 #include <float.h> /* LDBL_MAX, LDBL_MIN */ 36 37 #if defined(__sparc) 38 #define n0 0 39 #define n1 1 40 #define n2 2 41 #define n3 3 42 #define X86PDNRM1(x) 43 #define INC(px) { \ 44 if (++px[n3] == 0) \ 45 if (++px[n2] == 0) \ 46 if (++px[n1] == 0) \ 47 ++px[n0]; \ 48 } 49 #define DEC(px) { \ 50 if (--px[n3] == 0xffffffff) \ 51 if (--px[n2] == 0xffffffff) \ 52 if (--px[n1] == 0xffffffff) \ 53 --px[n0]; \ 54 } 55 #elif defined(__x86) 56 #define n0 2 57 #define n1 1 58 #define n2 0 59 #define n3 0 60 /* 61 * if pseudo-denormal, replace by the equivalent normal 62 */ 63 #define X86PDNRM1(x) if (XBIASED_EXP(x) == 0 && (((int *) &x)[1] & \ 64 0x80000000) != 0) \ 65 ((int *) &x)[2] |= 1 66 #define INC(px) { \ 67 if (++px[n2] == 0) \ 68 if ((++px[n1] & ~0x80000000) == 0) \ 69 px[n1] = 0x80000000, ++px[n0]; \ 70 } 71 #define DEC(px) { \ 72 if (--px[n2] == 0xffffffff) \ 73 if (--px[n1] == 0x7fffffff) \ 74 if ((--px[n0] & 0x7fff) != 0) \ 75 px[n1] |= 0x80000000; \ 76 } 77 #endif 78 79 long double 80 nexttowardl(long double x, long double y) { 81 int *px = (int *) &x; 82 int *py = (int *) &y; 83 84 if (x == y) 85 return (y); /* C99 requirement */ 86 if (x != x || y != y) 87 return (x * y); 88 89 if (ISZEROL(x)) { /* x == 0.0 */ 90 px[n0] = py[n0] & XSGNMSK; 91 px[n1] = px[n2] = 0; 92 px[n3] = 1; 93 } else { 94 X86PDNRM1(x); 95 if ((px[n0] & XSGNMSK) == 0) { /* x > 0.0 */ 96 if (x > y) /* x > y */ 97 DEC(px) 98 else 99 INC(px) 100 } else { 101 if (x < y) /* x < y */ 102 DEC(px) 103 else 104 INC(px) 105 } 106 } 107 #ifndef lint 108 { 109 volatile long double dummy; 110 int k = XBIASED_EXP(x); 111 112 if (k == 0) 113 dummy = LDBL_MIN * copysignl(LDBL_MIN, x); 114 else if (k == 0x7fff) 115 dummy = LDBL_MAX * copysignl(LDBL_MAX, x); 116 } 117 #endif 118 return (x); 119 } 120