0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #include "ieee754dp.h"
0011
0012 union ieee754dp ieee754dp_add(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_NORM, IEEE754_CLASS_INF):
0067 case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_INF):
0068 case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_INF):
0069 return y;
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 return y;
0092
0093 case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_DNORM):
0094 DPDNORMX;
0095 fallthrough;
0096 case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_DNORM):
0097 DPDNORMY;
0098 break;
0099
0100 case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_NORM):
0101 DPDNORMX;
0102 break;
0103
0104 case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_NORM):
0105 break;
0106 }
0107 assert(xm & DP_HIDDEN_BIT);
0108 assert(ym & DP_HIDDEN_BIT);
0109
0110
0111
0112
0113 xm <<= 3;
0114 ym <<= 3;
0115
0116 if (xe > ye) {
0117
0118
0119
0120 s = xe - ye;
0121 ym = XDPSRS(ym, s);
0122 ye += s;
0123 } else if (ye > xe) {
0124
0125
0126
0127 s = ye - xe;
0128 xm = XDPSRS(xm, s);
0129 xe += s;
0130 }
0131 assert(xe == ye);
0132 assert(xe <= DP_EMAX);
0133
0134 if (xs == ys) {
0135
0136
0137
0138
0139 xm = xm + ym;
0140
0141 if (xm >> (DP_FBITS + 1 + 3)) {
0142 xm = XDPSRS1(xm);
0143 xe++;
0144 }
0145 } else {
0146 if (xm >= ym) {
0147 xm = xm - ym;
0148 } else {
0149 xm = ym - xm;
0150 xs = ys;
0151 }
0152 if (xm == 0)
0153 return ieee754dp_zero(ieee754_csr.rm == FPU_CSR_RD);
0154
0155
0156
0157
0158 while ((xm >> (DP_FBITS + 3)) == 0) {
0159 xm <<= 1;
0160 xe--;
0161 }
0162 }
0163
0164 return ieee754dp_format(xs, xe, xm);
0165 }