[Gmp-commit] /var/hg/gmp: Rewrite to invoke mpn_sqr when appropriate.

mercurial at gmplib.org mercurial at gmplib.org
Mon Dec 23 20:26:52 UTC 2019


details:   /var/hg/gmp/rev/755155b633f6
changeset: 18000:755155b633f6
user:      Torbjorn Granlund <tg at gmplib.org>
date:      Mon Dec 23 21:26:40 2019 +0100
description:
Rewrite to invoke mpn_sqr when appropriate.

diffstat:

 mpf/mul.c |  132 +++++++++++++++++++++++++++++++++++++++----------------------
 1 files changed, 85 insertions(+), 47 deletions(-)

diffs (160 lines):

diff -r 12726da168ff -r 755155b633f6 mpf/mul.c
--- a/mpf/mul.c	Fri Dec 20 21:55:06 2019 +0100
+++ b/mpf/mul.c	Mon Dec 23 21:26:40 2019 +0100
@@ -1,6 +1,6 @@
 /* mpf_mul -- Multiply two floats.
 
-Copyright 1993, 1994, 1996, 2001, 2005 Free Software Foundation, Inc.
+Copyright 1993, 1994, 1996, 2001, 2005, 2019 Free Software Foundation, Inc.
 
 This file is part of the GNU MP Library.
 
@@ -33,64 +33,102 @@
 void
 mpf_mul (mpf_ptr r, mpf_srcptr u, mpf_srcptr v)
 {
-  mp_srcptr up, vp;
-  mp_size_t usize, vsize;
   mp_size_t sign_product;
   mp_size_t prec = r->_mp_prec;
-
-  usize = u->_mp_size;
-  vsize = v->_mp_size;
-  sign_product = usize ^ vsize;
+  mp_size_t rsize;
+  mp_limb_t cy_limb;
+  mp_ptr rp, tp;
+  mp_size_t adj;
+  TMP_DECL;
 
-  usize = ABS (usize);
-  vsize = ABS (vsize);
-
-  up = u->_mp_d;
-  vp = v->_mp_d;
-  if (usize > prec)
+  if (u == v)
     {
-      up += usize - prec;
-      usize = prec;
-    }
-  if (vsize > prec)
-    {
-      vp += vsize - prec;
-      vsize = prec;
-    }
+      mp_srcptr up;
+      mp_size_t usize;
+
+      usize = u->_mp_size;
+      sign_product = usize;
+
+      usize = ABS (usize);
+
+      up = u->_mp_d;
+      if (usize > prec)
+	{
+	  up += usize - prec;
+	  usize = prec;
+	}
 
-  if (usize == 0 || vsize == 0)
-    {
-      r->_mp_size = 0;
-      r->_mp_exp = 0;		/* ??? */
+      if (usize == 0)
+	{
+	  r->_mp_size = 0;
+	  r->_mp_exp = 0;		/* ??? */
+	  return;
+	}
+      else
+	{
+	  TMP_MARK;
+	  rsize = 2 * usize;
+	  tp = TMP_ALLOC_LIMBS (rsize);
+
+	  mpn_sqr (tp, up, usize);
+	  cy_limb = tp[rsize - 1];
+	}
     }
   else
     {
-      mp_size_t rsize;
-      mp_limb_t cy_limb;
-      mp_ptr rp, tp;
-      mp_size_t adj;
-      TMP_DECL;
+      mp_srcptr up, vp;
+      mp_size_t usize, vsize;
+
+      usize = u->_mp_size;
+      vsize = v->_mp_size;
+      sign_product = usize ^ vsize;
+
+      usize = ABS (usize);
+      vsize = ABS (vsize);
 
-      TMP_MARK;
-      rsize = usize + vsize;
-      tp = TMP_ALLOC_LIMBS (rsize);
-      cy_limb = (usize >= vsize
-		 ? mpn_mul (tp, up, usize, vp, vsize)
-		 : mpn_mul (tp, vp, vsize, up, usize));
+      up = u->_mp_d;
+      vp = v->_mp_d;
+      if (usize > prec)
+	{
+	  up += usize - prec;
+	  usize = prec;
+	}
+      if (vsize > prec)
+	{
+	  vp += vsize - prec;
+	  vsize = prec;
+	}
 
-      adj = cy_limb == 0;
-      rsize -= adj;
-      prec++;
-      if (rsize > prec)
+      if (usize == 0 || vsize == 0)
+	{
+	  r->_mp_size = 0;
+	  r->_mp_exp = 0;
+	  return;
+	}
+      else
 	{
-	  tp += rsize - prec;
-	  rsize = prec;
+	  TMP_MARK;
+	  rsize = usize + vsize;
+	  tp = TMP_ALLOC_LIMBS (rsize);
+	  cy_limb = (usize >= vsize
+		     ? mpn_mul (tp, up, usize, vp, vsize)
+		     : mpn_mul (tp, vp, vsize, up, usize));
+
 	}
-      rp = r->_mp_d;
-      MPN_COPY (rp, tp, rsize);
-      r->_mp_exp = u->_mp_exp + v->_mp_exp - adj;
-      r->_mp_size = sign_product >= 0 ? rsize : -rsize;
+    }
 
-      TMP_FREE;
+  adj = cy_limb == 0;
+  rsize -= adj;
+  prec++;
+  if (rsize > prec)
+    {
+      tp += rsize - prec;
+      rsize = prec;
     }
+  rp = r->_mp_d;
+  MPN_COPY (rp, tp, rsize);
+  r->_mp_exp = u->_mp_exp + v->_mp_exp - adj;
+  r->_mp_size = sign_product >= 0 ? rsize : -rsize;
+
+  TMP_FREE;
 }


More information about the gmp-commit mailing list