1 /* IEEE754 floating point arithmetic 2 * double precision: common utilities 3 */ 4 /* 5 * MIPS floating point support 6 * Copyright (C) 1994-2000 Algorithmics Ltd. 7 * 8 * ######################################################################## 9 * 10 * This program is free software; you can distribute it and/or modify it 11 * under the terms of the GNU General Public License (Version 2) as 12 * published by the Free Software Foundation. 13 * 14 * This program is distributed in the hope it will be useful, but WITHOUT 15 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 16 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 17 * for more details. 18 * 19 * You should have received a copy of the GNU General Public License along 20 * with this program; if not, write to the Free Software Foundation, Inc., 21 * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. 22 * 23 * ######################################################################## 24 */ 25 26 27 #include <linux/kernel.h> 28 #include "ieee754dp.h" 29 30 int ieee754dp_tint(ieee754dp x) 31 { 32 COMPXDP; 33 34 CLEARCX; 35 36 EXPLODEXDP; 37 FLUSHXDP; 38 39 switch (xc) { 40 case IEEE754_CLASS_SNAN: 41 case IEEE754_CLASS_QNAN: 42 case IEEE754_CLASS_INF: 43 SETCX(IEEE754_INVALID_OPERATION); 44 return ieee754si_xcpt(ieee754si_indef(), "dp_tint", x); 45 case IEEE754_CLASS_ZERO: 46 return 0; 47 case IEEE754_CLASS_DNORM: 48 case IEEE754_CLASS_NORM: 49 break; 50 } 51 if (xe > 31) { 52 /* Set invalid. We will only use overflow for floating 53 point overflow */ 54 SETCX(IEEE754_INVALID_OPERATION); 55 return ieee754si_xcpt(ieee754si_indef(), "dp_tint", x); 56 } 57 /* oh gawd */ 58 if (xe > DP_MBITS) { 59 xm <<= xe - DP_MBITS; 60 } else if (xe < DP_MBITS) { 61 u64 residue; 62 int round; 63 int sticky; 64 int odd; 65 66 if (xe < -1) { 67 residue = xm; 68 round = 0; 69 sticky = residue != 0; 70 xm = 0; 71 } else { 72 residue = xm << (64 - DP_MBITS + xe); 73 round = (residue >> 63) != 0; 74 sticky = (residue << 1) != 0; 75 xm >>= DP_MBITS - xe; 76 } 77 /* Note: At this point upper 32 bits of xm are guaranteed 78 to be zero */ 79 odd = (xm & 0x1) != 0x0; 80 switch (ieee754_csr.rm) { 81 case IEEE754_RN: 82 if (round && (sticky || odd)) 83 xm++; 84 break; 85 case IEEE754_RZ: 86 break; 87 case IEEE754_RU: /* toward +Infinity */ 88 if ((round || sticky) && !xs) 89 xm++; 90 break; 91 case IEEE754_RD: /* toward -Infinity */ 92 if ((round || sticky) && xs) 93 xm++; 94 break; 95 } 96 /* look for valid corner case 0x80000000 */ 97 if ((xm >> 31) != 0 && (xs == 0 || xm != 0x80000000)) { 98 /* This can happen after rounding */ 99 SETCX(IEEE754_INVALID_OPERATION); 100 return ieee754si_xcpt(ieee754si_indef(), "dp_tint", x); 101 } 102 if (round || sticky) 103 SETCX(IEEE754_INEXACT); 104 } 105 if (xs) 106 return -xm; 107 else 108 return xm; 109 } 110 111 112 unsigned int ieee754dp_tuns(ieee754dp x) 113 { 114 ieee754dp hb = ieee754dp_1e31(); 115 116 /* what if x < 0 ?? */ 117 if (ieee754dp_lt(x, hb)) 118 return (unsigned) ieee754dp_tint(x); 119 120 return (unsigned) ieee754dp_tint(ieee754dp_sub(x, hb)) | 121 ((unsigned) 1 << 31); 122 } 123