summaryrefslogtreecommitdiff
path: root/mpn/cray
diff options
context:
space:
mode:
authortege <tege@gmplib.org>2001-03-05 04:32:04 +0100
committertege <tege@gmplib.org>2001-03-05 04:32:04 +0100
commit5d38a9991d9fc011e1477034713440ca7c6f4ddb (patch)
tree406e9beba38b8adc75272dbc83ccb1e0e8d41535 /mpn/cray
parent85916aaa96f52baef331e51de14a3edbfa71eca7 (diff)
downloadgmp-5d38a9991d9fc011e1477034713440ca7c6f4ddb.tar.gz
Add special case for argument overlap.
Diffstat (limited to 'mpn/cray')
-rw-r--r--mpn/cray/ieee/mul_1.c13
1 files changed, 11 insertions, 2 deletions
diff --git a/mpn/cray/ieee/mul_1.c b/mpn/cray/ieee/mul_1.c
index bf74e535d..6f005e1b9 100644
--- a/mpn/cray/ieee/mul_1.c
+++ b/mpn/cray/ieee/mul_1.c
@@ -35,6 +35,15 @@ mpn_mul_1 (mp_ptr rp, mp_srcptr up, mp_size_t n, mp_limb_t vl)
mp_size_t i;
int more_carries;
+ if (up == rp)
+ {
+ /* The algorithm used below cannot handle overlap. Handle it here by
+ making a temporary copy of the source vector, then call ourselves. */
+ mp_limb_t xp[n];
+ MPN_COPY (xp, up, n);
+ return mpn_mul_1 (rp, xp, n, vl);
+ }
+
a = up[0] * vl;
rp[0] = a;
cy[0] = 0;
@@ -55,7 +64,7 @@ mpn_mul_1 (mp_ptr rp, mp_srcptr up, mp_size_t n, mp_limb_t vl)
store the new sum back to rp[0]. */
more_carries = 0;
#pragma _CRI ivdep
- for (i = 1; i < n; i++)
+ for (i = 2; i < n; i++)
{
r = rp[i];
c0 = cy[i - 1];
@@ -70,7 +79,7 @@ mpn_mul_1 (mp_ptr rp, mp_srcptr up, mp_size_t n, mp_limb_t vl)
mp_limb_t cyrec = 0;
/* Look for places where rp[k] is zero and cy[k-1] is non-zero.
These are where we got a recurrency carry. */
- for (i = 1; i < n; i++)
+ for (i = 2; i < n; i++)
{
r = rp[i];
c0 = (r == 0 && cy[i - 1] != 0);