From bcd9ec5103a2be29face2bacfe44187ba8b1bd30 Mon Sep 17 00:00:00 2001 From: sebres Date: Mon, 4 Feb 2019 09:21:25 +0000 Subject: partial cherry pick of [c5c83014d6]: Many simplifications in tclExecute.c, now that libtommath provides new functions mp_tc_and, mp_tc_or and mp_tc_xor --- generic/tclExecute.c | 126 ++-------------------------------------------- generic/tclStubInit.c | 3 ++ generic/tclTomMath.decls | 11 ++++ generic/tclTomMathDecls.h | 21 ++++++++ unix/Makefile.in | 15 +++++- win/Makefile.in | 3 ++ win/makefile.vc | 3 ++ 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 \ -- cgit v0.12