Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
dp_tint.c
Go to the documentation of this file.
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:
44  return ieee754si_xcpt(ieee754si_indef(), "dp_tint", x);
45  case IEEE754_CLASS_ZERO:
46  return 0;
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 */
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 */
100  return ieee754si_xcpt(ieee754si_indef(), "dp_tint", x);
101  }
102  if (round || sticky)
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 }