about summary refs log tree commit diff
path: root/soft-fp/op-4.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-4.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-4.h')
-rw-r--r--soft-fp/op-4.h128
1 files changed, 71 insertions, 57 deletions
diff --git a/soft-fp/op-4.h b/soft-fp/op-4.h
index fd31da90f8..f16870d0f7 100644
--- a/soft-fp/op-4.h
+++ b/soft-fp/op-4.h
@@ -142,6 +142,8 @@
 #define _FP_FRAC_ZEROP_4(X)     ((X##_f[0] | X##_f[1] | X##_f[2] | X##_f[3]) == 0)
 #define _FP_FRAC_NEGP_4(X)      ((_FP_WS_TYPE)X##_f[3] < 0)
 #define _FP_FRAC_OVERP_4(fs,X)  (_FP_FRAC_HIGH_##fs(X) & _FP_OVERFLOW_##fs)
+#define _FP_FRAC_HIGHBIT_DW_4(fs,X)	\
+  (_FP_FRAC_HIGH_DW_##fs(X) & _FP_HIGHBIT_DW_##fs)
 #define _FP_FRAC_CLEAR_OVERP_4(fs,X)  (_FP_FRAC_HIGH_##fs(X) &= ~_FP_OVERFLOW_##fs)
 
 #define _FP_FRAC_EQ_4(X,Y)				\
@@ -246,81 +248,88 @@
 
 /* Given a 1W * 1W => 2W primitive, do the extended multiplication.  */
 
-#define _FP_MUL_MEAT_4_wide(wfracbits, R, X, Y, doit)			    \
+#define _FP_MUL_MEAT_DW_4_wide(wfracbits, R, X, Y, doit)		    \
   do {									    \
-    _FP_FRAC_DECL_8(_z); _FP_FRAC_DECL_2(_b); _FP_FRAC_DECL_2(_c);	    \
+    _FP_FRAC_DECL_2(_b); _FP_FRAC_DECL_2(_c);				    \
     _FP_FRAC_DECL_2(_d); _FP_FRAC_DECL_2(_e); _FP_FRAC_DECL_2(_f);	    \
 									    \
-    doit(_FP_FRAC_WORD_8(_z,1), _FP_FRAC_WORD_8(_z,0), X##_f[0], Y##_f[0]); \
+    doit(_FP_FRAC_WORD_8(R,1), _FP_FRAC_WORD_8(R,0), X##_f[0], Y##_f[0]);   \
     doit(_b_f1, _b_f0, X##_f[0], Y##_f[1]);				    \
     doit(_c_f1, _c_f0, X##_f[1], Y##_f[0]);				    \
     doit(_d_f1, _d_f0, X##_f[1], Y##_f[1]);				    \
     doit(_e_f1, _e_f0, X##_f[0], Y##_f[2]);				    \
     doit(_f_f1, _f_f0, X##_f[2], Y##_f[0]);				    \
-    __FP_FRAC_ADD_3(_FP_FRAC_WORD_8(_z,3),_FP_FRAC_WORD_8(_z,2),	    \
-		    _FP_FRAC_WORD_8(_z,1), 0,_b_f1,_b_f0,		    \
-		    0,0,_FP_FRAC_WORD_8(_z,1));				    \
-    __FP_FRAC_ADD_3(_FP_FRAC_WORD_8(_z,3),_FP_FRAC_WORD_8(_z,2),	    \
-		    _FP_FRAC_WORD_8(_z,1), 0,_c_f1,_c_f0,		    \
-		    _FP_FRAC_WORD_8(_z,3),_FP_FRAC_WORD_8(_z,2),	    \
-		    _FP_FRAC_WORD_8(_z,1));				    \
-    __FP_FRAC_ADD_3(_FP_FRAC_WORD_8(_z,4),_FP_FRAC_WORD_8(_z,3),	    \
-		    _FP_FRAC_WORD_8(_z,2), 0,_d_f1,_d_f0,		    \
-		    0,_FP_FRAC_WORD_8(_z,3),_FP_FRAC_WORD_8(_z,2));	    \
-    __FP_FRAC_ADD_3(_FP_FRAC_WORD_8(_z,4),_FP_FRAC_WORD_8(_z,3),	    \
-		    _FP_FRAC_WORD_8(_z,2), 0,_e_f1,_e_f0,		    \
-		    _FP_FRAC_WORD_8(_z,4),_FP_FRAC_WORD_8(_z,3),	    \
-		    _FP_FRAC_WORD_8(_z,2));				    \
-    __FP_FRAC_ADD_3(_FP_FRAC_WORD_8(_z,4),_FP_FRAC_WORD_8(_z,3),	    \
-		    _FP_FRAC_WORD_8(_z,2), 0,_f_f1,_f_f0,		    \
-		    _FP_FRAC_WORD_8(_z,4),_FP_FRAC_WORD_8(_z,3),	    \
-		    _FP_FRAC_WORD_8(_z,2));				    \
+    __FP_FRAC_ADD_3(_FP_FRAC_WORD_8(R,3),_FP_FRAC_WORD_8(R,2),		    \
+		    _FP_FRAC_WORD_8(R,1), 0,_b_f1,_b_f0,		    \
+		    0,0,_FP_FRAC_WORD_8(R,1));				    \
+    __FP_FRAC_ADD_3(_FP_FRAC_WORD_8(R,3),_FP_FRAC_WORD_8(R,2),		    \
+		    _FP_FRAC_WORD_8(R,1), 0,_c_f1,_c_f0,		    \
+		    _FP_FRAC_WORD_8(R,3),_FP_FRAC_WORD_8(R,2),		    \
+		    _FP_FRAC_WORD_8(R,1));				    \
+    __FP_FRAC_ADD_3(_FP_FRAC_WORD_8(R,4),_FP_FRAC_WORD_8(R,3),		    \
+		    _FP_FRAC_WORD_8(R,2), 0,_d_f1,_d_f0,		    \
+		    0,_FP_FRAC_WORD_8(R,3),_FP_FRAC_WORD_8(R,2));	    \
+    __FP_FRAC_ADD_3(_FP_FRAC_WORD_8(R,4),_FP_FRAC_WORD_8(R,3),		    \
+		    _FP_FRAC_WORD_8(R,2), 0,_e_f1,_e_f0,		    \
+		    _FP_FRAC_WORD_8(R,4),_FP_FRAC_WORD_8(R,3),		    \
+		    _FP_FRAC_WORD_8(R,2));				    \
+    __FP_FRAC_ADD_3(_FP_FRAC_WORD_8(R,4),_FP_FRAC_WORD_8(R,3),		    \
+		    _FP_FRAC_WORD_8(R,2), 0,_f_f1,_f_f0,		    \
+		    _FP_FRAC_WORD_8(R,4),_FP_FRAC_WORD_8(R,3),		    \
+		    _FP_FRAC_WORD_8(R,2));				    \
     doit(_b_f1, _b_f0, X##_f[0], Y##_f[3]);				    \
     doit(_c_f1, _c_f0, X##_f[3], Y##_f[0]);				    \
     doit(_d_f1, _d_f0, X##_f[1], Y##_f[2]);				    \
     doit(_e_f1, _e_f0, X##_f[2], Y##_f[1]);				    \
-    __FP_FRAC_ADD_3(_FP_FRAC_WORD_8(_z,5),_FP_FRAC_WORD_8(_z,4),	    \
-		    _FP_FRAC_WORD_8(_z,3), 0,_b_f1,_b_f0,		    \
-		    0,_FP_FRAC_WORD_8(_z,4),_FP_FRAC_WORD_8(_z,3));	    \
-    __FP_FRAC_ADD_3(_FP_FRAC_WORD_8(_z,5),_FP_FRAC_WORD_8(_z,4),	    \
-		    _FP_FRAC_WORD_8(_z,3), 0,_c_f1,_c_f0,		    \
-		    _FP_FRAC_WORD_8(_z,5),_FP_FRAC_WORD_8(_z,4),	    \
-		    _FP_FRAC_WORD_8(_z,3));				    \
-    __FP_FRAC_ADD_3(_FP_FRAC_WORD_8(_z,5),_FP_FRAC_WORD_8(_z,4),	    \
-		    _FP_FRAC_WORD_8(_z,3), 0,_d_f1,_d_f0,		    \
-		    _FP_FRAC_WORD_8(_z,5),_FP_FRAC_WORD_8(_z,4),	    \
-		    _FP_FRAC_WORD_8(_z,3));				    \
-    __FP_FRAC_ADD_3(_FP_FRAC_WORD_8(_z,5),_FP_FRAC_WORD_8(_z,4),	    \
-		    _FP_FRAC_WORD_8(_z,3), 0,_e_f1,_e_f0,		    \
-		    _FP_FRAC_WORD_8(_z,5),_FP_FRAC_WORD_8(_z,4),	    \
-		    _FP_FRAC_WORD_8(_z,3));				    \
+    __FP_FRAC_ADD_3(_FP_FRAC_WORD_8(R,5),_FP_FRAC_WORD_8(R,4),		    \
+		    _FP_FRAC_WORD_8(R,3), 0,_b_f1,_b_f0,		    \
+		    0,_FP_FRAC_WORD_8(R,4),_FP_FRAC_WORD_8(R,3));	    \
+    __FP_FRAC_ADD_3(_FP_FRAC_WORD_8(R,5),_FP_FRAC_WORD_8(R,4),		    \
+		    _FP_FRAC_WORD_8(R,3), 0,_c_f1,_c_f0,		    \
+		    _FP_FRAC_WORD_8(R,5),_FP_FRAC_WORD_8(R,4),		    \
+		    _FP_FRAC_WORD_8(R,3));				    \
+    __FP_FRAC_ADD_3(_FP_FRAC_WORD_8(R,5),_FP_FRAC_WORD_8(R,4),		    \
+		    _FP_FRAC_WORD_8(R,3), 0,_d_f1,_d_f0,		    \
+		    _FP_FRAC_WORD_8(R,5),_FP_FRAC_WORD_8(R,4),		    \
+		    _FP_FRAC_WORD_8(R,3));				    \
+    __FP_FRAC_ADD_3(_FP_FRAC_WORD_8(R,5),_FP_FRAC_WORD_8(R,4),		    \
+		    _FP_FRAC_WORD_8(R,3), 0,_e_f1,_e_f0,		    \
+		    _FP_FRAC_WORD_8(R,5),_FP_FRAC_WORD_8(R,4),		    \
+		    _FP_FRAC_WORD_8(R,3));				    \
     doit(_b_f1, _b_f0, X##_f[2], Y##_f[2]);				    \
     doit(_c_f1, _c_f0, X##_f[1], Y##_f[3]);				    \
     doit(_d_f1, _d_f0, X##_f[3], Y##_f[1]);				    \
     doit(_e_f1, _e_f0, X##_f[2], Y##_f[3]);				    \
     doit(_f_f1, _f_f0, X##_f[3], Y##_f[2]);				    \
-    __FP_FRAC_ADD_3(_FP_FRAC_WORD_8(_z,6),_FP_FRAC_WORD_8(_z,5),	    \
-		    _FP_FRAC_WORD_8(_z,4), 0,_b_f1,_b_f0,		    \
-		    0,_FP_FRAC_WORD_8(_z,5),_FP_FRAC_WORD_8(_z,4));	    \
-    __FP_FRAC_ADD_3(_FP_FRAC_WORD_8(_z,6),_FP_FRAC_WORD_8(_z,5),	    \
-		    _FP_FRAC_WORD_8(_z,4), 0,_c_f1,_c_f0,		    \
-		    _FP_FRAC_WORD_8(_z,6),_FP_FRAC_WORD_8(_z,5),	    \
-		    _FP_FRAC_WORD_8(_z,4));				    \
-    __FP_FRAC_ADD_3(_FP_FRAC_WORD_8(_z,6),_FP_FRAC_WORD_8(_z,5),	    \
-		    _FP_FRAC_WORD_8(_z,4), 0,_d_f1,_d_f0,		    \
-		    _FP_FRAC_WORD_8(_z,6),_FP_FRAC_WORD_8(_z,5),	    \
-		    _FP_FRAC_WORD_8(_z,4));				    \
-    __FP_FRAC_ADD_3(_FP_FRAC_WORD_8(_z,7),_FP_FRAC_WORD_8(_z,6),	    \
-		    _FP_FRAC_WORD_8(_z,5), 0,_e_f1,_e_f0,		    \
-		    0,_FP_FRAC_WORD_8(_z,6),_FP_FRAC_WORD_8(_z,5));	    \
-    __FP_FRAC_ADD_3(_FP_FRAC_WORD_8(_z,7),_FP_FRAC_WORD_8(_z,6),	    \
-		    _FP_FRAC_WORD_8(_z,5), 0,_f_f1,_f_f0,		    \
-		    _FP_FRAC_WORD_8(_z,7),_FP_FRAC_WORD_8(_z,6),	    \
-		    _FP_FRAC_WORD_8(_z,5));				    \
+    __FP_FRAC_ADD_3(_FP_FRAC_WORD_8(R,6),_FP_FRAC_WORD_8(R,5),		    \
+		    _FP_FRAC_WORD_8(R,4), 0,_b_f1,_b_f0,		    \
+		    0,_FP_FRAC_WORD_8(R,5),_FP_FRAC_WORD_8(R,4));	    \
+    __FP_FRAC_ADD_3(_FP_FRAC_WORD_8(R,6),_FP_FRAC_WORD_8(R,5),		    \
+		    _FP_FRAC_WORD_8(R,4), 0,_c_f1,_c_f0,		    \
+		    _FP_FRAC_WORD_8(R,6),_FP_FRAC_WORD_8(R,5),		    \
+		    _FP_FRAC_WORD_8(R,4));				    \
+    __FP_FRAC_ADD_3(_FP_FRAC_WORD_8(R,6),_FP_FRAC_WORD_8(R,5),		    \
+		    _FP_FRAC_WORD_8(R,4), 0,_d_f1,_d_f0,		    \
+		    _FP_FRAC_WORD_8(R,6),_FP_FRAC_WORD_8(R,5),		    \
+		    _FP_FRAC_WORD_8(R,4));				    \
+    __FP_FRAC_ADD_3(_FP_FRAC_WORD_8(R,7),_FP_FRAC_WORD_8(R,6),		    \
+		    _FP_FRAC_WORD_8(R,5), 0,_e_f1,_e_f0,		    \
+		    0,_FP_FRAC_WORD_8(R,6),_FP_FRAC_WORD_8(R,5));	    \
+    __FP_FRAC_ADD_3(_FP_FRAC_WORD_8(R,7),_FP_FRAC_WORD_8(R,6),		    \
+		    _FP_FRAC_WORD_8(R,5), 0,_f_f1,_f_f0,		    \
+		    _FP_FRAC_WORD_8(R,7),_FP_FRAC_WORD_8(R,6),		    \
+		    _FP_FRAC_WORD_8(R,5));				    \
     doit(_b_f1, _b_f0, X##_f[3], Y##_f[3]);				    \
-    __FP_FRAC_ADD_2(_FP_FRAC_WORD_8(_z,7),_FP_FRAC_WORD_8(_z,6),	    \
+    __FP_FRAC_ADD_2(_FP_FRAC_WORD_8(R,7),_FP_FRAC_WORD_8(R,6),		    \
 		    _b_f1,_b_f0,					    \
-		    _FP_FRAC_WORD_8(_z,7),_FP_FRAC_WORD_8(_z,6));	    \
+		    _FP_FRAC_WORD_8(R,7),_FP_FRAC_WORD_8(R,6));		    \
+  } while (0)
+
+#define _FP_MUL_MEAT_4_wide(wfracbits, R, X, Y, doit)			    \
+  do {									    \
+    _FP_FRAC_DECL_8(_z);						    \
+									    \
+    _FP_MUL_MEAT_DW_4_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	    \
@@ -330,11 +339,16 @@
 		    _FP_FRAC_WORD_8(_z,1), _FP_FRAC_WORD_8(_z,0));	    \
   } while (0)
 
+#define _FP_MUL_MEAT_DW_4_gmp(wfracbits, R, X, Y)			    \
+  do {									    \
+    mpn_mul_n(R##_f, _x_f, _y_f, 4);					    \
+  } while (0)
+
 #define _FP_MUL_MEAT_4_gmp(wfracbits, R, X, Y)				    \
   do {									    \
     _FP_FRAC_DECL_8(_z);						    \
 									    \
-    mpn_mul_n(_z_f, _x_f, _y_f, 4);					    \
+    _FP_MUL_MEAT_DW_4_gmp(wfracbits, _z, 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	    \