summaryrefslogtreecommitdiff
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)
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 \