summaryrefslogtreecommitdiffstats
path: root/include/math-emu
diff options
context:
space:
mode:
Diffstat (limited to 'include/math-emu')
-rw-r--r--include/math-emu/double.h2
-rw-r--r--include/math-emu/extended.h2
-rw-r--r--include/math-emu/op-2.h4
-rw-r--r--include/math-emu/op-common.h85
-rw-r--r--include/math-emu/quad.h2
-rw-r--r--include/math-emu/single.h1
-rw-r--r--include/math-emu/soft-fp.h7
7 files changed, 98 insertions, 5 deletions
diff --git a/include/math-emu/double.h b/include/math-emu/double.h
index ee581c2da..04c4c0f45 100644
--- a/include/math-emu/double.h
+++ b/include/math-emu/double.h
@@ -115,6 +115,7 @@ union _FP_UNION_D
#define FP_CMP_EQ_D(r,X,Y) _FP_CMP_EQ(D,2,r,X,Y)
#define FP_TO_INT_D(r,X,rsz,rsg) _FP_TO_INT(D,2,r,X,rsz,rsg)
+#define FP_TO_INT_ROUND_D(r,X,rsz,rsg) _FP_TO_INT_ROUND(D,2,r,X,rsz,rsg)
#define FP_FROM_INT_D(X,r,rs,rt) _FP_FROM_INT(D,2,X,r,rs,rt)
#define _FP_FRAC_HIGH_D(X) _FP_FRAC_HIGH_2(X)
@@ -189,6 +190,7 @@ union _FP_UNION_D
#define FP_CMP_EQ_D(r,X,Y) _FP_CMP_EQ(D,1,r,X,Y)
#define FP_TO_INT_D(r,X,rsz,rsg) _FP_TO_INT(D,1,r,X,rsz,rsg)
+#define FP_TO_INT_ROUND_D(r,X,rsz,rsg) _FP_TO_INT_ROUND(D,1,r,X,rsz,rsg)
#define FP_FROM_INT_D(X,r,rs,rt) _FP_FROM_INT(D,1,X,r,rs,rt)
#define _FP_FRAC_HIGH_D(X) _FP_FRAC_HIGH_1(X)
diff --git a/include/math-emu/extended.h b/include/math-emu/extended.h
index 4a1d7e711..ae73cecb3 100644
--- a/include/math-emu/extended.h
+++ b/include/math-emu/extended.h
@@ -226,6 +226,7 @@ union _FP_UNION_E
#define FP_CMP_EQ_E(r,X,Y) _FP_CMP_EQ(E,4,r,X,Y)
#define FP_TO_INT_E(r,X,rsz,rsg) _FP_TO_INT(E,4,r,X,rsz,rsg)
+#define FP_TO_INT_ROUND_E(r,X,rsz,rsg) _FP_TO_INT_ROUND(E,4,r,X,rsz,rsg)
#define FP_FROM_INT_E(X,r,rs,rt) _FP_FROM_INT(E,4,X,r,rs,rt)
#define _FP_FRAC_HIGH_E(X) (X##_f[2])
@@ -380,6 +381,7 @@ union _FP_UNION_E
#define FP_CMP_EQ_E(r,X,Y) _FP_CMP_EQ(E,2,r,X,Y)
#define FP_TO_INT_E(r,X,rsz,rsg) _FP_TO_INT(E,2,r,X,rsz,rsg)
+#define FP_TO_INT_ROUND_E(r,X,rsz,rsg) _FP_TO_INT_ROUND(E,2,r,X,rsz,rsg)
#define FP_FROM_INT_E(X,r,rs,rt) _FP_FROM_INT(E,2,X,r,rs,rt)
#define _FP_FRAC_HIGH_E(X) (X##_f1)
diff --git a/include/math-emu/op-2.h b/include/math-emu/op-2.h
index ad3fbc538..184eb3c3b 100644
--- a/include/math-emu/op-2.h
+++ b/include/math-emu/op-2.h
@@ -113,9 +113,9 @@
#define _FP_FRAC_OVERP_2(fs,X) (_FP_FRAC_HIGH_##fs(X) & _FP_OVERFLOW_##fs)
#define _FP_FRAC_EQ_2(X, Y) (X##_f1 == Y##_f1 && X##_f0 == Y##_f0)
#define _FP_FRAC_GT_2(X, Y) \
- (X##_f1 > Y##_f1 || X##_f1 == Y##_f1 && X##_f0 > Y##_f0)
+ (X##_f1 > Y##_f1 || (X##_f1 == Y##_f1 && X##_f0 > Y##_f0))
#define _FP_FRAC_GE_2(X, Y) \
- (X##_f1 > Y##_f1 || X##_f1 == Y##_f1 && X##_f0 >= Y##_f0)
+ (X##_f1 > Y##_f1 || (X##_f1 == Y##_f1 && X##_f0 >= Y##_f0))
#define _FP_ZEROFRAC_2 0, 0
#define _FP_MINFRAC_2 0, 1
diff --git a/include/math-emu/op-common.h b/include/math-emu/op-common.h
index 207aa7738..e03e40e65 100644
--- a/include/math-emu/op-common.h
+++ b/include/math-emu/op-common.h
@@ -54,6 +54,11 @@ do { \
X##_e -= _FP_EXPBIAS_##fs - 1 + _shift; \
X##_c = FP_CLS_NORMAL; \
FP_SET_EXCEPTION(FP_EX_DENORM); \
+ if (FP_DENORM_ZERO) \
+ { \
+ FP_SET_EXCEPTION(FP_EX_INEXACT); \
+ X##_c = FP_CLS_ZERO; \
+ } \
} \
break; \
\
@@ -618,6 +623,8 @@ do { \
* 1: the number is required to be -(2^(rsize-1))..(2^(rsize-1))-1, if not, NV is
* set plus the result is either -(2^(rsize-1)) or (2^(rsize-1))-1 depending
* on the sign in such case.
+ * 2: the number is required to be -(2^(rsize-1))..(2^(rsize-1))-1, if not, NV is
+ * set plus the result is truncated to fit into destination.
* -1: the number is required to be -(2^(rsize-1))..(2^rsize)-1, if not, NV is
* set plus the result is either -(2^(rsize-1)) or (2^(rsize-1))-1 depending
* on the sign in such case.
@@ -638,12 +645,25 @@ do { \
{ /* overflow */ \
case FP_CLS_NAN: \
case FP_CLS_INF: \
- if (rsigned) \
+ if (rsigned == 2) \
+ { \
+ if (X##_c != FP_CLS_NORMAL \
+ || X##_e >= rsize - 1 + _FP_WFRACBITS_##fs) \
+ r = 0; \
+ else \
+ { \
+ _FP_FRAC_SLL_##wc(X, (X##_e - _FP_WFRACBITS_##fs + 1)); \
+ _FP_FRAC_ASSEMBLE_##wc(r, X, rsize); \
+ } \
+ } \
+ else if (rsigned) \
{ \
r = 1; \
r <<= rsize - 1; \
r -= 1 - X##_s; \
- } else { \
+ } \
+ else \
+ { \
r = 0; \
if (X##_s) \
r = ~r; \
@@ -678,6 +698,67 @@ do { \
} \
} while (0)
+#define _FP_TO_INT_ROUND(fs, wc, r, X, rsize, rsigned) \
+ do { \
+ r = 0; \
+ switch (X##_c) \
+ { \
+ case FP_CLS_NORMAL: \
+ if (X##_e >= _FP_FRACBITS_##fs - 1) \
+ { \
+ if (X##_e < rsize - 1 + _FP_WFRACBITS_##fs) \
+ { \
+ if (X##_e >= _FP_WFRACBITS_##fs - 1) \
+ { \
+ _FP_FRAC_ASSEMBLE_##wc(r, X, rsize); \
+ r <<= X##_e - _FP_WFRACBITS_##fs + 1; \
+ } \
+ else \
+ { \
+ _FP_FRAC_SRL_##wc(X, _FP_WORKBITS - X##_e \
+ + _FP_FRACBITS_##fs - 1); \
+ _FP_FRAC_ASSEMBLE_##wc(r, X, rsize); \
+ } \
+ } \
+ } \
+ else \
+ { \
+ 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_ROUND(wc, X); \
+ _FP_FRAC_SRL_##wc(X, _FP_WORKBITS); \
+ _FP_FRAC_ASSEMBLE_##wc(r, X, rsize); \
+ } \
+ if (rsigned && X##_s) \
+ r = -r; \
+ if (X##_e >= rsize - (rsigned > 0 || X##_s) \
+ || (!rsigned && X##_s)) \
+ { /* overflow */ \
+ case FP_CLS_NAN: \
+ case FP_CLS_INF: \
+ if (!rsigned) \
+ { \
+ r = 0; \
+ if (X##_s) \
+ r = ~r; \
+ } \
+ else if (rsigned != 2) \
+ { \
+ r = 1; \
+ r <<= rsize - 1; \
+ r -= 1 - X##_s; \
+ } \
+ FP_SET_EXCEPTION(FP_EX_INVALID); \
+ } \
+ break; \
+ case FP_CLS_ZERO: \
+ break; \
+ } \
+ } while (0)
+
#define _FP_FROM_INT(fs, wc, X, r, rsize, rtype) \
do { \
if (r) \
diff --git a/include/math-emu/quad.h b/include/math-emu/quad.h
index 92a1e2b48..23b20c3e6 100644
--- a/include/math-emu/quad.h
+++ b/include/math-emu/quad.h
@@ -121,6 +121,7 @@ union _FP_UNION_Q
#define FP_CMP_EQ_Q(r,X,Y) _FP_CMP_EQ(Q,4,r,X,Y)
#define FP_TO_INT_Q(r,X,rsz,rsg) _FP_TO_INT(Q,4,r,X,rsz,rsg)
+#define FP_TO_INT_ROUND_Q(r,X,rsz,rsg) _FP_TO_INT_ROUND(Q,4,r,X,rsz,rsg)
#define FP_FROM_INT_Q(X,r,rs,rt) _FP_FROM_INT(Q,4,X,r,rs,rt)
#define _FP_FRAC_HIGH_Q(X) _FP_FRAC_HIGH_4(X)
@@ -193,6 +194,7 @@ union _FP_UNION_Q
#define FP_CMP_EQ_Q(r,X,Y) _FP_CMP_EQ(Q,2,r,X,Y)
#define FP_TO_INT_Q(r,X,rsz,rsg) _FP_TO_INT(Q,2,r,X,rsz,rsg)
+#define FP_TO_INT_ROUND_Q(r,X,rsz,rsg) _FP_TO_INT_ROUND(Q,2,r,X,rsz,rsg)
#define FP_FROM_INT_Q(X,r,rs,rt) _FP_FROM_INT(Q,2,X,r,rs,rt)
#define _FP_FRAC_HIGH_Q(X) _FP_FRAC_HIGH_2(X)
diff --git a/include/math-emu/single.h b/include/math-emu/single.h
index 6504e5283..ea12cb8b0 100644
--- a/include/math-emu/single.h
+++ b/include/math-emu/single.h
@@ -104,6 +104,7 @@ union _FP_UNION_S
#define FP_CMP_EQ_S(r,X,Y) _FP_CMP_EQ(S,1,r,X,Y)
#define FP_TO_INT_S(r,X,rsz,rsg) _FP_TO_INT(S,1,r,X,rsz,rsg)
+#define FP_TO_INT_ROUND_S(r,X,rsz,rsg) _FP_TO_INT_ROUND(S,1,r,X,rsz,rsg)
#define FP_FROM_INT_S(X,r,rs,rt) _FP_FROM_INT(S,1,X,r,rs,rt)
#define _FP_FRAC_HIGH_S(X) _FP_FRAC_HIGH_1(X)
diff --git a/include/math-emu/soft-fp.h b/include/math-emu/soft-fp.h
index 3c5072e51..1d1345134 100644
--- a/include/math-emu/soft-fp.h
+++ b/include/math-emu/soft-fp.h
@@ -24,7 +24,7 @@
#ifndef SOFT_FP_H
#define SOFT_FP_H
-#include "sfp-machine.h"
+#include <asm/sfp-machine.h>
/* Allow sfp-machine to have its own byte order definitions. */
#ifndef __BYTE_ORDER
@@ -83,6 +83,11 @@
#define FP_HANDLE_EXCEPTIONS do {} while (0)
#endif
+/* By default we never flush denormal input operands to signed zero. */
+#ifndef FP_DENORM_ZERO
+#define FP_DENORM_ZERO 0
+#endif
+
#ifndef FP_INHIBIT_RESULTS
/* By default we write the results always.
* sfp-machine may override this and e.g.