summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorH. Peter Anvin <hpa@linux.intel.com>2012-03-20 02:37:53 (GMT)
committerH. Peter Anvin <hpa@linux.intel.com>2012-03-20 02:49:30 (GMT)
commite9675457d605686fb76e34539d14e1a8893269f0 (patch)
tree9dcef02b7f2d8507ee99bb42a2feeb6f9a005724
parentfc3eb93a04d2b9d0ab7821b6bbf95e852d13c847 (diff)
downloadpbn-e9675457d605686fb76e34539d14e1a8893269f0.zip
pbn-e9675457d605686fb76e34539d14e1a8893269f0.tar.gz
pbn-e9675457d605686fb76e34539d14e1a8893269f0.tar.bz2
pbn-e9675457d605686fb76e34539d14e1a8893269f0.tar.xz
Add pbn_muls() -- long * short multiplication
Add pbn_muls() for multiplication of a PBN with a short number (single limb).
-rw-r--r--Makefile4
-rw-r--r--pbn.h1
-rw-r--r--pbn_muls.c59
3 files changed, 62 insertions, 2 deletions
diff --git a/Makefile b/Makefile
index 57c06ba..b2724f1 100644
--- a/Makefile
+++ b/Makefile
@@ -4,8 +4,8 @@ LDFLAGS =
AR = ar
RANLIB = ranlib
-LIBOBJ = pbn_add.o pbn_cmp.o pbn_dump.o pbn_init.o pbn_mul.o pbn_shift.o \
- pbn_and.o pbn_or.o pbn_xor.o pbn_bit.o \
+LIBOBJ = pbn_add.o pbn_cmp.o pbn_dump.o pbn_init.o pbn_mul.o pbn_muls.o \
+ pbn_shift.o pbn_and.o pbn_or.o pbn_xor.o pbn_bit.o \
pbn_abs.o pbn_div.o pbn_divs.o
LIB = pbn.a
diff --git a/pbn.h b/pbn.h
index fc4fbfd..afc5249 100644
--- a/pbn.h
+++ b/pbn.h
@@ -66,6 +66,7 @@ struct pbn *pbn_addsub(struct pbn *, struct pbn *, int issub);
int pbn_cmp(const struct pbn *, const struct pbn *);
int pbn_abscmp(const struct pbn *, const struct pbn *);
struct pbn *pbn_mul(struct pbn *, struct pbn *);
+struct pbn *pbn_muls(struct pbn *, pbn_slimb_t);
int pbn_div(struct pbn **, struct pbn **, struct pbn *, struct pbn *);
int pbn_divs(struct pbn **, pbn_slimb_t *, struct pbn *, pbn_slimb_t);
struct pbn *pbn_abs(struct pbn *);
diff --git a/pbn_muls.c b/pbn_muls.c
new file mode 100644
index 0000000..7a601aa
--- /dev/null
+++ b/pbn_muls.c
@@ -0,0 +1,59 @@
+/* ----------------------------------------------------------------------- *
+ *
+ * Copyright 2007 H. Peter Anvin - All Rights Reserved
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation, Inc.,
+ * 59 Temple Place Ste 330, Boston MA 02111-1307, USA; version 2.1,
+ * incorporated herein by reference.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * pbn_muls.c
+ *
+ * Multiply a PBN with a single limb number.
+ */
+
+#include "pbnint.h"
+
+struct pbn *pbn_muls(struct pbn *s1, pbn_slimb_t s2)
+{
+ size_t bits, len;
+ struct pbn *d;
+ int i;
+ pbn_limb_t s2u, c, *s1p, *dp;
+ pbn_2limb_t t;
+
+ if (unlikely(s1->bits == 0)) {
+ return s1; /* s1 == 0 */
+ }
+
+ bits = s1->bits + PBN_LIMB_BITS;
+ len = (bits+PBN_LIMB_BITS-1)/PBN_LIMB_BITS;
+
+ d = pbn_new(len);
+ d->bits = bits;
+
+ d->minus = s1->minus;
+ s2u = s2;
+ if (s2 < 0) {
+ s2u = -s2;
+ d->minus ^= 1;
+ }
+
+ c = 0;
+ s1p = s1->num;
+ dp = d->num;
+ for (i = 0; i < s1->len; i++) {
+ t = (pbn_2limb_t)*s1p++ * s2u + c;
+ *dp++ = (pbn_limb_t)t;
+ c = t >> PBN_LIMB_BITS;
+ }
+ *dp = c;
+
+ pbn_free(s1);
+
+ return pbn_adjust_bits(d);
+}