/* IEEE754 floating point arithmetic1* single precision2*/3/*4* MIPS floating point support5* Copyright (C) 1994-2000 Algorithmics Ltd.6*7* ########################################################################8*9* This program is free software; you can distribute it and/or modify it10* under the terms of the GNU General Public License (Version 2) as11* published by the Free Software Foundation.12*13* This program is distributed in the hope it will be useful, but WITHOUT14* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or15* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License16* for more details.17*18* You should have received a copy of the GNU General Public License along19* with this program; if not, write to the Free Software Foundation, Inc.,20* 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.21*22* ########################################################################23*/242526#include <linux/kernel.h>27#include "ieee754sp.h"2829int ieee754sp_tint(ieee754sp x)30{31COMPXSP;3233CLEARCX;3435EXPLODEXSP;36FLUSHXSP;3738switch (xc) {39case IEEE754_CLASS_SNAN:40case IEEE754_CLASS_QNAN:41case IEEE754_CLASS_INF:42SETCX(IEEE754_INVALID_OPERATION);43return ieee754si_xcpt(ieee754si_indef(), "sp_tint", x);44case IEEE754_CLASS_ZERO:45return 0;46case IEEE754_CLASS_DNORM:47case IEEE754_CLASS_NORM:48break;49}50if (xe >= 31) {51/* look for valid corner case */52if (xe == 31 && xs && xm == SP_HIDDEN_BIT)53return -0x80000000;54/* Set invalid. We will only use overflow for floating55point overflow */56SETCX(IEEE754_INVALID_OPERATION);57return ieee754si_xcpt(ieee754si_indef(), "sp_tint", x);58}59/* oh gawd */60if (xe > SP_MBITS) {61xm <<= xe - SP_MBITS;62} else {63u32 residue;64int round;65int sticky;66int odd;6768if (xe < -1) {69residue = xm;70round = 0;71sticky = residue != 0;72xm = 0;73} else {74/* Shifting a u32 32 times does not work,75* so we do it in two steps. Be aware that xe76* may be -1 */77residue = xm << (xe + 1);78residue <<= 31 - SP_MBITS;79round = (residue >> 31) != 0;80sticky = (residue << 1) != 0;81xm >>= SP_MBITS - xe;82}83odd = (xm & 0x1) != 0x0;84switch (ieee754_csr.rm) {85case IEEE754_RN:86if (round && (sticky || odd))87xm++;88break;89case IEEE754_RZ:90break;91case IEEE754_RU: /* toward +Infinity */92if ((round || sticky) && !xs)93xm++;94break;95case IEEE754_RD: /* toward -Infinity */96if ((round || sticky) && xs)97xm++;98break;99}100if ((xm >> 31) != 0) {101/* This can happen after rounding */102SETCX(IEEE754_INVALID_OPERATION);103return ieee754si_xcpt(ieee754si_indef(), "sp_tint", x);104}105if (round || sticky)106SETCX(IEEE754_INEXACT);107}108if (xs)109return -xm;110else111return xm;112}113114115unsigned int ieee754sp_tuns(ieee754sp x)116{117ieee754sp hb = ieee754sp_1e31();118119/* what if x < 0 ?? */120if (ieee754sp_lt(x, hb))121return (unsigned) ieee754sp_tint(x);122123return (unsigned) ieee754sp_tint(ieee754sp_sub(x, hb)) |124((unsigned) 1 << 31);125}126127128