[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