patch-2.2.11 linux/arch/sparc64/math-emu/op-common.h
Next file: linux/arch/sparc64/math-emu/sfp-machine.h
Previous file: linux/arch/sparc64/math-emu/fstox.c
Back to the patch index
Back to the overall index
- Lines: 417
- Date:
Mon Aug 9 12:05:09 1999
- Orig file:
v2.2.10/linux/arch/sparc64/math-emu/op-common.h
- Orig date:
Wed Mar 10 16:53:37 1999
diff -u --recursive --new-file v2.2.10/linux/arch/sparc64/math-emu/op-common.h linux/arch/sparc64/math-emu/op-common.h
@@ -1,6 +1,5 @@
-
#define _FP_DECL(wc, X) \
- _FP_I_TYPE X##_c, X##_s, X##_e; \
+ _FP_I_TYPE X##_c, X##_s, X##_e, X##_r=0; \
_FP_FRAC_DECL_##wc(X)
/*
@@ -8,6 +7,7 @@
* of fp value and normalizing both the exponent and the fraction.
*/
+#ifndef _FP_UNPACK_CANONICAL
#define _FP_UNPACK_CANONICAL(fs, wc, X) \
do { \
switch (X##_e) \
@@ -23,15 +23,8 @@
if (_FP_FRAC_ZEROP_##wc(X)) \
X##_c = FP_CLS_ZERO; \
else \
- { \
- /* a denormalized number */ \
- _FP_I_TYPE _shift; \
- _FP_FRAC_CLZ_##wc(_shift, X); \
- _shift -= _FP_FRACXBITS_##fs; \
- _FP_FRAC_SLL_##wc(X, (_shift+_FP_WORKBITS)); \
- X##_e -= _FP_EXPBIAS_##fs - 1 + _shift; \
- X##_c = FP_CLS_NORMAL; \
- } \
+ /* a denormalized number */ \
+ __FP_UNPACK_DENORM(fs, wc, X) \
break; \
\
case _FP_EXPMAX_##fs: \
@@ -43,6 +36,7 @@
break; \
} \
} while (0)
+#endif /* _FP_UNPACK_CANONICAL */
/*
@@ -52,15 +46,16 @@
* extracted -- but that is ok, we can regenerate them now.
*/
+#ifndef _FP_PACK_CANONICAL
#define _FP_PACK_CANONICAL(fs, wc, X) \
-({int __ret = 0; \
+({int __pk__ret = X##_r; \
switch (X##_c) \
{ \
case FP_CLS_NORMAL: \
X##_e += _FP_EXPBIAS_##fs; \
if (X##_e > 0) \
{ \
- __ret |= _FP_ROUND(wc, X); \
+ __pk__ret |= _FP_ROUND(wc, X); \
if (_FP_FRAC_OVERP_##wc(fs, X)) \
{ \
_FP_FRAC_SRL_##wc(X, (_FP_WORKBITS+1)); \
@@ -73,7 +68,7 @@
/* overflow to infinity */ \
X##_e = _FP_EXPMAX_##fs; \
_FP_FRAC_SET_##wc(X, _FP_ZEROFRAC_##wc); \
- __ret |= EFLAG_OVERFLOW; \
+ __pk__ret |= EFLAG_OVERFLOW; \
} \
} \
else \
@@ -83,7 +78,7 @@
if (X##_e <= _FP_WFRACBITS_##fs) \
{ \
_FP_FRAC_SRS_##wc(X, X##_e, _FP_WFRACBITS_##fs); \
- __ret |= _FP_ROUND(wc, X); \
+ __pk__ret |= _FP_ROUND(wc, X); \
_FP_FRAC_SLL_##wc(X, 1); \
if (_FP_FRAC_OVERP_##wc(fs, X)) \
{ \
@@ -94,7 +89,7 @@
{ \
X##_e = 0; \
_FP_FRAC_SRL_##wc(X, _FP_WORKBITS+1); \
- __ret |= EFLAG_UNDERFLOW; \
+ __pk__ret |= EFLAG_UNDERFLOW; \
} \
} \
else \
@@ -102,7 +97,7 @@
/* underflow to zero */ \
X##_e = 0; \
_FP_FRAC_SET_##wc(X, _FP_ZEROFRAC_##wc); \
- __ret |= EFLAG_UNDERFLOW; \
+ __pk__ret |= EFLAG_UNDERFLOW; \
} \
} \
break; \
@@ -128,16 +123,18 @@
_FP_FRAC_HIGH_##wc(X) |= _FP_QNANBIT_##fs; \
break; \
} \
- __ret; \
+ __pk__ret; \
})
-
+#endif /* _FP_PACK_CANONICAL */
/*
* Main addition routine. The input values should be cooked.
*/
-
+#ifndef _FP_ADD
#define _FP_ADD(fs, wc, R, X, Y) \
do { \
+ /* Propagate any flags that may have been set during unpacking */ \
+ R##_r |= (X##_r | Y##_r); \
switch (_FP_CLS_COMBINE(X##_c, Y##_c)) \
{ \
case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_NORMAL): \
@@ -150,8 +147,10 @@
diff = -diff; \
if (diff <= _FP_WFRACBITS_##fs) \
_FP_FRAC_SRS_##wc(X, diff, _FP_WFRACBITS_##fs); \
- else if (!_FP_FRAC_ZEROP_##wc(X)) \
+ else if (!_FP_FRAC_ZEROP_##wc(X)) { \
_FP_FRAC_SET_##wc(X, _FP_MINFRAC_##wc); \
+ R_r |= EFLAG_INEXACT; \
+ } \
else \
_FP_FRAC_SET_##wc(X, _FP_ZEROFRAC_##wc); \
R##_e = Y##_e; \
@@ -162,8 +161,10 @@
{ \
if (diff <= _FP_WFRACBITS_##fs) \
_FP_FRAC_SRS_##wc(Y, diff, _FP_WFRACBITS_##fs); \
- else if (!_FP_FRAC_ZEROP_##wc(Y)) \
+ else if (!_FP_FRAC_ZEROP_##wc(Y)) { \
_FP_FRAC_SET_##wc(Y, _FP_MINFRAC_##wc); \
+ R_r |= EFLAG_INEXACT; \
+ } \
else \
_FP_FRAC_SET_##wc(Y, _FP_ZEROFRAC_##wc); \
} \
@@ -247,6 +248,7 @@
_FP_FRAC_SET_##wc(R, _FP_NANFRAC_##fs); \
R##_s = X##_s ^ Y##_s; \
R##_c = FP_CLS_NAN; \
+ R##_r |= EFLAG_INVALID; \
break; \
} \
/* FALLTHRU */ \
@@ -276,28 +278,33 @@
abort(); \
} \
} while (0)
+#endif /* _FP_ADD */
/*
* Main negation routine. FIXME -- when we care about setting exception
* bits reliably, this will not do. We should examine all of the fp classes.
*/
-
+#ifndef _FP_NEG
#define _FP_NEG(fs, wc, R, X) \
do { \
+ R##_r |= X##_r; \
_FP_FRAC_COPY_##wc(R, X); \
R##_c = X##_c; \
R##_e = X##_e; \
R##_s = 1 ^ X##_s; \
} while (0)
+#endif /* _FP_NEG */
/*
* Main multiplication routine. The input values should be cooked.
*/
-
+#ifndef _FP_MUL
#define _FP_MUL(fs, wc, R, X, Y) \
do { \
+ /* Propagate any flags that may have been set during unpacking */ \
+ R##_r |= (X##_r | Y##_r); \
R##_s = X##_s ^ Y##_s; \
switch (_FP_CLS_COMBINE(X##_c, Y##_c)) \
{ \
@@ -351,14 +358,17 @@
abort(); \
} \
} while (0)
+#endif /* _FP_MUL */
/*
* Main division routine. The input values should be cooked.
*/
-
+#ifndef _FP_DIV
#define _FP_DIV(fs, wc, R, X, Y) \
do { \
+ /* Propagate any flags that may have been set during unpacking */ \
+ R##_r |= (X##_r | Y##_r); \
R##_s = X##_s ^ Y##_s; \
switch (_FP_CLS_COMBINE(X##_c, Y##_c)) \
{ \
@@ -411,13 +421,14 @@
abort(); \
} \
} while (0)
+#endif _FP_DIV
/*
* Main differential comparison routine. The inputs should be raw not
* cooked. The return is -1,0,1 for normal values, 2 otherwise.
*/
-
+#ifndef _FP_CMP
#define _FP_CMP(fs, wc, ret, X, Y, un) \
do { \
/* NANs are unordered */ \
@@ -426,6 +437,18 @@
{ \
ret = un; \
} \
+ /* Deal with infinities */ \
+ else if (X##_c == FP_CLS_INF) { \
+ if(Y##_c == FP_CLS_INF) { \
+ ret = Y##_s - X##_s; \
+ } \
+ else { \
+ ret = X##_s ? -1 : 1; \
+ } \
+ } \
+ else if(Y##_c == FP_CLS_INF) { \
+ ret = Y##_s ? 1 : -1; \
+ } \
else \
{ \
int __is_zero_x; \
@@ -454,10 +477,12 @@
ret = 0; \
} \
} while (0)
+#endif /* _FP_CMP */
/* Simplification for strict equality. */
+#ifndef _FP_CMP_EQ
#define _FP_CMP_EQ(fs, wc, ret, X, Y) \
do { \
/* NANs are unordered */ \
@@ -473,21 +498,21 @@
&& (X##_s == Y##_s || !X##_e && _FP_FRAC_ZEROP_##wc(X))); \
} \
} while (0)
+#endif /* _FP_CMP_EQ */
/*
* Main square root routine. The input value should be cooked.
*/
-
+#ifndef _FP_SQRT
#define _FP_SQRT(fs, wc, R, X) \
do { \
_FP_FRAC_DECL_##wc(T); _FP_FRAC_DECL_##wc(S); \
_FP_W_TYPE q; \
+ R##_r |= X##_r; \
switch (X##_c) \
{ \
case FP_CLS_NAN: \
- R##_s = 0; \
- R##_c = FP_CLS_NAN; \
- _FP_FRAC_SET_##wc(X, _FP_ZEROFRAC_##wc); \
+ _FP_CHOOSENAN_SQRT(fs, wc, R, X); \
break; \
case FP_CLS_INF: \
if (X##_s) \
@@ -524,6 +549,7 @@
_FP_FRAC_SRL_##wc(R, 1); \
} \
} while (0)
+#endif /* FP_SQRT */
/*
* Convert from FP to integer
@@ -552,56 +578,60 @@
* in r be signed or unsigned?'. r is always(?) declared unsigned.
* Comments below are mine, BTW -- PMM
*/
-#define _FP_TO_INT(fs, wc, r, X, rsize, rsigned) \
- do { \
- switch (X##_c) \
- { \
- case FP_CLS_NORMAL: \
- if (X##_e < 0) \
- { \
- /* case FP_CLS_NAN: see above! */ \
- case FP_CLS_ZERO: \
- r = 0; \
- } \
- else if (X##_e >= rsize - (rsigned != 0)) \
- { /* overflow */ \
- case FP_CLS_NAN: \
- case FP_CLS_INF: \
- if (rsigned) \
- { \
- r = 1; \
- r <<= rsize - 1; \
- r -= 1 - X##_s; \
- } \
- else \
- { \
- r = 0; \
- if (!X##_s) \
- r = ~r; \
- } \
- } \
- else \
- { \
- if (_FP_W_TYPE_SIZE*wc < rsize) \
- { \
- _FP_FRAC_ASSEMBLE_##wc(r, X, rsize); \
- r <<= X##_e - _FP_WFRACBITS_##fs; \
- } \
- else \
- { \
- if (X##_e >= _FP_WFRACBITS_##fs) \
- _FP_FRAC_SLL_##wc(X, (X##_e - _FP_WFRACBITS_##fs + 1)); \
- else \
- _FP_FRAC_SRL_##wc(X, (_FP_WFRACBITS_##fs - X##_e - 1)); \
- _FP_FRAC_ASSEMBLE_##wc(r, X, rsize); \
- } \
- if (rsigned && X##_s) \
- r = -r; \
- } \
- break; \
- } \
+#ifndef _FP_TO_INT
+#define _FP_TO_INT(fs, wc, r, X, rsize, rsigned) \
+ do { \
+ switch (X##_c) \
+ { \
+ case FP_CLS_NORMAL: \
+ if (X##_e < 0) \
+ { \
+ /* case FP_CLS_NAN: see above! */ \
+ case FP_CLS_ZERO: \
+ r = 0; \
+ } \
+ else if (X##_e >= rsize - (rsigned != 0)) \
+ { /* overflow */ \
+ case FP_CLS_NAN: \
+ case FP_CLS_INF: \
+ if (rsigned) \
+ { \
+ r = 1; \
+ r <<= rsize - 1; \
+ r -= 1 - X##_s; \
+ } \
+ else \
+ { \
+ r = 0; \
+ if (!X##_s) \
+ r = ~r; \
+ } \
+ } \
+ else \
+ { \
+ if (_FP_W_TYPE_SIZE*wc < rsize) \
+ { \
+ _FP_FRAC_ASSEMBLE_##wc(r, X, rsize); \
+ r <<= X##_e - _FP_WFRACBITS_##fs; \
+ } \
+ else \
+ { \
+ if (X##_e >= _FP_WFRACBITS_##fs) \
+ _FP_FRAC_SLL_##wc(X, (X##_e - _FP_WFRACBITS_##fs + 1)); \
+ else \
+ _FP_FRAC_SRL_##wc(X, (_FP_WFRACBITS_##fs - X##_e - 1)); \
+ _FP_FRAC_ASSEMBLE_##wc(r, X, rsize); \
+ } \
+ if (rsigned && X##_s) \
+ r = -r; \
+ } \
+ break; \
+ } \
} while (0)
+#endif /* _FP_TO_INT */
+
+#ifndef _FP_FROM_INT
#define _FP_FROM_INT(fs, wc, X, r, rsize, rtype) \
do { \
if (r) \
@@ -633,15 +663,18 @@
X##_c = FP_CLS_ZERO, X##_s = 0; \
} \
} while (0)
+#endif /* FP_FROM_INT */
-
+#ifndef FP_CONV
#define FP_CONV(dfs,sfs,dwc,swc,D,S) \
do { \
_FP_FRAC_CONV_##dwc##_##swc(dfs, sfs, D, S); \
D##_e = S##_e; \
D##_c = S##_c; \
D##_s = S##_s; \
+ D##_r |= S##_r; \
} while (0)
+#endif FP_CONV
/*
* Helper primitives.
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)