Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
sp_tint.c
Go to the documentation of this file.
1 /* IEEE754 floating point arithmetic
2  * single precision
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 "ieee754sp.h"
29 
30 int ieee754sp_tint(ieee754sp x)
31 {
32  COMPXSP;
33 
34  CLEARCX;
35 
36  EXPLODEXSP;
37  FLUSHXSP;
38 
39  switch (xc) {
40  case IEEE754_CLASS_SNAN:
41  case IEEE754_CLASS_QNAN:
42  case IEEE754_CLASS_INF:
44  return ieee754si_xcpt(ieee754si_indef(), "sp_tint", x);
45  case IEEE754_CLASS_ZERO:
46  return 0;
48  case IEEE754_CLASS_NORM:
49  break;
50  }
51  if (xe >= 31) {
52  /* look for valid corner case */
53  if (xe == 31 && xs && xm == SP_HIDDEN_BIT)
54  return -0x80000000;
55  /* Set invalid. We will only use overflow for floating
56  point overflow */
58  return ieee754si_xcpt(ieee754si_indef(), "sp_tint", x);
59  }
60  /* oh gawd */
61  if (xe > SP_MBITS) {
62  xm <<= xe - SP_MBITS;
63  } else {
64  u32 residue;
65  int round;
66  int sticky;
67  int odd;
68 
69  if (xe < -1) {
70  residue = xm;
71  round = 0;
72  sticky = residue != 0;
73  xm = 0;
74  } else {
75  /* Shifting a u32 32 times does not work,
76  * so we do it in two steps. Be aware that xe
77  * may be -1 */
78  residue = xm << (xe + 1);
79  residue <<= 31 - SP_MBITS;
80  round = (residue >> 31) != 0;
81  sticky = (residue << 1) != 0;
82  xm >>= SP_MBITS - xe;
83  }
84  odd = (xm & 0x1) != 0x0;
85  switch (ieee754_csr.rm) {
86  case IEEE754_RN:
87  if (round && (sticky || odd))
88  xm++;
89  break;
90  case IEEE754_RZ:
91  break;
92  case IEEE754_RU: /* toward +Infinity */
93  if ((round || sticky) && !xs)
94  xm++;
95  break;
96  case IEEE754_RD: /* toward -Infinity */
97  if ((round || sticky) && xs)
98  xm++;
99  break;
100  }
101  if ((xm >> 31) != 0) {
102  /* This can happen after rounding */
104  return ieee754si_xcpt(ieee754si_indef(), "sp_tint", x);
105  }
106  if (round || sticky)
108  }
109  if (xs)
110  return -xm;
111  else
112  return xm;
113 }
114 
115 
116 unsigned int ieee754sp_tuns(ieee754sp x)
117 {
118  ieee754sp hb = ieee754sp_1e31();
119 
120  /* what if x < 0 ?? */
121  if (ieee754sp_lt(x, hb))
122  return (unsigned) ieee754sp_tint(x);
123 
124  return (unsigned) ieee754sp_tint(ieee754sp_sub(x, hb)) |
125  ((unsigned) 1 << 31);
126 }