about summary refs log tree commit diff
path: root/soft-fp/op-1.h
diff options
context:
space:
mode:
authorJoseph Myers <joseph@codesourcery.com>2013-07-02 14:55:32 +0000
committerJoseph Myers <joseph@codesourcery.com>2013-07-02 14:55:32 +0000
commit77f01ab5d1d2eead1bd4a9135d6a76ebd3fe21e5 (patch)
tree84727a1d5b17bbfe868ef2246e59bffc98f57495 /soft-fp/op-1.h
parent1413c693d3390e02399a0042ef97b73918749977 (diff)
downloadglibc-77f01ab5d1d2eead1bd4a9135d6a76ebd3fe21e5.tar.gz
glibc-77f01ab5d1d2eead1bd4a9135d6a76ebd3fe21e5.tar.xz
glibc-77f01ab5d1d2eead1bd4a9135d6a76ebd3fe21e5.zip
Implement fma in soft-fp.
Diffstat (limited to 'soft-fp/op-1.h')
-rw-r--r--soft-fp/op-1.h36
1 files changed, 27 insertions, 9 deletions
diff --git a/soft-fp/op-1.h b/soft-fp/op-1.h
index 8e05e2fab7..a9ad0d62cd 100644
--- a/soft-fp/op-1.h
+++ b/soft-fp/op-1.h
@@ -72,6 +72,7 @@ do {							\
 #define _FP_FRAC_ZEROP_1(X)	(X##_f == 0)
 #define _FP_FRAC_OVERP_1(fs,X)	(X##_f & _FP_OVERFLOW_##fs)
 #define _FP_FRAC_CLEAR_OVERP_1(fs,X)	(X##_f &= ~_FP_OVERFLOW_##fs)
+#define _FP_FRAC_HIGHBIT_DW_1(fs,X)	(X##_f & _FP_HIGHBIT_DW_##fs)
 #define _FP_FRAC_EQ_1(X, Y)	(X##_f == Y##_f)
 #define _FP_FRAC_GE_1(X, Y)	(X##_f >= Y##_f)
 #define _FP_FRAC_GT_1(X, Y)	(X##_f > Y##_f)
@@ -137,9 +138,14 @@ do {							\
 /* Basic.  Assuming the host word size is >= 2*FRACBITS, we can do the
    multiplication immediately.  */
 
-#define _FP_MUL_MEAT_1_imm(wfracbits, R, X, Y)				\
+#define _FP_MUL_MEAT_DW_1_imm(wfracbits, R, X, Y)			\
   do {									\
     R##_f = X##_f * Y##_f;						\
+  } while (0)
+
+#define _FP_MUL_MEAT_1_imm(wfracbits, R, X, Y)				\
+  do {									\
+    _FP_MUL_MEAT_DW_1_imm(wfracbits, R, X, Y);				\
     /* Normalize since we know where the msb of the multiplicands	\
        were (bit B), we know that the msb of the of the product is	\
        at either 2B or 2B-1.  */					\
@@ -148,10 +154,15 @@ do {							\
 
 /* Given a 1W * 1W => 2W primitive, do the extended multiplication.  */
 
+#define _FP_MUL_MEAT_DW_1_wide(wfracbits, R, X, Y, doit)		\
+  do {									\
+    doit(R##_f1, R##_f0, X##_f, Y##_f);					\
+  } while (0)
+
 #define _FP_MUL_MEAT_1_wide(wfracbits, R, X, Y, doit)			\
   do {									\
-    _FP_W_TYPE _Z_f0, _Z_f1;						\
-    doit(_Z_f1, _Z_f0, X##_f, Y##_f);					\
+    _FP_FRAC_DECL_2(_Z);						\
+    _FP_MUL_MEAT_DW_1_wide(wfracbits, _Z, X, Y, doit);			\
     /* Normalize since we know where the msb of the multiplicands	\
        were (bit B), we know that the msb of the of the product is	\
        at either 2B or 2B-1.  */					\
@@ -161,9 +172,10 @@ do {							\
 
 /* Finally, a simple widening multiply algorithm.  What fun!  */
 
-#define _FP_MUL_MEAT_1_hard(wfracbits, R, X, Y)				\
+#define _FP_MUL_MEAT_DW_1_hard(wfracbits, R, X, Y)			\
   do {									\
-    _FP_W_TYPE _xh, _xl, _yh, _yl, _z_f0, _z_f1, _a_f0, _a_f1;		\
+    _FP_W_TYPE _xh, _xl, _yh, _yl;					\
+    _FP_FRAC_DECL_2(_a);						\
 									\
     /* split the words in half */					\
     _xh = X##_f >> (_FP_W_TYPE_SIZE/2);					\
@@ -172,17 +184,23 @@ do {							\
     _yl = Y##_f & (((_FP_W_TYPE)1 << (_FP_W_TYPE_SIZE/2)) - 1);		\
 									\
     /* multiply the pieces */						\
-    _z_f0 = _xl * _yl;							\
+    R##_f0 = _xl * _yl;							\
     _a_f0 = _xh * _yl;							\
     _a_f1 = _xl * _yh;							\
-    _z_f1 = _xh * _yh;							\
+    R##_f1 = _xh * _yh;							\
 									\
     /* reassemble into two full words */				\
     if ((_a_f0 += _a_f1) < _a_f1)					\
-      _z_f1 += (_FP_W_TYPE)1 << (_FP_W_TYPE_SIZE/2);			\
+      R##_f1 += (_FP_W_TYPE)1 << (_FP_W_TYPE_SIZE/2);			\
     _a_f1 = _a_f0 >> (_FP_W_TYPE_SIZE/2);				\
     _a_f0 = _a_f0 << (_FP_W_TYPE_SIZE/2);				\
-    _FP_FRAC_ADD_2(_z, _z, _a);						\
+    _FP_FRAC_ADD_2(R, R, _a);						\
+  } while (0)
+
+#define _FP_MUL_MEAT_1_hard(wfracbits, R, X, Y)				\
+  do {									\
+    _FP_FRAC_DECL_2(_z);						\
+    _FP_MUL_MEAT_DW_1_hard(wfracbits, _z, X, Y);			\
 									\
     /* normalize */							\
     _FP_FRAC_SRS_2(_z, wfracbits - 1, 2*wfracbits);			\