aboutsummaryrefslogtreecommitdiff
path: root/include/math-emu
diff options
context:
space:
mode:
Diffstat (limited to 'include/math-emu')
-rw-r--r--include/math-emu/op-2.h2
-rw-r--r--include/math-emu/op-common.h44
-rw-r--r--include/math-emu/soft-fp.h19
3 files changed, 52 insertions, 13 deletions
diff --git a/include/math-emu/op-2.h b/include/math-emu/op-2.h
index e193fb08fd5..4f26ecc1411 100644
--- a/include/math-emu/op-2.h
+++ b/include/math-emu/op-2.h
@@ -25,7 +25,7 @@
#ifndef __MATH_EMU_OP_2_H__
#define __MATH_EMU_OP_2_H__
-#define _FP_FRAC_DECL_2(X) _FP_W_TYPE X##_f0, X##_f1
+#define _FP_FRAC_DECL_2(X) _FP_W_TYPE X##_f0 = 0, X##_f1 = 0
#define _FP_FRAC_COPY_2(D,S) (D##_f0 = S##_f0, D##_f1 = S##_f1)
#define _FP_FRAC_SET_2(X,I) __FP_FRAC_SET_2(X, I)
#define _FP_FRAC_HIGH_2(X) (X##_f1)
diff --git a/include/math-emu/op-common.h b/include/math-emu/op-common.h
index bb46e7645d5..6bdf8c61d22 100644
--- a/include/math-emu/op-common.h
+++ b/include/math-emu/op-common.h
@@ -29,7 +29,7 @@
_FP_FRAC_DECL_##wc(X)
/*
- * Finish truely unpacking a native fp value by classifying the kind
+ * Finish truly unpacking a native fp value by classifying the kind
* of fp value and normalizing both the exponent and the fraction.
*/
@@ -73,7 +73,7 @@ do { \
X##_c = FP_CLS_NAN; \
/* Check for signaling NaN */ \
if (!(_FP_FRAC_HIGH_RAW_##fs(X) & _FP_QNANBIT_##fs)) \
- FP_SET_EXCEPTION(FP_EX_INVALID); \
+ FP_SET_EXCEPTION(FP_EX_INVALID | FP_EX_INVALID_SNAN); \
} \
break; \
} \
@@ -139,18 +139,27 @@ do { \
if (X##_e <= _FP_WFRACBITS_##fs) \
{ \
_FP_FRAC_SRS_##wc(X, X##_e, _FP_WFRACBITS_##fs); \
- _FP_ROUND(wc, X); \
if (_FP_FRAC_HIGH_##fs(X) \
& (_FP_OVERFLOW_##fs >> 1)) \
{ \
X##_e = 1; \
_FP_FRAC_SET_##wc(X, _FP_ZEROFRAC_##wc); \
- FP_SET_EXCEPTION(FP_EX_INEXACT); \
} \
else \
{ \
- X##_e = 0; \
- _FP_FRAC_SRL_##wc(X, _FP_WORKBITS); \
+ _FP_ROUND(wc, X); \
+ if (_FP_FRAC_HIGH_##fs(X) \
+ & (_FP_OVERFLOW_##fs >> 1)) \
+ { \
+ X##_e = 1; \
+ _FP_FRAC_SET_##wc(X, _FP_ZEROFRAC_##wc); \
+ FP_SET_EXCEPTION(FP_EX_INEXACT); \
+ } \
+ else \
+ { \
+ X##_e = 0; \
+ _FP_FRAC_SRL_##wc(X, _FP_WORKBITS); \
+ } \
} \
if ((FP_CUR_EXCEPTIONS & FP_EX_INEXACT) || \
(FP_TRAPPING_EXCEPTIONS & FP_EX_UNDERFLOW)) \
@@ -324,7 +333,7 @@ do { \
_FP_FRAC_SET_##wc(R, _FP_NANFRAC_##fs); \
R##_s = _FP_NANSIGN_##fs; \
R##_c = FP_CLS_NAN; \
- FP_SET_EXCEPTION(FP_EX_INVALID); \
+ FP_SET_EXCEPTION(FP_EX_INVALID | FP_EX_INVALID_ISI); \
break; \
} \
/* FALLTHRU */ \
@@ -431,7 +440,7 @@ do { \
R##_s = _FP_NANSIGN_##fs; \
R##_c = FP_CLS_NAN; \
_FP_FRAC_SET_##wc(R, _FP_NANFRAC_##fs); \
- FP_SET_EXCEPTION(FP_EX_INVALID); \
+ FP_SET_EXCEPTION(FP_EX_INVALID | FP_EX_INVALID_IMZ);\
break; \
\
default: \
@@ -490,11 +499,17 @@ do { \
break; \
\
case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_INF): \
+ R##_s = _FP_NANSIGN_##fs; \
+ R##_c = FP_CLS_NAN; \
+ _FP_FRAC_SET_##wc(R, _FP_NANFRAC_##fs); \
+ FP_SET_EXCEPTION(FP_EX_INVALID | FP_EX_INVALID_IDI);\
+ break; \
+ \
case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_ZERO): \
R##_s = _FP_NANSIGN_##fs; \
R##_c = FP_CLS_NAN; \
_FP_FRAC_SET_##wc(R, _FP_NANFRAC_##fs); \
- FP_SET_EXCEPTION(FP_EX_INVALID); \
+ FP_SET_EXCEPTION(FP_EX_INVALID | FP_EX_INVALID_ZDZ);\
break; \
\
default: \
@@ -670,7 +685,7 @@ do { \
else \
{ \
r = 0; \
- if (X##_s) \
+ if (!X##_s) \
r = ~r; \
} \
FP_SET_EXCEPTION(FP_EX_INVALID); \
@@ -728,12 +743,17 @@ do { \
} \
else \
{ \
+ int _lz0, _lz1; \
if (X##_e <= -_FP_WORKBITS - 1) \
_FP_FRAC_SET_##wc(X, _FP_MINFRAC_##wc); \
else \
_FP_FRAC_SRS_##wc(X, _FP_FRACBITS_##fs - 1 - X##_e, \
_FP_WFRACBITS_##fs); \
+ _FP_FRAC_CLZ_##wc(_lz0, X); \
_FP_ROUND(wc, X); \
+ _FP_FRAC_CLZ_##wc(_lz1, X); \
+ if (_lz1 < _lz0) \
+ X##_e++; /* For overflow detection. */ \
_FP_FRAC_SRL_##wc(X, _FP_WORKBITS); \
_FP_FRAC_ASSEMBLE_##wc(r, X, rsize); \
} \
@@ -747,7 +767,7 @@ do { \
if (!rsigned) \
{ \
r = 0; \
- if (X##_s) \
+ if (!X##_s) \
r = ~r; \
} \
else if (rsigned != 2) \
@@ -784,7 +804,7 @@ do { \
X##_e -= (_FP_W_TYPE_SIZE - rsize); \
X##_e = rsize - X##_e - 1; \
\
- if (_FP_FRACBITS_##fs < rsize && _FP_WFRACBITS_##fs < X##_e) \
+ if (_FP_FRACBITS_##fs < rsize && _FP_WFRACBITS_##fs <= X##_e) \
__FP_FRAC_SRS_1(ur_, (X##_e - _FP_WFRACBITS_##fs + 1), rsize);\
_FP_FRAC_DISASSEMBLE_##wc(X, ur_, rsize); \
if ((_FP_WFRACBITS_##fs - X##_e - 1) > 0) \
diff --git a/include/math-emu/soft-fp.h b/include/math-emu/soft-fp.h
index a6f873b45f9..3f284bc0318 100644
--- a/include/math-emu/soft-fp.h
+++ b/include/math-emu/soft-fp.h
@@ -51,6 +51,25 @@
#ifndef FP_EX_INVALID
#define FP_EX_INVALID 0
#endif
+#ifndef FP_EX_INVALID_SNAN
+#define FP_EX_INVALID_SNAN 0
+#endif
+/* inf - inf */
+#ifndef FP_EX_INVALID_ISI
+#define FP_EX_INVALID_ISI 0
+#endif
+/* inf / inf */
+#ifndef FP_EX_INVALID_IDI
+#define FP_EX_INVALID_IDI 0
+#endif
+/* 0 / 0 */
+#ifndef FP_EX_INVALID_ZDZ
+#define FP_EX_INVALID_ZDZ 0
+#endif
+/* inf * 0 */
+#ifndef FP_EX_INVALID_IMZ
+#define FP_EX_INVALID_IMZ 0
+#endif
#ifndef FP_EX_OVERFLOW
#define FP_EX_OVERFLOW 0
#endif