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_sub.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 "
ieee754sp.h
"
28
29
ieee754sp
ieee754sp_sub
(ieee754sp
x
, ieee754sp
y
)
30
{
31
COMPXSP
;
32
COMPYSP
;
33
34
EXPLODEXSP
;
35
EXPLODEYSP
;
36
37
CLEARCX
;
38
39
FLUSHXSP
;
40
FLUSHYSP
;
41
42
switch
(
CLPAIR
(
xc
, yc)) {
43
case
CLPAIR
(
IEEE754_CLASS_SNAN
,
IEEE754_CLASS_QNAN
):
44
case
CLPAIR
(
IEEE754_CLASS_QNAN
,
IEEE754_CLASS_SNAN
):
45
case
CLPAIR
(
IEEE754_CLASS_SNAN
,
IEEE754_CLASS_SNAN
):
46
case
CLPAIR
(
IEEE754_CLASS_ZERO
,
IEEE754_CLASS_SNAN
):
47
case
CLPAIR
(
IEEE754_CLASS_NORM
,
IEEE754_CLASS_SNAN
):
48
case
CLPAIR
(
IEEE754_CLASS_DNORM
,
IEEE754_CLASS_SNAN
):
49
case
CLPAIR
(
IEEE754_CLASS_INF
,
IEEE754_CLASS_SNAN
):
50
case
CLPAIR
(
IEEE754_CLASS_SNAN
,
IEEE754_CLASS_ZERO
):
51
case
CLPAIR
(
IEEE754_CLASS_SNAN
,
IEEE754_CLASS_NORM
):
52
case
CLPAIR
(
IEEE754_CLASS_SNAN
,
IEEE754_CLASS_DNORM
):
53
case
CLPAIR
(
IEEE754_CLASS_SNAN
,
IEEE754_CLASS_INF
):
54
SETCX
(
IEEE754_INVALID_OPERATION
);
55
return
ieee754sp_nanxcpt
(
ieee754sp_indef
(),
"sub"
, x, y);
56
57
case
CLPAIR
(
IEEE754_CLASS_ZERO
,
IEEE754_CLASS_QNAN
):
58
case
CLPAIR
(
IEEE754_CLASS_NORM
,
IEEE754_CLASS_QNAN
):
59
case
CLPAIR
(
IEEE754_CLASS_DNORM
,
IEEE754_CLASS_QNAN
):
60
case
CLPAIR
(
IEEE754_CLASS_INF
,
IEEE754_CLASS_QNAN
):
61
return
y
;
62
63
case
CLPAIR
(
IEEE754_CLASS_QNAN
,
IEEE754_CLASS_QNAN
):
64
case
CLPAIR
(
IEEE754_CLASS_QNAN
,
IEEE754_CLASS_ZERO
):
65
case
CLPAIR
(
IEEE754_CLASS_QNAN
,
IEEE754_CLASS_NORM
):
66
case
CLPAIR
(
IEEE754_CLASS_QNAN
,
IEEE754_CLASS_DNORM
):
67
case
CLPAIR
(
IEEE754_CLASS_QNAN
,
IEEE754_CLASS_INF
):
68
return
x
;
69
70
71
/* Infinity handling
72
*/
73
74
case
CLPAIR
(
IEEE754_CLASS_INF
,
IEEE754_CLASS_INF
):
75
if
(
xs
!=
ys
)
76
return
x
;
77
SETCX
(
IEEE754_INVALID_OPERATION
);
78
return
ieee754sp_xcpt
(
ieee754sp_indef
(),
"sub"
, x, y);
79
80
case
CLPAIR
(
IEEE754_CLASS_ZERO
,
IEEE754_CLASS_INF
):
81
case
CLPAIR
(
IEEE754_CLASS_DNORM
,
IEEE754_CLASS_INF
):
82
case
CLPAIR
(
IEEE754_CLASS_NORM
,
IEEE754_CLASS_INF
):
83
return
ieee754sp_inf
(
ys
^ 1);
84
85
case
CLPAIR
(
IEEE754_CLASS_INF
,
IEEE754_CLASS_ZERO
):
86
case
CLPAIR
(
IEEE754_CLASS_INF
,
IEEE754_CLASS_NORM
):
87
case
CLPAIR
(
IEEE754_CLASS_INF
,
IEEE754_CLASS_DNORM
):
88
return
x
;
89
90
/* Zero handling
91
*/
92
93
case
CLPAIR
(
IEEE754_CLASS_ZERO
,
IEEE754_CLASS_ZERO
):
94
if
(
xs
!=
ys
)
95
return
x
;
96
else
97
return
ieee754sp_zero
(
ieee754_csr
.rm ==
98
IEEE754_RD
);
99
100
case
CLPAIR
(
IEEE754_CLASS_NORM
,
IEEE754_CLASS_ZERO
):
101
case
CLPAIR
(
IEEE754_CLASS_DNORM
,
IEEE754_CLASS_ZERO
):
102
return
x
;
103
104
case
CLPAIR
(
IEEE754_CLASS_ZERO
,
IEEE754_CLASS_NORM
):
105
case
CLPAIR
(
IEEE754_CLASS_ZERO
,
IEEE754_CLASS_DNORM
):
106
/* quick fix up */
107
DPSIGN
(y) ^= 1;
108
return
y
;
109
110
case
CLPAIR
(
IEEE754_CLASS_DNORM
,
IEEE754_CLASS_DNORM
):
111
SPDNORMX
;
112
113
case
CLPAIR
(
IEEE754_CLASS_NORM
,
IEEE754_CLASS_DNORM
):
114
SPDNORMY
;
115
break
;
116
117
case
CLPAIR
(
IEEE754_CLASS_DNORM
,
IEEE754_CLASS_NORM
):
118
SPDNORMX
;
119
break
;
120
121
case
CLPAIR
(
IEEE754_CLASS_NORM
,
IEEE754_CLASS_NORM
):
122
break
;
123
}
124
/* flip sign of y and handle as add */
125
ys
^= 1;
126
127
assert
(xm &
SP_HIDDEN_BIT
);
128
assert
(ym & SP_HIDDEN_BIT);
129
130
131
/* provide guard,round and stick bit space */
132
xm <<= 3;
133
ym <<= 3;
134
135
if
(
xe
>
ye
) {
136
/* have to shift y fraction right to align
137
*/
138
int
s
=
xe
-
ye
;
139
SPXSRSYn
(s);
140
}
else
if
(
ye
>
xe
) {
141
/* have to shift x fraction right to align
142
*/
143
int
s
=
ye
-
xe
;
144
SPXSRSXn
(s);
145
}
146
assert
(
xe
==
ye
);
147
assert
(
xe
<=
SP_EMAX
);
148
149
if
(
xs
==
ys
) {
150
/* generate 28 bit result of adding two 27 bit numbers
151
*/
152
xm = xm + ym;
153
xe
=
xe
;
154
xs
=
xs
;
155
156
if
(xm >> (
SP_MBITS
+ 1 + 3)) {
/* carry out */
157
SPXSRSX1
();
/* shift preserving sticky */
158
}
159
}
else
{
160
if
(xm >= ym) {
161
xm = xm - ym;
162
xe
=
xe
;
163
xs
=
xs
;
164
}
else
{
165
xm = ym - xm;
166
xe
=
xe
;
167
xs
=
ys
;
168
}
169
if
(xm == 0) {
170
if
(
ieee754_csr
.rm ==
IEEE754_RD
)
171
return
ieee754sp_zero
(1);
/* round negative inf. => sign = -1 */
172
else
173
return
ieee754sp_zero
(0);
/* other round modes => sign = 1 */
174
}
175
/* normalize to rounding precision
176
*/
177
while
((xm >> (
SP_MBITS
+ 3)) == 0) {
178
xm <<= 1;
179
xe
--;
180
}
181
}
182
SPNORMRET2
(
xs
,
xe
, xm,
"sub"
, x, y);
183
}
Generated on Thu Jan 10 2013 13:11:40 for Linux Kernel by
1.8.2