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 __rintf = rintf 32 33 34 /* 35 * aintf(x) return x chopped to integral value 36 * anintf(x) return sign(x)*(|x|+0.5) chopped to integral value 37 * irintf(x) return rint(x) in integer format 38 * nintf(x) return anint(x) in integer format 39 * rintf(x) return x rounded to integral according to the rounding direction 40 * 41 * NOTE: rintf(x), aintf(x) and anintf(x) return results with the same sign as 42 * x's, including 0.0. 43 */ 44 45 #include "libm.h" 46 47 static const float xf[] = { 48 /* ZEROF */ 49 0.0f, 50 /* TWO_23F */ 8.3886080000e6f, 51 /* MTWO_23F */ -8.3886080000e6f, 52 /* ONEF */ 1.0f, 53 /* MONEF */ -1.0f, 54 /* HALFF */ 0.5f, 55 /* MHALFF */ -0.5f, 56 /* HUGEF */ 1.0e30f, 57 }; 58 59 #define ZEROF xf[0] 60 #define TWO_23F xf[1] 61 #define MTWO_23F xf[2] 62 #define ONEF xf[3] 63 #define MONEF xf[4] 64 #define HALFF xf[5] 65 #define MHALFF xf[6] 66 #define HUGEF xf[7] 67 68 float 69 aintf(float x) 70 { 71 int hx, k; 72 float y; 73 74 hx = *(int *)&x; 75 k = (hx & ~0x80000000) >> 23; 76 77 if (k < 150) { 78 y = (float)((int)x); 79 80 /* 81 * make sure y has the same sign of x when |x|<0.5 82 * (i.e., y=0.0) 83 */ 84 return (((k - 127) & hx) < 0 ? -y : y); 85 } else { 86 /* signal invalid if x is a SNaN */ 87 return (x * ONEF); /* +0 -> *1 for Cheetah */ 88 } 89 } 90 91 float 92 anintf(float x) 93 { 94 volatile float dummy __unused; 95 int hx, k, j, ix; 96 97 hx = *(int *)&x; 98 ix = hx & ~0x80000000; 99 k = ix >> 23; 100 101 if (((k - 127) ^ (k - 150)) < 0) { 102 j = 1 << (149 - k); 103 k = j + j - 1; 104 105 if ((k & hx) != 0) 106 dummy = HUGEF + x; /* raise inexact */ 107 108 *(int *)&x = (hx + j) & ~k; 109 return (x); 110 } else if (k <= 126) { 111 dummy = HUGEF + x; 112 *(int *)&x = (0x3f800000 & ((125 - k) >> 31)) | 113 (0x80000000 & hx); 114 return (x); 115 } else { 116 /* signal invalid if x is a SNaN */ 117 return (x * ONEF); /* +0 -> *1 for Cheetah */ 118 } 119 } 120 121 int 122 irintf(float x) 123 { 124 float v; 125 int hx, k; 126 127 hx = *(int *)&x; 128 k = (hx & ~0x80000000) >> 23; 129 v = xf[((k - 150) >> 31) & (1 - (hx >> 31))]; 130 return ((int)((float)(x + v) - v)); 131 } 132 133 int 134 nintf(float x) 135 { 136 int hx, ix, k, j, m; 137 volatile float dummy __unused; 138 139 hx = *(int *)&x; 140 k = (hx & ~0x80000000) >> 23; 141 142 if (((k - 126) ^ (k - 150)) < 0) { 143 ix = (hx & 0x00ffffff) | 0x800000; 144 m = 149 - k; 145 j = 1 << m; 146 147 if ((ix & (j + j - 1)) != 0) 148 dummy = HUGEF + x; 149 150 hx = hx >> 31; 151 return ((((ix + j) >> (m + 1)) ^ hx) - hx); 152 } else { 153 return ((int)x); 154 } 155 } 156 157 float 158 rintf(float x) 159 { 160 float w, v; 161 int hx, k; 162 163 hx = *(int *)&x; 164 k = (hx & ~0x80000000) >> 23; 165 #if defined(FPADD_TRAPS_INCOMPLETE_ON_NAN) 166 if (k >= 150) 167 return (x * ONEF); 168 169 v = xf[1 - (hx >> 31)]; 170 #else 171 v = xf[((k - 150) >> 31) & (1 - (hx >> 31))]; 172 #endif 173 w = (float)(x + v); 174 175 if (k < 127 && w == v) 176 return (ZEROF * x); 177 else 178 return (w - v); 179 }