Linux Kernel
3.7.1
Main Page
Related Pages
Modules
Namespaces
Data Structures
Files
File List
Globals
All
Data Structures
Namespaces
Files
Functions
Variables
Typedefs
Enumerations
Enumerator
Macros
Groups
Pages
arch
mips
math-emu
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
:
43
SETCX
(
IEEE754_INVALID_OPERATION
);
44
return
ieee754si_xcpt
(
ieee754si_indef
(),
"sp_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
/* 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 */
57
SETCX
(
IEEE754_INVALID_OPERATION
);
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 */
103
SETCX
(
IEEE754_INVALID_OPERATION
);
104
return
ieee754si_xcpt
(
ieee754si_indef
(),
"sp_tint"
, x);
105
}
106
if
(round || sticky)
107
SETCX
(
IEEE754_INEXACT
);
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
}
Generated on Thu Jan 10 2013 13:11:40 for Linux Kernel by
1.8.2