diff options
author | dgp <dgp@users.sourceforge.net> | 2005-08-16 16:55:17 (GMT) |
---|---|---|
committer | dgp <dgp@users.sourceforge.net> | 2005-08-16 16:55:17 (GMT) |
commit | 69927787e086c6d240bbf2db1e2f802b21ee9cff (patch) | |
tree | bcf07b648c8562f863a68b88fba179eb911187c9 | |
parent | 042bc0becf8f6be6c639acc043defaeabacfbfa5 (diff) | |
download | tcl-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-- | ChangeLog | 12 | ||||
-rw-r--r-- | generic/tclExecute.c | 180 | ||||
-rw-r--r-- | generic/tclTomMath.h | 4 | ||||
-rw-r--r-- | unix/Makefile.in | 14 | ||||
-rw-r--r-- | win/Makefile.in | 4 | ||||
-rw-r--r-- | win/makefile.vc | 4 |
6 files changed, 209 insertions, 9 deletions
@@ -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 \ |