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