Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
torvalds
GitHub Repository: torvalds/linux
Path: blob/master/arch/mips/math-emu/sp_add.c
26424 views
1
// SPDX-License-Identifier: GPL-2.0-only
2
/* IEEE754 floating point arithmetic
3
* single precision
4
*/
5
/*
6
* MIPS floating point support
7
* Copyright (C) 1994-2000 Algorithmics Ltd.
8
*/
9
10
#include "ieee754sp.h"
11
12
union ieee754sp ieee754sp_add(union ieee754sp x, union ieee754sp y)
13
{
14
int s;
15
16
COMPXSP;
17
COMPYSP;
18
19
EXPLODEXSP;
20
EXPLODEYSP;
21
22
ieee754_clearcx();
23
24
FLUSHXSP;
25
FLUSHYSP;
26
27
switch (CLPAIR(xc, yc)) {
28
case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_SNAN):
29
case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_SNAN):
30
case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_SNAN):
31
case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_SNAN):
32
case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_SNAN):
33
return ieee754sp_nanxcpt(y);
34
35
case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_SNAN):
36
case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_QNAN):
37
case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_ZERO):
38
case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_NORM):
39
case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_DNORM):
40
case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_INF):
41
return ieee754sp_nanxcpt(x);
42
43
case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_QNAN):
44
case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_QNAN):
45
case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_QNAN):
46
case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_QNAN):
47
return y;
48
49
case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_QNAN):
50
case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_ZERO):
51
case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_NORM):
52
case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_DNORM):
53
case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_INF):
54
return x;
55
56
57
/*
58
* Infinity handling
59
*/
60
case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_INF):
61
if (xs == ys)
62
return x;
63
ieee754_setcx(IEEE754_INVALID_OPERATION);
64
return ieee754sp_indef();
65
66
case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_INF):
67
case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_INF):
68
case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_INF):
69
return y;
70
71
case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_ZERO):
72
case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_NORM):
73
case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_DNORM):
74
return x;
75
76
/*
77
* Zero handling
78
*/
79
case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_ZERO):
80
if (xs == ys)
81
return x;
82
else
83
return ieee754sp_zero(ieee754_csr.rm == FPU_CSR_RD);
84
85
case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_ZERO):
86
case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_ZERO):
87
return x;
88
89
case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_NORM):
90
case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_DNORM):
91
return y;
92
93
case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_DNORM):
94
SPDNORMX;
95
fallthrough;
96
case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_DNORM):
97
SPDNORMY;
98
break;
99
100
case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_NORM):
101
SPDNORMX;
102
break;
103
104
case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_NORM):
105
break;
106
}
107
assert(xm & SP_HIDDEN_BIT);
108
assert(ym & SP_HIDDEN_BIT);
109
110
/*
111
* Provide guard, round and stick bit space.
112
*/
113
xm <<= 3;
114
ym <<= 3;
115
116
if (xe > ye) {
117
/*
118
* Have to shift y fraction right to align.
119
*/
120
s = xe - ye;
121
ym = XSPSRS(ym, s);
122
ye += s;
123
} else if (ye > xe) {
124
/*
125
* Have to shift x fraction right to align.
126
*/
127
s = ye - xe;
128
xm = XSPSRS(xm, s);
129
xe += s;
130
}
131
assert(xe == ye);
132
assert(xe <= SP_EMAX);
133
134
if (xs == ys) {
135
/*
136
* Generate 28 bit result of adding two 27 bit numbers
137
* leaving result in xm, xs and xe.
138
*/
139
xm = xm + ym;
140
141
if (xm >> (SP_FBITS + 1 + 3)) { /* carry out */
142
SPXSRSX1();
143
}
144
} else {
145
if (xm >= ym) {
146
xm = xm - ym;
147
} else {
148
xm = ym - xm;
149
xs = ys;
150
}
151
if (xm == 0)
152
return ieee754sp_zero(ieee754_csr.rm == FPU_CSR_RD);
153
154
/*
155
* Normalize in extended single precision
156
*/
157
while ((xm >> (SP_FBITS + 3)) == 0) {
158
xm <<= 1;
159
xe--;
160
}
161
}
162
163
return ieee754sp_format(xs, xe, xm);
164
}
165
166