0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #ifndef __IEEE754INT_H
0011 #define __IEEE754INT_H
0012
0013 #include "ieee754.h"
0014
0015 #define CLPAIR(x, y) ((x)*6+(y))
0016
0017 enum maddf_flags {
0018 MADDF_NEGATE_PRODUCT = 1 << 0,
0019 MADDF_NEGATE_ADDITION = 1 << 1,
0020 };
0021
0022 static inline void ieee754_clearcx(void)
0023 {
0024 ieee754_csr.cx = 0;
0025 }
0026
0027 static inline void ieee754_setcx(const unsigned int flags)
0028 {
0029 ieee754_csr.cx |= flags;
0030 ieee754_csr.sx |= flags;
0031 }
0032
0033 static inline int ieee754_setandtestcx(const unsigned int x)
0034 {
0035 ieee754_setcx(x);
0036
0037 return ieee754_csr.mx & x;
0038 }
0039
0040 static inline int ieee754_class_nan(int xc)
0041 {
0042 return xc >= IEEE754_CLASS_SNAN;
0043 }
0044
0045 #define COMPXSP \
0046 unsigned int xm; int xe; int xs __maybe_unused; int xc
0047
0048 #define COMPYSP \
0049 unsigned int ym; int ye; int ys; int yc
0050
0051 #define COMPZSP \
0052 unsigned int zm; int ze; int zs; int zc
0053
0054 #define EXPLODESP(v, vc, vs, ve, vm) \
0055 { \
0056 vs = SPSIGN(v); \
0057 ve = SPBEXP(v); \
0058 vm = SPMANT(v); \
0059 if (ve == SP_EMAX+1+SP_EBIAS) { \
0060 if (vm == 0) \
0061 vc = IEEE754_CLASS_INF; \
0062 else if (ieee754_csr.nan2008 ^ !(vm & SP_MBIT(SP_FBITS - 1))) \
0063 vc = IEEE754_CLASS_QNAN; \
0064 else \
0065 vc = IEEE754_CLASS_SNAN; \
0066 } else if (ve == SP_EMIN-1+SP_EBIAS) { \
0067 if (vm) { \
0068 ve = SP_EMIN; \
0069 vc = IEEE754_CLASS_DNORM; \
0070 } else \
0071 vc = IEEE754_CLASS_ZERO; \
0072 } else { \
0073 ve -= SP_EBIAS; \
0074 vm |= SP_HIDDEN_BIT; \
0075 vc = IEEE754_CLASS_NORM; \
0076 } \
0077 }
0078 #define EXPLODEXSP EXPLODESP(x, xc, xs, xe, xm)
0079 #define EXPLODEYSP EXPLODESP(y, yc, ys, ye, ym)
0080 #define EXPLODEZSP EXPLODESP(z, zc, zs, ze, zm)
0081
0082
0083 #define COMPXDP \
0084 u64 xm; int xe; int xs __maybe_unused; int xc
0085
0086 #define COMPYDP \
0087 u64 ym; int ye; int ys; int yc
0088
0089 #define COMPZDP \
0090 u64 zm; int ze; int zs; int zc
0091
0092 #define EXPLODEDP(v, vc, vs, ve, vm) \
0093 { \
0094 vm = DPMANT(v); \
0095 vs = DPSIGN(v); \
0096 ve = DPBEXP(v); \
0097 if (ve == DP_EMAX+1+DP_EBIAS) { \
0098 if (vm == 0) \
0099 vc = IEEE754_CLASS_INF; \
0100 else if (ieee754_csr.nan2008 ^ !(vm & DP_MBIT(DP_FBITS - 1))) \
0101 vc = IEEE754_CLASS_QNAN; \
0102 else \
0103 vc = IEEE754_CLASS_SNAN; \
0104 } else if (ve == DP_EMIN-1+DP_EBIAS) { \
0105 if (vm) { \
0106 ve = DP_EMIN; \
0107 vc = IEEE754_CLASS_DNORM; \
0108 } else \
0109 vc = IEEE754_CLASS_ZERO; \
0110 } else { \
0111 ve -= DP_EBIAS; \
0112 vm |= DP_HIDDEN_BIT; \
0113 vc = IEEE754_CLASS_NORM; \
0114 } \
0115 }
0116 #define EXPLODEXDP EXPLODEDP(x, xc, xs, xe, xm)
0117 #define EXPLODEYDP EXPLODEDP(y, yc, ys, ye, ym)
0118 #define EXPLODEZDP EXPLODEDP(z, zc, zs, ze, zm)
0119
0120 #define FLUSHDP(v, vc, vs, ve, vm) \
0121 if (vc==IEEE754_CLASS_DNORM) { \
0122 if (ieee754_csr.nod) { \
0123 ieee754_setcx(IEEE754_INEXACT); \
0124 vc = IEEE754_CLASS_ZERO; \
0125 ve = DP_EMIN-1+DP_EBIAS; \
0126 vm = 0; \
0127 v = ieee754dp_zero(vs); \
0128 } \
0129 }
0130
0131 #define FLUSHSP(v, vc, vs, ve, vm) \
0132 if (vc==IEEE754_CLASS_DNORM) { \
0133 if (ieee754_csr.nod) { \
0134 ieee754_setcx(IEEE754_INEXACT); \
0135 vc = IEEE754_CLASS_ZERO; \
0136 ve = SP_EMIN-1+SP_EBIAS; \
0137 vm = 0; \
0138 v = ieee754sp_zero(vs); \
0139 } \
0140 }
0141
0142 #define FLUSHXDP FLUSHDP(x, xc, xs, xe, xm)
0143 #define FLUSHYDP FLUSHDP(y, yc, ys, ye, ym)
0144 #define FLUSHZDP FLUSHDP(z, zc, zs, ze, zm)
0145 #define FLUSHXSP FLUSHSP(x, xc, xs, xe, xm)
0146 #define FLUSHYSP FLUSHSP(y, yc, ys, ye, ym)
0147 #define FLUSHZSP FLUSHSP(z, zc, zs, ze, zm)
0148
0149 #endif