summaryrefslogtreecommitdiffstats
path: root/mpi-patches
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2012-09-17 07:37:40 -0700
committerKaz Kylheku <kaz@kylheku.com>2012-09-17 07:37:40 -0700
commit01628a8244053ced7dd0f20e13e4ce3ff3e81481 (patch)
treef92cca343580e6d1f6035482f3eaa8c2aae6a3cf /mpi-patches
parente27921f29d6b78d5c868d9160e5c12e9a49b4f97 (diff)
downloadtxr-01628a8244053ced7dd0f20e13e4ce3ff3e81481.tar.gz
txr-01628a8244053ced7dd0f20e13e4ce3ff3e81481.tar.bz2
txr-01628a8244053ced7dd0f20e13e4ce3ff3e81481.zip
* arith.c (highest_significant_bit): New static function.
(comp_clamp): Bugfix: avoid shifting left into sign bit. Function renamed to comp_trunc. (logtrunc, ash): New functions. * eval.c (eval_init): Registered logtrunc and ash intrinsics. * lib.h (logtrunc, ash): Declared. * mpi-patches/add-bitops (s_highest_bit_mp): Forward declaration for added. (mp_clamp_comp): Bugfix in handling remainder bits. Function renamed to mp_trunc_comp. (mp_trunc, mp_shift): New functions.
Diffstat (limited to 'mpi-patches')
-rw-r--r--mpi-patches/add-bitops117
1 files changed, 110 insertions, 7 deletions
diff --git a/mpi-patches/add-bitops b/mpi-patches/add-bitops
index 7e8dc696..7eae01cb 100644
--- a/mpi-patches/add-bitops
+++ b/mpi-patches/add-bitops
@@ -1,7 +1,7 @@
Index: mpi-1.8.6/mpi.c
===================================================================
--- mpi-1.8.6.orig/mpi.c 2012-09-16 10:50:08.270639006 -0700
-+++ mpi-1.8.6/mpi.c 2012-09-16 23:09:57.601600506 -0700
++++ mpi-1.8.6/mpi.c 2012-09-17 07:33:38.563334756 -0700
@@ -16,6 +16,9 @@
#include <ctype.h>
#include <math.h>
@@ -12,7 +12,15 @@ Index: mpi-1.8.6/mpi.c
typedef unsigned char mem_t;
extern mem_t *chk_malloc(size_t size);
extern mem_t *chk_calloc(size_t n, size_t size);
-@@ -2330,6 +2333,321 @@
+@@ -159,6 +162,7 @@
+ mp_err s_mp_grow(mp_int *mp, mp_size min); /* increase allocated size */
+ mp_err s_mp_pad(mp_int *mp, mp_size min); /* left pad with zeroes */
+
++static int s_highest_bit(mp_digit n);
+ int s_highest_bit_mp(mp_int *a);
+ mp_err s_mp_set_bit(mp_int *a, int bit);
+
+@@ -2330,6 +2334,414 @@
/* }}} */
@@ -287,7 +295,7 @@ Index: mpi-1.8.6/mpi.c
+ return MP_OKAY;
+}
+
-+mp_err mp_clamp_comp(mp_int *a, mp_int *b, mp_digit bits)
++mp_err mp_trunc_comp(mp_int *a, mp_int *b, mp_digit bits)
+{
+ mp_err res;
+ mp_size ix, dig = bits / DIGIT_BIT, rembits = bits % DIGIT_BIT;
@@ -319,7 +327,51 @@ Index: mpi-1.8.6/mpi.c
+
+ if (rembits) {
+ mp_digit mask = (MP_DIGIT_MAX >> (DIGIT_BIT - rembits));
-+ pb[ix] = (pa[ix] & mask) ^ mask;
++ pb[ix] = (((ix < adig) ? pa[ix] : padding) & mask) ^ mask;
++ }
++
++ USED(b) = dig + extra;
++
++ if (ISNEG(a))
++ mp_clear(&tmp);
++
++ s_mp_clamp(b);
++ return MP_OKAY;
++}
++
++mp_err mp_trunc(mp_int *a, mp_int *b, mp_digit bits)
++{
++ mp_err res;
++ mp_size ix, dig = bits / DIGIT_BIT, rembits = bits % DIGIT_BIT;
++ mp_size adig = USED(a);
++ mp_digit padding = ISNEG(a) ? MP_DIGIT_MAX : 0;
++ int extra = (rembits != 0);
++ mp_digit *pa, *pb;
++ mp_int tmp;
++
++ ARGCHK(a != NULL && b != NULL, MP_BADARG);
++
++ if (a != b)
++ res = mp_init_size(b, dig + extra);
++ else
++ res = s_mp_pad(b, dig + extra);
++
++ if (res != MP_OKAY)
++ return res;
++
++ if (ISNEG(a)) {
++ mp_init_size(&tmp, dig + extra);
++ if ((res = mp_2comp(a, &tmp, dig + extra)) != MP_OKAY)
++ return res;
++ a = &tmp;
++ }
++
++ for (pa = DIGITS(a), pb = DIGITS(b), ix = 0; ix < dig; ix++)
++ pb[ix] = (ix < adig) ? pa[ix] : padding;
++
++ if (rembits) {
++ mp_digit mask = (MP_DIGIT_MAX >> (DIGIT_BIT - rembits));
++ pb[ix] = ((ix < adig) ? pa[ix] : padding) & mask;
+ }
+
+ USED(b) = dig + extra;
@@ -331,13 +383,62 @@ Index: mpi-1.8.6/mpi.c
+ return MP_OKAY;
+}
+
++mp_err mp_shift(mp_int *a, mp_int *b, int bits)
++{
++ mp_int tmp;
++ mp_err res;
++ int a_neg = ISNEG(a);
++
++ if (bits == 0)
++ return mp_copy(a, b);
++
++ if (a_neg) {
++ mp_size ua = USED(a);
++ mp_init_size(&tmp, ua);
++ if ((res = mp_2comp(a, &tmp, ua)) != MP_OKAY)
++ return res;
++ SIGN(&tmp) = MP_ZPOS;
++ a = &tmp;
++ }
++
++ if (bits > 0)
++ res = mp_mul_2d(a, bits, b);
++ else
++ res = mp_div_2d(a, -bits, b, NULL);
++
++ if (res != MP_OKAY)
++ return res;
++
++ if (a_neg) {
++ int hb, msd;
++ mp_digit *db;
++
++ mp_clear(&tmp);
++
++ msd = USED(b)-1;
++ db = DIGITS(b);
++ hb = s_highest_bit(db[msd]);
++
++ if (hb < DIGIT_BIT)
++ db[msd] |= MP_DIGIT_MAX << hb;
++
++ if ((res = mp_2comp(b, b, USED(b))) != MP_OKAY)
++ return res;
++
++ SIGN(b) = MP_NEG;
++ s_mp_clamp(b);
++ }
++
++ return MP_OKAY;
++}
++
mp_err mp_to_double(mp_int *mp, double *d)
{
int ix;
Index: mpi-1.8.6/mpi.h
===================================================================
--- mpi-1.8.6.orig/mpi.h 2012-09-16 10:50:08.046513006 -0700
-+++ mpi-1.8.6/mpi.h 2012-09-16 21:45:17.713770006 -0700
++++ mpi-1.8.6/mpi.h 2012-09-17 07:32:54.738697256 -0700
@@ -54,6 +54,7 @@
/* Macros for accessing the mp_int internals */
@@ -346,7 +447,7 @@ Index: mpi-1.8.6/mpi.h
#define USED(MP) ((MP)->used)
#define ALLOC(MP) ((MP)->alloc)
#define DIGITS(MP) ((MP)->dp)
-@@ -187,6 +188,15 @@
+@@ -187,6 +188,17 @@
#endif /* end MP_NUMTH */
/*------------------------------------------------------------------------*/
@@ -356,7 +457,9 @@ Index: mpi-1.8.6/mpi.h
+mp_err mp_or(mp_int *a, mp_int *b, mp_int *c);
+mp_err mp_xor(mp_int *a, mp_int *b, mp_int *c);
+mp_err mp_comp(mp_int *a, mp_int *b);
-+mp_err mp_clamp_comp(mp_int *a, mp_int *b, mp_digit bits);
++mp_err mp_trunc_comp(mp_int *a, mp_int *b, mp_digit bits);
++mp_err mp_trunc(mp_int *a, mp_int *b, mp_digit bits);
++mp_err mp_shift(mp_int *a, mp_int *b, int bits); /* + left, - right */
+
+/*------------------------------------------------------------------------*/
/* Conversions */