From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!.POSTED!not-for-mail From: Tom Tromey Newsgroups: gmane.emacs.devel Subject: Re: bignum branch Date: Mon, 16 Jul 2018 08:35:56 -0600 Message-ID: <87a7qr8cz7.fsf@tromey.com> References: <87o9fbbw1t.fsf@tromey.com> <86in5jdj49.fsf@gmail.com> <83wotxaiwi.fsf@gnu.org> <86k1pxmvmx.fsf@gmail.com> <87efg4a9xc.fsf@tromey.com> NNTP-Posting-Host: blaine.gmane.org Mime-Version: 1.0 Content-Type: text/plain X-Trace: blaine.gmane.org 1531751718 30698 195.159.176.226 (16 Jul 2018 14:35:18 GMT) X-Complaints-To: usenet@blaine.gmane.org NNTP-Posting-Date: Mon, 16 Jul 2018 14:35:18 +0000 (UTC) User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/26.1.50 (gnu/linux) Cc: Andy Moreton , emacs-devel@gnu.org To: Tom Tromey Original-X-From: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Mon Jul 16 16:35:14 2018 Return-path: Envelope-to: ged-emacs-devel@m.gmane.org Original-Received: from lists.gnu.org ([208.118.235.17]) by blaine.gmane.org with esmtp (Exim 4.84_2) (envelope-from ) id 1ff4am-0007qN-UP for ged-emacs-devel@m.gmane.org; Mon, 16 Jul 2018 16:35:13 +0200 Original-Received: from localhost ([::1]:52183 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ff4cs-0000MV-8J for ged-emacs-devel@m.gmane.org; Mon, 16 Jul 2018 10:37:22 -0400 Original-Received: from eggs.gnu.org ([2001:4830:134:3::10]:45519) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ff4cf-0000MK-2k for emacs-devel@gnu.org; Mon, 16 Jul 2018 10:37:10 -0400 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1ff4cb-0005sH-4A for emacs-devel@gnu.org; Mon, 16 Jul 2018 10:37:09 -0400 Original-Received: from gateway30.websitewelcome.com ([192.185.152.11]:13453) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1ff4ca-0005pH-OP for emacs-devel@gnu.org; Mon, 16 Jul 2018 10:37:05 -0400 Original-Received: from cm15.websitewelcome.com (cm15.websitewelcome.com [100.42.49.9]) by gateway30.websitewelcome.com (Postfix) with ESMTP id F4096B23D for ; Mon, 16 Jul 2018 09:36:52 -0500 (CDT) Original-Received: from box5379.bluehost.com ([162.241.216.53]) by cmsmtp with SMTP id f4bVfdv0IbXuJf4c0flyRg; Mon, 16 Jul 2018 09:36:52 -0500 X-Authority-Reason: nr=8 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=tromey.com; s=default; h=Content-Type:MIME-Version:Message-ID:In-Reply-To:Date: References:Subject:Cc:To:From:Sender:Reply-To:Content-Transfer-Encoding: Content-ID:Content-Description:Resent-Date:Resent-From:Resent-Sender: Resent-To:Resent-Cc:Resent-Message-ID:List-Id:List-Help:List-Unsubscribe: List-Subscribe:List-Post:List-Owner:List-Archive; bh=lgqKoCenBYYawJgRdK3RQTYiKeQ28MHHfF9j3shw3Ss=; b=ur4mEYprHxQJKFmEXsRsCOvNZZ h2vmgeERh/dtsQrfvqY8pJiPW7n6WzB2nn4MCDZ6+IwipJCYu1equqCoT1xXzAALdXYxe/yyy9sGE p4/dO0sjEQjAY027Gx8juUMxN; Original-Received: from 75-166-85-72.hlrn.qwest.net ([75.166.85.72]:37908 helo=bapiya) by box5379.bluehost.com with esmtpsa (TLSv1.2:ECDHE-RSA-AES256-GCM-SHA384:256) (Exim 4.91) (envelope-from ) id 1ff4bV-0001du-6c; Mon, 16 Jul 2018 09:35:57 -0500 X-Attribution: Tom In-Reply-To: <87efg4a9xc.fsf@tromey.com> (Tom Tromey's message of "Sun, 15 Jul 2018 07:46:39 -0600") X-AntiAbuse: This header was added to track abuse, please include it with any abuse report X-AntiAbuse: Primary Hostname - box5379.bluehost.com X-AntiAbuse: Original Domain - gnu.org X-AntiAbuse: Originator/Caller UID/GID - [47 12] / [47 12] X-AntiAbuse: Sender Address Domain - tromey.com X-BWhitelist: no X-Source-IP: 75.166.85.72 X-Source-L: No X-Exim-ID: 1ff4bV-0001du-6c X-Source: X-Source-Args: X-Source-Dir: X-Source-Sender: 75-166-85-72.hlrn.qwest.net (bapiya) [75.166.85.72]:37908 X-Source-Auth: tom+tromey.com X-Email-Count: 2 X-Source-Cap: ZWx5bnJvYmk7ZWx5bnJvYmk7Ym94NTM3OS5ibHVlaG9zdC5jb20= X-Local-Domain: yes X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 192.185.152.11 X-BeenThere: emacs-devel@gnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: "Emacs development discussions." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Original-Sender: "Emacs-devel" Xref: news.gmane.org gmane.emacs.devel:227453 Archived-At: >>>>> "Tom" == Tom Tromey writes: Tom> I was thinking this is what I' have emacs do when Tom> sizeof(EMACS_INT) > sizeof(long). Please try this patch. Unfortunately I don't know how I can test it locally Tom diff --git a/src/alloc.c b/src/alloc.c index b775948fd9..1dc1bbb031 100644 --- a/src/alloc.c +++ b/src/alloc.c @@ -3824,6 +3824,36 @@ make_number (mpz_t value) return obj; } +void +mpz_set_intmax_slow (mpz_t result, intmax_t v) +{ + /* If long is larger then a faster path is taken. */ + eassert (sizeof (intmax_t) > sizeof (long)); + + bool negate = false; + if (v < 0) + { + v = -v; + negate = true; + } + mpz_set_uintmax_slow (result, (uintmax_t) v); + if (negate) + mpz_neg (result, result); +} + +void +mpz_set_uintmax_slow (mpz_t result, uintmax_t v) +{ + /* If long is larger then a faster path is taken. */ + eassert (sizeof (uintmax_t) > sizeof (unsigned long)); + /* This restriction could be lifted if needed. */ + eassert (sizeof (uintmax_t) <= 2 * sizeof (unsigned long)); + + mpz_set_ui (result, v >> (CHAR_BIT * sizeof (unsigned long))); + mpz_mul_2exp (result, result, CHAR_BIT * sizeof (unsigned long)); + mpz_add_ui (result, result, v & -1ul); +} + /* Return a newly created vector or string with specified arguments as elements. If all the arguments are characters that can fit diff --git a/src/data.c b/src/data.c index 862381229d..0deebdca1a 100644 --- a/src/data.c +++ b/src/data.c @@ -2882,7 +2882,7 @@ arith_driver (enum arithop code, ptrdiff_t nargs, Lisp_Object *args) if (BIGNUMP (val)) mpz_set (accum, XBIGNUM (val)->value); else - mpz_set_si (accum, XINT (val)); + mpz_set_intmax (accum, XINT (val)); if (nargs == 1) mpz_neg (accum, accum); } @@ -2905,7 +2905,7 @@ arith_driver (enum arithop code, ptrdiff_t nargs, Lisp_Object *args) if (BIGNUMP (val)) mpz_set (accum, XBIGNUM (val)->value); else - mpz_set_si (accum, XINT (val)); + mpz_set_intmax (accum, XINT (val)); } else { @@ -2933,7 +2933,8 @@ arith_driver (enum arithop code, ptrdiff_t nargs, Lisp_Object *args) else { mpz_t tem; - mpz_init_set_ui (tem, XUINT (val)); + mpz_init (tem); + mpz_set_uintmax (tem, XUINT (val)); mpz_and (accum, accum, tem); mpz_clear (tem); } @@ -2944,7 +2945,8 @@ arith_driver (enum arithop code, ptrdiff_t nargs, Lisp_Object *args) else { mpz_t tem; - mpz_init_set_ui (tem, XUINT (val)); + mpz_init (tem); + mpz_set_uintmax (tem, XUINT (val)); mpz_ior (accum, accum, tem); mpz_clear (tem); } @@ -2955,7 +2957,8 @@ arith_driver (enum arithop code, ptrdiff_t nargs, Lisp_Object *args) else { mpz_t tem; - mpz_init_set_ui (tem, XUINT (val)); + mpz_init (tem); + mpz_set_uintmax (tem, XUINT (val)); mpz_xor (accum, accum, tem); mpz_clear (tem); } @@ -3092,7 +3095,8 @@ Both must be integers or markers. */) xmp = &XBIGNUM (x)->value; else { - mpz_init_set_si (xm, XINT (x)); + mpz_init (xm); + mpz_set_intmax (xm, XINT (x)); xmp = &xm; } @@ -3100,7 +3104,8 @@ Both must be integers or markers. */) ymp = &XBIGNUM (y)->value; else { - mpz_init_set_si (ym, XINT (y)); + mpz_init (ym); + mpz_set_intmax (ym, XINT (y)); ymp = &ym; } @@ -3163,7 +3168,8 @@ Both X and Y must be numbers or markers. */) xmp = &XBIGNUM (x)->value; else { - mpz_init_set_si (xm, XINT (x)); + mpz_init (xm); + mpz_set_intmax (xm, XINT (x)); xmp = &xm; } @@ -3171,7 +3177,8 @@ Both X and Y must be numbers or markers. */) ymp = &XBIGNUM (y)->value; else { - mpz_init_set_si (ym, XINT (y)); + mpz_init (ym); + mpz_set_intmax (ym, XINT (y)); ymp = &ym; } @@ -3317,10 +3324,11 @@ ash_lsh_impl (Lisp_Object value, Lisp_Object count, bool lsh) /* Just do the work as bignums to make the code simpler. */ mpz_t result; eassume (FIXNUMP (value)); + mpz_init (result); if (lsh) - mpz_init_set_ui (result, XUINT (value)); + mpz_set_uintmax (result, XUINT (value)); else - mpz_init_set_si (result, XINT (value)); + mpz_set_intmax (result, XINT (value)); if (XINT (count) >= 0) mpz_mul_2exp (result, result, XINT (count)); else @@ -3376,7 +3384,8 @@ Markers are converted to integers. */) else { mpz_t num; - mpz_init_set_si (num, XINT (number) + 1); + mpz_init (num); + mpz_set_intmax (num, XINT (number) + 1); number = make_number (num); mpz_clear (num); } @@ -3410,7 +3419,8 @@ Markers are converted to integers. */) else { mpz_t num; - mpz_init_set_si (num, XINT (number) - 1); + mpz_init (num); + mpz_set_intmax (num, XINT (number) - 1); number = make_number (num); mpz_clear (num); } diff --git a/src/emacs-module.c b/src/emacs-module.c index 7709eeca94..83eccae1f7 100644 --- a/src/emacs-module.c +++ b/src/emacs-module.c @@ -536,7 +536,8 @@ module_make_integer (emacs_env *env, intmax_t n) if (FIXNUM_OVERFLOW_P (n)) { mpz_t val; - mpz_init_set_si (val, n); + mpz_init (val); + mpz_set_uintmax (val, n); obj = make_number (val); mpz_clear (val); } diff --git a/src/floatfns.c b/src/floatfns.c index 9a5f0a3ad2..563c65f827 100644 --- a/src/floatfns.c +++ b/src/floatfns.c @@ -288,7 +288,8 @@ DEFUN ("abs", Fabs, Sabs, 1, 1, 0, else if (FIXNUMP (arg) && XINT (arg) == MOST_NEGATIVE_FIXNUM) { mpz_t val; - mpz_init_set_si (val, - MOST_NEGATIVE_FIXNUM); + mpz_init (val); + mpz_set_intmax (val, - MOST_NEGATIVE_FIXNUM); arg = make_number (val); mpz_clear (val); } diff --git a/src/lisp.h b/src/lisp.h index e046429c1b..4208634fa9 100644 --- a/src/lisp.h +++ b/src/lisp.h @@ -3655,6 +3655,32 @@ extern Lisp_Object listn (enum constype, ptrdiff_t, Lisp_Object, ...); extern Lisp_Object make_bignum_str (const char *num, int base); extern Lisp_Object make_number (mpz_t value); +extern void mpz_set_intmax_slow (mpz_t result, intmax_t v); +extern void mpz_set_uintmax_slow (mpz_t result, uintmax_t v); + +INLINE void +mpz_set_intmax (mpz_t result, intmax_t v) +{ + /* mpz_set_si works in terms of long, but Emacs may use a wider + integer type, and so sometimes will have to construct the mpz_t + by hand. */ + if (sizeof (intmax_t) > sizeof (long) && (long) v != v) + mpz_set_intmax_slow (result, v); + else + mpz_set_si (result, v); +} + +INLINE void +mpz_set_uintmax (mpz_t result, uintmax_t v) +{ + /* mpz_set_ui works in terms of unsigned long, but Emacs may use a + wider integer type, and so sometimes will have to construct the + mpz_t by hand. */ + if (sizeof (uintmax_t) > sizeof (unsigned long) && (unsigned long) v != v) + mpz_set_uintmax_slow (result, v); + else + mpz_set_ui (result, v); +} /* Build a frequently used 2/3/4-integer lists. */