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