[kaffe] CVS kaffe (robilad): Fixed biginteger gmp (j)long x86-64 bug
Kaffe CVS
cvs-commits at kaffe.org
Thu Dec 15 17:25:16 PST 2005
PatchSet 7004
Date: 2005/12/16 01:16:27
Author: robilad
Branch: HEAD
Tag: (none)
Log:
Fixed biginteger gmp (j)long x86-64 bug
2005-12-16 Dalibor Topic <robilad at kaffe.org>,
Alan Eliasen <eliasen at mindspring.com>
* libraries/clib/native/math/BigInteger.c:
(Java_java_math_BigInteger_assignLong0) Made faster for platforms
where a jlong has the size of a long. If the jlong paramter needs to
be split into two 32 bit values, use a bitmask to sparete the bits
instead of casting down to jint and up again. Added more comments.
Members:
ChangeLog:1.4525->1.4526
libraries/clib/math/BigInteger.c:1.28->1.29
Index: kaffe/ChangeLog
diff -u kaffe/ChangeLog:1.4525 kaffe/ChangeLog:1.4526
--- kaffe/ChangeLog:1.4525 Wed Dec 14 12:31:34 2005
+++ kaffe/ChangeLog Fri Dec 16 01:16:27 2005
@@ -1,3 +1,12 @@
+2005-12-16 Dalibor Topic <robilad at kaffe.org>,
+ Alan Eliasen <eliasen at mindspring.com>
+
+ * libraries/clib/native/math/BigInteger.c:
+ (Java_java_math_BigInteger_assignLong0) Made faster for platforms
+ where a jlong has the size of a long. If the jlong paramter needs to
+ be split into two 32 bit values, use a bitmask to sparete the bits
+ instead of casting down to jint and up again. Added more comments.
+
2005-12-14 Dalibor Topic <robilad at kaffe.org>
* developers/resync-classpath.sh: Make sure that we sync with the
Index: kaffe/libraries/clib/math/BigInteger.c
diff -u kaffe/libraries/clib/math/BigInteger.c:1.28 kaffe/libraries/clib/math/BigInteger.c:1.29
--- kaffe/libraries/clib/math/BigInteger.c:1.28 Wed Oct 19 20:10:39 2005
+++ kaffe/libraries/clib/math/BigInteger.c Fri Dec 16 01:16:32 2005
@@ -8,6 +8,7 @@
* of this file.
*/
+#include <limits.h>
#include <stdio.h>
#include "config.h"
@@ -77,24 +78,42 @@
Java_java_math_BigInteger_assignLong0(JNIEnv* env, jobject r, jlong v)
{
mpz_ptr res;
- int negative = v < 0 ? -1 : 0;
res = (*env)->GetObjectField(env, r, number);
- if (negative)
- v = -v;
- /* Note that v will remain negative if it's LONG_LONG_MIN.
- This is not a problem because any sign copying in the right
- shift will be stripped with the cast to jint, and the
- number will be considered positive. Furthermore, in this
- case, (jint)v will be zero, so the addition will be a
- do-nothing operation. At last, the number will be made
- negative, as appropriate. */
- mpz_set_ui(res, (unsigned long)(jint)(v >> 32));
- mpz_mul_2exp(res, res, 32);
- mpz_add_ui(res, res, (unsigned long)(jint)v);
- if (negative)
- mpz_neg(res, res);
+ /* If a jlong is of the size of a long, we can sinply use the
+ * function provided in gmp.
+ */
+ if (sizeof(v) == sizeof(long)) {
+ mpz_set_si(res, v);
+ }
+ else {
+ /* We need to break down v into long sized pieces. Typically
+ * the case is that a long is 32 bits on a platform, while a jlong
+ * has 64 bits, so we need to set the upper and lower 32 bits
+ * using separate calls to gmp routines.
+ */
+ const int negative = v < 0 ? -1 : 0;
+ const unsigned int shift_distance = sizeof(long) * CHAR_BIT;
+
+ if (negative)
+ v = -v;
+
+ /* Note that v will remain negative if it's LONG_LONG_MIN.
+ This is not a problem because any sign copying in the right
+ shift will be stripped with the cast to jint, and the
+ number will be considered positive. Furthermore, in this
+ case, (jint)v will be zero, so the addition will be a
+ do-nothing operation. At last, the number will be made
+ negative, as appropriate. */
+
+ mpz_set_ui(res, (unsigned long)((v & 0x7FFFFFFF00000000L) >> shift_distance));
+ mpz_mul_2exp(res, res, shift_distance);
+ mpz_add_ui(res, res, (unsigned long)(v & 0x00000000FFFFFFFFL));
+
+ if (negative)
+ mpz_neg(res, res);
+ }
}
void
More information about the kaffe
mailing list