summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authordgp <dgp@users.sourceforge.net>2005-08-16 16:55:17 (GMT)
committerdgp <dgp@users.sourceforge.net>2005-08-16 16:55:17 (GMT)
commit69927787e086c6d240bbf2db1e2f802b21ee9cff (patch)
treebcf07b648c8562f863a68b88fba179eb911187c9
parent042bc0becf8f6be6c639acc043defaeabacfbfa5 (diff)
downloadtcl-69927787e086c6d240bbf2db1e2f802b21ee9cff.zip
tcl-69927787e086c6d240bbf2db1e2f802b21ee9cff.tar.gz
tcl-69927787e086c6d240bbf2db1e2f802b21ee9cff.tar.bz2
[kennykb_numerics_branch]
* generic/tclExecute.c: Made binary bitwise opcodes bignum-aware. * generic/tclTomMath.h: Added mp_or and mp_xor to routines from * unix/Makefile.in: libtommath used by Tcl. * win/Makefile.in: * win/makefile.vc:
-rw-r--r--ChangeLog12
-rw-r--r--generic/tclExecute.c180
-rw-r--r--generic/tclTomMath.h4
-rw-r--r--unix/Makefile.in14
-rw-r--r--win/Makefile.in4
-rw-r--r--win/makefile.vc4
6 files changed, 209 insertions, 9 deletions
diff --git a/ChangeLog b/ChangeLog
index 8f36d40..4c62e7a 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,7 +1,17 @@
+2005-08-16 Don Porter <dgp@users.sourceforge.net>
+
+ [kennykb_numerics_branch]
+
+ * generic/tclExecute.c: Made binary bitwise opcodes bignum-aware.
+
+ * generic/tclTomMath.h: Added mp_or and mp_xor to routines from
+ * unix/Makefile.in: libtommath used by Tcl.
+ * win/Makefile.in:
+ * win/makefile.vc:
+
2005-08-15 Don Porter <dgp@users.sourceforge.net>
[kennykb_numerics_branch] Updates from HEAD.
-
* generic/tclExecute.c: More revisions to IllegalExprOperandType.
Merged INST_BITNOT with INST_UMINUS and make it bignum-aware
according to the rule: ~a = -a - 1. Disabled unused code and
diff --git a/generic/tclExecute.c b/generic/tclExecute.c
index 4e18ba4..ccc6005 100644
--- a/generic/tclExecute.c
+++ b/generic/tclExecute.c
@@ -12,7 +12,7 @@
* See the file "license.terms" for information on usage and redistribution of
* this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
- * RCS: @(#) $Id: tclExecute.c,v 1.167.2.22 2005/08/16 04:26:40 dgp Exp $
+ * RCS: @(#) $Id: tclExecute.c,v 1.167.2.23 2005/08/16 16:55:18 dgp Exp $
*/
#include "tclInt.h"
@@ -3686,12 +3686,183 @@ TclExecuteByteCode(interp, codePtr)
NEXT_INST_F(0, 2, 1);
}
+ case INST_BITOR:
+ case INST_BITXOR:
+ case INST_BITAND: {
+ Tcl_Obj *valuePtr, *value2Ptr;
+ mp_int big1, big2, bigResult;
+ mp_int *Pos, *Neg, *Other;
+ int numPos = 0;
+
+ value2Ptr = *tosPtr;
+ valuePtr = *(tosPtr - 1);
+ result = Tcl_GetBignumFromObj(NULL, valuePtr, &big1);
+ if (result != TCL_OK) {
+ TRACE(("%.20s %.20s => ILLEGAL 1st TYPE %s\n", O2S(valuePtr),
+ O2S(value2Ptr), (valuePtr->typePtr?
+ valuePtr->typePtr->name : "null")));
+ IllegalExprOperandType(interp, pc, valuePtr);
+ goto checkForCatch;
+ }
+ result = Tcl_GetBignumFromObj(NULL, value2Ptr, &big2);
+ if (result != TCL_OK) {
+ mp_clear(&big1);
+ TRACE(("%.20s %.20s => ILLEGAL 2nd TYPE %s\n", O2S(valuePtr),
+ O2S(value2Ptr), (value2Ptr->typePtr?
+ value2Ptr->typePtr->name : "null")));
+ IllegalExprOperandType(interp, pc, value2Ptr);
+ goto checkForCatch;
+ }
+ if (big1.sign == MP_ZPOS) {
+ numPos++;
+ Pos = &big1;
+ if (big2.sign == MP_ZPOS) {
+ numPos++;
+ Other = &big2;
+ } else {
+ Neg = &big2;
+ }
+ } else {
+ Neg = &big1;
+ if (big2.sign == MP_ZPOS) {
+ numPos++;
+ Pos = &big2;
+ } else {
+ Other = &big2;
+ }
+ }
+ mp_init(&bigResult);
+ switch (*pc) {
+ case INST_BITAND:
+ switch (numPos) {
+ case 2:
+ /* Both arguments positive, base case */
+ mp_and(Pos, Other, &bigResult);
+ break;
+ case 1: {
+ /* One arg positive; one negative
+ * P & N = P & ~~N = P&~(-N-1) = P & (P ^ (-N-1)) */
+ mp_int bigOne;
+ Tcl_GetBignumFromObj(NULL, eePtr->constants[1], &bigOne);
+ mp_neg(Neg, Neg);
+ mp_sub(Neg, &bigOne, Neg);
+ mp_clear(&bigOne);
+ mp_xor(Pos, Neg, &bigResult);
+ mp_and(Pos, &bigResult, &bigResult);
+ break;
+ }
+ case 0: {
+ /* Both arguments negative
+ * a & b = ~ (~a | ~b) = -(-a-1|-b-1)-1 */
+ mp_int bigOne;
+ Tcl_GetBignumFromObj(NULL, eePtr->constants[1], &bigOne);
+ mp_neg(Neg, Neg);
+ mp_sub(Neg, &bigOne, Neg);
+ mp_neg(Other, Other);
+ mp_sub(Other, &bigOne, Other);
+ mp_or(Neg, Other, &bigResult);
+ mp_neg(&bigResult, &bigResult);
+ mp_sub(&bigResult, &bigOne, &bigResult);
+ mp_clear(&bigOne);
+ break;
+ }
+ }
+ break;
+ case INST_BITOR:
+ switch (numPos) {
+ case 2:
+ /* Both arguments positive, base case */
+ mp_or(Pos, Other, &bigResult);
+ break;
+ case 1: {
+ /* One arg positive; one negative
+ * N|P = ~(~N&~P) = ~((-N-1)&~P) = -((-N-1)&((-N-1)^P))-1 */
+ mp_int bigOne;
+ Tcl_GetBignumFromObj(NULL, eePtr->constants[1], &bigOne);
+ mp_neg(Neg, Neg);
+ mp_sub(Neg, &bigOne, Neg);
+ mp_xor(Pos, Neg, &bigResult);
+ mp_and(Neg, &bigResult, &bigResult);
+ mp_neg(&bigResult, &bigResult);
+ mp_sub(&bigResult, &bigOne, &bigResult);
+ mp_clear(&bigOne);
+ break;
+ }
+ case 0: {
+ /* Both arguments negative
+ * a | b = ~ (~a & ~b) = -(-a-1&-b-1)-1 */
+ mp_int bigOne;
+ Tcl_GetBignumFromObj(NULL, eePtr->constants[1], &bigOne);
+ mp_neg(Neg, Neg);
+ mp_sub(Neg, &bigOne, Neg);
+ mp_neg(Other, Other);
+ mp_sub(Other, &bigOne, Other);
+ mp_and(Neg, Other, &bigResult);
+ mp_neg(&bigResult, &bigResult);
+ mp_sub(&bigResult, &bigOne, &bigResult);
+ mp_clear(&bigOne);
+ break;
+ }
+ }
+ break;
+ case INST_BITXOR:
+ switch (numPos) {
+ case 2:
+ /* Both arguments positive, base case */
+ mp_xor(Pos, Other, &bigResult);
+ break;
+ case 1: {
+ /* One arg positive; one negative
+ * P^N = ~(P^~N) = -(P^(-N-1))-1
+ */
+ mp_int bigOne;
+ Tcl_GetBignumFromObj(NULL, eePtr->constants[1], &bigOne);
+ mp_neg(Neg, Neg);
+ mp_sub(Neg, &bigOne, Neg);
+ mp_xor(Pos, Neg, &bigResult);
+ mp_neg(&bigResult, &bigResult);
+ mp_sub(&bigResult, &bigOne, &bigResult);
+ mp_clear(&bigOne);
+ break;
+ }
+ case 0: {
+ /* Both arguments negative
+ * a ^ b = (~a ^ ~b) = (-a-1^-b-1) */
+ mp_int bigOne;
+ Tcl_GetBignumFromObj(NULL, eePtr->constants[1], &bigOne);
+ mp_neg(Neg, Neg);
+ mp_sub(Neg, &bigOne, Neg);
+ mp_neg(Other, Other);
+ mp_sub(Other, &bigOne, Other);
+ mp_xor(Neg, Other, &bigResult);
+ mp_clear(&bigOne);
+ break;
+ }
+ }
+ break;
+ }
+ mp_clear(&big1);
+ mp_clear(&big2);
+ TRACE(("%s %s => ", O2S(valuePtr), O2S(value2Ptr)));
+ if (Tcl_IsShared(valuePtr)) {
+ objResultPtr = Tcl_NewBignumObj(&bigResult);
+ TRACE(("%s\n", O2S(objResultPtr)));
+ NEXT_INST_F(1, 2, 1);
+ }
+ Tcl_SetBignumObj(valuePtr, &bigResult);
+ TRACE(("%s\n", O2S(valuePtr)));
+ NEXT_INST_F(1, 1, 0);
+ }
+
case INST_MOD:
case INST_LSHIFT:
case INST_RSHIFT:
+#if 0
case INST_BITOR:
case INST_BITXOR:
- case INST_BITAND: {
+ case INST_BITAND:
+#endif
+ {
/*
* Only integers are allowed. We compute value op value2.
*/
@@ -3979,6 +4150,7 @@ TclExecuteByteCode(interp, codePtr)
iResult = ~iResult;
}
break;
+#if 0
case INST_BITOR:
if (valuePtr->typePtr == &tclWideIntType
|| value2Ptr->typePtr == &tclWideIntType) {
@@ -4030,6 +4202,7 @@ TclExecuteByteCode(interp, codePtr)
}
iResult = i & i2;
break;
+#endif
}
/*
@@ -4530,11 +4703,14 @@ TclExecuteByteCode(interp, codePtr)
}
mp_clear(&big1);
mp_clear(&big2);
+ TRACE(("%s %s => ", O2S(valuePtr), O2S(value2Ptr)));
if (Tcl_IsShared(valuePtr)) {
objResultPtr = Tcl_NewBignumObj(&bigResult);
+ TRACE(("%s\n", O2S(objResultPtr)));
NEXT_INST_F(1, 2, 1);
}
Tcl_SetBignumObj(valuePtr, &bigResult);
+ TRACE(("%s\n", O2S(valuePtr)));
NEXT_INST_F(1, 1, 0);
}
#endif
diff --git a/generic/tclTomMath.h b/generic/tclTomMath.h
index 4f2bffa..3d3bebb 100644
--- a/generic/tclTomMath.h
+++ b/generic/tclTomMath.h
@@ -9,7 +9,7 @@
* See the file "license.terms" for information on usage and redistribution
* of this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
- * RCS: @(#) $Id: tclTomMath.h,v 1.1.2.3 2005/08/15 03:16:48 dgp Exp $
+ * RCS: @(#) $Id: tclTomMath.h,v 1.1.2.4 2005/08/16 16:55:18 dgp Exp $
*/
#ifndef TCLTOMMATH_H
@@ -98,6 +98,7 @@ void* TclBNCalloc( size_t, size_t );
#define mp_mul_2d TclBN_mp_mul_2d
#define mp_mul_d TclBN_mp_mul_d
#define mp_neg TclBN_mp_neg
+#define mp_or TclBN_mp_or
#define mp_radix_size TclBN_mp_radix_size
#define mp_read_radix TclBN_mp_read_radix
#define mp_rshd TclBN_mp_rshd
@@ -108,6 +109,7 @@ void* TclBNCalloc( size_t, size_t );
#define mp_toom_mul TclBN_mp_toom_mul
#define mp_toradix_n TclBN_mp_toradix_n
#define mp_unsigned_bin_size TclBN_mp_unsigned_bin_size
+#define mp_xor TclBN_mp_xor
#define mp_zero TclBN_mp_zero
#define s_mp_add TclBN_s_mp_add
#define s_mp_mul_digs TclBN_s_mp_mul_digs
diff --git a/unix/Makefile.in b/unix/Makefile.in
index 535610b..a1e18ad 100644
--- a/unix/Makefile.in
+++ b/unix/Makefile.in
@@ -5,7 +5,7 @@
# "autoconf" program (constructs like "@foo@" will get replaced in the
# actual Makefile.
#
-# RCS: @(#) $Id: Makefile.in,v 1.157.2.14 2005/08/15 03:16:48 dgp Exp $
+# RCS: @(#) $Id: Makefile.in,v 1.157.2.15 2005/08/16 16:55:18 dgp Exp $
VERSION = @TCL_VERSION@
MAJOR_VERSION = @TCL_MAJOR_VERSION@
@@ -323,13 +323,13 @@ TOMMATH_OBJS = bncore.o bn_reverse.o bn_fast_s_mp_mul_digs.o \
bn_mp_init_size.o bn_mp_karatsuba_mul.o \
bn_mp_karatsuba_sqr.o \
bn_mp_lshd.o bn_mp_mod.o bn_mp_mod_2d.o bn_mp_mul.o bn_mp_mul_2.o \
- bn_mp_mul_2d.o bn_mp_mul_d.o bn_mp_neg.o \
+ bn_mp_mul_2d.o bn_mp_mul_d.o bn_mp_neg.o bn_mp_or.o \
bn_mp_radix_size.o bn_mp_radix_smap.o \
bn_mp_read_radix.o bn_mp_rshd.o bn_mp_set.o bn_mp_shrink.o \
bn_mp_sqr.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_toom_mul.o bn_mp_toom_sqr.o bn_mp_toradix_n.o \
- bn_mp_unsigned_bin_size.o bn_mp_zero.o bn_s_mp_add.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
STUB_LIB_OBJS = tclStubLib.o ${COMPAT_OBJS}
@@ -468,6 +468,7 @@ TOMMATH_SRCS = \
$(TOMMATH_DIR)/bn_mp_mul_2d.c \
$(TOMMATH_DIR)/bn_mp_mul_d.c \
$(TOMMATH_DIR)/bn_mp_neg.c \
+ $(TOMMATH_DIR)/bn_mp_or.c \
$(TOMMATH_DIR)/bn_mp_radix_size.c \
$(TOMMATH_DIR)/bn_mp_radix_smap.c \
$(TOMMATH_DIR)/bn_mp_read_radix.c \
@@ -483,6 +484,7 @@ TOMMATH_SRCS = \
$(TOMMATH_DIR)/bn_mp_toom_sqr.c \
$(TOMMATH_DIR)/bn_mp_toradix_n.c \
$(TOMMATH_DIR)/bn_mp_unsigned_bin_size.c \
+ $(TOMMATH_DIR)/bn_mp_xor.c \
$(TOMMATH_DIR)/bn_mp_zero.c \
$(TOMMATH_DIR)/bn_s_mp_add.c \
$(TOMMATH_DIR)/bn_s_mp_mul_digs.c \
@@ -1292,6 +1294,9 @@ bn_mp_mul_d.o: $(TOMMATH_DIR)/bn_mp_mul_d.c
bn_mp_neg.o: $(TOMMATH_DIR)/bn_mp_neg.c
$(CC) -c $(CC_SWITCHES) $(TOMMATH_DIR)/bn_mp_neg.c
+bn_mp_or.o: $(TOMMATH_DIR)/bn_mp_or.c
+ $(CC) -c $(CC_SWITCHES) $(TOMMATH_DIR)/bn_mp_or.c
+
bn_mp_radix_size.o: $(TOMMATH_DIR)/bn_mp_radix_size.c
$(CC) -c $(CC_SWITCHES) $(TOMMATH_DIR)/bn_mp_radix_size.c
@@ -1337,6 +1342,9 @@ bn_mp_toradix_n.o: $(TOMMATH_DIR)/bn_mp_toradix_n.c
bn_mp_unsigned_bin_size.o: $(TOMMATH_DIR)/bn_mp_unsigned_bin_size.c
$(CC) -c $(CC_SWITCHES) $(TOMMATH_DIR)/bn_mp_unsigned_bin_size.c
+bn_mp_xor.o: $(TOMMATH_DIR)/bn_mp_xor.c
+ $(CC) -c $(CC_SWITCHES) $(TOMMATH_DIR)/bn_mp_xor.c
+
bn_mp_zero.o: $(TOMMATH_DIR)/bn_mp_zero.c
$(CC) -c $(CC_SWITCHES) $(TOMMATH_DIR)/bn_mp_zero.c
diff --git a/win/Makefile.in b/win/Makefile.in
index 44160ed..399af6a 100644
--- a/win/Makefile.in
+++ b/win/Makefile.in
@@ -5,7 +5,7 @@
# "autoconf" program (constructs like "@foo@" will get replaced in the
# actual Makefile.
#
-# RCS: @(#) $Id: Makefile.in,v 1.84.2.10 2005/08/15 18:14:15 dgp Exp $
+# RCS: @(#) $Id: Makefile.in,v 1.84.2.11 2005/08/16 16:55:18 dgp Exp $
VERSION = @TCL_VERSION@
@@ -319,6 +319,7 @@ TOMMATH_OBJS = \
bn_mp_mul_2d.${OBJEXT} \
bn_mp_mul_d.${OBJEXT} \
bn_mp_neg.${OBJEXT} \
+ bn_mp_or.${OBJEXT} \
bn_mp_radix_size.${OBJEXT} \
bn_mp_radix_smap.${OBJEXT} \
bn_mp_read_radix.${OBJEXT} \
@@ -334,6 +335,7 @@ TOMMATH_OBJS = \
bn_mp_toom_sqr.${OBJEXT} \
bn_mp_toradix_n.${OBJEXT} \
bn_mp_unsigned_bin_size.${OBJEXT} \
+ bn_mp_xor.${OBJEXT} \
bn_mp_zero.${OBJEXT} \
bn_s_mp_add.${OBJEXT} \
bn_s_mp_mul_digs.${OBJEXT} \
diff --git a/win/makefile.vc b/win/makefile.vc
index 317a628..d09bf42 100644
--- a/win/makefile.vc
+++ b/win/makefile.vc
@@ -12,7 +12,7 @@
# Copyright (c) 2001-2004 David Gravereaux.
#
#------------------------------------------------------------------------------
-# RCS: @(#) $Id: makefile.vc,v 1.135.2.6 2005/08/15 18:14:15 dgp Exp $
+# RCS: @(#) $Id: makefile.vc,v 1.135.2.7 2005/08/16 16:55:18 dgp Exp $
#------------------------------------------------------------------------------
# Check to see we are configured to build with MSVC (MSDEVDIR or MSVCDIR)
@@ -371,6 +371,7 @@ TCLOBJS = \
$(TMP_DIR)\bn_mp_mul_2d.obj \
$(TMP_DIR)\bn_mp_mul_d.obj \
$(TMP_DIR)\bn_mp_neg.obj \
+ $(TMP_DIR)\bn_mp_or.obj \
$(TMP_DIR)\bn_mp_radix_size.obj \
$(TMP_DIR)\bn_mp_radix_smap.obj \
$(TMP_DIR)\bn_mp_read_radix.obj \
@@ -386,6 +387,7 @@ TCLOBJS = \
$(TMP_DIR)\bn_mp_toom_sqr.obj \
$(TMP_DIR)\bn_mp_toradix_n.obj \
$(TMP_DIR)\bn_mp_unsigned_bin_size.obj \
+ $(TMP_DIR)\bn_mp_xor.obj \
$(TMP_DIR)\bn_mp_zero.obj \
$(TMP_DIR)\bn_s_mp_add.obj \
$(TMP_DIR)\bn_s_mp_mul_digs.obj \