0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #include "ieee754dp.h"
0011
0012 union ieee754dp ieee754dp_sub(union ieee754dp x, union ieee754dp y)
0013 {
0014 int s;
0015
0016 COMPXDP;
0017 COMPYDP;
0018
0019 EXPLODEXDP;
0020 EXPLODEYDP;
0021
0022 ieee754_clearcx();
0023
0024 FLUSHXDP;
0025 FLUSHYDP;
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 ieee754dp_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 ieee754dp_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 ieee754dp_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 ieee754dp_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 ieee754dp_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 DPSIGN(y) ^= 1;
0093 return y;
0094
0095 case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_DNORM):
0096 DPDNORMX;
0097 fallthrough;
0098 case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_DNORM):
0099
0100 DPDNORMY;
0101 break;
0102
0103 case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_NORM):
0104
0105 DPDNORMX;
0106 break;
0107
0108 case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_NORM):
0109 break;
0110 }
0111
0112 ys ^= 1;
0113
0114 assert(xm & DP_HIDDEN_BIT);
0115 assert(ym & DP_HIDDEN_BIT);
0116
0117
0118
0119 xm <<= 3;
0120 ym <<= 3;
0121
0122 if (xe > ye) {
0123
0124
0125
0126 s = xe - ye;
0127 ym = XDPSRS(ym, s);
0128 ye += s;
0129 } else if (ye > xe) {
0130
0131
0132
0133 s = ye - xe;
0134 xm = XDPSRS(xm, s);
0135 xe += s;
0136 }
0137 assert(xe == ye);
0138 assert(xe <= DP_EMAX);
0139
0140 if (xs == ys) {
0141
0142
0143 xm = xm + ym;
0144
0145 if (xm >> (DP_FBITS + 1 + 3)) {
0146 xm = XDPSRS1(xm);
0147 xe++;
0148 }
0149 } else {
0150 if (xm >= ym) {
0151 xm = xm - ym;
0152 } else {
0153 xm = ym - xm;
0154 xs = ys;
0155 }
0156 if (xm == 0) {
0157 if (ieee754_csr.rm == FPU_CSR_RD)
0158 return ieee754dp_zero(1);
0159 else
0160 return ieee754dp_zero(0);
0161 }
0162
0163
0164
0165 while ((xm >> (DP_FBITS + 3)) == 0) {
0166 xm <<= 1;
0167 xe--;
0168 }
0169 }
0170
0171 return ieee754dp_format(xs, xe, xm);
0172 }