.. | .. |
---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-only |
---|
1 | 2 | /* |
---|
2 | 3 | * IEEE754 floating point arithmetic |
---|
3 | 4 | * single 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 "ieee754sp.h" |
---|
.. | .. |
---|
38 | 35 | FLUSHZSP; |
---|
39 | 36 | |
---|
40 | 37 | ieee754_clearcx(); |
---|
| 38 | + |
---|
| 39 | + rs = xs ^ ys; |
---|
| 40 | + if (flags & MADDF_NEGATE_PRODUCT) |
---|
| 41 | + rs ^= 1; |
---|
| 42 | + if (flags & MADDF_NEGATE_ADDITION) |
---|
| 43 | + zs ^= 1; |
---|
41 | 44 | |
---|
42 | 45 | /* |
---|
43 | 46 | * Handle the cases when at least one of x, y or z is a NaN. |
---|
.. | .. |
---|
76 | 79 | case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_NORM): |
---|
77 | 80 | case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_DNORM): |
---|
78 | 81 | case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_INF): |
---|
79 | | - if ((zc == IEEE754_CLASS_INF) && |
---|
80 | | - ((!(flags & MADDF_NEGATE_PRODUCT) && (zs != (xs ^ ys))) || |
---|
81 | | - ((flags & MADDF_NEGATE_PRODUCT) && (zs == (xs ^ ys))))) { |
---|
| 82 | + if ((zc == IEEE754_CLASS_INF) && (zs != rs)) { |
---|
82 | 83 | /* |
---|
83 | 84 | * Cases of addition of infinities with opposite signs |
---|
84 | 85 | * or subtraction of infinities with same signs. |
---|
.. | .. |
---|
88 | 89 | } |
---|
89 | 90 | /* |
---|
90 | 91 | * z is here either not an infinity, or an infinity having the |
---|
91 | | - * same sign as product (x*y) (in case of MADDF.D instruction) |
---|
92 | | - * or product -(x*y) (in MSUBF.D case). The result must be an |
---|
93 | | - * infinity, and its sign is determined only by the value of |
---|
94 | | - * (flags & MADDF_NEGATE_PRODUCT) and the signs of x and y. |
---|
| 92 | + * same sign as product (x*y). The result must be an infinity, |
---|
| 93 | + * and its sign is determined only by the sign of product (x*y). |
---|
95 | 94 | */ |
---|
96 | | - if (flags & MADDF_NEGATE_PRODUCT) |
---|
97 | | - return ieee754sp_inf(1 ^ (xs ^ ys)); |
---|
98 | | - else |
---|
99 | | - return ieee754sp_inf(xs ^ ys); |
---|
| 95 | + return ieee754sp_inf(rs); |
---|
100 | 96 | |
---|
101 | 97 | case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_ZERO): |
---|
102 | 98 | case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_NORM): |
---|
.. | .. |
---|
107 | 103 | return ieee754sp_inf(zs); |
---|
108 | 104 | if (zc == IEEE754_CLASS_ZERO) { |
---|
109 | 105 | /* Handle cases +0 + (-0) and similar ones. */ |
---|
110 | | - if ((!(flags & MADDF_NEGATE_PRODUCT) |
---|
111 | | - && (zs == (xs ^ ys))) || |
---|
112 | | - ((flags & MADDF_NEGATE_PRODUCT) |
---|
113 | | - && (zs != (xs ^ ys)))) |
---|
| 106 | + if (zs == rs) |
---|
114 | 107 | /* |
---|
115 | 108 | * Cases of addition of zeros of equal signs |
---|
116 | 109 | * or subtraction of zeroes of opposite signs. |
---|
.. | .. |
---|
126 | 119 | |
---|
127 | 120 | case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_DNORM): |
---|
128 | 121 | SPDNORMX; |
---|
129 | | - /* fall through */ |
---|
130 | | - |
---|
| 122 | + fallthrough; |
---|
131 | 123 | case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_DNORM): |
---|
132 | 124 | if (zc == IEEE754_CLASS_INF) |
---|
133 | 125 | return ieee754sp_inf(zs); |
---|
.. | .. |
---|
161 | 153 | assert(ym & SP_HIDDEN_BIT); |
---|
162 | 154 | |
---|
163 | 155 | re = xe + ye; |
---|
164 | | - rs = xs ^ ys; |
---|
165 | | - if (flags & MADDF_NEGATE_PRODUCT) |
---|
166 | | - rs ^= 1; |
---|
167 | 156 | |
---|
168 | 157 | /* Multiple 24 bit xm and ym to give 48 bit results */ |
---|
169 | 158 | rm64 = (uint64_t)xm * ym; |
---|
.. | .. |
---|
263 | 252 | { |
---|
264 | 253 | return _sp_maddf(z, x, y, MADDF_NEGATE_PRODUCT); |
---|
265 | 254 | } |
---|
| 255 | + |
---|
| 256 | +union ieee754sp ieee754sp_madd(union ieee754sp z, union ieee754sp x, |
---|
| 257 | + union ieee754sp y) |
---|
| 258 | +{ |
---|
| 259 | + return _sp_maddf(z, x, y, 0); |
---|
| 260 | +} |
---|
| 261 | + |
---|
| 262 | +union ieee754sp ieee754sp_msub(union ieee754sp z, union ieee754sp x, |
---|
| 263 | + union ieee754sp y) |
---|
| 264 | +{ |
---|
| 265 | + return _sp_maddf(z, x, y, MADDF_NEGATE_ADDITION); |
---|
| 266 | +} |
---|
| 267 | + |
---|
| 268 | +union ieee754sp ieee754sp_nmadd(union ieee754sp z, union ieee754sp x, |
---|
| 269 | + union ieee754sp y) |
---|
| 270 | +{ |
---|
| 271 | + return _sp_maddf(z, x, y, MADDF_NEGATE_PRODUCT|MADDF_NEGATE_ADDITION); |
---|
| 272 | +} |
---|
| 273 | + |
---|
| 274 | +union ieee754sp ieee754sp_nmsub(union ieee754sp z, union ieee754sp x, |
---|
| 275 | + union ieee754sp y) |
---|
| 276 | +{ |
---|
| 277 | + return _sp_maddf(z, x, y, MADDF_NEGATE_PRODUCT); |
---|
| 278 | +} |
---|