From e282487f0d6df6c3e1e815e08a107cb2a81d3b0d Mon Sep 17 00:00:00 2001 From: Juan Jose Garcia Ripoll Date: Mon, 2 Mar 2009 23:56:39 +0100 Subject: [PATCH] Added support for long long and unsigned long, and [u]intN_t in the FFI. --- src/aclocal.m4 | 41 +++++++++---- src/c/arch/ffi_x86.d | 85 +++++++++++++++++++++++++- src/c/arch/ffi_x86_64.d | 55 ++++++++++++++++- src/c/ffi.d | 86 +++++++++++++++++++++++++- src/c/number.d | 132 ++++++++++++++++++++++++++++++++++++++++ src/c/symbols_list.h | 12 +++- src/c/symbols_list2.h | 12 +++- src/configure | 89 +++++++++++++++++++++++---- src/h/config.h.in | 3 + src/h/external.h | 9 ++- src/h/object.h | 33 ++++++++++ 11 files changed, 524 insertions(+), 33 deletions(-) diff --git a/src/aclocal.m4 b/src/aclocal.m4 index 6a545c4b6..6e920548f 100644 --- a/src/aclocal.m4 +++ b/src/aclocal.m4 @@ -4,18 +4,37 @@ dnl -------------------------------------------------------------- dnl http://autoconf-archive.cryp.to/ac_c_long_long_.html dnl Provides a test for the existance of the long long int type and defines HAVE_LONG_LONG if it is found. AC_DEFUN([AC_C_LONG_LONG], -[AC_CACHE_CHECK(for long long int, ac_cv_c_long_long, -[if test "$GCC" = yes; then +[AC_MSG_CHECKING(size of long long) +if test "$GCC" = yes; then ac_cv_c_long_long=yes - else - AC_TRY_COMPILE(,[long long int i;], - ac_cv_c_long_long=yes, - ac_cv_c_long_long=no) - fi]) - if test $ac_cv_c_long_long = yes; then - AC_DEFINE(ecl_long_long_t, long long, [compiler understands long long]) - AC_DEFINE(ecl_ulong_long_t, unsigned long long, [compiler understands long long]) - fi +else + AC_TRY_COMPILE(,[long long int i;], + ac_cv_c_long_long=yes, + ac_cv_c_long_long=no) +fi +if test $ac_cv_c_long_long = yes; then + AC_RUN_IFELSE([AC_LANG_SOURCE([[#include +int main() { + const char *int_type; + int bits; + unsigned long long x = 1; + FILE *f=fopen("conftestval", "w"); + if (!f) exit(1); + for (bits = 0; x; bits++) { + x <<= 1; + } + fprintf(f,"ECL_LONG_LONG_BITS='%d'",bits); + exit(0); +}]])],[eval "`cat conftestval`"],[],[]) +fi +if test -z "$ECL_LONG_LONG_BITS"; then + AC_MSG_RESULT(not available) +else + AC_MSG_RESULT([$ECL_LONG_LONG_BITS]) + AC_DEFINE(ecl_long_long_t, long long, [compiler understands long long]) + AC_DEFINE(ecl_ulong_long_t, unsigned long long, [compiler understands long long]) + AC_DEFINE_UNQUOTED([ECL_LONG_LONG_BITS],[$ECL_LONG_LONG_BITS]) +fi ]) dnl -------------------------------------------------------------- diff --git a/src/c/arch/ffi_x86.d b/src/c/arch/ffi_x86.d index a4fe8eb6e..1cd43ee99 100644 --- a/src/c/arch/ffi_x86.d +++ b/src/c/arch/ffi_x86.d @@ -35,10 +35,18 @@ ecl_fficall_push_arg(union ecl_ffi_values *data, enum ecl_ffi_tag type) case ECL_FFI_UNSIGNED_BYTE: i = data->ub; goto INT; case ECL_FFI_SHORT: i = data->s; goto INT; case ECL_FFI_UNSIGNED_SHORT: i = data->us; goto INT; +#ifdef ecl_uint16_t + case ECL_FFI_INT16_T: i = data->i16; goto INT; + case ECL_FFI_UINT16_T: i = data->u16; goto INT; +#endif case ECL_FFI_INT: case ECL_FFI_LONG: case ECL_FFI_UNSIGNED_INT: case ECL_FFI_UNSIGNED_LONG: +#ifdef ecl_uint32_t + case ECL_FFI_INT32_T: + case ECL_FFI_UINT32_T: +#endif case ECL_FFI_POINTER_VOID: case ECL_FFI_CSTRING: case ECL_FFI_OBJECT: @@ -55,6 +63,20 @@ ecl_fficall_push_arg(union ecl_ffi_values *data, enum ecl_ffi_tag type) ecl_fficall_align(sizeof(int)); ecl_fficall_push_bytes(&data->f, sizeof(float)); break; +#ifdef ecl_uint64_t + case ECL_FFI_UINT64_T: + case ECL_FFI_INT64_T: + ecl_fficall_align(sizeof(ecl_uint64_t)); + ecl_fficall_push_bytes(&data->ull, sizeof(ecl_uint64_t)); + break; +#endif +#ifdef ecl_long_long_t + case ECL_FFI_UNSIGNED_LONG_LONG: + case ECL_FFI_LONG_LONG: + ecl_fficall_align(sizeof(unsigned long)); + ecl_fficall_push_bytes(&data->ull, sizeof(unsigned long long)); + break; +#endif case ECL_FFI_VOID: FEerror("VOID is not a valid argument type for a C function", 0); } @@ -98,7 +120,36 @@ ecl_fficall_execute(void *f_ptr, struct ecl_fficall *fficall, enum ecl_ffi_tag r fficall->output.f = ((float (*)())f_ptr)(); } else if (return_type == ECL_FFI_DOUBLE) { fficall->output.d = ((double (*)())f_ptr)(); - } else { + } +#ifdef ecl_uint16_t + else if (return_type == ECL_FFI_INT16_T) { + fficall->output.i16 = ((ecl_int16_t (*)())f_ptr)(); + } else if (return_type == ECL_FFI_UINT16_T) { + fficall->output.u16 = ((ecl_uint16_t (*)())f_ptr)(); + } +#endif +#ifdef ecl_uint32_t + else if (return_type == ECL_FFI_INT32_T) { + fficall->output.i32 = ((ecl_int32_t (*)())f_ptr)(); + } else if (return_type == ECL_FFI_UINT32_T) { + fficall->output.u32 = ((ecl_uint32_t (*)())f_ptr)(); + } +#endif +#ifdef ecl_uint64_t + else if (return_type == ECL_FFI_INT64_T) { + fficall->output.i64 = ((ecl_int64_t (*)())f_ptr)(); + } else if (return_type == ECL_FFI_UINT32_T) { + fficall->output.u64 = ((ecl_uint64_t (*)())f_ptr)(); + } +#endif +#ifdef ecl_long_long_t + else if (return_type == ECL_FFI_LONG_LONG) { + fficall->output.ll = ((ecl_long_long_t (*)())f_ptr)(); + } else if (return_type == ECL_FFI_UNSIGNED_LONG_LONG) { + fficall->output.ull = ((ecl_ulong_long_t (*)())f_ptr)(); + } +#endif + else { ((void (*)())f_ptr)(); } #ifdef _MSC_VER @@ -149,13 +200,23 @@ ecl_dynamic_callback_execute(cl_object cbk_info, char *arg_buffer) case ECL_FFI_UNSIGNED_CHAR: i = output.uc; goto INT; case ECL_FFI_BYTE: i = output.b; goto INT; case ECL_FFI_UNSIGNED_BYTE: i = output.ub; goto INT; +#ifdef ecl_uint32_t + case ECL_FFI_INT16_T: +#endif case ECL_FFI_SHORT: i = output.s; goto INT; +#ifdef ecl_uint32_t + case ECL_FFI_UINT16_T: +#endif case ECL_FFI_UNSIGNED_SHORT: i = output.us; goto INT; case ECL_FFI_POINTER_VOID: case ECL_FFI_OBJECT: case ECL_FFI_CSTRING: case ECL_FFI_INT: case ECL_FFI_UNSIGNED_INT: +#ifdef ecl_uint32_t + case ECL_FFI_INT32_T: + case ECL_FFI_UINT32_T: +#endif case ECL_FFI_LONG: case ECL_FFI_UNSIGNED_LONG: i = output.i; @@ -169,6 +230,28 @@ INT: } #endif return; +#if defined(ecl_long_long_t) || defined(ecl_uint64_t) +# ifdef ecl_long_long_t + case ECL_FFI_LONG_LONG: + case ECL_FFI_UNSIGNED_LONG_LONG: +# endif +# ifdef ecl_uint64_t + case ECL_FFI_INT64_T: + case ECL_FFI_UINT64_T: +# endif +# ifdef _MSC_VER + __asm mov eax,output.l2[0] + __asm mov edx,output.l2[1] +# else + { + register int eax asm("eax"); + register int edx asm("edx"); + eax = output.l2[0]; + edx = output.l2[1]; + } +# endif + return; +#endif /* ecl_long_long_t */ case ECL_FFI_DOUBLE: { #ifdef _MSC_VER __asm fld output.d diff --git a/src/c/arch/ffi_x86_64.d b/src/c/arch/ffi_x86_64.d index b8667e0fe..c20324a3d 100644 --- a/src/c/arch/ffi_x86_64.d +++ b/src/c/arch/ffi_x86_64.d @@ -49,12 +49,24 @@ ecl_fficall_push_arg(union ecl_ffi_values *data, enum ecl_ffi_tag type) case ECL_FFI_UNSIGNED_CHAR: i = data->uc; goto INT; case ECL_FFI_BYTE: i = data->b; goto INT; case ECL_FFI_UNSIGNED_BYTE: i = data->ub; goto INT; +#ifdef ecl_uint16_t + case ECL_FFI_INT16_T: i = data->i16; goto INT; + case ECL_FFI_UINT16_T: i = data->u16; goto INT; +#endif case ECL_FFI_SHORT: i = data->s; goto INT; case ECL_FFI_UNSIGNED_SHORT: i = data->us; goto INT; +#ifdef ecl_uint32_t + case ECL_FFI_INT32_T: i = data->i32; goto INT; + case ECL_FFI_UINT32_T: i = data->u32; goto INT; +#endif case ECL_FFI_INT: i = data->i; goto INT; case ECL_FFI_UNSIGNED_INT: i = data->ui; goto INT; case ECL_FFI_LONG: case ECL_FFI_UNSIGNED_LONG: +#ifdef ecl_uint64_t + case ECL_FFI_INT64_T: + case ECL_FFI_UINT64_T: +#endif case ECL_FFI_POINTER_VOID: case ECL_FFI_CSTRING: case ECL_FFI_OBJECT: @@ -145,7 +157,36 @@ ecl_fficall_execute(void *_f_ptr, struct ecl_fficall *fficall, enum ecl_ffi_tag fficall->output.f = ((float (*)())f_ptr)(); } else if (return_type == ECL_FFI_DOUBLE) { fficall->output.d = ((double (*)())f_ptr)(); - } else { + } +#ifdef ecl_uint16_t + else if (return_type == ECL_FFI_INT16_T) { + fficall->output.i16 = ((ecl_int16_t (*)())f_ptr)(); + } else if (return_type == ECL_FFI_UINT16_T) { + fficall->output.u16 = ((ecl_uint16_t (*)())f_ptr)(); + } +#endif +#ifdef ecl_uint32_t + else if (return_type == ECL_FFI_INT32_T) { + fficall->output.i32 = ((ecl_int32_t (*)())f_ptr)(); + } else if (return_type == ECL_FFI_UINT32_T) { + fficall->output.u32 = ((ecl_uint32_t (*)())f_ptr)(); + } +#endif +#ifdef ecl_uint64_t + else if (return_type == ECL_FFI_INT64_T) { + fficall->output.i64 = ((ecl_int64_t (*)())f_ptr)(); + } else if (return_type == ECL_FFI_UINT32_T) { + fficall->output.u64 = ((ecl_uint64_t (*)())f_ptr)(); + } +#endif +#ifdef ecl_long_long_t + else if (return_type == ECL_FFI_LONG_LONG) { + fficall->output.ll = ((ecl_long_long_t (*)())f_ptr)(); + } else if (return_type == ECL_FFI_UNSIGNED_LONG_LONG) { + fficall->output.ull = ((ecl_ulong_long_t (*)())f_ptr)(); + } +#endif + else { ((void (*)())f_ptr)(); } @@ -227,8 +268,16 @@ ARG_FROM_STACK: case ECL_FFI_UNSIGNED_CHAR: i = output.uc; goto INT; case ECL_FFI_BYTE: i = output.b; goto INT; case ECL_FFI_UNSIGNED_BYTE: i = output.ub; goto INT; +#ifdef ecl_uint16_t + case ECL_FFI_INT16_T: i = output.i16; goto INT; + case ECL_FFI_UINT16_T: i = output.u16; goto INT +#endif case ECL_FFI_SHORT: i = output.s; goto INT; case ECL_FFI_UNSIGNED_SHORT: i = output.us; goto INT; +#ifdef ecl_uint32_t + case ECL_FFI_INT32_T: i = output.i32; goto INT; + case ECL_FFI_UINT32_T: i = output.u32; goto INT; +#endif case ECL_FFI_POINTER_VOID: case ECL_FFI_OBJECT: case ECL_FFI_CSTRING: @@ -236,6 +285,10 @@ ARG_FROM_STACK: case ECL_FFI_UNSIGNED_INT: case ECL_FFI_LONG: case ECL_FFI_UNSIGNED_LONG: +#ifdef ecl_uint64_t + case ECL_FFI_INT64_T: + case ECL_FFI_UINT64_T: +#endif i = output.i; INT: { diff --git a/src/c/ffi.d b/src/c/ffi.d index 969719858..d77f91f02 100644 --- a/src/c/ffi.d +++ b/src/c/ffi.d @@ -28,12 +28,29 @@ static const cl_object ecl_foreign_type_table[] = { @':unsigned-int', @':long', @':unsigned-long', +#ifdef ecl_uint16_t + @':int16-t', + @':uint16-t', +#endif +#ifdef ecl_uint32_t + @':int64-t', + @':uint64-t', +#endif +#ifdef ecl_uint64_t + @':int64-t', + @':uint64-t', +#endif +#ifdef ecl_long_long_t + @':long-long', + @':unsigned-long-long', +#endif @':pointer-void', @':cstring', @':object', @':float', @':double', - @':void'}; + @':void' +}; static const cl_object ecl_foreign_cc_table[] = { @':cdecl', @@ -51,12 +68,29 @@ static unsigned int ecl_foreign_type_size[] = { sizeof(unsigned int), sizeof(long), sizeof(unsigned long), +#ifdef ecl_uint16_t + sizeof(ecl_int16_t), + sizeof(ecl_uint16_t), +#endif +#ifdef ecl_uint32_t + sizeof(ecl_int32_t), + sizeof(ecl_uint32_t), +#endif +#ifdef ecl_uint64_t + sizeof(ecl_int64_t), + sizeof(ecl_uint64_t), +#endif +#ifdef ecl_long_long_t + sizeof(long long), + sizeof(unsigned long long), +#endif sizeof(void *), sizeof(char *), sizeof(cl_object), sizeof(float), sizeof(double), - 0}; + 0 +}; cl_object ecl_make_foreign_data(cl_object tag, cl_index size, void *data) @@ -284,6 +318,30 @@ ecl_foreign_data_ref_elt(void *p, enum ecl_ffi_tag tag) return ecl_make_unsigned_integer(*(unsigned int *)p); case ECL_FFI_LONG: return ecl_make_integer(*(long *)p); +#ifdef ecl_uint16_t + case ECL_FFI_INT16_T: + return ecl_make_int16_t(*(ecl_int16_t *)p); + case ECL_FFI_UINT16_T: + return ecl_make_uint16_t(*(ecl_uint16_t *)p); +#endif +#ifdef ecl_uint32_t + case ECL_FFI_INT32_T: + return ecl_make_int32_t(*(ecl_int32_t *)p); + case ECL_FFI_UINT32_T: + return ecl_make_uint32_t(*(ecl_uint32_t *)p); +#endif +#ifdef ecl_uint64_t + case ECL_FFI_INT64_T: + return ecl_make_int64_t(*(ecl_int64_t *)p); + case ECL_FFI_UINT64_T: + return ecl_make_uint64_t(*(ecl_uint64_t *)p); +#endif +#ifdef ecl_long_long_t + case ECL_FFI_LONG_LONG: + return ecl_make_long_long(*(ecl_long_long_t *)p); + case ECL_FFI_UNSIGNED_LONG_LONG: + return ecl_make_unsigned_long_long(*(ecl_ulong_long_t *)p); +#endif case ECL_FFI_UNSIGNED_LONG: return ecl_make_unsigned_integer(*(unsigned long *)p); case ECL_FFI_POINTER_VOID: @@ -335,6 +393,30 @@ ecl_foreign_data_set_elt(void *p, enum ecl_ffi_tag tag, cl_object value) case ECL_FFI_UNSIGNED_LONG: *(unsigned long *)p = fixnnint(value); break; +#ifdef ecl_uint16_t + case ECL_FFI_INT16_T: + *(ecl_int16_t *)p = ecl_to_int16_t(value); + case ECL_FFI_UINT16_T: + *(ecl_uint16_t *)p = ecl_to_uint16_t(value); +#endif +#ifdef ecl_uint32_t + case ECL_FFI_INT32_T: + *(ecl_int32_t *)p = ecl_to_int32_t(value); + case ECL_FFI_UINT32_T: + *(ecl_uint32_t *)p = ecl_to_uint32_t(value); +#endif +#ifdef ecl_uint64_t + case ECL_FFI_INT64_T: + *(ecl_int64_t *)p = ecl_to_int64_t(value); + case ECL_FFI_UINT64_T: + *(ecl_uint64_t *)p = ecl_to_uint64_t(value); +#endif +#ifdef ecl_long_long_t + case ECL_FFI_LONG_LONG: + *(ecl_long_long_t *)p = ecl_to_long_long(value); + case ECL_FFI_UNSIGNED_LONG_LONG: + *(ecl_ulong_long_t *)p = ecl_to_unsigned_long_long(value); +#endif case ECL_FFI_POINTER_VOID: *(void **)p = ecl_foreign_data_pointer_safe(value); break; diff --git a/src/c/number.d b/src/c/number.d index 899a15930..6773379a7 100644 --- a/src/c/number.d +++ b/src/c/number.d @@ -301,6 +301,138 @@ ecl_make_int64_t(ecl_int64_t i) # endif /* FIXNUM_BITS < 64 */ #endif /* ecl_uint64_t */ +#if defined(ecl_ulong_long_t) +# if defined(ecl_uint32_t) && ECL_LONG_LONG_BITS == 32 +ecl_ulong_long_t +ecl_to_unsigned_long_long(cl_object x) { + return (ecl_ulong_long_t)ecl_to_uint32_t(x); +} + +ecl_long_long_t +ecl_to_long_long(cl_object x) { + return (ecl_long_long_t)ecl_to_int32_t(x); +} +cl_object +ecl_make_unsigned_long_long(ecl_ulong_long_t i) { + return ecl_make_uint32_t(i); +} +cl_object +ecl_make_long_long(ecl_long_long_t i) { + return ecl_make_int32_t(i); +} +# else +# if defined(ecl_uint64_t) && ECL_LONG_LONG_BITS == 64 +ecl_ulong_long_t +ecl_to_unsigned_long_long(cl_object x) { + return (ecl_ulong_long_t)ecl_to_uint64_t(x); +} +ecl_long_long_t +ecl_to_long_long(cl_object x) { + return (ecl_long_long_t)ecl_to_int64_t(x); +} +cl_object +ecl_make_unsigned_long_long(ecl_ulong_long_t i) { + return ecl_make_uint64_t(i); +} +cl_object +ecl_make_long_long(ecl_long_long_t i) { + return ecl_make_int64_t(i); +} +# else +# if !defined(WITH_GMP) +# error "Cannot handle ecl_ulong_long_t without GMP" +# endif +ecl_ulong_long_t +ecl_to_unsigned_long_long(cl_object x) { + do { + if (!ecl_minusp(x)) { + if (FIXNUMP(x)) { + return (ecl_ulong_long_t)fix(x); + } else if (type_of(x) != t_bignum) { + (void)0; + } else if (mpz_fits_ulong_p(x->big.big_num)) { + return (ecl_ulong_long_t)mpz_get_ui(x->big.big_num); + } else { + cl_object copy = big_register0_get(); + int i = ECL_LONG_LONG_BITS - CL_FIXNUM_BITS; + mpz_fdiv_q_2exp(copy->bit.big_num, x->big.big_num, i); + if (mpz_fits_ulong_p(copy->big.big_num)) { + volatile ecl_ulong_long_t output; + output = mpz_get_ui(copy->big.big_num); + for (i -= CL_FIXNUM_BITS; i; i-= CL_FIXNUM_BITS) { + output = (output << CL_FIXNUM_BITS); + output += mpz_get_ui(x->big.big_num); + } + return output; + } + } + } + x = ecl_type_error(@'coerce', "variable", x, + cl_list(3,@'integer',MAKE_FIXNUM(0), + ecl_one_minus(ecl_ash(MAKE_FIXNUM(1), + ECL_LONG_LONG_BITS)))); + } while(1); +} + +ecl_long_long_t +ecl_to_long_long(cl_object x) +{ + do { + if (FIXNUMP(x)) { + return (ecl_long_long_t)fix(x); + } else if (type_of(x) != t_bignum) { + (void)0; + } else if (mpz_fits_slong_p(x->big.big_num)) { + return (ecl_long_long_t)mpz_get_si(x->big.big_num); + } else { + cl_object copy = big_register0_get(); + int i = ECL_LONG_LONG_BITS - CL_FIXNUM_BITS; + mpz_fdiv_q_2exp(copy->bit.big_num, x->big.big_num, i); + if (mpz_fits_ulong_p(copy->big.big_num)) { + volatile ecl_long_long_t output; + output = mpz_get_si(copy->big.big_num); + for (i -= CL_FIXNUM_BITS; i; i-= CL_FIXNUM_BITS) { + output = (output << CL_FIXNUM_BITS); + output += mpz_get_ui(x->big.big_num); + } + return output; + } + } + x = ecl_type_error(@'coerce', "variable", x, + cl_list(3,@'integer', + ecl_negate(ecl_ash(MAKE_FIXNUM(1), ECL_LONG_LONG_BITS-1)), + ecl_one_minus(ecl_ash(MAKE_FIXNUM(1), ECL_LONG_LONG_BITS-1)))); + } while(1); +} + +cl_object +ecl_make_unsigned_long_long(ecl_ulong_long_t i) +{ + if (i <= MOST_POSITIVE_FIXNUM) { + return MAKE_FIXNUM(i); + } else if (i <= ~(ecl_uint32_t)0) { + return ecl_make_uint32_t(i); + } else { + cl_object aux = ecl_make_uint32_t(i >> 32); + return cl_logior(2, ecl_ash(aux, 32), + ecl_make_uint32_t((ecl_uint32_t)i)); + } +} + +cl_object +ecl_make_long_long(ecl_long_long_t i) +{ + if (i >= MOST_NEGATIVE_FIXNUM && i <= MOST_POSITIVE_FIXNUM) { + return MAKE_FIXNUM(i); + } else { + cl_object aux = ecl_make_int32_t(i >> 32); + return cl_logior(2, ecl_ash(aux, 32), ecl_make_uint32_t((ecl_uint32_t)i)); + } +} +# endif +# endif +#endif /* ecl_ulong_long_t */ + cl_object ecl_make_ratio(cl_object num, cl_object den) { diff --git a/src/c/symbols_list.h b/src/c/symbols_list.h index 8c1dad273..d26bcd28b 100644 --- a/src/c/symbols_list.h +++ b/src/c/symbols_list.h @@ -1417,17 +1417,27 @@ cl_symbols[] = { {KEY_ "FIXNUM", KEYWORD, NULL, -1, OBJNULL}, {KEY_ "FLOAT", KEYWORD, NULL, -1, OBJNULL}, {KEY_ "INT", KEYWORD, NULL, -1, OBJNULL}, +{KEY_ "INT8-T", KEYWORD, NULL, -1, OBJNULL}, +{KEY_ "INT16-T", KEYWORD, NULL, -1, OBJNULL}, +{KEY_ "INT32-T", KEYWORD, NULL, -1, OBJNULL}, +{KEY_ "INT64-T", KEYWORD, NULL, -1, OBJNULL}, {KEY_ "LONG", KEYWORD, NULL, -1, OBJNULL}, +{KEY_ "LONG-LONG", KEYWORD, NULL, -1, OBJNULL}, {KEY_ "POINTER-SELF", KEYWORD, NULL, -1, OBJNULL}, {KEY_ "POINTER-VOID", KEYWORD, NULL, -1, OBJNULL}, {KEY_ "SHORT", KEYWORD, NULL, -1, OBJNULL}, {KEY_ "STRUCT", KEYWORD, NULL, -1, OBJNULL}, {KEY_ "UNION", KEYWORD, NULL, -1, OBJNULL}, {KEY_ "VOID", KEYWORD, NULL, -1, OBJNULL}, +{KEY_ "UINT8-T", KEYWORD, NULL, -1, OBJNULL}, +{KEY_ "UINT16-T", KEYWORD, NULL, -1, OBJNULL}, +{KEY_ "UINT32-T", KEYWORD, NULL, -1, OBJNULL}, +{KEY_ "UINT64-T", KEYWORD, NULL, -1, OBJNULL}, {KEY_ "UNSIGNED-BYTE", KEYWORD, NULL, -1, OBJNULL}, {KEY_ "UNSIGNED-CHAR", KEYWORD, NULL, -1, OBJNULL}, {KEY_ "UNSIGNED-INT", KEYWORD, NULL, -1, OBJNULL}, {KEY_ "UNSIGNED-LONG", KEYWORD, NULL, -1, OBJNULL}, +{KEY_ "UNSIGNED-LONG-LONG", KEYWORD, NULL, -1, OBJNULL}, {KEY_ "UNSIGNED-SHORT", KEYWORD, NULL, -1, OBJNULL}, {SYS_ "C-CHAR-BIT", SI_CONSTANT, NULL, -1, MAKE_FIXNUM(CHAR_BIT)}, {SYS_ "C-CHAR-MAX", SI_CONSTANT, NULL, -1, MAKE_FIXNUM(CHAR_MAX)}, @@ -1442,7 +1452,7 @@ cl_symbols[] = { {SYS_ "C-UINT-MAX", SI_CONSTANT, NULL, -1, OBJNULL}, /* See main.d */ {SYS_ "C-USHORT-MAX", SI_CONSTANT, NULL, -1, MAKE_FIXNUM(USHRT_MAX)}, {SYS_ "C-ULONG-MAX", SI_CONSTANT, NULL, -1, OBJNULL}, /* See main.d */ - +{SYS_ "C-ULONG-LONG-MAX",SI_CONSTANT,NULL,-1,OBJNULL}, /* See main.d */ #ifdef GBC_BOEHM {SYS_ "GC", SI_ORDINARY, si_gc, 1, OBJNULL}, {SYS_ "GC-DUMP", SI_ORDINARY, si_gc_dump, 0, OBJNULL}, diff --git a/src/c/symbols_list2.h b/src/c/symbols_list2.h index d77d25753..219632328 100644 --- a/src/c/symbols_list2.h +++ b/src/c/symbols_list2.h @@ -1417,17 +1417,27 @@ cl_symbols[] = { {KEY_ "FIXNUM",NULL}, {KEY_ "FLOAT",NULL}, {KEY_ "INT",NULL}, +{KEY_ "INT8-T",NULL}, +{KEY_ "INT16-T",NULL}, +{KEY_ "INT32-T",NULL}, +{KEY_ "INT64-T",NULL}, {KEY_ "LONG",NULL}, +{KEY_ "LONG-LONG",NULL}, {KEY_ "POINTER-SELF",NULL}, {KEY_ "POINTER-VOID",NULL}, {KEY_ "SHORT",NULL}, {KEY_ "STRUCT",NULL}, {KEY_ "UNION",NULL}, {KEY_ "VOID",NULL}, +{KEY_ "UINT8-T",NULL}, +{KEY_ "UINT16-T",NULL}, +{KEY_ "UINT32-T",NULL}, +{KEY_ "UINT64-T",NULL}, {KEY_ "UNSIGNED-BYTE",NULL}, {KEY_ "UNSIGNED-CHAR",NULL}, {KEY_ "UNSIGNED-INT",NULL}, {KEY_ "UNSIGNED-LONG",NULL}, +{KEY_ "UNSIGNED-LONG-LONG",NULL}, {KEY_ "UNSIGNED-SHORT",NULL}, {SYS_ "C-CHAR-BIT",NULL}, {SYS_ "C-CHAR-MAX",NULL}, @@ -1442,7 +1452,7 @@ cl_symbols[] = { {SYS_ "C-UINT-MAX",NULL}, /* See main.d */ {SYS_ "C-USHORT-MAX",NULL}, {SYS_ "C-ULONG-MAX",NULL}, /* See main.d */ - +{SYS_ "C-ULONG-LONG-MAX",NULL}, /* See main.d */ #ifdef GBC_BOEHM {SYS_ "GC","si_gc"}, {SYS_ "GC-DUMP","si_gc_dump"}, diff --git a/src/configure b/src/configure index 7109fb030..58067a03d 100755 --- a/src/configure +++ b/src/configure @@ -7054,15 +7054,12 @@ _ACEOF fi -{ echo "$as_me:$LINENO: checking for long long int" >&5 -echo $ECHO_N "checking for long long int... $ECHO_C" >&6; } -if test "${ac_cv_c_long_long+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - if test "$GCC" = yes; then +{ echo "$as_me:$LINENO: checking size of long long" >&5 +echo $ECHO_N "checking size of long long... $ECHO_C" >&6; } +if test "$GCC" = yes; then ac_cv_c_long_long=yes - else - cat >conftest.$ac_ext <<_ACEOF +else + cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext @@ -7103,11 +7100,73 @@ sed 's/^/| /' conftest.$ac_ext >&5 fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - fi fi -{ echo "$as_me:$LINENO: result: $ac_cv_c_long_long" >&5 -echo "${ECHO_T}$ac_cv_c_long_long" >&6; } - if test $ac_cv_c_long_long = yes; then +if test $ac_cv_c_long_long = yes; then + if test "$cross_compiling" = yes; then + { { echo "$as_me:$LINENO: error: cannot run test program while cross compiling +See \`config.log' for more details." >&5 +echo "$as_me: error: cannot run test program while cross compiling +See \`config.log' for more details." >&2;} + { (exit 1); exit 1; }; } +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +int main() { + const char *int_type; + int bits; + unsigned long long x = 1; + FILE *f=fopen("conftestval", "w"); + if (!f) exit(1); + for (bits = 0; x; bits++) { + x <<= 1; + } + fprintf(f,"ECL_LONG_LONG_BITS='%d'",bits); + exit(0); +} +_ACEOF +rm -f conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { ac_try='./conftest$ac_exeext' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + eval "`cat conftestval`" +else + echo "$as_me: program exited with status $ac_status" >&5 +echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext +fi + + +fi +if test -z "$ECL_LONG_LONG_BITS"; then + { echo "$as_me:$LINENO: result: not available" >&5 +echo "${ECHO_T}not available" >&6; } +else + { echo "$as_me:$LINENO: result: $ECL_LONG_LONG_BITS" >&5 +echo "${ECHO_T}$ECL_LONG_LONG_BITS" >&6; } cat >>confdefs.h <<\_ACEOF #define ecl_long_long_t long long @@ -7118,7 +7177,11 @@ cat >>confdefs.h <<\_ACEOF #define ecl_ulong_long_t unsigned long long _ACEOF - fi + cat >>confdefs.h <<_ACEOF +#define ECL_LONG_LONG_BITS $ECL_LONG_LONG_BITS +_ACEOF + +fi diff --git a/src/h/config.h.in b/src/h/config.h.in index 052956f17..945bae433 100644 --- a/src/h/config.h.in +++ b/src/h/config.h.in @@ -1,3 +1,4 @@ + /* config.h.in -- Template configuration file. */ @@ -312,6 +313,8 @@ typedef unsigned @CL_FIXNUM_TYPE@ cl_hashkey; #undef HAVE_UNAME #undef HAVE_UNISTD_H #undef HAVE_SYS_WAIT_H +/* size of long long */ +#undef ECL_LONG_LONG_BITS /* * we do not manage to get proper signal handling of floating point diff --git a/src/h/external.h b/src/h/external.h index f4e746004..a189c0bd6 100644 --- a/src/h/external.h +++ b/src/h/external.h @@ -943,7 +943,6 @@ extern ECL_API ecl_uint8_t ecl_to_uint8_t(cl_object o); extern ECL_API ecl_int8_t ecl_to_int8_t(cl_object o); #define ecl_make_uint8_t(i) MAKE_FIXNUM(i) #define ecl_make_int8_t(i) MAKE_FIXNUM(i) - #if FIXNUM_BITS < 32 # error "Unsupported platforms with FIXNUM_BITS < 32" #endif @@ -953,7 +952,6 @@ extern ECL_API ecl_int16_t ecl_to_int16_t(cl_object o); # define ecl_make_uint16_t(i) MAKE_FIXNUM(i) # define ecl_make_int16_t(i) MAKE_FIXNUM(i) #endif /* ecl_uint16_t */ - #ifdef ecl_uint32_t # if FIXNUM_BITS == 32 # define ecl_to_uint32_t fixnnint @@ -967,7 +965,6 @@ extern ECL_API ecl_uint32_t ecl_to_uint32_t(cl_object o); extern ECL_API ecl_int32_t ecl_to_int32_t(cl_object o); # endif #endif /* ecl_uint32_t */ - #ifdef ecl_uint64_t # if FIXNUM_BITS >= 64 # define ecl_to_uint64_t fixnnint @@ -981,6 +978,12 @@ extern ECL_API cl_object ecl_make_uint64_t(ecl_uint64_t i); extern ECL_API cl_object ecl_make_int64_t(ecl_int64_t i); # endif #endif /* ecl_uint64_t */ +#ifdef ecl_long_long_t +extern ECL_API ecl_ulong_long_t ecl_to_unsigned_long_long(cl_object p); +extern ECL_API ecl_long_long_t ecl_to_long_long(cl_object p); +extern ECL_API cl_object ecl_make_unsigned_long_long(ecl_ulong_long_t i); +extern ECL_API cl_object ecl_make_long_long(ecl_long_long_t i); +#endif /* ecl_long_long_t */ extern ECL_API cl_object ecl_make_ratio(cl_object num, cl_object den); extern ECL_API cl_object ecl_make_singlefloat(float f); diff --git a/src/h/object.h b/src/h/object.h index dfcf3d94a..686cae822 100644 --- a/src/h/object.h +++ b/src/h/object.h @@ -717,6 +717,22 @@ enum ecl_ffi_tag { ECL_FFI_UNSIGNED_INT, ECL_FFI_LONG, ECL_FFI_UNSIGNED_LONG, +#ifdef ecl_uint16_t + ECL_FFI_INT16_T, + ECL_FFI_UINT16_T, +#endif +#ifdef ecl_uint32_t + ECL_FFI_INT32_T, + ECL_FFI_UINT32_T, +#endif +#ifdef ecl_uint64_t + ECL_FFI_INT64_T, + ECL_FFI_UINT64_T, +#endif +#ifdef ecl_long_long_t + ECL_FFI_LONG_LONG, + ECL_FFI_UNSIGNED_LONG_LONG, +#endif ECL_FFI_POINTER_VOID, ECL_FFI_CSTRING, ECL_FFI_OBJECT, @@ -736,6 +752,23 @@ union ecl_ffi_values { unsigned short us; long l; unsigned long ul; +#ifdef ecl_uint16_t + ecl_int16_t i16; + ecl_uint16_t u16; +#endif +#ifdef ecl_uint32_t + ecl_int32_t i32; + ecl_uint32_t u32; +#endif +#ifdef ecl_uint64_t + ecl_int64_t i64; + ecl_uint64_t u64; +#endif +#ifdef ecl_long_long_t + ecl_long_long_t ll; + ecl_ulong_long_t ull; + unsigned long l2[2]; +#endif void *pv; char *pc; cl_object o;