1*25c28e83SPiotr Jasiukajtis /* 2*25c28e83SPiotr Jasiukajtis * CDDL HEADER START 3*25c28e83SPiotr Jasiukajtis * 4*25c28e83SPiotr Jasiukajtis * The contents of this file are subject to the terms of the 5*25c28e83SPiotr Jasiukajtis * Common Development and Distribution License (the "License"). 6*25c28e83SPiotr Jasiukajtis * You may not use this file except in compliance with the License. 7*25c28e83SPiotr Jasiukajtis * 8*25c28e83SPiotr Jasiukajtis * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9*25c28e83SPiotr Jasiukajtis * or http://www.opensolaris.org/os/licensing. 10*25c28e83SPiotr Jasiukajtis * See the License for the specific language governing permissions 11*25c28e83SPiotr Jasiukajtis * and limitations under the License. 12*25c28e83SPiotr Jasiukajtis * 13*25c28e83SPiotr Jasiukajtis * When distributing Covered Code, include this CDDL HEADER in each 14*25c28e83SPiotr Jasiukajtis * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15*25c28e83SPiotr Jasiukajtis * If applicable, add the following below this CDDL HEADER, with the 16*25c28e83SPiotr Jasiukajtis * fields enclosed by brackets "[]" replaced with your own identifying 17*25c28e83SPiotr Jasiukajtis * information: Portions Copyright [yyyy] [name of copyright owner] 18*25c28e83SPiotr Jasiukajtis * 19*25c28e83SPiotr Jasiukajtis * CDDL HEADER END 20*25c28e83SPiotr Jasiukajtis */ 21*25c28e83SPiotr Jasiukajtis 22*25c28e83SPiotr Jasiukajtis /* 23*25c28e83SPiotr Jasiukajtis * Copyright 2011 Nexenta Systems, Inc. All rights reserved. 24*25c28e83SPiotr Jasiukajtis */ 25*25c28e83SPiotr Jasiukajtis /* 26*25c28e83SPiotr Jasiukajtis * Copyright 2006 Sun Microsystems, Inc. All rights reserved. 27*25c28e83SPiotr Jasiukajtis * Use is subject to license terms. 28*25c28e83SPiotr Jasiukajtis */ 29*25c28e83SPiotr Jasiukajtis 30*25c28e83SPiotr Jasiukajtis #pragma weak nexttowardf = __nexttowardf 31*25c28e83SPiotr Jasiukajtis 32*25c28e83SPiotr Jasiukajtis #include "libm.h" 33*25c28e83SPiotr Jasiukajtis 34*25c28e83SPiotr Jasiukajtis static union { 35*25c28e83SPiotr Jasiukajtis unsigned i; 36*25c28e83SPiotr Jasiukajtis float f; 37*25c28e83SPiotr Jasiukajtis } C[] = { 38*25c28e83SPiotr Jasiukajtis 0x00800000, 39*25c28e83SPiotr Jasiukajtis 0x7f000000, 40*25c28e83SPiotr Jasiukajtis 0x7fffffff 41*25c28e83SPiotr Jasiukajtis }; 42*25c28e83SPiotr Jasiukajtis 43*25c28e83SPiotr Jasiukajtis #define tiny C[0].f 44*25c28e83SPiotr Jasiukajtis #define huge C[1].f 45*25c28e83SPiotr Jasiukajtis #define qnan C[2].f 46*25c28e83SPiotr Jasiukajtis 47*25c28e83SPiotr Jasiukajtis #if defined(__sparc) 48*25c28e83SPiotr Jasiukajtis 49*25c28e83SPiotr Jasiukajtis enum fcc_type { 50*25c28e83SPiotr Jasiukajtis fcc_equal = 0, 51*25c28e83SPiotr Jasiukajtis fcc_less = 1, 52*25c28e83SPiotr Jasiukajtis fcc_greater = 2, 53*25c28e83SPiotr Jasiukajtis fcc_unordered = 3 54*25c28e83SPiotr Jasiukajtis }; 55*25c28e83SPiotr Jasiukajtis 56*25c28e83SPiotr Jasiukajtis #ifdef __sparcv9 57*25c28e83SPiotr Jasiukajtis #define _Q_cmp _Qp_cmp 58*25c28e83SPiotr Jasiukajtis #endif 59*25c28e83SPiotr Jasiukajtis 60*25c28e83SPiotr Jasiukajtis extern enum fcc_type _Q_cmp(const long double *, const long double *); 61*25c28e83SPiotr Jasiukajtis 62*25c28e83SPiotr Jasiukajtis float 63*25c28e83SPiotr Jasiukajtis __nexttowardf(float x, long double y) { 64*25c28e83SPiotr Jasiukajtis union { 65*25c28e83SPiotr Jasiukajtis unsigned i; 66*25c28e83SPiotr Jasiukajtis float f; 67*25c28e83SPiotr Jasiukajtis } xx; 68*25c28e83SPiotr Jasiukajtis union { 69*25c28e83SPiotr Jasiukajtis unsigned i[4]; 70*25c28e83SPiotr Jasiukajtis long double q; 71*25c28e83SPiotr Jasiukajtis } yy; 72*25c28e83SPiotr Jasiukajtis long double lx; 73*25c28e83SPiotr Jasiukajtis unsigned hx; 74*25c28e83SPiotr Jasiukajtis volatile float dummy; 75*25c28e83SPiotr Jasiukajtis enum fcc_type rel; 76*25c28e83SPiotr Jasiukajtis 77*25c28e83SPiotr Jasiukajtis /* 78*25c28e83SPiotr Jasiukajtis * It would be somewhat more efficient to check for NaN and 79*25c28e83SPiotr Jasiukajtis * zero operands before converting x to long double and then 80*25c28e83SPiotr Jasiukajtis * to code the comparison in line rather than calling _Q_cmp. 81*25c28e83SPiotr Jasiukajtis * However, since this code probably won't get used much, 82*25c28e83SPiotr Jasiukajtis * I'm opting in favor of simplicity instead. 83*25c28e83SPiotr Jasiukajtis */ 84*25c28e83SPiotr Jasiukajtis lx = xx.f = x; 85*25c28e83SPiotr Jasiukajtis hx = xx.i & ~0x80000000; 86*25c28e83SPiotr Jasiukajtis 87*25c28e83SPiotr Jasiukajtis /* check for each of four possible orderings */ 88*25c28e83SPiotr Jasiukajtis rel = _Q_cmp(&lx, &y); 89*25c28e83SPiotr Jasiukajtis if (rel == fcc_unordered) 90*25c28e83SPiotr Jasiukajtis return (qnan); 91*25c28e83SPiotr Jasiukajtis 92*25c28e83SPiotr Jasiukajtis if (rel == fcc_equal) { 93*25c28e83SPiotr Jasiukajtis if (hx == 0) { /* x is zero; return zero with y's sign */ 94*25c28e83SPiotr Jasiukajtis yy.q = y; 95*25c28e83SPiotr Jasiukajtis xx.i = yy.i[0]; 96*25c28e83SPiotr Jasiukajtis return (xx.f); 97*25c28e83SPiotr Jasiukajtis } 98*25c28e83SPiotr Jasiukajtis return (x); 99*25c28e83SPiotr Jasiukajtis } 100*25c28e83SPiotr Jasiukajtis 101*25c28e83SPiotr Jasiukajtis if (rel == fcc_less) { 102*25c28e83SPiotr Jasiukajtis if (hx == 0) /* x is zero */ 103*25c28e83SPiotr Jasiukajtis xx.i = 0x00000001; 104*25c28e83SPiotr Jasiukajtis else if ((int) xx.i >= 0) /* x is positive */ 105*25c28e83SPiotr Jasiukajtis xx.i++; 106*25c28e83SPiotr Jasiukajtis else 107*25c28e83SPiotr Jasiukajtis xx.i--; 108*25c28e83SPiotr Jasiukajtis } else { 109*25c28e83SPiotr Jasiukajtis if (hx == 0) /* x is zero */ 110*25c28e83SPiotr Jasiukajtis xx.i = 0x80000001; 111*25c28e83SPiotr Jasiukajtis else if ((int) xx.i >= 0) /* x is positive */ 112*25c28e83SPiotr Jasiukajtis xx.i--; 113*25c28e83SPiotr Jasiukajtis else 114*25c28e83SPiotr Jasiukajtis xx.i++; 115*25c28e83SPiotr Jasiukajtis } 116*25c28e83SPiotr Jasiukajtis 117*25c28e83SPiotr Jasiukajtis /* raise exceptions as needed */ 118*25c28e83SPiotr Jasiukajtis hx = xx.i & ~0x80000000; 119*25c28e83SPiotr Jasiukajtis if (hx == 0x7f800000) { 120*25c28e83SPiotr Jasiukajtis dummy = huge; 121*25c28e83SPiotr Jasiukajtis dummy *= huge; 122*25c28e83SPiotr Jasiukajtis } else if (hx < 0x00800000) { 123*25c28e83SPiotr Jasiukajtis dummy = tiny; 124*25c28e83SPiotr Jasiukajtis dummy *= tiny; 125*25c28e83SPiotr Jasiukajtis } 126*25c28e83SPiotr Jasiukajtis 127*25c28e83SPiotr Jasiukajtis return (xx.f); 128*25c28e83SPiotr Jasiukajtis } 129*25c28e83SPiotr Jasiukajtis 130*25c28e83SPiotr Jasiukajtis #elif defined(__x86) 131*25c28e83SPiotr Jasiukajtis 132*25c28e83SPiotr Jasiukajtis float 133*25c28e83SPiotr Jasiukajtis __nexttowardf(float x, long double y) { 134*25c28e83SPiotr Jasiukajtis union { 135*25c28e83SPiotr Jasiukajtis unsigned i; 136*25c28e83SPiotr Jasiukajtis float f; 137*25c28e83SPiotr Jasiukajtis } xx; 138*25c28e83SPiotr Jasiukajtis unsigned hx; 139*25c28e83SPiotr Jasiukajtis long double lx; 140*25c28e83SPiotr Jasiukajtis volatile float dummy; 141*25c28e83SPiotr Jasiukajtis 142*25c28e83SPiotr Jasiukajtis lx = xx.f = x; 143*25c28e83SPiotr Jasiukajtis hx = xx.i & ~0x80000000; 144*25c28e83SPiotr Jasiukajtis 145*25c28e83SPiotr Jasiukajtis /* check for each of four possible orderings */ 146*25c28e83SPiotr Jasiukajtis if (isunordered(lx, y)) 147*25c28e83SPiotr Jasiukajtis return ((float) (lx + y)); 148*25c28e83SPiotr Jasiukajtis 149*25c28e83SPiotr Jasiukajtis if (lx == y) 150*25c28e83SPiotr Jasiukajtis return ((float) y); 151*25c28e83SPiotr Jasiukajtis 152*25c28e83SPiotr Jasiukajtis if (lx < y) { 153*25c28e83SPiotr Jasiukajtis if (hx == 0) /* x is zero */ 154*25c28e83SPiotr Jasiukajtis xx.i = 0x00000001; 155*25c28e83SPiotr Jasiukajtis else if ((int) xx.i >= 0) /* x is positive */ 156*25c28e83SPiotr Jasiukajtis xx.i++; 157*25c28e83SPiotr Jasiukajtis else 158*25c28e83SPiotr Jasiukajtis xx.i--; 159*25c28e83SPiotr Jasiukajtis } else { 160*25c28e83SPiotr Jasiukajtis if (hx == 0) /* x is zero */ 161*25c28e83SPiotr Jasiukajtis xx.i = 0x80000001; 162*25c28e83SPiotr Jasiukajtis else if ((int) xx.i >= 0) /* x is positive */ 163*25c28e83SPiotr Jasiukajtis xx.i--; 164*25c28e83SPiotr Jasiukajtis else 165*25c28e83SPiotr Jasiukajtis xx.i++; 166*25c28e83SPiotr Jasiukajtis } 167*25c28e83SPiotr Jasiukajtis 168*25c28e83SPiotr Jasiukajtis /* raise exceptions as needed */ 169*25c28e83SPiotr Jasiukajtis hx = xx.i & ~0x80000000; 170*25c28e83SPiotr Jasiukajtis if (hx == 0x7f800000) { 171*25c28e83SPiotr Jasiukajtis dummy = huge; 172*25c28e83SPiotr Jasiukajtis dummy *= huge; 173*25c28e83SPiotr Jasiukajtis } else if (hx < 0x00800000) { 174*25c28e83SPiotr Jasiukajtis dummy = tiny; 175*25c28e83SPiotr Jasiukajtis dummy *= tiny; 176*25c28e83SPiotr Jasiukajtis } 177*25c28e83SPiotr Jasiukajtis 178*25c28e83SPiotr Jasiukajtis return (xx.f); 179*25c28e83SPiotr Jasiukajtis } 180*25c28e83SPiotr Jasiukajtis 181*25c28e83SPiotr Jasiukajtis #else 182*25c28e83SPiotr Jasiukajtis #error Unknown architecture 183*25c28e83SPiotr Jasiukajtis #endif 184