1 // SPDX-License-Identifier: GPL-2.0-only 1 // SPDX-License-Identifier: GPL-2.0-only 2 /* IEEE754 floating point arithmetic 2 /* IEEE754 floating point arithmetic 3 * single precision 3 * single precision 4 */ 4 */ 5 /* 5 /* 6 * MIPS floating point support 6 * MIPS floating point support 7 * Copyright (C) 1994-2000 Algorithmics Ltd. 7 * Copyright (C) 1994-2000 Algorithmics Ltd. 8 */ 8 */ 9 9 10 #include "ieee754sp.h" 10 #include "ieee754sp.h" 11 11 12 union ieee754sp ieee754sp_sub(union ieee754sp 12 union ieee754sp ieee754sp_sub(union ieee754sp x, union ieee754sp y) 13 { 13 { 14 int s; 14 int s; 15 15 16 COMPXSP; 16 COMPXSP; 17 COMPYSP; 17 COMPYSP; 18 18 19 EXPLODEXSP; 19 EXPLODEXSP; 20 EXPLODEYSP; 20 EXPLODEYSP; 21 21 22 ieee754_clearcx(); 22 ieee754_clearcx(); 23 23 24 FLUSHXSP; 24 FLUSHXSP; 25 FLUSHYSP; 25 FLUSHYSP; 26 26 27 switch (CLPAIR(xc, yc)) { 27 switch (CLPAIR(xc, yc)) { 28 case CLPAIR(IEEE754_CLASS_QNAN, IEEE75 28 case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_SNAN): 29 case CLPAIR(IEEE754_CLASS_ZERO, IEEE75 29 case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_SNAN): 30 case CLPAIR(IEEE754_CLASS_NORM, IEEE75 30 case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_SNAN): 31 case CLPAIR(IEEE754_CLASS_DNORM, IEEE7 31 case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_SNAN): 32 case CLPAIR(IEEE754_CLASS_INF, IEEE754 32 case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_SNAN): 33 return ieee754sp_nanxcpt(y); 33 return ieee754sp_nanxcpt(y); 34 34 35 case CLPAIR(IEEE754_CLASS_SNAN, IEEE75 35 case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_SNAN): 36 case CLPAIR(IEEE754_CLASS_SNAN, IEEE75 36 case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_QNAN): 37 case CLPAIR(IEEE754_CLASS_SNAN, IEEE75 37 case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_ZERO): 38 case CLPAIR(IEEE754_CLASS_SNAN, IEEE75 38 case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_NORM): 39 case CLPAIR(IEEE754_CLASS_SNAN, IEEE75 39 case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_DNORM): 40 case CLPAIR(IEEE754_CLASS_SNAN, IEEE75 40 case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_INF): 41 return ieee754sp_nanxcpt(x); 41 return ieee754sp_nanxcpt(x); 42 42 43 case CLPAIR(IEEE754_CLASS_ZERO, IEEE75 43 case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_QNAN): 44 case CLPAIR(IEEE754_CLASS_NORM, IEEE75 44 case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_QNAN): 45 case CLPAIR(IEEE754_CLASS_DNORM, IEEE7 45 case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_QNAN): 46 case CLPAIR(IEEE754_CLASS_INF, IEEE754 46 case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_QNAN): 47 return y; 47 return y; 48 48 49 case CLPAIR(IEEE754_CLASS_QNAN, IEEE75 49 case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_QNAN): 50 case CLPAIR(IEEE754_CLASS_QNAN, IEEE75 50 case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_ZERO): 51 case CLPAIR(IEEE754_CLASS_QNAN, IEEE75 51 case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_NORM): 52 case CLPAIR(IEEE754_CLASS_QNAN, IEEE75 52 case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_DNORM): 53 case CLPAIR(IEEE754_CLASS_QNAN, IEEE75 53 case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_INF): 54 return x; 54 return x; 55 55 56 56 57 /* 57 /* 58 * Infinity handling 58 * Infinity handling 59 */ 59 */ 60 case CLPAIR(IEEE754_CLASS_INF, IEEE754 60 case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_INF): 61 if (xs != ys) 61 if (xs != ys) 62 return x; 62 return x; 63 ieee754_setcx(IEEE754_INVALID_ 63 ieee754_setcx(IEEE754_INVALID_OPERATION); 64 return ieee754sp_indef(); 64 return ieee754sp_indef(); 65 65 66 case CLPAIR(IEEE754_CLASS_ZERO, IEEE75 66 case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_INF): 67 case CLPAIR(IEEE754_CLASS_DNORM, IEEE7 67 case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_INF): 68 case CLPAIR(IEEE754_CLASS_NORM, IEEE75 68 case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_INF): 69 return ieee754sp_inf(ys ^ 1); 69 return ieee754sp_inf(ys ^ 1); 70 70 71 case CLPAIR(IEEE754_CLASS_INF, IEEE754 71 case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_ZERO): 72 case CLPAIR(IEEE754_CLASS_INF, IEEE754 72 case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_NORM): 73 case CLPAIR(IEEE754_CLASS_INF, IEEE754 73 case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_DNORM): 74 return x; 74 return x; 75 75 76 /* 76 /* 77 * Zero handling 77 * Zero handling 78 */ 78 */ 79 case CLPAIR(IEEE754_CLASS_ZERO, IEEE75 79 case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_ZERO): 80 if (xs != ys) 80 if (xs != ys) 81 return x; 81 return x; 82 else 82 else 83 return ieee754sp_zero( 83 return ieee754sp_zero(ieee754_csr.rm == FPU_CSR_RD); 84 84 85 case CLPAIR(IEEE754_CLASS_NORM, IEEE75 85 case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_ZERO): 86 case CLPAIR(IEEE754_CLASS_DNORM, IEEE7 86 case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_ZERO): 87 return x; 87 return x; 88 88 89 case CLPAIR(IEEE754_CLASS_ZERO, IEEE75 89 case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_NORM): 90 case CLPAIR(IEEE754_CLASS_ZERO, IEEE75 90 case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_DNORM): 91 /* quick fix up */ 91 /* quick fix up */ 92 SPSIGN(y) ^= 1; 92 SPSIGN(y) ^= 1; 93 return y; 93 return y; 94 94 95 case CLPAIR(IEEE754_CLASS_DNORM, IEEE7 95 case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_DNORM): 96 SPDNORMX; 96 SPDNORMX; 97 fallthrough; 97 fallthrough; 98 case CLPAIR(IEEE754_CLASS_NORM, IEEE75 98 case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_DNORM): 99 SPDNORMY; 99 SPDNORMY; 100 break; 100 break; 101 101 102 case CLPAIR(IEEE754_CLASS_DNORM, IEEE7 102 case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_NORM): 103 SPDNORMX; 103 SPDNORMX; 104 break; 104 break; 105 105 106 case CLPAIR(IEEE754_CLASS_NORM, IEEE75 106 case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_NORM): 107 break; 107 break; 108 } 108 } 109 /* flip sign of y and handle as add */ 109 /* flip sign of y and handle as add */ 110 ys ^= 1; 110 ys ^= 1; 111 111 112 assert(xm & SP_HIDDEN_BIT); 112 assert(xm & SP_HIDDEN_BIT); 113 assert(ym & SP_HIDDEN_BIT); 113 assert(ym & SP_HIDDEN_BIT); 114 114 115 115 116 /* provide guard,round and stick bit s 116 /* provide guard,round and stick bit space */ 117 xm <<= 3; 117 xm <<= 3; 118 ym <<= 3; 118 ym <<= 3; 119 119 120 if (xe > ye) { 120 if (xe > ye) { 121 /* 121 /* 122 * have to shift y fraction ri 122 * have to shift y fraction right to align 123 */ 123 */ 124 s = xe - ye; 124 s = xe - ye; 125 ym = XSPSRS(ym, s); 125 ym = XSPSRS(ym, s); 126 ye += s; 126 ye += s; 127 } else if (ye > xe) { 127 } else if (ye > xe) { 128 /* 128 /* 129 * have to shift x fraction ri 129 * have to shift x fraction right to align 130 */ 130 */ 131 s = ye - xe; 131 s = ye - xe; 132 xm = XSPSRS(xm, s); 132 xm = XSPSRS(xm, s); 133 xe += s; 133 xe += s; 134 } 134 } 135 assert(xe == ye); 135 assert(xe == ye); 136 assert(xe <= SP_EMAX); 136 assert(xe <= SP_EMAX); 137 137 138 if (xs == ys) { 138 if (xs == ys) { 139 /* generate 28 bit result of a 139 /* generate 28 bit result of adding two 27 bit numbers 140 */ 140 */ 141 xm = xm + ym; 141 xm = xm + ym; 142 142 143 if (xm >> (SP_FBITS + 1 + 3)) 143 if (xm >> (SP_FBITS + 1 + 3)) { /* carry out */ 144 SPXSRSX1(); /* shi 144 SPXSRSX1(); /* shift preserving sticky */ 145 } 145 } 146 } else { 146 } else { 147 if (xm >= ym) { 147 if (xm >= ym) { 148 xm = xm - ym; 148 xm = xm - ym; 149 } else { 149 } else { 150 xm = ym - xm; 150 xm = ym - xm; 151 xs = ys; 151 xs = ys; 152 } 152 } 153 if (xm == 0) { 153 if (xm == 0) { 154 if (ieee754_csr.rm == 154 if (ieee754_csr.rm == FPU_CSR_RD) 155 return ieee754 155 return ieee754sp_zero(1); /* round negative inf. => sign = -1 */ 156 else 156 else 157 return ieee754 157 return ieee754sp_zero(0); /* other round modes => sign = 1 */ 158 } 158 } 159 /* normalize to rounding preci 159 /* normalize to rounding precision 160 */ 160 */ 161 while ((xm >> (SP_FBITS + 3)) 161 while ((xm >> (SP_FBITS + 3)) == 0) { 162 xm <<= 1; 162 xm <<= 1; 163 xe--; 163 xe--; 164 } 164 } 165 } 165 } 166 166 167 return ieee754sp_format(xs, xe, xm); 167 return ieee754sp_format(xs, xe, xm); 168 } 168 } 169 169
Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.