Commit a7c03ee1 authored by Erick's avatar Erick

Going back one more time: MPI doesn't work with native 64 bits on

MacOS. As a consequence, the wrapper functions in gmp.c are 32 bits
and use a different strategy in presence of values which cannot be
represented with 32 bits (conversion to/from string). This is slow,
but it seems to work.
parent ddfcac82
Erick Gallesio by cut/paste from the original GMP 3.1.1 version
Erick Gallesio for packaging and GMP wrapper.
Michael J. Fromberger for mpi.{c,h}
noinst_LIBRARIES = libgmp.a
libgmp_a_SOURCES = mpi.c gmp.c
all: mpi-types.h libgmp.a
all-local: libgmp.a
@mkdir -p .libs
cp libgmp.a ./.libs
mpi-types.h: types
types > ./mpi-types.h
types: types.c
$(CC) $(CFLAGS) -o types types.c
test: all
(cd tests; $(MAKE) test)
......@@ -22,7 +16,6 @@ clean:
distclean: clean
(cd tests; make distclean)
/bin/rm -f types mpi-types.h
/bin/rm -f config.h stamp-h1
/bin/rm -f config.status config.cache config.log configure.lineno \
config.status.lineno
......
......@@ -457,7 +457,7 @@ distcleancheck: distclean
exit 1; } >&2
check-am: all-am
check: check-am
all-am: Makefile $(LIBRARIES) config.h
all-am: Makefile $(LIBRARIES) config.h all-local
installdirs:
install: install-am
install-exec: install-exec-am
......@@ -552,8 +552,8 @@ uninstall-am:
.MAKE: all install-am install-strip
.PHONY: CTAGS GTAGS all all-am am--refresh check check-am clean \
clean-generic clean-noinstLIBRARIES ctags dist dist-all \
.PHONY: CTAGS GTAGS all all-am all-local am--refresh check check-am \
clean clean-generic clean-noinstLIBRARIES ctags dist dist-all \
dist-bzip2 dist-gzip dist-lzma dist-shar dist-tarZ dist-xz \
dist-zip distcheck distclean distclean-compile \
distclean-generic distclean-hdr distclean-tags distcleancheck \
......@@ -568,16 +568,10 @@ uninstall-am:
ps ps-am tags uninstall uninstall-am
all: mpi-types.h libgmp.a
all-local: libgmp.a
@mkdir -p .libs
cp libgmp.a ./.libs
mpi-types.h: types
types > ./mpi-types.h
types: types.c
$(CC) $(CFLAGS) -o types types.c
test: all
(cd tests; $(MAKE) test)
......@@ -589,7 +583,6 @@ clean:
distclean: clean
(cd tests; make distclean)
/bin/rm -f types mpi-types.h
/bin/rm -f config.h stamp-h1
/bin/rm -f config.status config.cache config.log configure.lineno \
config.status.lineno
......
This is a GMPlite version.
This version is built for STklos from the transitive closure of the
functions used in src/numbers.c
This version is a new version built as a wrapper around the MPI
library (http://spinning-yarns.org/michael/mpi). It replaces the
previous version built with starting from the sources of an old
version of GMP (3.1.1) as transitive closure of the functions used in
src/numbers.c.
This version is used if there is no GMP library installed on the
system at configure time (otherwise the system GMP is used).
The rewriting was necessary because old GMPlite was hard to maintain
(it embeds asm code and is hard to understand). On the contrary MPI,
is simpler (it is basically one source file).
In any case, GMPlite is a poor replacement of GMP and should not be
used. It is a only used if there is no GMP library installed on the
system at configure time (otherwise the system GMP is used).
......@@ -21,7 +21,7 @@
*
* Author: Erick Gallesio [eg@unice.fr]
* Creation date: 12-Oct-2009 19:27 (eg)
* Last file update: 26-Oct-2009 19:43 (eg)
* Last file update: 28-Oct-2009 10:13 (eg)
*/
#include <stdio.h>
......@@ -29,16 +29,28 @@
#include "gmp.h"
#if 0
static void trace_bignum(mpz_t bn)
#define MAXBUF 100 /* size for temporary string buffer */
#define MAX32_SI 2147483647
#define MIN32_SI (-MAX32_SI + -1)
#define MAX32_UI 4294967295UL
#define bit64_si(si) ((si) < MIN32_SI || (si) > MAX32_SI)
#define bit64_ui(si) ((ui) > MAX32_UI)
#ifdef STK_DEBUG
void mpz_trace_bignum(char *msg, mpz_t bn)
{
char *buffer = alloca(mp_radix_size(bn, 10) + 10);
mp_toradix(bn, (unsigned char *)buffer, 10);
fprintf(stderr, " [%s] ", buffer);
fprintf(stderr, "%s[%s] ", msg, buffer);
}
#endif
static void lowerstring(char *str)
{
while (*str) {
......@@ -74,29 +86,39 @@ void mpz_init_set(mpz_t bn1, mpz_t bn2)
mp_init(bn1);
mp_copy(bn2, bn1);
}
#endif
void mpz_init_set_si(mpz_t bn, signed long int si)
{
mp_init(bn);
mp_set_int(bn, (long) si);
if (bit64_si(si)) {
char buffer[MAXBUF];
snprintf(buffer, MAXBUF, "%ld", si);
mpz_init_set_str(bn, buffer, 10L);
} else {
mp_init(bn);
mp_set_int(bn, (long) si);
}
}
#endif
int mpz_init_set_str(mpz_t bn, char *s, long base)
{
mp_init(bn);
return (mp_read_radix(bn, (unsigned char *) s, (int) base) == MP_YES)? 0 : -1;
}
void mpz_init_set_ui(mpz_t bn, unsigned long int ui)
{
char buffer[100];
char buffer[MAXBUF];
snprintf(buffer, 100, "%ld", ui);
snprintf(buffer, MAXBUF, "%lu", ui);
mpz_init_set_str(bn, buffer, 10L);
}
int mpz_init_set_str(mpz_t bn, char *s, long base)
{
mp_init(bn);
return (mp_read_radix(bn, (unsigned char *) s, (int) base) == MP_YES)? 0 : -1;
}
/* ----------------------------------------------------------------------
* Free
* ---------------------------------------------------------------------- */
......@@ -113,18 +135,18 @@ void mpz_clear(mpz_t bn)
* ---------------------------------------------------------------------- */
signed long int mpz_get_si(mpz_t bn)
{
char buffer[100];
char buffer[MAXBUF];
mp_toradix(bn, (unsigned char *)buffer, 10);
return atol(buffer);
return strtol(buffer, NULL, 10);
}
unsigned long int mpz_get_ui(mpz_t bn)
{
char buffer[100];
char buffer[MAXBUF];
mp_toradix(bn, (unsigned char *)buffer, 10);
return atof(buffer);
return strtoul(buffer, NULL,10);
}
......@@ -144,11 +166,6 @@ char *mpz_get_str(char *str, int base, mpz_t bn)
* Comparison
* ---------------------------------------------------------------------- */
#ifndef GMP_USE_MACROS
int mpz_cmp_si(mpz_t bn, long v)
{
return mp_cmp_int(bn, v);
}
int mpz_cmp(mpz_t a, mpz_t b)
{
return mp_cmp(a, b);
......@@ -161,18 +178,41 @@ int mpz_sgn(mpz_t a)
#endif
int mpz_cmp_ui(mpz_t bn, unsigned long int ui)
int mpz_cmp_si(mpz_t bn, signed long si)
{
char buffer[100];
mpz_t tmp;
int res;
if (bit64_si(si)) {
char buffer[MAXBUF];
mpz_t tmp;
int res;
snprintf(buffer, MAXBUF, "%ld", si);
mpz_init_set_str(tmp, buffer, 10);
res = mp_cmp(bn, tmp);
mp_clear(tmp);
return res;
} else {
return mp_cmp_int(bn, si);
}
}
snprintf(buffer, 100, "%ld", ui);
mpz_init_set_str(tmp, buffer, 10);
res = mp_cmp(bn, tmp);
mp_clear(tmp);
return res;
int mpz_cmp_ui(mpz_t bn, unsigned long int ui)
{
if (ui > (unsigned long int) MAX32_SI) {
char buffer[MAXBUF];
mpz_t tmp;
int res;
snprintf(buffer, MAXBUF, "%lu", ui);
mpz_init_set_str(tmp, buffer, 10);
res = mp_cmp(bn, tmp);
mp_clear(tmp);
return res;
} else {
/* this is a small unsigned value, we can use signed comparison */
return mp_cmp_int(bn, (signed long int) ui);
}
}
/* ----------------------------------------------------------------------
......
......@@ -21,7 +21,7 @@
*
* Author: Erick Gallesio [eg@unice.fr]
* Creation date: 12-Oct-2009 19:29 (eg)
* Last file update: 26-Oct-2009 19:54 (eg)
* Last file update: 28-Oct-2009 10:10 (eg)
*/
......@@ -53,14 +53,12 @@ void mp_set_memory_functions(void *(*allocate) (size_t),
#ifndef GMP_USE_MACROS
void mpz_init(mpz_t bn);
void mpz_init_set(mpz_t bn1, mpz_t bn2);
void mpz_init_set_si(mpz_t bn, signed long int si);
#else
# define mpz_init(bn) mp_init(bn)
# define mpz_init_set(bn1, bn2) { mp_init(bn1); mp_copy(bn2, bn1); }
# define mpz_init_set_si(bn, si) { mp_init(bn); mp_set_int(bn, (long) si); }
#endif
void mpz_init_set_si(mpz_t bn, signed long int si);
int mpz_init_set_str(mpz_t bn, char *s, long base);
void mpz_init_set_ui(mpz_t bn, unsigned long int ui);
......@@ -84,7 +82,6 @@ char *mpz_get_str(char *str, int base, mpz_t bn);
* Comparison
* ---------------------------------------------------------------------- */
#ifndef GMP_USE_MACROS
int mpz_cmp_si(mpz_t bn, long v);
int mpz_cmp(mpz_t a, mpz_t b);
int mpz_sgn(mpz_t a);
#else
......@@ -92,6 +89,7 @@ int mpz_sgn(mpz_t a);
# define mpz_cmp(a, b) mp_cmp(a, b)
# define mpz_sgn(a) mp_cmp_z(a)
#endif
int mpz_cmp_si(mpz_t bn, signed long v);
int mpz_cmp_ui(mpz_t bn, unsigned long int ui);
/* ----------------------------------------------------------------------
......
......@@ -42,7 +42,24 @@
#define MP_UNDEF -5 /* answer is undefined */
#define MP_LAST_CODE MP_UNDEF
#include "mpi-types.h"
/* ---------------------------------------------------------------------- */
typedef char mp_sign;
typedef unsigned short mp_digit; /* 2 byte type */
typedef unsigned int mp_word; /* 4 byte type */
typedef unsigned int mp_size;
typedef int mp_err;
#define MP_DIGIT_BIT (CHAR_BIT*sizeof(mp_digit))
#define MP_DIGIT_MAX USHRT_MAX
#define MP_WORD_BIT (CHAR_BIT*sizeof(mp_word))
#define MP_WORD_MAX UINT_MAX
#define RADIX (MP_DIGIT_MAX+1)
#define MP_DIGIT_SIZE 2
#define DIGIT_FMT "%04X"
/* ---------------------------------------------------------------------- */
/* Included for compatibility... */
#define DIGIT_BIT MP_DIGIT_BIT
......
/*
* types.c -- Build source of the mpi-types.h file
*
* Copyright 2009 Erick Gallesio - Polytech'Nice-Sophia <eg@unice.fr>
*
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
* USA.
*
* Author: Erick Gallesio [eg@unice.fr]
* Creation date: 27-Oct-2009 21:19 (eg)
* Last file update: 27-Oct-2009 22:03 (eg)
*/
#include <stdio.h>
#include <stdlib.h>
void write_code(char *type1, int len1, char *max1,
char* type2, int len2, char* max2)
{
printf("/* File definitions generated by program. DO NOT edit */\n");
printf("\n");
printf("typedef char mp_sign;\n");
printf("typedef %s mp_digit; /* %d byte type */\n", type1, len1);
printf("typedef %s mp_word; /* %d byte type */\n", type2, len2);
printf("typedef unsigned int mp_size;\n");
printf("typedef int mp_err;\n");
printf("\n");
printf("#define MP_DIGIT_BIT (CHAR_BIT*sizeof(mp_digit))\n");
printf("#define MP_DIGIT_MAX %s\n", max1);
printf("#define MP_WORD_BIT (CHAR_BIT*sizeof(mp_word))\n");
printf("#define MP_WORD_MAX %s\n", max2);
printf("\n");
printf("#define RADIX (MP_DIGIT_MAX+1)\n");
printf("\n");
printf("#define MP_DIGIT_SIZE %d\n", len1);
printf("#define DIGIT_FMT \"%%0%dX\"\n", len2);
}
void generate_file(int ch, int sh, int in , int lo)
{
if ((ch == 1) && (sh == 2) && (in == 4) && (lo == 4)) {
/* Classical 32 bits */
write_code("unsigned short", 2, "USHRT_MAX",
"unsigned int", 4, "UINT_MAX");
}
else if ((ch == 1) && (sh == 2) && (in == 4) && (lo == 8)) {
/* Classical 64 bits */
write_code("unsigned int", 4, "UINT_MAX",
"unsigned long", 8, "ULONG_MAX");
}
else {
fprintf(stderr, "Cannot produce code for %d %d %d %d\n", ch, sh, in, lo);
exit(1);
}
}
int main()
{
generate_file(sizeof(unsigned char),
sizeof(unsigned short),
sizeof(unsigned int),
sizeof(unsigned long));
return 0;
}
......@@ -21,7 +21,7 @@
*
* Author: Erick Gallesio [eg@kaolin.unice.fr]
* Creation date: 12-May-1993 10:34
* Last file update: 20-Oct-2009 23:20 (eg)
* Last file update: 27-Oct-2009 23:02 (eg)
*/
......@@ -3100,12 +3100,6 @@ int STk_init_number(void)
ADD_PRIMITIVE(decode_float);
//! ADD_PRIMITIVE(bit_or);
//! ADD_PRIMITIVE(bit_and);
//! ADD_PRIMITIVE(bit_xor);
//! ADD_PRIMITIVE(bit_rshift);
//! ADD_PRIMITIVE(bit_lshift);
/* Add parameter for float numbers precision */
STk_make_C_parameter("real-precision",
MAKE_INT(real_precision),
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment