.. | .. |
---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-only |
---|
1 | 2 | /* |
---|
2 | 3 | * IEEE754 floating point arithmetic |
---|
3 | 4 | * double precision: MADDF.f (Fused Multiply Add) |
---|
.. | .. |
---|
6 | 7 | * MIPS floating point support |
---|
7 | 8 | * Copyright (C) 2015 Imagination Technologies, Ltd. |
---|
8 | 9 | * Author: Markos Chandras <markos.chandras@imgtec.com> |
---|
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 as published by the |
---|
12 | | - * Free Software Foundation; version 2 of the License. |
---|
13 | 10 | */ |
---|
14 | 11 | |
---|
15 | 12 | #include "ieee754dp.h" |
---|
.. | .. |
---|
71 | 68 | |
---|
72 | 69 | ieee754_clearcx(); |
---|
73 | 70 | |
---|
| 71 | + rs = xs ^ ys; |
---|
| 72 | + if (flags & MADDF_NEGATE_PRODUCT) |
---|
| 73 | + rs ^= 1; |
---|
| 74 | + if (flags & MADDF_NEGATE_ADDITION) |
---|
| 75 | + zs ^= 1; |
---|
| 76 | + |
---|
74 | 77 | /* |
---|
75 | 78 | * Handle the cases when at least one of x, y or z is a NaN. |
---|
76 | 79 | * Order of precedence is sNaN, qNaN and z, x, y. |
---|
.. | .. |
---|
107 | 110 | case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_NORM): |
---|
108 | 111 | case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_DNORM): |
---|
109 | 112 | case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_INF): |
---|
110 | | - if ((zc == IEEE754_CLASS_INF) && |
---|
111 | | - ((!(flags & MADDF_NEGATE_PRODUCT) && (zs != (xs ^ ys))) || |
---|
112 | | - ((flags & MADDF_NEGATE_PRODUCT) && (zs == (xs ^ ys))))) { |
---|
| 113 | + if ((zc == IEEE754_CLASS_INF) && (zs != rs)) { |
---|
113 | 114 | /* |
---|
114 | 115 | * Cases of addition of infinities with opposite signs |
---|
115 | 116 | * or subtraction of infinities with same signs. |
---|
.. | .. |
---|
119 | 120 | } |
---|
120 | 121 | /* |
---|
121 | 122 | * z is here either not an infinity, or an infinity having the |
---|
122 | | - * same sign as product (x*y) (in case of MADDF.D instruction) |
---|
123 | | - * or product -(x*y) (in MSUBF.D case). The result must be an |
---|
124 | | - * infinity, and its sign is determined only by the value of |
---|
125 | | - * (flags & MADDF_NEGATE_PRODUCT) and the signs of x and y. |
---|
| 123 | + * same sign as product (x*y). The result must be an infinity, |
---|
| 124 | + * and its sign is determined only by the sign of product (x*y). |
---|
126 | 125 | */ |
---|
127 | | - if (flags & MADDF_NEGATE_PRODUCT) |
---|
128 | | - return ieee754dp_inf(1 ^ (xs ^ ys)); |
---|
129 | | - else |
---|
130 | | - return ieee754dp_inf(xs ^ ys); |
---|
| 126 | + return ieee754dp_inf(rs); |
---|
131 | 127 | |
---|
132 | 128 | case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_ZERO): |
---|
133 | 129 | case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_NORM): |
---|
.. | .. |
---|
138 | 134 | return ieee754dp_inf(zs); |
---|
139 | 135 | if (zc == IEEE754_CLASS_ZERO) { |
---|
140 | 136 | /* Handle cases +0 + (-0) and similar ones. */ |
---|
141 | | - if ((!(flags & MADDF_NEGATE_PRODUCT) |
---|
142 | | - && (zs == (xs ^ ys))) || |
---|
143 | | - ((flags & MADDF_NEGATE_PRODUCT) |
---|
144 | | - && (zs != (xs ^ ys)))) |
---|
| 137 | + if (zs == rs) |
---|
145 | 138 | /* |
---|
146 | 139 | * Cases of addition of zeros of equal signs |
---|
147 | 140 | * or subtraction of zeroes of opposite signs. |
---|
.. | .. |
---|
157 | 150 | |
---|
158 | 151 | case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_DNORM): |
---|
159 | 152 | DPDNORMX; |
---|
160 | | - /* fall through */ |
---|
161 | | - |
---|
| 153 | + fallthrough; |
---|
162 | 154 | case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_DNORM): |
---|
163 | 155 | if (zc == IEEE754_CLASS_INF) |
---|
164 | 156 | return ieee754dp_inf(zs); |
---|
.. | .. |
---|
190 | 182 | assert(ym & DP_HIDDEN_BIT); |
---|
191 | 183 | |
---|
192 | 184 | re = xe + ye; |
---|
193 | | - rs = xs ^ ys; |
---|
194 | | - if (flags & MADDF_NEGATE_PRODUCT) |
---|
195 | | - rs ^= 1; |
---|
196 | 185 | |
---|
197 | 186 | /* shunt to top of word */ |
---|
198 | 187 | xm <<= 64 - (DP_FBITS + 1); |
---|
.. | .. |
---|
343 | 332 | { |
---|
344 | 333 | return _dp_maddf(z, x, y, MADDF_NEGATE_PRODUCT); |
---|
345 | 334 | } |
---|
| 335 | + |
---|
| 336 | +union ieee754dp ieee754dp_madd(union ieee754dp z, union ieee754dp x, |
---|
| 337 | + union ieee754dp y) |
---|
| 338 | +{ |
---|
| 339 | + return _dp_maddf(z, x, y, 0); |
---|
| 340 | +} |
---|
| 341 | + |
---|
| 342 | +union ieee754dp ieee754dp_msub(union ieee754dp z, union ieee754dp x, |
---|
| 343 | + union ieee754dp y) |
---|
| 344 | +{ |
---|
| 345 | + return _dp_maddf(z, x, y, MADDF_NEGATE_ADDITION); |
---|
| 346 | +} |
---|
| 347 | + |
---|
| 348 | +union ieee754dp ieee754dp_nmadd(union ieee754dp z, union ieee754dp x, |
---|
| 349 | + union ieee754dp y) |
---|
| 350 | +{ |
---|
| 351 | + return _dp_maddf(z, x, y, MADDF_NEGATE_PRODUCT|MADDF_NEGATE_ADDITION); |
---|
| 352 | +} |
---|
| 353 | + |
---|
| 354 | +union ieee754dp ieee754dp_nmsub(union ieee754dp z, union ieee754dp x, |
---|
| 355 | + union ieee754dp y) |
---|
| 356 | +{ |
---|
| 357 | + return _dp_maddf(z, x, y, MADDF_NEGATE_PRODUCT); |
---|
| 358 | +} |
---|