diff options
Diffstat (limited to 'include/math-emu')
-rw-r--r-- | include/math-emu/double.h | 2 | ||||
-rw-r--r-- | include/math-emu/extended.h | 2 | ||||
-rw-r--r-- | include/math-emu/op-2.h | 4 | ||||
-rw-r--r-- | include/math-emu/op-common.h | 85 | ||||
-rw-r--r-- | include/math-emu/quad.h | 2 | ||||
-rw-r--r-- | include/math-emu/single.h | 1 | ||||
-rw-r--r-- | include/math-emu/soft-fp.h | 7 |
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. |