summaryrefslogtreecommitdiffstats
path: root/generic/tclExecute.c
diff options
context:
space:
mode:
authorsebres <sebres@users.sourceforge.net>2019-02-04 09:21:25 (GMT)
committersebres <sebres@users.sourceforge.net>2019-02-04 09:21:25 (GMT)
commitbcd9ec5103a2be29face2bacfe44187ba8b1bd30 (patch)
treee94f6fb7df77eae6891d138eeec8d37d84c2e83c /generic/tclExecute.c
parent04ed7f99daa6ac1ca3e5a2903fc7c9325cd4d581 (diff)
downloadtcl-bcd9ec5103a2be29face2bacfe44187ba8b1bd30.zip
tcl-bcd9ec5103a2be29face2bacfe44187ba8b1bd30.tar.gz
tcl-bcd9ec5103a2be29face2bacfe44187ba8b1bd30.tar.bz2
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
Diffstat (limited to 'generic/tclExecute.c')
-rw-r--r--generic/tclExecute.c126
1 files changed, 5 insertions, 121 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;
}