mirror of
https://git.savannah.gnu.org/git/guile.git
synced 2025-05-20 19:50:24 +02:00
Do not assume that sizeof (long) == sizeof (void *) == sizeof (SCM).
This assumption does not hold on systems that use the LLP64 data model. Partially fixes <https://debbugs.gnu.org/22406>. Reported by Peter TB Brett <peter@peter-b.co.uk>. * libguile/numbers.h (scm_t_inum): Move here from numbers.c, and change to be equivalent to 'long' (formerly 'scm_t_signed_bits'). (SCM_MOST_POSITIVE_FIXNUM, SCM_MOST_NEGATIVE_FIXNUM): Define based on SCM_I_FIXNUM_BIT instead of SCM_T_SIGNED_BITS_MAX. (SCM_I_INUM): Adjust definitions to return a 'scm_t_inum', and avoiding the assumption that SCM_UNPACK returns a 'long'. * libguile/numbers.c (scm_t_inum): Move definition to numbers.h. Verify that 'scm_t_inum' fits within a SCM value. (scm_i_inum2big): Remove preprocessor code that forced a compile error unless sizeof (long) == sizeof (void *). * libguile/vm-i-scheme.c (_CX): For fixnum assembly functions, choose the register size based on SCM_I_FIXNUM_BIT instead of SIZEOF_VOID_P. (ASM_MUL, "ash", "vector-ref", "vector-set", BV_FIXABLE_INT_REF) (BV_INT_REF, BV_FLOAT_REF, BV_FIXABLE_INT_SET, BV_INT_SET) (BV_FLOAT_SET): Use 'scm_t_inum' for fixnums instead of 'scm_t_signed_bits'.
This commit is contained in:
parent
1e86dc32a4
commit
b0a702d773
3 changed files with 32 additions and 37 deletions
|
@ -87,7 +87,9 @@
|
||||||
/* FIXME: We assume that FLT_RADIX is 2 */
|
/* FIXME: We assume that FLT_RADIX is 2 */
|
||||||
verify (FLT_RADIX == 2);
|
verify (FLT_RADIX == 2);
|
||||||
|
|
||||||
typedef scm_t_signed_bits scm_t_inum;
|
/* Make sure that scm_t_inum fits within a SCM value. */
|
||||||
|
verify (sizeof (scm_t_inum) <= sizeof (scm_t_bits));
|
||||||
|
|
||||||
#define scm_from_inum(x) (scm_from_signed_integer (x))
|
#define scm_from_inum(x) (scm_from_signed_integer (x))
|
||||||
|
|
||||||
/* Test an inum to see if it can be converted to a double without loss
|
/* Test an inum to see if it can be converted to a double without loss
|
||||||
|
@ -272,13 +274,7 @@ scm_i_inum2big (scm_t_inum x)
|
||||||
{
|
{
|
||||||
/* Return a newly created bignum initialized to X. */
|
/* Return a newly created bignum initialized to X. */
|
||||||
SCM z = make_bignum ();
|
SCM z = make_bignum ();
|
||||||
#if SIZEOF_VOID_P == SIZEOF_LONG
|
|
||||||
mpz_init_set_si (SCM_I_BIG_MPZ (z), x);
|
mpz_init_set_si (SCM_I_BIG_MPZ (z), x);
|
||||||
#else
|
|
||||||
/* Note that in this case, you'll also have to check all mpz_*_ui and
|
|
||||||
mpz_*_si invocations in Guile. */
|
|
||||||
#error creation of mpz not implemented for this inum size
|
|
||||||
#endif
|
|
||||||
return z;
|
return z;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3,8 +3,8 @@
|
||||||
#ifndef SCM_NUMBERS_H
|
#ifndef SCM_NUMBERS_H
|
||||||
#define SCM_NUMBERS_H
|
#define SCM_NUMBERS_H
|
||||||
|
|
||||||
/* Copyright (C) 1995,1996,1998,2000,2001,2002,2003,2004,2005, 2006,
|
/* Copyright (C) 1995, 1996, 1998, 2000-2006, 2008-2011, 2013, 2014,
|
||||||
* 2008, 2009, 2010, 2011, 2013, 2014 Free Software Foundation, Inc.
|
* 2016 Free Software Foundation, Inc.
|
||||||
*
|
*
|
||||||
* This library is free software; you can redistribute it and/or
|
* This library is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU Lesser General Public License
|
* modify it under the terms of the GNU Lesser General Public License
|
||||||
|
@ -38,16 +38,15 @@ typedef scm_t_int32 scm_t_wchar;
|
||||||
|
|
||||||
/* Immediate Numbers, also known as fixnums
|
/* Immediate Numbers, also known as fixnums
|
||||||
*
|
*
|
||||||
* Inums are exact integer data that fits within an SCM word. */
|
* Inums are exact integers that fit within an SCM word
|
||||||
|
* (along with two tagging bits).
|
||||||
/* SCM_T_SIGNED_MAX is (- (expt 2 n) 1),
|
*
|
||||||
* SCM_MOST_POSITIVE_FIXNUM should be (- (expt 2 (- n 2)) 1)
|
* In the current implementation, Inums must also fit within a long
|
||||||
* which is the same as (/ (- (expt 2 n) 4) 4)
|
* because that's what GMP's mpz_*_si functions accept. */
|
||||||
*/
|
typedef long scm_t_inum;
|
||||||
|
|
||||||
#define SCM_I_FIXNUM_BIT (SCM_LONG_BIT - 2)
|
#define SCM_I_FIXNUM_BIT (SCM_LONG_BIT - 2)
|
||||||
#define SCM_MOST_POSITIVE_FIXNUM ((SCM_T_SIGNED_BITS_MAX-3)/4)
|
#define SCM_MOST_NEGATIVE_FIXNUM (-1L << (SCM_I_FIXNUM_BIT - 1))
|
||||||
#define SCM_MOST_NEGATIVE_FIXNUM (-SCM_MOST_POSITIVE_FIXNUM-1)
|
#define SCM_MOST_POSITIVE_FIXNUM (- (SCM_MOST_NEGATIVE_FIXNUM + 1))
|
||||||
|
|
||||||
/* SCM_SRS (X, Y) is signed right shift, defined as floor (X / 2^Y),
|
/* SCM_SRS (X, Y) is signed right shift, defined as floor (X / 2^Y),
|
||||||
where Y must be non-negative and less than the width in bits of X.
|
where Y must be non-negative and less than the width in bits of X.
|
||||||
|
@ -74,12 +73,12 @@ typedef scm_t_int32 scm_t_wchar;
|
||||||
|
|
||||||
NOTE: X must not perform side effects. */
|
NOTE: X must not perform side effects. */
|
||||||
#ifdef __GNUC__
|
#ifdef __GNUC__
|
||||||
# define SCM_I_INUM(x) (SCM_SRS ((scm_t_signed_bits) SCM_UNPACK (x), 2))
|
# define SCM_I_INUM(x) (SCM_SRS ((scm_t_inum) SCM_UNPACK (x), 2))
|
||||||
#else
|
#else
|
||||||
# define SCM_I_INUM(x) \
|
# define SCM_I_INUM(x) \
|
||||||
(SCM_UNPACK (x) > LONG_MAX \
|
(SCM_UNPACK (x) > SCM_T_SIGNED_BITS_MAX \
|
||||||
? -1 - (scm_t_signed_bits) (~SCM_UNPACK (x) >> 2) \
|
? -1 - (scm_t_inum) (~SCM_UNPACK (x) >> 2) \
|
||||||
: (scm_t_signed_bits) (SCM_UNPACK (x) >> 2))
|
: (scm_t_inum) (SCM_UNPACK (x) >> 2))
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define SCM_I_INUMP(x) (2 & SCM_UNPACK (x))
|
#define SCM_I_INUMP(x) (2 & SCM_UNPACK (x))
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* Copyright (C) 2001, 2009-2014 Free Software Foundation, Inc.
|
/* Copyright (C) 2001, 2009-2014, 2016 Free Software Foundation, Inc.
|
||||||
*
|
*
|
||||||
* This library is free software; you can redistribute it and/or
|
* This library is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU Lesser General Public License
|
* modify it under the terms of the GNU Lesser General Public License
|
||||||
|
@ -236,9 +236,9 @@ VM_DEFINE_FUNCTION (149, ge, "ge?", 2)
|
||||||
#if SCM_GNUC_PREREQ (4, 5) && (defined __x86_64__ || defined __i386__)
|
#if SCM_GNUC_PREREQ (4, 5) && (defined __x86_64__ || defined __i386__)
|
||||||
|
|
||||||
# undef _CX
|
# undef _CX
|
||||||
# if SIZEOF_VOID_P == 8
|
# if SCM_I_FIXNUM_BIT == 62
|
||||||
# define _CX "rcx"
|
# define _CX "rcx"
|
||||||
# elif SIZEOF_VOID_P == 4
|
# elif SCM_I_FIXNUM_BIT == 30
|
||||||
# define _CX "ecx"
|
# define _CX "ecx"
|
||||||
# else
|
# else
|
||||||
# error unsupported word size
|
# error unsupported word size
|
||||||
|
@ -291,7 +291,7 @@ VM_DEFINE_FUNCTION (149, ge, "ge?", 2)
|
||||||
|
|
||||||
# define ASM_MUL(x, y) \
|
# define ASM_MUL(x, y) \
|
||||||
{ \
|
{ \
|
||||||
scm_t_signed_bits xx = SCM_I_INUM (x); \
|
scm_t_inum xx = SCM_I_INUM (x); \
|
||||||
asm volatile goto ("mov %1, %%"_CX"; " \
|
asm volatile goto ("mov %1, %%"_CX"; " \
|
||||||
"test %[tag], %%cl; je %l[slow_mul]; " \
|
"test %[tag], %%cl; je %l[slow_mul]; " \
|
||||||
"sub %[tag], %%"_CX"; " \
|
"sub %[tag], %%"_CX"; " \
|
||||||
|
@ -360,7 +360,7 @@ VM_DEFINE_FUNCTION (149, ge, "ge?", 2)
|
||||||
# define ASM_MUL(x, y) \
|
# define ASM_MUL(x, y) \
|
||||||
if (SCM_LIKELY (SCM_I_INUMP (x) && SCM_I_INUMP (y))) \
|
if (SCM_LIKELY (SCM_I_INUMP (x) && SCM_I_INUMP (y))) \
|
||||||
{ \
|
{ \
|
||||||
scm_t_signed_bits rlo, rhi; \
|
scm_t_inum rlo, rhi; \
|
||||||
asm ("smull %0, %1, %2, %3\n" \
|
asm ("smull %0, %1, %2, %3\n" \
|
||||||
: "=&r" (rlo), "=&r" (rhi) \
|
: "=&r" (rlo), "=&r" (rhi) \
|
||||||
: "r" (SCM_UNPACK (x) - scm_tc2_int), \
|
: "r" (SCM_UNPACK (x) - scm_tc2_int), \
|
||||||
|
@ -496,7 +496,7 @@ VM_DEFINE_FUNCTION (159, ash, "ash", 2)
|
||||||
else
|
else
|
||||||
/* Left shift. See comments in scm_ash. */
|
/* Left shift. See comments in scm_ash. */
|
||||||
{
|
{
|
||||||
scm_t_signed_bits nn, bits_to_shift;
|
scm_t_inum nn, bits_to_shift;
|
||||||
|
|
||||||
nn = SCM_I_INUM (x);
|
nn = SCM_I_INUM (x);
|
||||||
bits_to_shift = SCM_I_INUM (y);
|
bits_to_shift = SCM_I_INUM (y);
|
||||||
|
@ -552,7 +552,7 @@ VM_DEFINE_FUNCTION (162, logxor, "logxor", 2)
|
||||||
|
|
||||||
VM_DEFINE_FUNCTION (163, vector_ref, "vector-ref", 2)
|
VM_DEFINE_FUNCTION (163, vector_ref, "vector-ref", 2)
|
||||||
{
|
{
|
||||||
scm_t_signed_bits i = 0;
|
scm_t_inum i = 0;
|
||||||
ARGS2 (vect, idx);
|
ARGS2 (vect, idx);
|
||||||
if (SCM_LIKELY (SCM_I_IS_NONWEAK_VECTOR (vect)
|
if (SCM_LIKELY (SCM_I_IS_NONWEAK_VECTOR (vect)
|
||||||
&& SCM_I_INUMP (idx)
|
&& SCM_I_INUMP (idx)
|
||||||
|
@ -568,7 +568,7 @@ VM_DEFINE_FUNCTION (163, vector_ref, "vector-ref", 2)
|
||||||
|
|
||||||
VM_DEFINE_INSTRUCTION (164, vector_set, "vector-set", 0, 3, 0)
|
VM_DEFINE_INSTRUCTION (164, vector_set, "vector-set", 0, 3, 0)
|
||||||
{
|
{
|
||||||
scm_t_signed_bits i = 0;
|
scm_t_inum i = 0;
|
||||||
SCM vect, idx, val;
|
SCM vect, idx, val;
|
||||||
POP3 (val, idx, vect);
|
POP3 (val, idx, vect);
|
||||||
if (SCM_LIKELY (SCM_I_IS_NONWEAK_VECTOR (vect)
|
if (SCM_LIKELY (SCM_I_IS_NONWEAK_VECTOR (vect)
|
||||||
|
@ -792,7 +792,7 @@ BV_REF_WITH_ENDIANNESS (f64, ieee_double)
|
||||||
|
|
||||||
#define BV_FIXABLE_INT_REF(stem, fn_stem, type, size) \
|
#define BV_FIXABLE_INT_REF(stem, fn_stem, type, size) \
|
||||||
{ \
|
{ \
|
||||||
scm_t_signed_bits i; \
|
scm_t_inum i; \
|
||||||
const scm_t_ ## type *int_ptr; \
|
const scm_t_ ## type *int_ptr; \
|
||||||
ARGS2 (bv, idx); \
|
ARGS2 (bv, idx); \
|
||||||
\
|
\
|
||||||
|
@ -814,7 +814,7 @@ BV_REF_WITH_ENDIANNESS (f64, ieee_double)
|
||||||
|
|
||||||
#define BV_INT_REF(stem, type, size) \
|
#define BV_INT_REF(stem, type, size) \
|
||||||
{ \
|
{ \
|
||||||
scm_t_signed_bits i; \
|
scm_t_inum i; \
|
||||||
const scm_t_ ## type *int_ptr; \
|
const scm_t_ ## type *int_ptr; \
|
||||||
ARGS2 (bv, idx); \
|
ARGS2 (bv, idx); \
|
||||||
\
|
\
|
||||||
|
@ -845,7 +845,7 @@ BV_REF_WITH_ENDIANNESS (f64, ieee_double)
|
||||||
|
|
||||||
#define BV_FLOAT_REF(stem, fn_stem, type, size) \
|
#define BV_FLOAT_REF(stem, fn_stem, type, size) \
|
||||||
{ \
|
{ \
|
||||||
scm_t_signed_bits i; \
|
scm_t_inum i; \
|
||||||
const type *float_ptr; \
|
const type *float_ptr; \
|
||||||
ARGS2 (bv, idx); \
|
ARGS2 (bv, idx); \
|
||||||
\
|
\
|
||||||
|
@ -933,7 +933,7 @@ BV_SET_WITH_ENDIANNESS (f64, ieee_double)
|
||||||
|
|
||||||
#define BV_FIXABLE_INT_SET(stem, fn_stem, type, min, max, size) \
|
#define BV_FIXABLE_INT_SET(stem, fn_stem, type, min, max, size) \
|
||||||
{ \
|
{ \
|
||||||
scm_t_signed_bits i, j = 0; \
|
scm_t_inum i, j = 0; \
|
||||||
SCM bv, idx, val; \
|
SCM bv, idx, val; \
|
||||||
scm_t_ ## type *int_ptr; \
|
scm_t_ ## type *int_ptr; \
|
||||||
\
|
\
|
||||||
|
@ -960,7 +960,7 @@ BV_SET_WITH_ENDIANNESS (f64, ieee_double)
|
||||||
|
|
||||||
#define BV_INT_SET(stem, type, size) \
|
#define BV_INT_SET(stem, type, size) \
|
||||||
{ \
|
{ \
|
||||||
scm_t_signed_bits i = 0; \
|
scm_t_inum i = 0; \
|
||||||
SCM bv, idx, val; \
|
SCM bv, idx, val; \
|
||||||
scm_t_ ## type *int_ptr; \
|
scm_t_ ## type *int_ptr; \
|
||||||
\
|
\
|
||||||
|
@ -984,7 +984,7 @@ BV_SET_WITH_ENDIANNESS (f64, ieee_double)
|
||||||
|
|
||||||
#define BV_FLOAT_SET(stem, fn_stem, type, size) \
|
#define BV_FLOAT_SET(stem, fn_stem, type, size) \
|
||||||
{ \
|
{ \
|
||||||
scm_t_signed_bits i = 0; \
|
scm_t_inum i = 0; \
|
||||||
SCM bv, idx, val; \
|
SCM bv, idx, val; \
|
||||||
type *float_ptr; \
|
type *float_ptr; \
|
||||||
\
|
\
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue