25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis/*
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis * CDDL HEADER START
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis *
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis * The contents of this file are subject to the terms of the
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis * Common Development and Distribution License (the "License").
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis * You may not use this file except in compliance with the License.
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis *
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis * or http://www.opensolaris.org/os/licensing.
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis * See the License for the specific language governing permissions
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis * and limitations under the License.
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis *
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis * When distributing Covered Code, include this CDDL HEADER in each
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis * If applicable, add the following below this CDDL HEADER, with the
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis * fields enclosed by brackets "[]" replaced with your own identifying
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis * information: Portions Copyright [yyyy] [name of copyright owner]
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis *
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis * CDDL HEADER END
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis */
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis/*
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis * Copyright 2011 Nexenta Systems, Inc. All rights reserved.
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis */
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis/*
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis * Use is subject to license terms.
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis */
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis
ddc0e0b53c661f6e439e3b7072b3ef353eadb4afRichard Lowe#pragma weak __rintf = rintf
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis/* INDENT OFF */
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis/*
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis * aintf(x) return x chopped to integral value
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis * anintf(x) return sign(x)*(|x|+0.5) chopped to integral value
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis * irintf(x) return rint(x) in integer format
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis * nintf(x) return anint(x) in integer format
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis * rintf(x) return x rounded to integral according to the rounding direction
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis *
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis * NOTE: rintf(x), aintf(x) and anintf(x) return results with the same sign as
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis * x's, including 0.0.
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis */
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis#include "libm.h"
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtisstatic const float xf[] = {
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis/* ZEROF */ 0.0f,
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis/* TWO_23F */ 8.3886080000e6f,
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis/* MTWO_23F */ -8.3886080000e6f,
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis/* ONEF */ 1.0f,
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis/* MONEF */ -1.0f,
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis/* HALFF */ 0.5f,
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis/* MHALFF */ -0.5f,
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis/* HUGEF */ 1.0e30f,
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis};
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis#define ZEROF xf[0]
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis#define TWO_23F xf[1]
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis#define MTWO_23F xf[2]
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis#define ONEF xf[3]
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis#define MONEF xf[4]
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis#define HALFF xf[5]
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis#define MHALFF xf[6]
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis#define HUGEF xf[7]
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis/* INDENT ON */
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtisfloat
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtisaintf(float x) {
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis int hx, k;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis float y;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis hx = *(int *) &x;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis k = (hx & ~0x80000000) >> 23;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis if (k < 150) {
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis y = (float) ((int) x);
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis /*
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis * make sure y has the same sign of x when |x|<0.5
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis * (i.e., y=0.0)
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis */
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis return (((k - 127) & hx) < 0 ? -y : y);
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis } else
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis /* signal invalid if x is a SNaN */
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis return (x * ONEF); /* +0 -> *1 for Cheetah */
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis}
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtisfloat
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtisanintf(float x) {
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis volatile float dummy;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis int hx, k, j, ix;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis hx = *(int *) &x;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis ix = hx & ~0x80000000;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis k = ix >> 23;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis if (((k - 127) ^ (k - 150)) < 0) {
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis j = 1 << (149 - k);
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis k = j + j - 1;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis if ((k & hx) != 0)
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis dummy = HUGEF + x; /* raise inexact */
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis *(int *) &x = (hx + j) & ~k;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis return (x);
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis } else if (k <= 126) {
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis dummy = HUGEF + x;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis *(int *) &x = (0x3f800000 & ((125 - k) >> 31)) |
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis (0x80000000 & hx);
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis return (x);
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis } else
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis /* signal invalid if x is a SNaN */
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis return (x * ONEF); /* +0 -> *1 for Cheetah */
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis}
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtisint
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtisirintf(float x) {
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis float v;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis int hx, k;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis hx = *(int *) &x;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis k = (hx & ~0x80000000) >> 23;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis v = xf[((k - 150) >> 31) & (1 - (hx >> 31))];
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis return ((int) ((float) (x + v) - v));
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis}
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtisint
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtisnintf(float x) {
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis int hx, ix, k, j, m;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis volatile float dummy;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis hx = *(int *) &x;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis k = (hx & ~0x80000000) >> 23;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis if (((k - 126) ^ (k - 150)) < 0) {
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis ix = (hx & 0x00ffffff) | 0x800000;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis m = 149 - k;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis j = 1 << m;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis if ((ix & (j + j - 1)) != 0)
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis dummy = HUGEF + x;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis hx = hx >> 31;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis return ((((ix + j) >> (m + 1)) ^ hx) - hx);
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis } else
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis return ((int) x);
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis}
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtisfloat
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtisrintf(float x) {
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis float w, v;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis int hx, k;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis hx = *(int *) &x;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis k = (hx & ~0x80000000) >> 23;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis#if defined(FPADD_TRAPS_INCOMPLETE_ON_NAN)
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis if (k >= 150)
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis return (x * ONEF);
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis v = xf[1 - (hx >> 31)];
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis#else
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis v = xf[((k - 150) >> 31) & (1 - (hx >> 31))];
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis#endif
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis w = (float) (x + v);
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis if (k < 127 && w == v)
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis return (ZEROF * x);
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis else
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis return (w - v);
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis}