1 // SPDX-License-Identifier: GPL-2.0-only 1 2 /* IEEE754 floating point arithmetic 3 * single precision 4 */ 5 /* 6 * MIPS floating point support 7 * Copyright (C) 1994-2000 Algorithmics Ltd. 8 */ 9 10 #include "ieee754sp.h" 11 12 union ieee754sp ieee754sp_mul(union ieee754sp 13 { 14 int re; 15 int rs; 16 unsigned int rm; 17 unsigned short lxm; 18 unsigned short hxm; 19 unsigned short lym; 20 unsigned short hym; 21 unsigned int lrm; 22 unsigned int hrm; 23 unsigned int t; 24 unsigned int at; 25 26 COMPXSP; 27 COMPYSP; 28 29 EXPLODEXSP; 30 EXPLODEYSP; 31 32 ieee754_clearcx(); 33 34 FLUSHXSP; 35 FLUSHYSP; 36 37 switch (CLPAIR(xc, yc)) { 38 case CLPAIR(IEEE754_CLASS_QNAN, IEEE75 39 case CLPAIR(IEEE754_CLASS_ZERO, IEEE75 40 case CLPAIR(IEEE754_CLASS_NORM, IEEE75 41 case CLPAIR(IEEE754_CLASS_DNORM, IEEE7 42 case CLPAIR(IEEE754_CLASS_INF, IEEE754 43 return ieee754sp_nanxcpt(y); 44 45 case CLPAIR(IEEE754_CLASS_SNAN, IEEE75 46 case CLPAIR(IEEE754_CLASS_SNAN, IEEE75 47 case CLPAIR(IEEE754_CLASS_SNAN, IEEE75 48 case CLPAIR(IEEE754_CLASS_SNAN, IEEE75 49 case CLPAIR(IEEE754_CLASS_SNAN, IEEE75 50 case CLPAIR(IEEE754_CLASS_SNAN, IEEE75 51 return ieee754sp_nanxcpt(x); 52 53 case CLPAIR(IEEE754_CLASS_ZERO, IEEE75 54 case CLPAIR(IEEE754_CLASS_NORM, IEEE75 55 case CLPAIR(IEEE754_CLASS_DNORM, IEEE7 56 case CLPAIR(IEEE754_CLASS_INF, IEEE754 57 return y; 58 59 case CLPAIR(IEEE754_CLASS_QNAN, IEEE75 60 case CLPAIR(IEEE754_CLASS_QNAN, IEEE75 61 case CLPAIR(IEEE754_CLASS_QNAN, IEEE75 62 case CLPAIR(IEEE754_CLASS_QNAN, IEEE75 63 case CLPAIR(IEEE754_CLASS_QNAN, IEEE75 64 return x; 65 66 67 /* 68 * Infinity handling 69 */ 70 case CLPAIR(IEEE754_CLASS_INF, IEEE754 71 case CLPAIR(IEEE754_CLASS_ZERO, IEEE75 72 ieee754_setcx(IEEE754_INVALID_ 73 return ieee754sp_indef(); 74 75 case CLPAIR(IEEE754_CLASS_NORM, IEEE75 76 case CLPAIR(IEEE754_CLASS_DNORM, IEEE7 77 case CLPAIR(IEEE754_CLASS_INF, IEEE754 78 case CLPAIR(IEEE754_CLASS_INF, IEEE754 79 case CLPAIR(IEEE754_CLASS_INF, IEEE754 80 return ieee754sp_inf(xs ^ ys); 81 82 case CLPAIR(IEEE754_CLASS_ZERO, IEEE75 83 case CLPAIR(IEEE754_CLASS_ZERO, IEEE75 84 case CLPAIR(IEEE754_CLASS_ZERO, IEEE75 85 case CLPAIR(IEEE754_CLASS_NORM, IEEE75 86 case CLPAIR(IEEE754_CLASS_DNORM, IEEE7 87 return ieee754sp_zero(xs ^ ys) 88 89 90 case CLPAIR(IEEE754_CLASS_DNORM, IEEE7 91 SPDNORMX; 92 fallthrough; 93 case CLPAIR(IEEE754_CLASS_NORM, IEEE75 94 SPDNORMY; 95 break; 96 97 case CLPAIR(IEEE754_CLASS_DNORM, IEEE7 98 SPDNORMX; 99 break; 100 101 case CLPAIR(IEEE754_CLASS_NORM, IEEE75 102 break; 103 } 104 /* rm = xm * ym, re = xe+ye basically 105 assert(xm & SP_HIDDEN_BIT); 106 assert(ym & SP_HIDDEN_BIT); 107 108 re = xe + ye; 109 rs = xs ^ ys; 110 111 /* shunt to top of word */ 112 xm <<= 32 - (SP_FBITS + 1); 113 ym <<= 32 - (SP_FBITS + 1); 114 115 /* 116 * Multiply 32 bits xm, ym to give hig 117 */ 118 lxm = xm & 0xffff; 119 hxm = xm >> 16; 120 lym = ym & 0xffff; 121 hym = ym >> 16; 122 123 lrm = lxm * lym; /* 16 * 16 => 124 hrm = hxm * hym; /* 16 * 16 => 125 126 t = lxm * hym; /* 16 * 16 => 32 */ 127 at = lrm + (t << 16); 128 hrm += at < lrm; 129 lrm = at; 130 hrm = hrm + (t >> 16); 131 132 t = hxm * lym; /* 16 * 16 => 32 */ 133 at = lrm + (t << 16); 134 hrm += at < lrm; 135 lrm = at; 136 hrm = hrm + (t >> 16); 137 138 rm = hrm | (lrm != 0); 139 140 /* 141 * Sticky shift down to normal roundin 142 */ 143 if ((int) rm < 0) { 144 rm = (rm >> (32 - (SP_FBITS + 145 ((rm << (SP_FBITS + 1 + 3) 146 re++; 147 } else { 148 rm = (rm >> (32 - (SP_FBITS + 149 ((rm << (SP_FBITS + 1 + 3 150 } 151 assert(rm & (SP_HIDDEN_BIT << 3)); 152 153 return ieee754sp_format(rs, re, rm); 154 } 155
Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.