| .. | .. |
|---|
| 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 | +} |
|---|