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