Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
torvalds
GitHub Repository: torvalds/linux
Path: blob/master/arch/mips/math-emu/dp_add.c
26442 views
1
// SPDX-License-Identifier: GPL-2.0-only
2
/* IEEE754 floating point arithmetic
3
* double precision: common utilities
4
*/
5
/*
6
* MIPS floating point support
7
* Copyright (C) 1994-2000 Algorithmics Ltd.
8
*/
9
10
#include "ieee754dp.h"
11
12
union ieee754dp ieee754dp_add(union ieee754dp x, union ieee754dp y)
13
{
14
int s;
15
16
COMPXDP;
17
COMPYDP;
18
19
EXPLODEXDP;
20
EXPLODEYDP;
21
22
ieee754_clearcx();
23
24
FLUSHXDP;
25
FLUSHYDP;
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 ieee754dp_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 ieee754dp_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 ieee754dp_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 ieee754dp_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
DPDNORMX;
95
fallthrough;
96
case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_DNORM):
97
DPDNORMY;
98
break;
99
100
case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_NORM):
101
DPDNORMX;
102
break;
103
104
case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_NORM):
105
break;
106
}
107
assert(xm & DP_HIDDEN_BIT);
108
assert(ym & DP_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 = XDPSRS(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 = XDPSRS(xm, s);
129
xe += s;
130
}
131
assert(xe == ye);
132
assert(xe <= DP_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 >> (DP_FBITS + 1 + 3)) { /* carry out */
142
xm = XDPSRS1(xm);
143
xe++;
144
}
145
} else {
146
if (xm >= ym) {
147
xm = xm - ym;
148
} else {
149
xm = ym - xm;
150
xs = ys;
151
}
152
if (xm == 0)
153
return ieee754dp_zero(ieee754_csr.rm == FPU_CSR_RD);
154
155
/*
156
* Normalize to rounding precision.
157
*/
158
while ((xm >> (DP_FBITS + 3)) == 0) {
159
xm <<= 1;
160
xe--;
161
}
162
}
163
164
return ieee754dp_format(xs, xe, xm);
165
}
166
167