summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--generic/tclExecute.c126
-rw-r--r--generic/tclStubInit.c3
-rw-r--r--generic/tclTomMath.decls11
-rw-r--r--generic/tclTomMathDecls.h21
-rw-r--r--unix/Makefile.in15
-rw-r--r--win/Makefile.in3
-rw-r--r--win/makefile.vc3
7 files changed, 60 insertions, 122 deletions
diff --git a/generic/tclExecute.c b/generic/tclExecute.c
index fafd511..89e61b8 100644
--- a/generic/tclExecute.c
+++ b/generic/tclExecute.c
@@ -8292,7 +8292,7 @@ ExecuteExtendedBinaryMathOp(
Tcl_WideInt w1, w2, wResult;
mp_int big1, big2, bigResult, bigRemainder;
Tcl_Obj *objResultPtr;
- int invalid, numPos, zero;
+ int invalid, zero;
long shift;
(void) GetNumberFromObj(NULL, valuePtr, &ptr1, &type1);
@@ -8321,7 +8321,7 @@ ExecuteExtendedBinaryMathOp(
w1 = *((const Tcl_WideInt *)ptr1);
if (type2 != TCL_NUMBER_BIG) {
Tcl_WideInt wQuotient, wRemainder;
- Tcl_GetWideIntFromObj(NULL, value2Ptr, &w2);
+ TclGetWideIntFromObj(NULL, value2Ptr, &w2);
wQuotient = w1 / w2;
/*
@@ -8539,138 +8539,22 @@ ExecuteExtendedBinaryMathOp(
case INST_BITXOR:
case INST_BITAND:
if ((type1 == TCL_NUMBER_BIG) || (type2 == TCL_NUMBER_BIG)) {
- mp_int *First, *Second;
-
Tcl_TakeBignumFromObj(NULL, valuePtr, &big1);
Tcl_TakeBignumFromObj(NULL, value2Ptr, &big2);
- /*
- * Count how many positive arguments we have. If only one of the
- * arguments is negative, store it in 'Second'.
- */
-
- if (mp_cmp_d(&big1, 0) != MP_LT) {
- numPos = 1 + (mp_cmp_d(&big2, 0) != MP_LT);
- First = &big1;
- Second = &big2;
- } else {
- First = &big2;
- Second = &big1;
- numPos = (mp_cmp_d(First, 0) != MP_LT);
- }
mp_init(&bigResult);
switch (opcode) {
case INST_BITAND:
- switch (numPos) {
- case 2:
- /*
- * Both arguments positive, base case.
- */
-
- mp_and(First, Second, &bigResult);
- break;
- case 1:
- /*
- * First is positive; second negative:
- * P & N = P & ~~N = P&~(-N-1) = P & (P ^ (-N-1))
- */
-
- mp_neg(Second, Second);
- mp_sub_d(Second, 1, Second);
- mp_xor(First, Second, &bigResult);
- mp_and(First, &bigResult, &bigResult);
- break;
- case 0:
- /*
- * Both arguments negative:
- * a & b = ~ (~a | ~b) = -(-a-1|-b-1)-1
- */
-
- mp_neg(First, First);
- mp_sub_d(First, 1, First);
- mp_neg(Second, Second);
- mp_sub_d(Second, 1, Second);
- mp_or(First, Second, &bigResult);
- mp_neg(&bigResult, &bigResult);
- mp_sub_d(&bigResult, 1, &bigResult);
- break;
- }
+ mp_tc_and(&big1, &big2, &bigResult);
break;
case INST_BITOR:
- switch (numPos) {
- case 2:
- /*
- * Both arguments positive, base case.
- */
-
- mp_or(First, Second, &bigResult);
- break;
- case 1:
- /*
- * First is positive; second negative:
- * N|P = ~(~N&~P) = ~((-N-1)&~P) = -((-N-1)&((-N-1)^P))-1
- */
-
- mp_neg(Second, Second);
- mp_sub_d(Second, 1, Second);
- mp_xor(First, Second, &bigResult);
- mp_and(Second, &bigResult, &bigResult);
- mp_neg(&bigResult, &bigResult);
- mp_sub_d(&bigResult, 1, &bigResult);
- break;
- case 0:
- /*
- * Both arguments negative:
- * a | b = ~ (~a & ~b) = -(-a-1&-b-1)-1
- */
-
- mp_neg(First, First);
- mp_sub_d(First, 1, First);
- mp_neg(Second, Second);
- mp_sub_d(Second, 1, Second);
- mp_and(First, Second, &bigResult);
- mp_neg(&bigResult, &bigResult);
- mp_sub_d(&bigResult, 1, &bigResult);
- break;
- }
+ mp_tc_or(&big1, &big2, &bigResult);
break;
case INST_BITXOR:
- switch (numPos) {
- case 2:
- /*
- * Both arguments positive, base case.
- */
-
- mp_xor(First, Second, &bigResult);
- break;
- case 1:
- /*
- * First is positive; second negative:
- * P^N = ~(P^~N) = -(P^(-N-1))-1
- */
-
- mp_neg(Second, Second);
- mp_sub_d(Second, 1, Second);
- mp_xor(First, Second, &bigResult);
- mp_neg(&bigResult, &bigResult);
- mp_sub_d(&bigResult, 1, &bigResult);
- break;
- case 0:
- /*
- * Both arguments negative:
- * a ^ b = (~a ^ ~b) = (-a-1^-b-1)
- */
-
- mp_neg(First, First);
- mp_sub_d(First, 1, First);
- mp_neg(Second, Second);
- mp_sub_d(Second, 1, Second);
- mp_xor(First, Second, &bigResult);
- break;
- }
+ mp_tc_xor(&big1, &big2, &bigResult);
break;
}
diff --git a/generic/tclStubInit.c b/generic/tclStubInit.c
index 3de8de1..ced89c0 100644
--- a/generic/tclStubInit.c
+++ b/generic/tclStubInit.c
@@ -850,6 +850,9 @@ const TclTomMathStubs tclTomMathStubs = {
TclBNInitBignumFromWideInt, /* 65 */
TclBNInitBignumFromWideUInt, /* 66 */
TclBN_mp_expt_d_ex, /* 67 */
+ TclBN_mp_tc_and, /* 73 */
+ TclBN_mp_tc_or, /* 74 */
+ TclBN_mp_tc_xor, /* 75 */
};
static const TclStubHooks tclStubHooks = {
diff --git a/generic/tclTomMath.decls b/generic/tclTomMath.decls
index 065fe09..6650067 100644
--- a/generic/tclTomMath.decls
+++ b/generic/tclTomMath.decls
@@ -238,6 +238,17 @@ declare 67 {
int TclBN_mp_expt_d_ex(const mp_int *a, mp_digit b, mp_int *c, int fast)
}
+# Added in libtommath 1.1.0
+declare 73 {
+ int TclBN_mp_tc_and(const mp_int *a, const mp_int *b, mp_int *c)
+}
+declare 74 {
+ int TclBN_mp_tc_or(const mp_int *a, const mp_int *b, mp_int *c)
+}
+declare 75 {
+ int TclBN_mp_tc_xor(const mp_int *a, const mp_int *b, mp_int *c)
+}
+
# Local Variables:
# mode: tcl
# End:
diff --git a/generic/tclTomMathDecls.h b/generic/tclTomMathDecls.h
index 81cd7c9..18739cd 100644
--- a/generic/tclTomMathDecls.h
+++ b/generic/tclTomMathDecls.h
@@ -102,6 +102,9 @@
#define mp_sqrt TclBN_mp_sqrt
#define mp_sub TclBN_mp_sub
#define mp_sub_d TclBN_mp_sub_d
+#define mp_tc_and TclBN_mp_tc_and
+#define mp_tc_or TclBN_mp_tc_or
+#define mp_tc_xor TclBN_mp_tc_xor
#define mp_to_unsigned_bin TclBN_mp_to_unsigned_bin
#define mp_to_unsigned_bin_n TclBN_mp_to_unsigned_bin_n
#define mp_toom_mul TclBN_mp_toom_mul
@@ -307,6 +310,15 @@ EXTERN void TclBNInitBignumFromWideUInt(mp_int *bignum,
/* 67 */
EXTERN int TclBN_mp_expt_d_ex(const mp_int *a, mp_digit b,
mp_int *c, int fast);
+/* 73 */
+EXTERN int TclBN_mp_tc_and(const mp_int *a, const mp_int *b,
+ mp_int *c);
+/* 74 */
+EXTERN int TclBN_mp_tc_or(const mp_int *a, const mp_int *b,
+ mp_int *c);
+/* 75 */
+EXTERN int TclBN_mp_tc_xor(const mp_int *a, const mp_int *b,
+ mp_int *c);
typedef struct TclTomMathStubs {
int magic;
@@ -380,6 +392,9 @@ typedef struct TclTomMathStubs {
void (*tclBNInitBignumFromWideInt) (mp_int *bignum, Tcl_WideInt initVal); /* 65 */
void (*tclBNInitBignumFromWideUInt) (mp_int *bignum, Tcl_WideUInt initVal); /* 66 */
int (*tclBN_mp_expt_d_ex) (const mp_int *a, mp_digit b, mp_int *c, int fast); /* 67 */
+ int (*tclBN_mp_tc_and) (const mp_int *a, const mp_int *b, mp_int *c); /* 73 */
+ int (*tclBN_mp_tc_or) (const mp_int *a, const mp_int *b, mp_int *c); /* 74 */
+ int (*tclBN_mp_tc_xor) (const mp_int *a, const mp_int *b, mp_int *c); /* 75 */
} TclTomMathStubs;
extern const TclTomMathStubs *tclTomMathStubsPtr;
@@ -530,6 +545,12 @@ extern const TclTomMathStubs *tclTomMathStubsPtr;
(tclTomMathStubsPtr->tclBNInitBignumFromWideUInt) /* 66 */
#define TclBN_mp_expt_d_ex \
(tclTomMathStubsPtr->tclBN_mp_expt_d_ex) /* 67 */
+#define TclBN_mp_tc_and \
+ (tclTomMathStubsPtr->tclBN_mp_tc_and) /* 73 */
+#define TclBN_mp_tc_or \
+ (tclTomMathStubsPtr->tclBN_mp_tc_or) /* 74 */
+#define TclBN_mp_tc_xor \
+ (tclTomMathStubsPtr->tclBN_mp_tc_xor) /* 75 */
#endif /* defined(USE_TCL_STUBS) */
diff --git a/unix/Makefile.in b/unix/Makefile.in
index d13c490..a5f942c 100644
--- a/unix/Makefile.in
+++ b/unix/Makefile.in
@@ -332,7 +332,8 @@ TOMMATH_OBJS = bncore.o bn_reverse.o bn_fast_s_mp_mul_digs.o \
bn_mp_read_radix.o bn_mp_rshd.o bn_mp_set.o bn_mp_set_int.o \
bn_mp_shrink.o \
bn_mp_sqr.o bn_mp_sqrt.o bn_mp_sub.o bn_mp_sub_d.o \
- bn_mp_to_unsigned_bin.o bn_mp_to_unsigned_bin_n.o \
+ bn_mp_tc_and.o bn_mp_tc_or.o bn_mp_tc_xor.o \
+ bn_mp_to_unsigned_bin.o bn_mp_to_unsigned_bin_n.o \
bn_mp_toom_mul.o bn_mp_toom_sqr.o bn_mp_toradix_n.o \
bn_mp_unsigned_bin_size.o bn_mp_xor.o bn_mp_zero.o bn_s_mp_add.o \
bn_s_mp_mul_digs.o bn_s_mp_sqr.o bn_s_mp_sub.o
@@ -535,6 +536,9 @@ TOMMATH_SRCS = \
$(TOMMATH_DIR)/bn_mp_sqrt.c \
$(TOMMATH_DIR)/bn_mp_sub.c \
$(TOMMATH_DIR)/bn_mp_sub_d.c \
+ $(TOMMATH_DIR)/bn_mp_tc_and.c \
+ $(TOMMATH_DIR)/bn_mp_tc_or.c \
+ $(TOMMATH_DIR)/bn_mp_tc_xor.c \
$(TOMMATH_DIR)/bn_mp_to_unsigned_bin.c \
$(TOMMATH_DIR)/bn_mp_to_unsigned_bin_n.c \
$(TOMMATH_DIR)/bn_mp_toom_mul.c \
@@ -1513,6 +1517,15 @@ bn_mp_sub.o: $(TOMMATH_DIR)/bn_mp_sub.c $(MATHHDRS)
bn_mp_sub_d.o: $(TOMMATH_DIR)/bn_mp_sub_d.c $(MATHHDRS)
$(CC) -c $(CC_SWITCHES) $(TOMMATH_DIR)/bn_mp_sub_d.c
+bn_mp_tc_and.o: $(TOMMATH_DIR)/bn_mp_tc_and.c $(MATHHDRS)
+ $(CC) -c $(CC_SWITCHES) $(TOMMATH_DIR)/bn_mp_tc_and.c
+
+bn_mp_tc_or.o: $(TOMMATH_DIR)/bn_mp_tc_or.c $(MATHHDRS)
+ $(CC) -c $(CC_SWITCHES) $(TOMMATH_DIR)/bn_mp_tc_or.c
+
+bn_mp_tc_xor.o: $(TOMMATH_DIR)/bn_mp_tc_xor.c $(MATHHDRS)
+ $(CC) -c $(CC_SWITCHES) $(TOMMATH_DIR)/bn_mp_tc_xor.c
+
bn_mp_to_unsigned_bin.o: $(TOMMATH_DIR)/bn_mp_to_unsigned_bin.c $(MATHHDRS)
$(CC) -c $(CC_SWITCHES) $(TOMMATH_DIR)/bn_mp_to_unsigned_bin.c
diff --git a/win/Makefile.in b/win/Makefile.in
index e6b9801..4d6011b 100644
--- a/win/Makefile.in
+++ b/win/Makefile.in
@@ -364,6 +364,9 @@ TOMMATH_OBJS = \
bn_mp_sqrt.${OBJEXT} \
bn_mp_sub.${OBJEXT} \
bn_mp_sub_d.${OBJEXT} \
+ bn_mp_tc_and.${OBJEXT} \
+ bn_mp_tc_or.${OBJEXT} \
+ bn_mp_tc_xor.${OBJEXT} \
bn_mp_to_unsigned_bin.${OBJEXT} \
bn_mp_to_unsigned_bin_n.${OBJEXT} \
bn_mp_toom_mul.${OBJEXT} \
diff --git a/win/makefile.vc b/win/makefile.vc
index a6709d1..a607aaf 100644
--- a/win/makefile.vc
+++ b/win/makefile.vc
@@ -304,6 +304,9 @@ TOMMATHOBJS = \
$(TMP_DIR)\bn_mp_sqrt.obj \
$(TMP_DIR)\bn_mp_sub.obj \
$(TMP_DIR)\bn_mp_sub_d.obj \
+ $(TMP_DIR)\bn_mp_tc_and.obj \
+ $(TMP_DIR)\bn_mp_tc_or.obj \
+ $(TMP_DIR)\bn_mp_tc_xor.obj \
$(TMP_DIR)\bn_mp_to_unsigned_bin.obj \
$(TMP_DIR)\bn_mp_to_unsigned_bin_n.obj \
$(TMP_DIR)\bn_mp_toom_mul.obj \