^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * IEEE754 floating point arithmetic
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * single precision: MADDF.f (Fused Multiply Add)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * MADDF.fmt: FPR[fd] = FPR[fd] + (FPR[fs] x FPR[ft])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * MIPS floating point support
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) * Copyright (C) 2015 Imagination Technologies, Ltd.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) * Author: Markos Chandras <markos.chandras@imgtec.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include "ieee754sp.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) static union ieee754sp _sp_maddf(union ieee754sp z, union ieee754sp x,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) union ieee754sp y, enum maddf_flags flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) int re;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) int rs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) unsigned int rm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) u64 rm64;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) u64 zm64;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) int s;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) COMPXSP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) COMPYSP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) COMPZSP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) EXPLODEXSP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) EXPLODEYSP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) EXPLODEZSP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) FLUSHXSP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) FLUSHYSP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) FLUSHZSP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) ieee754_clearcx();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) rs = xs ^ ys;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) if (flags & MADDF_NEGATE_PRODUCT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) rs ^= 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) if (flags & MADDF_NEGATE_ADDITION)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) zs ^= 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) * Handle the cases when at least one of x, y or z is a NaN.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) * Order of precedence is sNaN, qNaN and z, x, y.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) if (zc == IEEE754_CLASS_SNAN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) return ieee754sp_nanxcpt(z);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) if (xc == IEEE754_CLASS_SNAN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) return ieee754sp_nanxcpt(x);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) if (yc == IEEE754_CLASS_SNAN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) return ieee754sp_nanxcpt(y);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) if (zc == IEEE754_CLASS_QNAN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) return z;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) if (xc == IEEE754_CLASS_QNAN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) return x;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) if (yc == IEEE754_CLASS_QNAN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) return y;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) if (zc == IEEE754_CLASS_DNORM)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) SPDNORMZ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) /* ZERO z cases are handled separately below */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) switch (CLPAIR(xc, yc)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) * Infinity handling
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_ZERO):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_INF):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) ieee754_setcx(IEEE754_INVALID_OPERATION);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) return ieee754sp_indef();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_INF):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_INF):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_NORM):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_DNORM):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_INF):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) if ((zc == IEEE754_CLASS_INF) && (zs != rs)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) * Cases of addition of infinities with opposite signs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) * or subtraction of infinities with same signs.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) ieee754_setcx(IEEE754_INVALID_OPERATION);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) return ieee754sp_indef();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) * z is here either not an infinity, or an infinity having the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) * same sign as product (x*y). The result must be an infinity,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) * and its sign is determined only by the sign of product (x*y).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) return ieee754sp_inf(rs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_ZERO):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_NORM):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_DNORM):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_ZERO):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_ZERO):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) if (zc == IEEE754_CLASS_INF)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) return ieee754sp_inf(zs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) if (zc == IEEE754_CLASS_ZERO) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) /* Handle cases +0 + (-0) and similar ones. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) if (zs == rs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) * Cases of addition of zeros of equal signs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) * or subtraction of zeroes of opposite signs.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) * The sign of the resulting zero is in any
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) * such case determined only by the sign of z.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) return z;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) return ieee754sp_zero(ieee754_csr.rm == FPU_CSR_RD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) /* x*y is here 0, and z is not 0, so just return z */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) return z;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_DNORM):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) SPDNORMX;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) fallthrough;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_DNORM):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) if (zc == IEEE754_CLASS_INF)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) return ieee754sp_inf(zs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) SPDNORMY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_NORM):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) if (zc == IEEE754_CLASS_INF)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) return ieee754sp_inf(zs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) SPDNORMX;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_NORM):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) if (zc == IEEE754_CLASS_INF)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) return ieee754sp_inf(zs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) /* continue to real computations */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) /* Finally get to do some computation */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) * Do the multiplication bit first
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) * rm = xm * ym, re = xe + ye basically
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) * At this point xm and ym should have been normalized.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) /* rm = xm * ym, re = xe+ye basically */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) assert(xm & SP_HIDDEN_BIT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) assert(ym & SP_HIDDEN_BIT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) re = xe + ye;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) /* Multiple 24 bit xm and ym to give 48 bit results */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) rm64 = (uint64_t)xm * ym;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) /* Shunt to top of word */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) rm64 = rm64 << 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) /* Put explicit bit at bit 62 if necessary */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) if ((int64_t) rm64 < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) rm64 = rm64 >> 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) re++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) assert(rm64 & (1 << 62));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) if (zc == IEEE754_CLASS_ZERO) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) * Move explicit bit from bit 62 to bit 26 since the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) * ieee754sp_format code expects the mantissa to be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) * 27 bits wide (24 + 3 rounding bits).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) rm = XSPSRS64(rm64, (62 - 26));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) return ieee754sp_format(rs, re, rm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) /* Move explicit bit from bit 23 to bit 62 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) zm64 = (uint64_t)zm << (62 - 23);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) assert(zm64 & (1 << 62));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) /* Make the exponents the same */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) if (ze > re) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) * Have to shift r fraction right to align.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) s = ze - re;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) rm64 = XSPSRS64(rm64, s);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) re += s;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) } else if (re > ze) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) * Have to shift z fraction right to align.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) s = re - ze;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) zm64 = XSPSRS64(zm64, s);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) ze += s;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) assert(ze == re);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) assert(ze <= SP_EMAX);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) /* Do the addition */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) if (zs == rs) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) * Generate 64 bit result by adding two 63 bit numbers
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) * leaving result in zm64, zs and ze.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) zm64 = zm64 + rm64;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) if ((int64_t)zm64 < 0) { /* carry out */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) zm64 = XSPSRS1(zm64);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) ze++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) if (zm64 >= rm64) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) zm64 = zm64 - rm64;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) zm64 = rm64 - zm64;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) zs = rs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) if (zm64 == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) return ieee754sp_zero(ieee754_csr.rm == FPU_CSR_RD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) * Put explicit bit at bit 62 if necessary.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) while ((zm64 >> 62) == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) zm64 <<= 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) ze--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) * Move explicit bit from bit 62 to bit 26 since the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) * ieee754sp_format code expects the mantissa to be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) * 27 bits wide (24 + 3 rounding bits).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) zm = XSPSRS64(zm64, (62 - 26));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) return ieee754sp_format(zs, ze, zm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) union ieee754sp ieee754sp_maddf(union ieee754sp z, union ieee754sp x,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) union ieee754sp y)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) return _sp_maddf(z, x, y, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) union ieee754sp ieee754sp_msubf(union ieee754sp z, union ieee754sp x,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) union ieee754sp y)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) return _sp_maddf(z, x, y, MADDF_NEGATE_PRODUCT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) union ieee754sp ieee754sp_madd(union ieee754sp z, union ieee754sp x,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) union ieee754sp y)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) return _sp_maddf(z, x, y, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) union ieee754sp ieee754sp_msub(union ieee754sp z, union ieee754sp x,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) union ieee754sp y)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) return _sp_maddf(z, x, y, MADDF_NEGATE_ADDITION);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) union ieee754sp ieee754sp_nmadd(union ieee754sp z, union ieee754sp x,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) union ieee754sp y)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) return _sp_maddf(z, x, y, MADDF_NEGATE_PRODUCT|MADDF_NEGATE_ADDITION);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) union ieee754sp ieee754sp_nmsub(union ieee754sp z, union ieee754sp x,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) union ieee754sp y)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) return _sp_maddf(z, x, y, MADDF_NEGATE_PRODUCT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) }