/* IEEE754 floating point arithmetic1* double precision: common utilities2*/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 "ieee754dp.h"2829int ieee754dp_tint(ieee754dp x)30{31COMPXDP;3233CLEARCX;3435EXPLODEXDP;36FLUSHXDP;3738switch (xc) {39case IEEE754_CLASS_SNAN:40case IEEE754_CLASS_QNAN:41case IEEE754_CLASS_INF:42SETCX(IEEE754_INVALID_OPERATION);43return ieee754si_xcpt(ieee754si_indef(), "dp_tint", x);44case IEEE754_CLASS_ZERO:45return 0;46case IEEE754_CLASS_DNORM:47case IEEE754_CLASS_NORM:48break;49}50if (xe > 31) {51/* Set invalid. We will only use overflow for floating52point overflow */53SETCX(IEEE754_INVALID_OPERATION);54return ieee754si_xcpt(ieee754si_indef(), "dp_tint", x);55}56/* oh gawd */57if (xe > DP_MBITS) {58xm <<= xe - DP_MBITS;59} else if (xe < DP_MBITS) {60u64 residue;61int round;62int sticky;63int odd;6465if (xe < -1) {66residue = xm;67round = 0;68sticky = residue != 0;69xm = 0;70} else {71residue = xm << (64 - DP_MBITS + xe);72round = (residue >> 63) != 0;73sticky = (residue << 1) != 0;74xm >>= DP_MBITS - xe;75}76/* Note: At this point upper 32 bits of xm are guaranteed77to be zero */78odd = (xm & 0x1) != 0x0;79switch (ieee754_csr.rm) {80case IEEE754_RN:81if (round && (sticky || odd))82xm++;83break;84case IEEE754_RZ:85break;86case IEEE754_RU: /* toward +Infinity */87if ((round || sticky) && !xs)88xm++;89break;90case IEEE754_RD: /* toward -Infinity */91if ((round || sticky) && xs)92xm++;93break;94}95/* look for valid corner case 0x80000000 */96if ((xm >> 31) != 0 && (xs == 0 || xm != 0x80000000)) {97/* This can happen after rounding */98SETCX(IEEE754_INVALID_OPERATION);99return ieee754si_xcpt(ieee754si_indef(), "dp_tint", x);100}101if (round || sticky)102SETCX(IEEE754_INEXACT);103}104if (xs)105return -xm;106else107return xm;108}109110111unsigned int ieee754dp_tuns(ieee754dp x)112{113ieee754dp hb = ieee754dp_1e31();114115/* what if x < 0 ?? */116if (ieee754dp_lt(x, hb))117return (unsigned) ieee754dp_tint(x);118119return (unsigned) ieee754dp_tint(ieee754dp_sub(x, hb)) |120((unsigned) 1 << 31);121}122123124