0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #include "ieee754sp.h"
0011
0012 union ieee754sp ieee754sp_sub(union ieee754sp x, union ieee754sp y)
0013 {
0014 int s;
0015
0016 COMPXSP;
0017 COMPYSP;
0018
0019 EXPLODEXSP;
0020 EXPLODEYSP;
0021
0022 ieee754_clearcx();
0023
0024 FLUSHXSP;
0025 FLUSHYSP;
0026
0027 switch (CLPAIR(xc, yc)) {
0028 case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_SNAN):
0029 case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_SNAN):
0030 case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_SNAN):
0031 case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_SNAN):
0032 case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_SNAN):
0033 return ieee754sp_nanxcpt(y);
0034
0035 case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_SNAN):
0036 case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_QNAN):
0037 case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_ZERO):
0038 case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_NORM):
0039 case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_DNORM):
0040 case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_INF):
0041 return ieee754sp_nanxcpt(x);
0042
0043 case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_QNAN):
0044 case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_QNAN):
0045 case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_QNAN):
0046 case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_QNAN):
0047 return y;
0048
0049 case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_QNAN):
0050 case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_ZERO):
0051 case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_NORM):
0052 case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_DNORM):
0053 case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_INF):
0054 return x;
0055
0056
0057
0058
0059
0060 case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_INF):
0061 if (xs != ys)
0062 return x;
0063 ieee754_setcx(IEEE754_INVALID_OPERATION);
0064 return ieee754sp_indef();
0065
0066 case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_INF):
0067 case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_INF):
0068 case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_INF):
0069 return ieee754sp_inf(ys ^ 1);
0070
0071 case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_ZERO):
0072 case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_NORM):
0073 case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_DNORM):
0074 return x;
0075
0076
0077
0078
0079 case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_ZERO):
0080 if (xs != ys)
0081 return x;
0082 else
0083 return ieee754sp_zero(ieee754_csr.rm == FPU_CSR_RD);
0084
0085 case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_ZERO):
0086 case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_ZERO):
0087 return x;
0088
0089 case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_NORM):
0090 case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_DNORM):
0091
0092 SPSIGN(y) ^= 1;
0093 return y;
0094
0095 case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_DNORM):
0096 SPDNORMX;
0097 fallthrough;
0098 case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_DNORM):
0099 SPDNORMY;
0100 break;
0101
0102 case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_NORM):
0103 SPDNORMX;
0104 break;
0105
0106 case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_NORM):
0107 break;
0108 }
0109
0110 ys ^= 1;
0111
0112 assert(xm & SP_HIDDEN_BIT);
0113 assert(ym & SP_HIDDEN_BIT);
0114
0115
0116
0117 xm <<= 3;
0118 ym <<= 3;
0119
0120 if (xe > ye) {
0121
0122
0123
0124 s = xe - ye;
0125 ym = XSPSRS(ym, s);
0126 ye += s;
0127 } else if (ye > xe) {
0128
0129
0130
0131 s = ye - xe;
0132 xm = XSPSRS(xm, s);
0133 xe += s;
0134 }
0135 assert(xe == ye);
0136 assert(xe <= SP_EMAX);
0137
0138 if (xs == ys) {
0139
0140
0141 xm = xm + ym;
0142
0143 if (xm >> (SP_FBITS + 1 + 3)) {
0144 SPXSRSX1();
0145 }
0146 } else {
0147 if (xm >= ym) {
0148 xm = xm - ym;
0149 } else {
0150 xm = ym - xm;
0151 xs = ys;
0152 }
0153 if (xm == 0) {
0154 if (ieee754_csr.rm == FPU_CSR_RD)
0155 return ieee754sp_zero(1);
0156 else
0157 return ieee754sp_zero(0);
0158 }
0159
0160
0161 while ((xm >> (SP_FBITS + 3)) == 0) {
0162 xm <<= 1;
0163 xe--;
0164 }
0165 }
0166
0167 return ieee754sp_format(xs, xe, xm);
0168 }