From 9d13fb2413921c713f83efe331e8e4d219c62c6b Mon Sep 17 00:00:00 2001 From: Ulrich Drepper Date: Wed, 14 Dec 2005 15:06:39 +0000 Subject: Moved to csu/errno-loc.c. --- stdlib/getcontext.c | 32 +++ stdlib/getenv.c | 98 +++++++++ stdlib/inlines.c | 3 + stdlib/labs.c | 29 +++ stdlib/ldbl2mpn.c | 1 + stdlib/ldiv.c | 54 +++++ stdlib/llabs.c | 31 +++ stdlib/lldiv.c | 57 ++++++ stdlib/lshift.c | 87 ++++++++ stdlib/makecontext.c | 30 +++ stdlib/mod_1.c | 197 ++++++++++++++++++ stdlib/mp_clz_tab.c | 37 ++++ stdlib/mpn2dbl.c | 30 +++ stdlib/mpn2flt.c | 30 +++ stdlib/mpn2ldbl.c | 1 + stdlib/mul.c | 152 ++++++++++++++ stdlib/mul_1.c | 59 ++++++ stdlib/mul_n.c | 401 ++++++++++++++++++++++++++++++++++++ stdlib/putenv.c | 72 +++++++ stdlib/rshift.c | 88 ++++++++ stdlib/setcontext.c | 32 +++ stdlib/setenv.c | 353 ++++++++++++++++++++++++++++++++ stdlib/strtoimax.c | 1 + stdlib/strtol.c | 111 ++++++++++ stdlib/strtol_l.c | 557 +++++++++++++++++++++++++++++++++++++++++++++++++++ stdlib/strtold_l.c | 58 ++++++ stdlib/strtoll.c | 34 ++++ stdlib/strtoll_l.c | 28 +++ stdlib/strtoul.c | 21 ++ stdlib/strtoul_l.c | 28 +++ stdlib/strtoull.c | 34 ++++ stdlib/strtoull_l.c | 29 +++ stdlib/strtoumax.c | 1 + stdlib/sub_n.c | 62 ++++++ stdlib/submul_1.c | 65 ++++++ stdlib/swapcontext.c | 33 +++ stdlib/system.c | 38 ++++ stdlib/udiv_qrnnd.c | 10 + stdlib/wcstoimax.c | 1 + stdlib/wcstoumax.c | 1 + 40 files changed, 2986 insertions(+) create mode 100644 stdlib/getcontext.c create mode 100644 stdlib/getenv.c create mode 100644 stdlib/inlines.c create mode 100644 stdlib/labs.c create mode 100644 stdlib/ldbl2mpn.c create mode 100644 stdlib/ldiv.c create mode 100644 stdlib/llabs.c create mode 100644 stdlib/lldiv.c create mode 100644 stdlib/lshift.c create mode 100644 stdlib/makecontext.c create mode 100644 stdlib/mod_1.c create mode 100644 stdlib/mp_clz_tab.c create mode 100644 stdlib/mpn2dbl.c create mode 100644 stdlib/mpn2flt.c create mode 100644 stdlib/mpn2ldbl.c create mode 100644 stdlib/mul.c create mode 100644 stdlib/mul_1.c create mode 100644 stdlib/mul_n.c create mode 100644 stdlib/putenv.c create mode 100644 stdlib/rshift.c create mode 100644 stdlib/setcontext.c create mode 100644 stdlib/setenv.c create mode 100644 stdlib/strtoimax.c create mode 100644 stdlib/strtol.c create mode 100644 stdlib/strtol_l.c create mode 100644 stdlib/strtold_l.c create mode 100644 stdlib/strtoll.c create mode 100644 stdlib/strtoll_l.c create mode 100644 stdlib/strtoul.c create mode 100644 stdlib/strtoul_l.c create mode 100644 stdlib/strtoull.c create mode 100644 stdlib/strtoull_l.c create mode 100644 stdlib/strtoumax.c create mode 100644 stdlib/sub_n.c create mode 100644 stdlib/submul_1.c create mode 100644 stdlib/swapcontext.c create mode 100644 stdlib/system.c create mode 100644 stdlib/udiv_qrnnd.c create mode 100644 stdlib/wcstoimax.c create mode 100644 stdlib/wcstoumax.c (limited to 'stdlib') diff --git a/stdlib/getcontext.c b/stdlib/getcontext.c new file mode 100644 index 0000000000..e417575a58 --- /dev/null +++ b/stdlib/getcontext.c @@ -0,0 +1,32 @@ +/* Copyright (C) 1998 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#include +#include + +int +getcontext (ucp) + ucontext_t *ucp; +{ + __set_errno (ENOSYS); + return -1; +} + + +stub_warning (getcontext) +#include diff --git a/stdlib/getenv.c b/stdlib/getenv.c new file mode 100644 index 0000000000..6cdfe2b266 --- /dev/null +++ b/stdlib/getenv.c @@ -0,0 +1,98 @@ +/* Copyright (C) 1991,92,94,96,98,99,2002,2005 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#include +#include +#include +#include +#include +#include + + +/* Return the value of the environment variable NAME. This implementation + is tuned a bit in that it assumes no environment variable has an empty + name which of course should always be true. We have a special case for + one character names so that for the general case we can assume at least + two characters which we can access. By doing this we can avoid using the + `strncmp' most of the time. */ +char * +getenv (name) + const char *name; +{ + size_t len = strlen (name); + char **ep; + uint16_t name_start; + + if (__environ == NULL || name[0] == '\0') + return NULL; + + if (name[1] == '\0') + { + /* The name of the variable consists of only one character. Therefore + the first two characters of the environment entry are this character + and a '=' character. */ +#if __BYTE_ORDER == __LITTLE_ENDIAN || !_STRING_ARCH_unaligned + name_start = ('=' << 8) | *(const unsigned char *) name; +#else +# if __BYTE_ORDER == __BIG_ENDIAN + name_start = '=' | ((*(const unsigned char *) name) << 8); +# else + #error "Funny byte order." +# endif +#endif + for (ep = __environ; *ep != NULL; ++ep) + { +#if _STRING_ARCH_unaligned + uint16_t ep_start = *(uint16_t *) *ep; +#else + uint16_t ep_start = (((unsigned char *) *ep)[0] + | (((unsigned char *) *ep)[1] << 8)); +#endif + if (name_start == ep_start) + return &(*ep)[2]; + } + } + else + { +#if _STRING_ARCH_unaligned + name_start = *(const uint16_t *) name; +#else + name_start = (((const unsigned char *) name)[0] + | (((const unsigned char *) name)[1] << 8)); +#endif + len -= 2; + name += 2; + + for (ep = __environ; *ep != NULL; ++ep) + { +#if _STRING_ARCH_unaligned + uint16_t ep_start = *(uint16_t *) *ep; +#else + uint16_t ep_start = (((unsigned char *) *ep)[0] + | (((unsigned char *) *ep)[1] << 8)); +#endif + + if (name_start == ep_start && !strncmp (*ep + 2, name, len) + && (*ep)[len + 2] == '=') + return &(*ep)[len + 3]; + } + } + + return NULL; +} +libc_hidden_def (getenv) diff --git a/stdlib/inlines.c b/stdlib/inlines.c new file mode 100644 index 0000000000..5f1065ea13 --- /dev/null +++ b/stdlib/inlines.c @@ -0,0 +1,3 @@ +#define _FORCE_INLINES +#define _EXTERN_INLINE /* empty */ +#include diff --git a/stdlib/labs.c b/stdlib/labs.c new file mode 100644 index 0000000000..c568e44454 --- /dev/null +++ b/stdlib/labs.c @@ -0,0 +1,29 @@ +/* Copyright (C) 1991, 1997 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#include + +#undef labs + + +/* Return the absolute value of I. */ +long int +labs (long int i) +{ + return i < 0 ? -i : i; +} diff --git a/stdlib/ldbl2mpn.c b/stdlib/ldbl2mpn.c new file mode 100644 index 0000000000..450f9381cc --- /dev/null +++ b/stdlib/ldbl2mpn.c @@ -0,0 +1 @@ +/* Empty. Not needed unless ldbl support is in. */ diff --git a/stdlib/ldiv.c b/stdlib/ldiv.c new file mode 100644 index 0000000000..a7796d8e95 --- /dev/null +++ b/stdlib/ldiv.c @@ -0,0 +1,54 @@ +/* Copyright (C) 1992, 1997 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#include + + +/* Return the `ldiv_t' representation of NUMER over DENOM. */ +ldiv_t +ldiv (long int numer, long int denom) +{ + ldiv_t result; + + result.quot = numer / denom; + result.rem = numer % denom; + + /* The ANSI standard says that |QUOT| <= |NUMER / DENOM|, where + NUMER / DENOM is to be computed in infinite precision. In + other words, we should always truncate the quotient towards + zero, never -infinity. Machine division and remainer may + work either way when one or both of NUMER or DENOM is + negative. If only one is negative and QUOT has been + truncated towards -infinity, REM will have the same sign as + DENOM and the opposite sign of NUMER; if both are negative + and QUOT has been truncated towards -infinity, REM will be + positive (will have the opposite sign of NUMER). These are + considered `wrong'. If both are NUM and DENOM are positive, + RESULT will always be positive. This all boils down to: if + NUMER >= 0, but REM < 0, we got the wrong answer. In that + case, to get the right answer, add 1 to QUOT and subtract + DENOM from REM. */ + + if (numer >= 0 && result.rem < 0) + { + ++result.quot; + result.rem -= denom; + } + + return result; +} diff --git a/stdlib/llabs.c b/stdlib/llabs.c new file mode 100644 index 0000000000..b15c347d32 --- /dev/null +++ b/stdlib/llabs.c @@ -0,0 +1,31 @@ +/* `long long int' absolute value. + Copyright (C) 1991, 1996, 1997 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#include + +#undef llabs + + +/* Return the absolute value of I. */ +long long int +llabs (i) + long long int i; +{ + return i < 0 ? -i : i; +} diff --git a/stdlib/lldiv.c b/stdlib/lldiv.c new file mode 100644 index 0000000000..28a016b744 --- /dev/null +++ b/stdlib/lldiv.c @@ -0,0 +1,57 @@ +/* `long long int' divison with remainder. + Copyright (C) 1992, 1996, 1997 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#include + + +/* Return the `lldiv_t' representation of NUMER over DENOM. */ +lldiv_t +lldiv (numer, denom) + long long int numer; + long long int denom; +{ + lldiv_t result; + + result.quot = numer / denom; + result.rem = numer % denom; + + /* The ANSI standard says that |QUOT| <= |NUMER / DENOM|, where + NUMER / DENOM is to be computed in infinite precision. In + other words, we should always truncate the quotient towards + zero, never -infinity. Machine division and remainer may + work either way when one or both of NUMER or DENOM is + negative. If only one is negative and QUOT has been + truncated towards -infinity, REM will have the same sign as + DENOM and the opposite sign of NUMER; if both are negative + and QUOT has been truncated towards -infinity, REM will be + positive (will have the opposite sign of NUMER). These are + considered `wrong'. If both are NUM and DENOM are positive, + RESULT will always be positive. This all boils down to: if + NUMER >= 0, but REM < 0, we got the wrong answer. In that + case, to get the right answer, add 1 to QUOT and subtract + DENOM from REM. */ + + if (numer >= 0 && result.rem < 0) + { + ++result.quot; + result.rem -= denom; + } + + return result; +} diff --git a/stdlib/lshift.c b/stdlib/lshift.c new file mode 100644 index 0000000000..bedf44229f --- /dev/null +++ b/stdlib/lshift.c @@ -0,0 +1,87 @@ +/* mpn_lshift -- Shift left low level. + +Copyright (C) 1991, 1993, 1994, 1996 Free Software Foundation, Inc. + +This file is part of the GNU MP Library. + +The GNU MP Library is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 2.1 of the License, or (at your +option) any later version. + +The GNU MP Library 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 Lesser General Public +License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with the GNU MP Library; see the file COPYING.LIB. If not, write to +the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, +MA 02111-1307, USA. */ + +#include +#include "gmp-impl.h" + +/* Shift U (pointed to by UP and USIZE digits long) CNT bits to the left + and store the USIZE least significant digits of the result at WP. + Return the bits shifted out from the most significant digit. + + Argument constraints: + 1. 0 < CNT < BITS_PER_MP_LIMB + 2. If the result is to be written over the input, WP must be >= UP. +*/ + +mp_limb_t +#if __STDC__ +mpn_lshift (register mp_ptr wp, + register mp_srcptr up, mp_size_t usize, + register unsigned int cnt) +#else +mpn_lshift (wp, up, usize, cnt) + register mp_ptr wp; + register mp_srcptr up; + mp_size_t usize; + register unsigned int cnt; +#endif +{ + register mp_limb_t high_limb, low_limb; + register unsigned sh_1, sh_2; + register mp_size_t i; + mp_limb_t retval; + +#ifdef DEBUG + if (usize == 0 || cnt == 0) + abort (); +#endif + + sh_1 = cnt; +#if 0 + if (sh_1 == 0) + { + if (wp != up) + { + /* Copy from high end to low end, to allow specified input/output + overlapping. */ + for (i = usize - 1; i >= 0; i--) + wp[i] = up[i]; + } + return 0; + } +#endif + + wp += 1; + sh_2 = BITS_PER_MP_LIMB - sh_1; + i = usize - 1; + low_limb = up[i]; + retval = low_limb >> sh_2; + high_limb = low_limb; + while (--i >= 0) + { + low_limb = up[i]; + wp[i] = (high_limb << sh_1) | (low_limb >> sh_2); + high_limb = low_limb; + } + wp[i] = high_limb << sh_1; + + return retval; +} diff --git a/stdlib/makecontext.c b/stdlib/makecontext.c new file mode 100644 index 0000000000..a65868827f --- /dev/null +++ b/stdlib/makecontext.c @@ -0,0 +1,30 @@ +/* Copyright (C) 1998 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#include +#include + +void +makecontext (ucontext_t *ucp, void (*func) (void), int argc, ...) +{ + __set_errno (ENOSYS); +} + + +stub_warning (makecontext) +#include diff --git a/stdlib/mod_1.c b/stdlib/mod_1.c new file mode 100644 index 0000000000..3273c9222d --- /dev/null +++ b/stdlib/mod_1.c @@ -0,0 +1,197 @@ +/* mpn_mod_1(dividend_ptr, dividend_size, divisor_limb) -- + Divide (DIVIDEND_PTR,,DIVIDEND_SIZE) by DIVISOR_LIMB. + Return the single-limb remainder. + There are no constraints on the value of the divisor. + +Copyright (C) 1991, 1993, 1994, Free Software Foundation, Inc. + +This file is part of the GNU MP Library. + +The GNU MP Library is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 2.1 of the License, or (at your +option) any later version. + +The GNU MP Library 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 Lesser General Public +License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with the GNU MP Library; see the file COPYING.LIB. If not, write to +the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, +MA 02111-1307, USA. */ + +#include +#include "gmp-impl.h" +#include "longlong.h" + +#ifndef UMUL_TIME +#define UMUL_TIME 1 +#endif + +#ifndef UDIV_TIME +#define UDIV_TIME UMUL_TIME +#endif + +/* FIXME: We should be using invert_limb (or invert_normalized_limb) + here (not udiv_qrnnd). */ + +mp_limb_t +#if __STDC__ +mpn_mod_1 (mp_srcptr dividend_ptr, mp_size_t dividend_size, + mp_limb_t divisor_limb) +#else +mpn_mod_1 (dividend_ptr, dividend_size, divisor_limb) + mp_srcptr dividend_ptr; + mp_size_t dividend_size; + mp_limb_t divisor_limb; +#endif +{ + mp_size_t i; + mp_limb_t n1, n0, r; + int dummy; + + /* Botch: Should this be handled at all? Rely on callers? */ + if (dividend_size == 0) + return 0; + + /* If multiplication is much faster than division, and the + dividend is large, pre-invert the divisor, and use + only multiplications in the inner loop. */ + + /* This test should be read: + Does it ever help to use udiv_qrnnd_preinv? + && Does what we save compensate for the inversion overhead? */ + if (UDIV_TIME > (2 * UMUL_TIME + 6) + && (UDIV_TIME - (2 * UMUL_TIME + 6)) * dividend_size > UDIV_TIME) + { + int normalization_steps; + + count_leading_zeros (normalization_steps, divisor_limb); + if (normalization_steps != 0) + { + mp_limb_t divisor_limb_inverted; + + divisor_limb <<= normalization_steps; + + /* Compute (2**2N - 2**N * DIVISOR_LIMB) / DIVISOR_LIMB. The + result is a (N+1)-bit approximation to 1/DIVISOR_LIMB, with the + most significant bit (with weight 2**N) implicit. */ + + /* Special case for DIVISOR_LIMB == 100...000. */ + if (divisor_limb << 1 == 0) + divisor_limb_inverted = ~(mp_limb_t) 0; + else + udiv_qrnnd (divisor_limb_inverted, dummy, + -divisor_limb, 0, divisor_limb); + + n1 = dividend_ptr[dividend_size - 1]; + r = n1 >> (BITS_PER_MP_LIMB - normalization_steps); + + /* Possible optimization: + if (r == 0 + && divisor_limb > ((n1 << normalization_steps) + | (dividend_ptr[dividend_size - 2] >> ...))) + ...one division less... */ + + for (i = dividend_size - 2; i >= 0; i--) + { + n0 = dividend_ptr[i]; + udiv_qrnnd_preinv (dummy, r, r, + ((n1 << normalization_steps) + | (n0 >> (BITS_PER_MP_LIMB - normalization_steps))), + divisor_limb, divisor_limb_inverted); + n1 = n0; + } + udiv_qrnnd_preinv (dummy, r, r, + n1 << normalization_steps, + divisor_limb, divisor_limb_inverted); + return r >> normalization_steps; + } + else + { + mp_limb_t divisor_limb_inverted; + + /* Compute (2**2N - 2**N * DIVISOR_LIMB) / DIVISOR_LIMB. The + result is a (N+1)-bit approximation to 1/DIVISOR_LIMB, with the + most significant bit (with weight 2**N) implicit. */ + + /* Special case for DIVISOR_LIMB == 100...000. */ + if (divisor_limb << 1 == 0) + divisor_limb_inverted = ~(mp_limb_t) 0; + else + udiv_qrnnd (divisor_limb_inverted, dummy, + -divisor_limb, 0, divisor_limb); + + i = dividend_size - 1; + r = dividend_ptr[i]; + + if (r >= divisor_limb) + r = 0; + else + i--; + + for (; i >= 0; i--) + { + n0 = dividend_ptr[i]; + udiv_qrnnd_preinv (dummy, r, r, + n0, divisor_limb, divisor_limb_inverted); + } + return r; + } + } + else + { + if (UDIV_NEEDS_NORMALIZATION) + { + int normalization_steps; + + count_leading_zeros (normalization_steps, divisor_limb); + if (normalization_steps != 0) + { + divisor_limb <<= normalization_steps; + + n1 = dividend_ptr[dividend_size - 1]; + r = n1 >> (BITS_PER_MP_LIMB - normalization_steps); + + /* Possible optimization: + if (r == 0 + && divisor_limb > ((n1 << normalization_steps) + | (dividend_ptr[dividend_size - 2] >> ...))) + ...one division less... */ + + for (i = dividend_size - 2; i >= 0; i--) + { + n0 = dividend_ptr[i]; + udiv_qrnnd (dummy, r, r, + ((n1 << normalization_steps) + | (n0 >> (BITS_PER_MP_LIMB - normalization_steps))), + divisor_limb); + n1 = n0; + } + udiv_qrnnd (dummy, r, r, + n1 << normalization_steps, + divisor_limb); + return r >> normalization_steps; + } + } + /* No normalization needed, either because udiv_qrnnd doesn't require + it, or because DIVISOR_LIMB is already normalized. */ + + i = dividend_size - 1; + r = dividend_ptr[i]; + + if (r >= divisor_limb) + r = 0; + else + i--; + + for (; i >= 0; i--) + { + n0 = dividend_ptr[i]; + udiv_qrnnd (dummy, r, r, n0, divisor_limb); + } + return r; + } +} diff --git a/stdlib/mp_clz_tab.c b/stdlib/mp_clz_tab.c new file mode 100644 index 0000000000..2220299e7c --- /dev/null +++ b/stdlib/mp_clz_tab.c @@ -0,0 +1,37 @@ +/* __clz_tab -- support for longlong.h + Copyright (C) 1991, 1993, 1994, 1997 Free Software Foundation, Inc. + This file is part of the GNU C Library. Its master source is NOT part of + the C library, however. The master source lives in the GNU MP Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#if 0 +#include +#include "gmp-impl.h" +#endif + +const +unsigned char __clz_tab[] = +{ + 0,1,2,2,3,3,3,3,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5, + 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, + 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, + 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, + 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, +}; diff --git a/stdlib/mpn2dbl.c b/stdlib/mpn2dbl.c new file mode 100644 index 0000000000..178edbf816 --- /dev/null +++ b/stdlib/mpn2dbl.c @@ -0,0 +1,30 @@ +/* Copyright (C) 1995, 1997 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#include +#include "gmp-impl.h" +#include + +/* Convert a multi-precision integer of the needed number of bits and an + integral power of two to a `double'. */ + +double +__mpn_construct_double (mp_srcptr frac_ptr, int expt, int negative) +{ +#error "__mpn_construct_double not implemented for this floating point format" +} diff --git a/stdlib/mpn2flt.c b/stdlib/mpn2flt.c new file mode 100644 index 0000000000..16ec73c174 --- /dev/null +++ b/stdlib/mpn2flt.c @@ -0,0 +1,30 @@ +/* Copyright (C) 1995, 1997 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#include "gmp.h" +#include "gmp-impl.h" +#include + +/* Convert a multi-precision integer of the needed number of bits and an + integral power of two to a `float'. */ + +float +__mpn_construct_float (mp_srcptr frac_ptr, int expt, int negative) +{ +#error "__mpn_construct_float not implemented for this floating point format" +} diff --git a/stdlib/mpn2ldbl.c b/stdlib/mpn2ldbl.c new file mode 100644 index 0000000000..450f9381cc --- /dev/null +++ b/stdlib/mpn2ldbl.c @@ -0,0 +1 @@ +/* Empty. Not needed unless ldbl support is in. */ diff --git a/stdlib/mul.c b/stdlib/mul.c new file mode 100644 index 0000000000..fe0cbf3d7f --- /dev/null +++ b/stdlib/mul.c @@ -0,0 +1,152 @@ +/* mpn_mul -- Multiply two natural numbers. + +Copyright (C) 1991, 1993, 1994, 1996 Free Software Foundation, Inc. + +This file is part of the GNU MP Library. + +The GNU MP Library is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 2.1 of the License, or (at your +option) any later version. + +The GNU MP Library 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 Lesser General Public +License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with the GNU MP Library; see the file COPYING.LIB. If not, write to +the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, +MA 02111-1307, USA. */ + +#include +#include "gmp-impl.h" + +/* Multiply the natural numbers u (pointed to by UP, with USIZE limbs) + and v (pointed to by VP, with VSIZE limbs), and store the result at + PRODP. USIZE + VSIZE limbs are always stored, but if the input + operands are normalized. Return the most significant limb of the + result. + + NOTE: The space pointed to by PRODP is overwritten before finished + with U and V, so overlap is an error. + + Argument constraints: + 1. USIZE >= VSIZE. + 2. PRODP != UP and PRODP != VP, i.e. the destination + must be distinct from the multiplier and the multiplicand. */ + +/* If KARATSUBA_THRESHOLD is not already defined, define it to a + value which is good on most machines. */ +#ifndef KARATSUBA_THRESHOLD +#define KARATSUBA_THRESHOLD 32 +#endif + +mp_limb_t +#if __STDC__ +mpn_mul (mp_ptr prodp, + mp_srcptr up, mp_size_t usize, + mp_srcptr vp, mp_size_t vsize) +#else +mpn_mul (prodp, up, usize, vp, vsize) + mp_ptr prodp; + mp_srcptr up; + mp_size_t usize; + mp_srcptr vp; + mp_size_t vsize; +#endif +{ + mp_ptr prod_endp = prodp + usize + vsize - 1; + mp_limb_t cy; + mp_ptr tspace; + TMP_DECL (marker); + + if (vsize < KARATSUBA_THRESHOLD) + { + /* Handle simple cases with traditional multiplication. + + This is the most critical code of the entire function. All + multiplies rely on this, both small and huge. Small ones arrive + here immediately. Huge ones arrive here as this is the base case + for Karatsuba's recursive algorithm below. */ + mp_size_t i; + mp_limb_t cy_limb; + mp_limb_t v_limb; + + if (vsize == 0) + return 0; + + /* Multiply by the first limb in V separately, as the result can be + stored (not added) to PROD. We also avoid a loop for zeroing. */ + v_limb = vp[0]; + if (v_limb <= 1) + { + if (v_limb == 1) + MPN_COPY (prodp, up, usize); + else + MPN_ZERO (prodp, usize); + cy_limb = 0; + } + else + cy_limb = mpn_mul_1 (prodp, up, usize, v_limb); + + prodp[usize] = cy_limb; + prodp++; + + /* For each iteration in the outer loop, multiply one limb from + U with one limb from V, and add it to PROD. */ + for (i = 1; i < vsize; i++) + { + v_limb = vp[i]; + if (v_limb <= 1) + { + cy_limb = 0; + if (v_limb == 1) + cy_limb = mpn_add_n (prodp, prodp, up, usize); + } + else + cy_limb = mpn_addmul_1 (prodp, up, usize, v_limb); + + prodp[usize] = cy_limb; + prodp++; + } + return cy_limb; + } + + TMP_MARK (marker); + + tspace = (mp_ptr) TMP_ALLOC (2 * vsize * BYTES_PER_MP_LIMB); + MPN_MUL_N_RECURSE (prodp, up, vp, vsize, tspace); + + prodp += vsize; + up += vsize; + usize -= vsize; + if (usize >= vsize) + { + mp_ptr tp = (mp_ptr) TMP_ALLOC (2 * vsize * BYTES_PER_MP_LIMB); + do + { + MPN_MUL_N_RECURSE (tp, up, vp, vsize, tspace); + cy = mpn_add_n (prodp, prodp, tp, vsize); + mpn_add_1 (prodp + vsize, tp + vsize, vsize, cy); + prodp += vsize; + up += vsize; + usize -= vsize; + } + while (usize >= vsize); + } + + /* True: usize < vsize. */ + + /* Make life simple: Recurse. */ + + if (usize != 0) + { + mpn_mul (tspace, vp, vsize, up, usize); + cy = mpn_add_n (prodp, prodp, tspace, vsize); + mpn_add_1 (prodp + vsize, tspace + vsize, usize, cy); + } + + TMP_FREE (marker); + return *prod_endp; +} diff --git a/stdlib/mul_1.c b/stdlib/mul_1.c new file mode 100644 index 0000000000..686e6c5efe --- /dev/null +++ b/stdlib/mul_1.c @@ -0,0 +1,59 @@ +/* mpn_mul_1 -- Multiply a limb vector with a single limb and + store the product in a second limb vector. + +Copyright (C) 1991, 1992, 1993, 1994, 1996 Free Software Foundation, Inc. + +This file is part of the GNU MP Library. + +The GNU MP Library is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 2.1 of the License, or (at your +option) any later version. + +The GNU MP Library 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 Lesser General Public +License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with the GNU MP Library; see the file COPYING.LIB. If not, write to +the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, +MA 02111-1307, USA. */ + +#include +#include "gmp-impl.h" +#include "longlong.h" + +mp_limb_t +mpn_mul_1 (res_ptr, s1_ptr, s1_size, s2_limb) + register mp_ptr res_ptr; + register mp_srcptr s1_ptr; + mp_size_t s1_size; + register mp_limb_t s2_limb; +{ + register mp_limb_t cy_limb; + register mp_size_t j; + register mp_limb_t prod_high, prod_low; + + /* The loop counter and index J goes from -S1_SIZE to -1. This way + the loop becomes faster. */ + j = -s1_size; + + /* Offset the base pointers to compensate for the negative indices. */ + s1_ptr -= j; + res_ptr -= j; + + cy_limb = 0; + do + { + umul_ppmm (prod_high, prod_low, s1_ptr[j], s2_limb); + + prod_low += cy_limb; + cy_limb = (prod_low < cy_limb) + prod_high; + + res_ptr[j] = prod_low; + } + while (++j != 0); + + return cy_limb; +} diff --git a/stdlib/mul_n.c b/stdlib/mul_n.c new file mode 100644 index 0000000000..b478c76aba --- /dev/null +++ b/stdlib/mul_n.c @@ -0,0 +1,401 @@ +/* mpn_mul_n -- Multiply two natural numbers of length n. + +Copyright (C) 1991, 1992, 1993, 1994, 1996 Free Software Foundation, Inc. + +This file is part of the GNU MP Library. + +The GNU MP Library is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 2.1 of the License, or (at your +option) any later version. + +The GNU MP Library 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 Lesser General Public +License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with the GNU MP Library; see the file COPYING.LIB. If not, write to +the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, +MA 02111-1307, USA. */ + +#include +#include "gmp-impl.h" + +/* Multiply the natural numbers u (pointed to by UP) and v (pointed to by VP), + both with SIZE limbs, and store the result at PRODP. 2 * SIZE limbs are + always stored. Return the most significant limb. + + Argument constraints: + 1. PRODP != UP and PRODP != VP, i.e. the destination + must be distinct from the multiplier and the multiplicand. */ + +/* If KARATSUBA_THRESHOLD is not already defined, define it to a + value which is good on most machines. */ +#ifndef KARATSUBA_THRESHOLD +#define KARATSUBA_THRESHOLD 32 +#endif + +/* The code can't handle KARATSUBA_THRESHOLD smaller than 2. */ +#if KARATSUBA_THRESHOLD < 2 +#undef KARATSUBA_THRESHOLD +#define KARATSUBA_THRESHOLD 2 +#endif + +/* Handle simple cases with traditional multiplication. + + This is the most critical code of multiplication. All multiplies rely + on this, both small and huge. Small ones arrive here immediately. Huge + ones arrive here as this is the base case for Karatsuba's recursive + algorithm below. */ + +void +#if __STDC__ +impn_mul_n_basecase (mp_ptr prodp, mp_srcptr up, mp_srcptr vp, mp_size_t size) +#else +impn_mul_n_basecase (prodp, up, vp, size) + mp_ptr prodp; + mp_srcptr up; + mp_srcptr vp; + mp_size_t size; +#endif +{ + mp_size_t i; + mp_limb_t cy_limb; + mp_limb_t v_limb; + + /* Multiply by the first limb in V separately, as the result can be + stored (not added) to PROD. We also avoid a loop for zeroing. */ + v_limb = vp[0]; + if (v_limb <= 1) + { + if (v_limb == 1) + MPN_COPY (prodp, up, size); + else + MPN_ZERO (prodp, size); + cy_limb = 0; + } + else + cy_limb = mpn_mul_1 (prodp, up, size, v_limb); + + prodp[size] = cy_limb; + prodp++; + + /* For each iteration in the outer loop, multiply one limb from + U with one limb from V, and add it to PROD. */ + for (i = 1; i < size; i++) + { + v_limb = vp[i]; + if (v_limb <= 1) + { + cy_limb = 0; + if (v_limb == 1) + cy_limb = mpn_add_n (prodp, prodp, up, size); + } + else + cy_limb = mpn_addmul_1 (prodp, up, size, v_limb); + + prodp[size] = cy_limb; + prodp++; + } +} + +void +#if __STDC__ +impn_mul_n (mp_ptr prodp, + mp_srcptr up, mp_srcptr vp, mp_size_t size, mp_ptr tspace) +#else +impn_mul_n (prodp, up, vp, size, tspace) + mp_ptr prodp; + mp_srcptr up; + mp_srcptr vp; + mp_size_t size; + mp_ptr tspace; +#endif +{ + if ((size & 1) != 0) + { + /* The size is odd, the code code below doesn't handle that. + Multiply the least significant (size - 1) limbs with a recursive + call, and handle the most significant limb of S1 and S2 + separately. */ + /* A slightly faster way to do this would be to make the Karatsuba + code below behave as if the size were even, and let it check for + odd size in the end. I.e., in essence move this code to the end. + Doing so would save us a recursive call, and potentially make the + stack grow a lot less. */ + + mp_size_t esize = size - 1; /* even size */ + mp_limb_t cy_limb; + + MPN_MUL_N_RECURSE (prodp, up, vp, esize, tspace); + cy_limb = mpn_addmul_1 (prodp + esize, up, esize, vp[esize]); + prodp[esize + esize] = cy_limb; + cy_limb = mpn_addmul_1 (prodp + esize, vp, size, up[esize]); + + prodp[esize + size] = cy_limb; + } + else + { + /* Anatolij Alekseevich Karatsuba's divide-and-conquer algorithm. + + Split U in two pieces, U1 and U0, such that + U = U0 + U1*(B**n), + and V in V1 and V0, such that + V = V0 + V1*(B**n). + + UV is then computed recursively using the identity + + 2n n n n + UV = (B + B )U V + B (U -U )(V -V ) + (B + 1)U V + 1 1 1 0 0 1 0 0 + + Where B = 2**BITS_PER_MP_LIMB. */ + + mp_size_t hsize = size >> 1; + mp_limb_t cy; + int negflg; + + /*** Product H. ________________ ________________ + |_____U1 x V1____||____U0 x V0_____| */ + /* Put result in upper part of PROD and pass low part of TSPACE + as new TSPACE. */ + MPN_MUL_N_RECURSE (prodp + size, up + hsize, vp + hsize, hsize, tspace); + + /*** Product M. ________________ + |_(U1-U0)(V0-V1)_| */ + if (mpn_cmp (up + hsize, up, hsize) >= 0) + { + mpn_sub_n (prodp, up + hsize, up, hsize); + negflg = 0; + } + else + { + mpn_sub_n (prodp, up, up + hsize, hsize); + negflg = 1; + } + if (mpn_cmp (vp + hsize, vp, hsize) >= 0) + { + mpn_sub_n (prodp + hsize, vp + hsize, vp, hsize); + negflg ^= 1; + } + else + { + mpn_sub_n (prodp + hsize, vp, vp + hsize, hsize); + /* No change of NEGFLG. */ + } + /* Read temporary operands from low part of PROD. + Put result in low part of TSPACE using upper part of TSPACE + as new TSPACE. */ + MPN_MUL_N_RECURSE (tspace, prodp, prodp + hsize, hsize, tspace + size); + + /*** Add/copy product H. */ + MPN_COPY (prodp + hsize, prodp + size, hsize); + cy = mpn_add_n (prodp + size, prodp + size, prodp + size + hsize, hsize); + + /*** Add product M (if NEGFLG M is a negative number). */ + if (negflg) + cy -= mpn_sub_n (prodp + hsize, prodp + hsize, tspace, size); + else + cy += mpn_add_n (prodp + hsize, prodp + hsize, tspace, size); + + /*** Product L. ________________ ________________ + |________________||____U0 x V0_____| */ + /* Read temporary operands from low part of PROD. + Put result in low part of TSPACE using upper part of TSPACE + as new TSPACE. */ + MPN_MUL_N_RECURSE (tspace, up, vp, hsize, tspace + size); + + /*** Add/copy Product L (twice). */ + + cy += mpn_add_n (prodp + hsize, prodp + hsize, tspace, size); + if (cy) + mpn_add_1 (prodp + hsize + size, prodp + hsize + size, hsize, cy); + + MPN_COPY (prodp, tspace, hsize); + cy = mpn_add_n (prodp + hsize, prodp + hsize, tspace + hsize, hsize); + if (cy) + mpn_add_1 (prodp + size, prodp + size, size, 1); + } +} + +void +#if __STDC__ +impn_sqr_n_basecase (mp_ptr prodp, mp_srcptr up, mp_size_t size) +#else +impn_sqr_n_basecase (prodp, up, size) + mp_ptr prodp; + mp_srcptr up; + mp_size_t size; +#endif +{ + mp_size_t i; + mp_limb_t cy_limb; + mp_limb_t v_limb; + + /* Multiply by the first limb in V separately, as the result can be + stored (not added) to PROD. We also avoid a loop for zeroing. */ + v_limb = up[0]; + if (v_limb <= 1) + { + if (v_limb == 1) + MPN_COPY (prodp, up, size); + else + MPN_ZERO (prodp, size); + cy_limb = 0; + } + else + cy_limb = mpn_mul_1 (prodp, up, size, v_limb); + + prodp[size] = cy_limb; + prodp++; + + /* For each iteration in the outer loop, multiply one limb from + U with one limb from V, and add it to PROD. */ + for (i = 1; i < size; i++) + { + v_limb = up[i]; + if (v_limb <= 1) + { + cy_limb = 0; + if (v_limb == 1) + cy_limb = mpn_add_n (prodp, prodp, up, size); + } + else + cy_limb = mpn_addmul_1 (prodp, up, size, v_limb); + + prodp[size] = cy_limb; + prodp++; + } +} + +void +#if __STDC__ +impn_sqr_n (mp_ptr prodp, + mp_srcptr up, mp_size_t size, mp_ptr tspace) +#else +impn_sqr_n (prodp, up, size, tspace) + mp_ptr prodp; + mp_srcptr up; + mp_size_t size; + mp_ptr tspace; +#endif +{ + if ((size & 1) != 0) + { + /* The size is odd, the code code below doesn't handle that. + Multiply the least significant (size - 1) limbs with a recursive + call, and handle the most significant limb of S1 and S2 + separately. */ + /* A slightly faster way to do this would be to make the Karatsuba + code below behave as if the size were even, and let it check for + odd size in the end. I.e., in essence move this code to the end. + Doing so would save us a recursive call, and potentially make the + stack grow a lot less. */ + + mp_size_t esize = size - 1; /* even size */ + mp_limb_t cy_limb; + + MPN_SQR_N_RECURSE (prodp, up, esize, tspace); + cy_limb = mpn_addmul_1 (prodp + esize, up, esize, up[esize]); + prodp[esize + esize] = cy_limb; + cy_limb = mpn_addmul_1 (prodp + esize, up, size, up[esize]); + + prodp[esize + size] = cy_limb; + } + else + { + mp_size_t hsize = size >> 1; + mp_limb_t cy; + + /*** Product H. ________________ ________________ + |_____U1 x U1____||____U0 x U0_____| */ + /* Put result in upper part of PROD and pass low part of TSPACE + as new TSPACE. */ + MPN_SQR_N_RECURSE (prodp + size, up + hsize, hsize, tspace); + + /*** Product M. ________________ + |_(U1-U0)(U0-U1)_| */ + if (mpn_cmp (up + hsize, up, hsize) >= 0) + { + mpn_sub_n (prodp, up + hsize, up, hsize); + } + else + { + mpn_sub_n (prodp, up, up + hsize, hsize); + } + + /* Read temporary operands from low part of PROD. + Put result in low part of TSPACE using upper part of TSPACE + as new TSPACE. */ + MPN_SQR_N_RECURSE (tspace, prodp, hsize, tspace + size); + + /*** Add/copy product H. */ + MPN_COPY (prodp + hsize, prodp + size, hsize); + cy = mpn_add_n (prodp + size, prodp + size, prodp + size + hsize, hsize); + + /*** Add product M (if NEGFLG M is a negative number). */ + cy -= mpn_sub_n (prodp + hsize, prodp + hsize, tspace, size); + + /*** Product L. ________________ ________________ + |________________||____U0 x U0_____| */ + /* Read temporary operands from low part of PROD. + Put result in low part of TSPACE using upper part of TSPACE + as new TSPACE. */ + MPN_SQR_N_RECURSE (tspace, up, hsize, tspace + size); + + /*** Add/copy Product L (twice). */ + + cy += mpn_add_n (prodp + hsize, prodp + hsize, tspace, size); + if (cy) + mpn_add_1 (prodp + hsize + size, prodp + hsize + size, hsize, cy); + + MPN_COPY (prodp, tspace, hsize); + cy = mpn_add_n (prodp + hsize, prodp + hsize, tspace + hsize, hsize); + if (cy) + mpn_add_1 (prodp + size, prodp + size, size, 1); + } +} + +/* This should be made into an inline function in gmp.h. */ +void +#if __STDC__ +mpn_mul_n (mp_ptr prodp, mp_srcptr up, mp_srcptr vp, mp_size_t size) +#else +mpn_mul_n (prodp, up, vp, size) + mp_ptr prodp; + mp_srcptr up; + mp_srcptr vp; + mp_size_t size; +#endif +{ + TMP_DECL (marker); + TMP_MARK (marker); + if (up == vp) + { + if (size < KARATSUBA_THRESHOLD) + { + impn_sqr_n_basecase (prodp, up, size); + } + else + { + mp_ptr tspace; + tspace = (mp_ptr) TMP_ALLOC (2 * size * BYTES_PER_MP_LIMB); + impn_sqr_n (prodp, up, size, tspace); + } + } + else + { + if (size < KARATSUBA_THRESHOLD) + { + impn_mul_n_basecase (prodp, up, vp, size); + } + else + { + mp_ptr tspace; + tspace = (mp_ptr) TMP_ALLOC (2 * size * BYTES_PER_MP_LIMB); + impn_mul_n (prodp, up, vp, size, tspace); + } + } + TMP_FREE (marker); +} diff --git a/stdlib/putenv.c b/stdlib/putenv.c new file mode 100644 index 0000000000..4e8693403a --- /dev/null +++ b/stdlib/putenv.c @@ -0,0 +1,72 @@ +/* Copyright (C) 1991, 94, 95, 96, 97, 98, 99 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#if defined _AIX && !defined __GNUC__ + #pragma alloca +#endif + +#if HAVE_CONFIG_H +# include +#endif + +#if _LIBC || HAVE_STDLIB_H +# include +#endif +#if _LIBC || HAVE_STRING_H +# include +#endif + +#if !__GNU_LIBRARY__ && !HAVE_STRCHR +# define strchr index +#endif + +#ifndef _LIBC +# ifdef HAVE_ALLOCA_H +# include +# else +# ifdef __GNUC__ +# define alloca __builtin_alloca +# else +extern char *alloca (); +# endif /* __GNUC__ */ +# endif /* HAVE_ALLOCA_H */ +#endif /* _LIBC */ + + +/* Put STRING, which is of the form "NAME=VALUE", in the environment. */ +int +putenv (string) + char *string; +{ + const char *const name_end = strchr (string, '='); + + if (name_end != NULL) + { +#ifdef _LIBC + char *name = strndupa (string, name_end - string); +#else + char *name = alloca (name_end - string + 1); + memcpy (name, string, name_end - string); + name[name_end - string] = '\0'; +#endif + return __add_to_environ (name, NULL, string, 1); + } + + __unsetenv (string); + return 0; +} diff --git a/stdlib/rshift.c b/stdlib/rshift.c new file mode 100644 index 0000000000..9d0a9c4c0e --- /dev/null +++ b/stdlib/rshift.c @@ -0,0 +1,88 @@ +/* mpn_rshift -- Shift right a low-level natural-number integer. + +Copyright (C) 1991, 1993, 1994, 1996 Free Software Foundation, Inc. + +This file is part of the GNU MP Library. + +The GNU MP Library is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 2.1 of the License, or (at your +option) any later version. + +The GNU MP Library 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 Lesser General Public +License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with the GNU MP Library; see the file COPYING.LIB. If not, write to +the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, +MA 02111-1307, USA. */ + +#include +#include "gmp-impl.h" + +/* Shift U (pointed to by UP and USIZE limbs long) CNT bits to the right + and store the USIZE least significant limbs of the result at WP. + The bits shifted out to the right are returned. + + Argument constraints: + 1. 0 < CNT < BITS_PER_MP_LIMB + 2. If the result is to be written over the input, WP must be <= UP. +*/ + +mp_limb_t +#if __STDC__ +mpn_rshift (register mp_ptr wp, + register mp_srcptr up, mp_size_t usize, + register unsigned int cnt) +#else +mpn_rshift (wp, up, usize, cnt) + register mp_ptr wp; + register mp_srcptr up; + mp_size_t usize; + register unsigned int cnt; +#endif +{ + register mp_limb_t high_limb, low_limb; + register unsigned sh_1, sh_2; + register mp_size_t i; + mp_limb_t retval; + +#ifdef DEBUG + if (usize == 0 || cnt == 0) + abort (); +#endif + + sh_1 = cnt; + +#if 0 + if (sh_1 == 0) + { + if (wp != up) + { + /* Copy from low end to high end, to allow specified input/output + overlapping. */ + for (i = 0; i < usize; i++) + wp[i] = up[i]; + } + return usize; + } +#endif + + wp -= 1; + sh_2 = BITS_PER_MP_LIMB - sh_1; + high_limb = up[0]; + retval = high_limb << sh_2; + low_limb = high_limb; + + for (i = 1; i < usize; i++) + { + high_limb = up[i]; + wp[i] = (low_limb >> sh_1) | (high_limb << sh_2); + low_limb = high_limb; + } + wp[i] = low_limb >> sh_1; + + return retval; +} diff --git a/stdlib/setcontext.c b/stdlib/setcontext.c new file mode 100644 index 0000000000..5841e20317 --- /dev/null +++ b/stdlib/setcontext.c @@ -0,0 +1,32 @@ +/* Copyright (C) 1998 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#include +#include + +int +setcontext (ucp) + const ucontext_t *ucp; +{ + __set_errno (ENOSYS); + return -1; +} + + +stub_warning (setcontext) +#include diff --git a/stdlib/setenv.c b/stdlib/setenv.c new file mode 100644 index 0000000000..48aaecffe0 --- /dev/null +++ b/stdlib/setenv.c @@ -0,0 +1,353 @@ +/* Copyright (C) 1992,1995-2001,2004 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#if HAVE_CONFIG_H +# include +#endif + +#include +#if !_LIBC +# if !defined errno && !defined HAVE_ERRNO_DECL +extern int errno; +# endif +# define __set_errno(ev) ((errno) = (ev)) +#endif + +#if _LIBC || HAVE_STDLIB_H +# include +#endif +#if _LIBC || HAVE_STRING_H +# include +#endif +#if _LIBC || HAVE_UNISTD_H +# include +#endif + +#if !_LIBC +# define __environ environ +# ifndef HAVE_ENVIRON_DECL +extern char **environ; +# endif +#endif + +#if _LIBC +/* This lock protects against simultaneous modifications of `environ'. */ +# include +__libc_lock_define_initialized (static, envlock) +# define LOCK __libc_lock_lock (envlock) +# define UNLOCK __libc_lock_unlock (envlock) +#else +# define LOCK +# define UNLOCK +#endif + +/* In the GNU C library we must keep the namespace clean. */ +#ifdef _LIBC +# define setenv __setenv +# define unsetenv __unsetenv +# define clearenv __clearenv +# define tfind __tfind +# define tsearch __tsearch +#endif + +/* In the GNU C library implementation we try to be more clever and + allow arbitrarily many changes of the environment given that the used + values are from a small set. Outside glibc this will eat up all + memory after a while. */ +#if defined _LIBC || (defined HAVE_SEARCH_H && defined HAVE_TSEARCH \ + && defined __GNUC__) +# define USE_TSEARCH 1 +# include + +/* This is a pointer to the root of the search tree with the known + values. */ +static void *known_values; + +# define KNOWN_VALUE(Str) \ + ({ \ + void *value = tfind (Str, &known_values, (__compar_fn_t) strcmp); \ + value != NULL ? *(char **) value : NULL; \ + }) +# define STORE_VALUE(Str) \ + tsearch (Str, &known_values, (__compar_fn_t) strcmp) + +#else +# undef USE_TSEARCH + +# define KNOWN_VALUE(Str) NULL +# define STORE_VALUE(Str) do { } while (0) + +#endif + + +/* If this variable is not a null pointer we allocated the current + environment. */ +static char **last_environ; + + +/* This function is used by `setenv' and `putenv'. The difference between + the two functions is that for the former must create a new string which + is then placed in the environment, while the argument of `putenv' + must be used directly. This is all complicated by the fact that we try + to reuse values once generated for a `setenv' call since we can never + free the strings. */ +int +__add_to_environ (name, value, combined, replace) + const char *name; + const char *value; + const char *combined; + int replace; +{ + register char **ep; + register size_t size; + const size_t namelen = strlen (name); + const size_t vallen = value != NULL ? strlen (value) + 1 : 0; + + LOCK; + + /* We have to get the pointer now that we have the lock and not earlier + since another thread might have created a new environment. */ + ep = __environ; + + size = 0; + if (ep != NULL) + { + for (; *ep != NULL; ++ep) + if (!strncmp (*ep, name, namelen) && (*ep)[namelen] == '=') + break; + else + ++size; + } + + if (ep == NULL || __builtin_expect (*ep == NULL, 1)) + { + char **new_environ; + + /* We allocated this space; we can extend it. */ + new_environ = (char **) realloc (last_environ, + (size + 2) * sizeof (char *)); + if (new_environ == NULL) + { + UNLOCK; + return -1; + } + + /* If the whole entry is given add it. */ + if (combined != NULL) + /* We must not add the string to the search tree since it belongs + to the user. */ + new_environ[size] = (char *) combined; + else + { + /* See whether the value is already known. */ +#ifdef USE_TSEARCH +# ifdef __GNUC__ + char new_value[namelen + 1 + vallen]; +# else + char *new_value = (char *) alloca (namelen + 1 + vallen); +# endif +# ifdef _LIBC + __mempcpy (__mempcpy (__mempcpy (new_value, name, namelen), "=", 1), + value, vallen); +# else + memcpy (new_value, name, namelen); + new_value[namelen] = '='; + memcpy (&new_value[namelen + 1], value, vallen); +# endif + + new_environ[size] = KNOWN_VALUE (new_value); + if (__builtin_expect (new_environ[size] == NULL, 1)) +#endif + { + new_environ[size] = (char *) malloc (namelen + 1 + vallen); + if (__builtin_expect (new_environ[size] == NULL, 0)) + { + __set_errno (ENOMEM); + UNLOCK; + return -1; + } + +#ifdef USE_TSEARCH + memcpy (new_environ[size], new_value, namelen + 1 + vallen); +#else + memcpy (new_environ[size], name, namelen); + new_environ[size][namelen] = '='; + memcpy (&new_environ[size][namelen + 1], value, vallen); +#endif + /* And save the value now. We cannot do this when we remove + the string since then we cannot decide whether it is a + user string or not. */ + STORE_VALUE (new_environ[size]); + } + } + + if (__environ != last_environ) + memcpy ((char *) new_environ, (char *) __environ, + size * sizeof (char *)); + + new_environ[size + 1] = NULL; + + last_environ = __environ = new_environ; + } + else if (replace) + { + char *np; + + /* Use the user string if given. */ + if (combined != NULL) + np = (char *) combined; + else + { +#ifdef USE_TSEARCH +# ifdef __GNUC__ + char new_value[namelen + 1 + vallen]; +# else + char *new_value = (char *) alloca (namelen + 1 + vallen); +# endif +# ifdef _LIBC + __mempcpy (__mempcpy (__mempcpy (new_value, name, namelen), "=", 1), + value, vallen); +# else + memcpy (new_value, name, namelen); + new_value[namelen] = '='; + memcpy (&new_value[namelen + 1], value, vallen); +# endif + + np = KNOWN_VALUE (new_value); + if (__builtin_expect (np == NULL, 1)) +#endif + { + np = malloc (namelen + 1 + vallen); + if (__builtin_expect (np == NULL, 0)) + { + UNLOCK; + return -1; + } + +#ifdef USE_TSEARCH + memcpy (np, new_value, namelen + 1 + vallen); +#else + memcpy (np, name, namelen); + np[namelen] = '='; + memcpy (&np[namelen + 1], value, vallen); +#endif + /* And remember the value. */ + STORE_VALUE (np); + } + } + + *ep = np; + } + + UNLOCK; + + return 0; +} + +int +setenv (name, value, replace) + const char *name; + const char *value; + int replace; +{ + if (name == NULL || *name == '\0' || strchr (name, '=') != NULL) + { + __set_errno (EINVAL); + return -1; + } + + return __add_to_environ (name, value, NULL, replace); +} + +int +unsetenv (name) + const char *name; +{ + size_t len; + char **ep; + + if (name == NULL || *name == '\0' || strchr (name, '=') != NULL) + { + __set_errno (EINVAL); + return -1; + } + + len = strlen (name); + + LOCK; + + ep = __environ; + while (*ep != NULL) + if (!strncmp (*ep, name, len) && (*ep)[len] == '=') + { + /* Found it. Remove this pointer by moving later ones back. */ + char **dp = ep; + + do + dp[0] = dp[1]; + while (*dp++); + /* Continue the loop in case NAME appears again. */ + } + else + ++ep; + + UNLOCK; + + return 0; +} + +/* The `clearenv' was planned to be added to POSIX.1 but probably + never made it. Nevertheless the POSIX.9 standard (POSIX bindings + for Fortran 77) requires this function. */ +int +clearenv () +{ + LOCK; + + if (__environ == last_environ && __environ != NULL) + { + /* We allocated this environment so we can free it. */ + free (__environ); + last_environ = NULL; + } + + /* Clear the environment pointer removes the whole environment. */ + __environ = NULL; + + UNLOCK; + + return 0; +} +#ifdef _LIBC +libc_freeres_fn (free_mem) +{ + /* Remove all traces. */ + clearenv (); + + /* Now remove the search tree. */ + __tdestroy (known_values, free); + known_values = NULL; +} + +# undef setenv +# undef unsetenv +# undef clearenv +weak_alias (__setenv, setenv) +weak_alias (__unsetenv, unsetenv) +weak_alias (__clearenv, clearenv) +#endif diff --git a/stdlib/strtoimax.c b/stdlib/strtoimax.c new file mode 100644 index 0000000000..f1de70f320 --- /dev/null +++ b/stdlib/strtoimax.c @@ -0,0 +1 @@ +#error "The correct implementation must be chosen based on the `intmax_t' type" diff --git a/stdlib/strtol.c b/stdlib/strtol.c new file mode 100644 index 0000000000..02ec19aabe --- /dev/null +++ b/stdlib/strtol.c @@ -0,0 +1,111 @@ +/* Convert string representation of a number into an integer value. + Copyright (C) 1991,92,94,95,96,97,98,99,2000,2001,2002,2003,2004 + Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#include +#include +#include + +#ifndef UNSIGNED +# define UNSIGNED 0 +# define INT LONG int +#else +# define INT unsigned LONG int +#endif + +#if UNSIGNED +# ifdef USE_WIDE_CHAR +# ifdef QUAD +# define strtol wcstoull +# define __strtol_l __wcstoull_l +# else +# define strtol wcstoul +# define __strtol_l __wcstoul_l +# endif +# else +# ifdef QUAD +# define strtol strtoull +# define __strtol_l __strtoull_l +# else +# define strtol strtoul +# define __strtol_l __strtoul_l +# endif +# endif +#else +# ifdef USE_WIDE_CHAR +# ifdef QUAD +# define strtol wcstoll +# define __strtol_l __wcstoll_l +# else +# define strtol wcstol +# define __strtol_l __wcstol_l +# endif +# else +# ifdef QUAD +# define strtol strtoll +# define __strtol_l __strtoll_l +# endif +# endif +#endif + + +/* If QUAD is defined, we are defining `strtoll' or `strtoull', + operating on `long long int's. */ +#ifdef QUAD +# define LONG long long +#else +# define LONG long +#endif + + +#ifdef USE_WIDE_CHAR +# define STRING_TYPE wchar_t +#else +# define STRING_TYPE char +#endif + + +#define INTERNAL(X) INTERNAL1(X) +#define INTERNAL1(X) __##X##_internal + + +extern INT INTERNAL (__strtol_l) (const STRING_TYPE *, STRING_TYPE **, int, + int, __locale_t); + + +INT +INTERNAL (strtol) (nptr, endptr, base, group) + const STRING_TYPE *nptr; + STRING_TYPE **endptr; + int base; + int group; +{ + return INTERNAL (__strtol_l) (nptr, endptr, base, group, _NL_CURRENT_LOCALE); +} +libc_hidden_def (INTERNAL (strtol)) + + +INT +strtol (nptr, endptr, base) + const STRING_TYPE *nptr; + STRING_TYPE **endptr; + int base; +{ + return INTERNAL (__strtol_l) (nptr, endptr, base, 0, _NL_CURRENT_LOCALE); +} diff --git a/stdlib/strtol_l.c b/stdlib/strtol_l.c new file mode 100644 index 0000000000..156083c748 --- /dev/null +++ b/stdlib/strtol_l.c @@ -0,0 +1,557 @@ +/* Convert string representing a number to integer value, using given locale. + Copyright (C) 1997, 2002, 2004 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Ulrich Drepper , 1997. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + + +#if HAVE_CONFIG_H +# include +#endif + +#ifdef _LIBC +# define USE_NUMBER_GROUPING +# define STDC_HEADERS +# define HAVE_LIMITS_H +#endif + +#include +#include +#ifndef __set_errno +# define __set_errno(Val) errno = (Val) +#endif + +#ifdef HAVE_LIMITS_H +# include +#endif + +#include +#include +#include +#include +#include +#include + +#ifdef USE_NUMBER_GROUPING +# include "../locale/localeinfo.h" +#endif + +/* Nonzero if we are defining `strtoul' or `strtoull', operating on + unsigned integers. */ +#ifndef UNSIGNED +# define UNSIGNED 0 +# define INT LONG int +#else +# define INT unsigned LONG int +#endif + +/* Determine the name. */ +#if UNSIGNED +# ifdef USE_WIDE_CHAR +# ifdef QUAD +# define strtol_l wcstoull_l +# else +# define strtol_l wcstoul_l +# endif +# else +# ifdef QUAD +# define strtol_l strtoull_l +# else +# define strtol_l strtoul_l +# endif +# endif +#else +# ifdef USE_WIDE_CHAR +# ifdef QUAD +# define strtol_l wcstoll_l +# else +# define strtol_l wcstol_l +# endif +# else +# ifdef QUAD +# define strtol_l strtoll_l +# else +# define strtol_l strtol_l +# endif +# endif +#endif + +#define __strtol_l __strtol_l2(strtol_l) +#define __strtol_l2(name) __strtol_l3(name) +#define __strtol_l3(name) __##name + + +/* If QUAD is defined, we are defining `strtoll' or `strtoull', + operating on `long long int's. */ +#ifdef QUAD +# define LONG long long +# define STRTOL_LONG_MIN LONG_LONG_MIN +# define STRTOL_LONG_MAX LONG_LONG_MAX +# define STRTOL_ULONG_MAX ULONG_LONG_MAX +#else +# define LONG long + +# ifndef ULONG_MAX +# define ULONG_MAX ((unsigned long int) ~(unsigned long int) 0) +# endif +# ifndef LONG_MAX +# define LONG_MAX ((long int) (ULONG_MAX >> 1)) +# endif +# define STRTOL_LONG_MIN LONG_MIN +# define STRTOL_LONG_MAX LONG_MAX +# define STRTOL_ULONG_MAX ULONG_MAX +#endif + + +/* We use this code for the extended locale handling where the + function gets as an additional argument the locale which has to be + used. To access the values we have to redefine the _NL_CURRENT and + _NL_CURRENT_WORD macros. */ +#undef _NL_CURRENT +#define _NL_CURRENT(category, item) \ + (current->values[_NL_ITEM_INDEX (item)].string) +#undef _NL_CURRENT_WORD +#define _NL_CURRENT_WORD(category, item) \ + ((uint32_t) current->values[_NL_ITEM_INDEX (item)].word) + +#if defined _LIBC || defined HAVE_WCHAR_H +# include +#endif + +#ifdef USE_WIDE_CHAR +# include +# define L_(Ch) L##Ch +# define UCHAR_TYPE wint_t +# define STRING_TYPE wchar_t +# define ISSPACE(Ch) __iswspace_l ((Ch), loc) +# define ISALPHA(Ch) __iswalpha_l ((Ch), loc) +# define TOUPPER(Ch) __towupper_l ((Ch), loc) +#else +# if defined _LIBC \ + || defined STDC_HEADERS || (!defined isascii && !defined HAVE_ISASCII) +# define IN_CTYPE_DOMAIN(c) 1 +# else +# define IN_CTYPE_DOMAIN(c) isascii(c) +# endif +# define L_(Ch) Ch +# define UCHAR_TYPE unsigned char +# define STRING_TYPE char +# define ISSPACE(Ch) __isspace_l ((Ch), loc) +# define ISALPHA(Ch) __isalpha_l ((Ch), loc) +# define TOUPPER(Ch) __toupper_l ((Ch), loc) +#endif + +#define INTERNAL(X) INTERNAL1(X) +#define INTERNAL1(X) __##X##_internal +#define WEAKNAME(X) WEAKNAME1(X) + +#ifdef USE_NUMBER_GROUPING +/* This file defines a function to check for correct grouping. */ +# include "grouping.h" +#endif + + +/* Define tables of maximum values and remainders in order to detect + overflow. Do this at compile-time in order to avoid the runtime + overhead of the division. */ + +#define DEF(TYPE, NAME) \ + const TYPE NAME[] attribute_hidden \ + __attribute__((section(".gnu.linkonce.r." #NAME))) = \ + { \ + F(2), F(3), F(4), F(5), F(6), F(7), F(8), F(9), F(10), \ + F(11), F(12), F(13), F(14), F(15), F(16), F(17), F(18), F(19), F(20), \ + F(21), F(22), F(23), F(24), F(25), F(26), F(27), F(28), F(29), F(30), \ + F(31), F(32), F(33), F(34), F(35), F(36) \ + } + +#define F(X) ULONG_MAX / X + DEF (unsigned long, __strtol_ul_max_tab); +#undef F +#if defined(QUAD) && __WORDSIZE == 32 +# define F(X) ULONG_LONG_MAX / X + DEF (unsigned long long, __strtol_ull_max_tab); +# undef F +# define F(X) ULONG_LONG_MAX % X + DEF (unsigned char, __strtol_ull_rem_tab); +# undef F +#else +# define F(X) ULONG_MAX % X + DEF (unsigned char, __strtol_ul_rem_tab); +# undef F +#endif +#undef DEF + +/* Define some more readable aliases for these arrays which correspond + to how they'll be used in the function below. */ +#define jmax_tab __strtol_ul_max_tab +#if defined(QUAD) && __WORDSIZE == 32 +# define cutoff_tab __strtol_ull_max_tab +# define cutlim_tab __strtol_ull_rem_tab +#else +# define cutoff_tab __strtol_ul_max_tab +# define cutlim_tab __strtol_ul_rem_tab +#endif + + +/* Convert NPTR to an `unsigned long int' or `long int' in base BASE. + If BASE is 0 the base is determined by the presence of a leading + zero, indicating octal or a leading "0x" or "0X", indicating hexadecimal. + If BASE is < 2 or > 36, it is reset to 10. + If ENDPTR is not NULL, a pointer to the character after the last + one converted is stored in *ENDPTR. */ + +INT +INTERNAL (__strtol_l) (nptr, endptr, base, group, loc) + const STRING_TYPE *nptr; + STRING_TYPE **endptr; + int base; + int group; + __locale_t loc; +{ + int negative; + register unsigned LONG int cutoff; + register unsigned int cutlim; + register unsigned LONG int i; + register const STRING_TYPE *s; + register UCHAR_TYPE c; + const STRING_TYPE *save, *end; + int overflow; +#ifndef USE_WIDE_CHAR + size_t cnt; +#endif + +#ifdef USE_NUMBER_GROUPING + struct locale_data *current = loc->__locales[LC_NUMERIC]; + /* The thousands character of the current locale. */ +# ifdef USE_WIDE_CHAR + wchar_t thousands = L'\0'; +# else + const char *thousands = NULL; + size_t thousands_len = 0; +# endif + /* The numeric grouping specification of the current locale, + in the format described in . */ + const char *grouping; + + if (__builtin_expect (group, 0)) + { + grouping = _NL_CURRENT (LC_NUMERIC, GROUPING); + if (*grouping <= 0 || *grouping == CHAR_MAX) + grouping = NULL; + else + { + /* Figure out the thousands separator character. */ +# ifdef USE_WIDE_CHAR +# ifdef _LIBC + thousands = _NL_CURRENT_WORD (LC_NUMERIC, + _NL_NUMERIC_THOUSANDS_SEP_WC); +# endif + if (thousands == L'\0') + grouping = NULL; +# else +# ifdef _LIBC + thousands = _NL_CURRENT (LC_NUMERIC, THOUSANDS_SEP); +# endif + if (*thousands == '\0') + { + thousands = NULL; + grouping = NULL; + } +# endif + } + } + else + grouping = NULL; +#endif + + if (base < 0 || base == 1 || base > 36) + { + __set_errno (EINVAL); + return 0; + } + + save = s = nptr; + + /* Skip white space. */ + while (ISSPACE (*s)) + ++s; + if (__builtin_expect (*s == L_('\0'), 0)) + goto noconv; + + /* Check for a sign. */ + negative = 0; + if (*s == L_('-')) + { + negative = 1; + ++s; + } + else if (*s == L_('+')) + ++s; + + /* Recognize number prefix and if BASE is zero, figure it out ourselves. */ + if (*s == L_('0')) + { + if ((base == 0 || base == 16) && TOUPPER (s[1]) == L_('X')) + { + s += 2; + base = 16; + } + else if (base == 0) + base = 8; + } + else if (base == 0) + base = 10; + + /* Save the pointer so we can check later if anything happened. */ + save = s; + +#ifdef USE_NUMBER_GROUPING + if (base != 10) + grouping = NULL; + + if (__builtin_expect (grouping != NULL, 0)) + { +# ifndef USE_WIDE_CHAR + thousands_len = strlen (thousands); +# endif + + /* Find the end of the digit string and check its grouping. */ + end = s; + if ( +# ifdef USE_WIDE_CHAR + *s != thousands +# else + ({ for (cnt = 0; cnt < thousands_len; ++cnt) + if (thousands[cnt] != end[cnt]) + break; + cnt < thousands_len; }) +# endif + ) + { + for (c = *end; c != L_('\0'); c = *++end) + if (((STRING_TYPE) c < L_('0') || (STRING_TYPE) c > L_('9')) +# ifdef USE_WIDE_CHAR + && (wchar_t) c != thousands +# else + && ({ for (cnt = 0; cnt < thousands_len; ++cnt) + if (thousands[cnt] != end[cnt]) + break; + cnt < thousands_len; }) +# endif + && (!ISALPHA (c) + || (int) (TOUPPER (c) - L_('A') + 10) >= base)) + break; + +# ifdef USE_WIDE_CHAR + end = __correctly_grouped_prefixwc (s, end, thousands, grouping); +# else + end = __correctly_grouped_prefixmb (s, end, thousands, grouping); +# endif + } + } + else +#endif + end = NULL; + + /* Avoid runtime division; lookup cutoff and limit. */ + cutoff = cutoff_tab[base - 2]; + cutlim = cutlim_tab[base - 2]; + + overflow = 0; + i = 0; + c = *s; + if (sizeof (long int) != sizeof (LONG int)) + { + unsigned long int j = 0; + unsigned long int jmax = jmax_tab[base - 2]; + + for (;c != L_('\0'); c = *++s) + { + if (s == end) + break; + if (c >= L_('0') && c <= L_('9')) + c -= L_('0'); +#ifdef USE_NUMBER_GROUPING +# ifdef USE_WIDE_CHAR + else if (grouping && (wchar_t) c == thousands) + continue; +# else + else if (thousands_len) + { + for (cnt = 0; cnt < thousands_len; ++cnt) + if (thousands[cnt] != s[cnt]) + break; + if (cnt == thousands_len) + { + s += thousands_len - 1; + continue; + } + if (ISALPHA (c)) + c = TOUPPER (c) - L_('A') + 10; + else + break; + } +# endif +#endif + else if (ISALPHA (c)) + c = TOUPPER (c) - L_('A') + 10; + else + break; + if ((int) c >= base) + break; + /* Note that we never can have an overflow. */ + else if (j >= jmax) + { + /* We have an overflow. Now use the long representation. */ + i = (unsigned LONG int) j; + goto use_long; + } + else + j = j * (unsigned long int) base + c; + } + + i = (unsigned LONG int) j; + } + else + for (;c != L_('\0'); c = *++s) + { + if (s == end) + break; + if (c >= L_('0') && c <= L_('9')) + c -= L_('0'); +#ifdef USE_NUMBER_GROUPING +# ifdef USE_WIDE_CHAR + else if (grouping && (wchar_t) c == thousands) + continue; +# else + else if (thousands_len) + { + for (cnt = 0; cnt < thousands_len; ++cnt) + if (thousands[cnt] != s[cnt]) + break; + if (cnt == thousands_len) + { + s += thousands_len - 1; + continue; + } + if (ISALPHA (c)) + c = TOUPPER (c) - L_('A') + 10; + else + break; + } +# endif +#endif + else if (ISALPHA (c)) + c = TOUPPER (c) - L_('A') + 10; + else + break; + if ((int) c >= base) + break; + /* Check for overflow. */ + if (i > cutoff || (i == cutoff && c > cutlim)) + overflow = 1; + else + { + use_long: + i *= (unsigned LONG int) base; + i += c; + } + } + + /* Check if anything actually happened. */ + if (s == save) + goto noconv; + + /* Store in ENDPTR the address of one character + past the last character we converted. */ + if (endptr != NULL) + *endptr = (STRING_TYPE *) s; + +#if !UNSIGNED + /* Check for a value that is within the range of + `unsigned LONG int', but outside the range of `LONG int'. */ + if (overflow == 0 + && i > (negative + ? -((unsigned LONG int) (STRTOL_LONG_MIN + 1)) + 1 + : (unsigned LONG int) STRTOL_LONG_MAX)) + overflow = 1; +#endif + + if (__builtin_expect (overflow, 0)) + { + __set_errno (ERANGE); +#if UNSIGNED + return STRTOL_ULONG_MAX; +#else + return negative ? STRTOL_LONG_MIN : STRTOL_LONG_MAX; +#endif + } + + /* Return the result of the appropriate sign. */ + return negative ? -i : i; + +noconv: + /* We must handle a special case here: the base is 0 or 16 and the + first two characters are '0' and 'x', but the rest are no + hexadecimal digits. This is no error case. We return 0 and + ENDPTR points to the `x`. */ + if (endptr != NULL) + { + if (save - nptr >= 2 && TOUPPER (save[-1]) == L_('X') + && save[-2] == L_('0')) + *endptr = (STRING_TYPE *) &save[-1]; + else + /* There was no number to convert. */ + *endptr = (STRING_TYPE *) nptr; + } + + return 0L; +} +#if defined _LIBC && !defined USE_WIDE_CHAR +libc_hidden_def (INTERNAL (__strtol_l)) +#endif + +/* External user entry point. */ + +#if _LIBC - 0 == 0 +# undef PARAMS +# if defined (__STDC__) && __STDC__ +# define PARAMS(Args) Args +# else +# define PARAMS(Args) () +# endif + +/* Prototype. */ +extern INT __strtol_l PARAMS ((const STRING_TYPE *nptr, STRING_TYPE **endptr, + int base)); +#endif + + +INT +#ifdef weak_function +weak_function +#endif +__strtol_l (nptr, endptr, base, loc) + const STRING_TYPE *nptr; + STRING_TYPE **endptr; + int base; + __locale_t loc; +{ + return INTERNAL (__strtol_l) (nptr, endptr, base, 0, loc); +} +weak_alias (__strtol_l, strtol_l) diff --git a/stdlib/strtold_l.c b/stdlib/strtold_l.c new file mode 100644 index 0000000000..690a8a92eb --- /dev/null +++ b/stdlib/strtold_l.c @@ -0,0 +1,58 @@ +/* Copyright (C) 1999, 2002, 2004 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#include +#include +#include + +#ifdef USE_WIDE_CHAR +# define STRING_TYPE wchar_t +# define STRTOLD wcstold_l +# define __STRTOLD __wcstold_l +# define __STRTOD __wcstod_l +#else +# define STRING_TYPE char +# define STRTOLD strtold_l +# define __STRTOLD __strtold_l +# define __STRTOD __strtod_l +#endif + +#define INTERNAL(x) INTERNAL1(x) +#define INTERNAL1(x) __##x##_internal + +extern double INTERNAL (__STRTOD) (const STRING_TYPE *, STRING_TYPE **, + int, __locale_t); + +/* There is no `long double' type, use the `double' implementations. */ +long double +INTERNAL (__STRTOLD) (const STRING_TYPE *nptr, STRING_TYPE **endptr, + int group, __locale_t loc) +{ + return INTERNAL (__STRTOD) (nptr, endptr, group, loc); +} +#ifndef USE_WIDE_CHAR +libc_hidden_def (INTERNAL (__STRTOLD)) +#endif + +long double +weak_function +__STRTOLD (const STRING_TYPE *nptr, STRING_TYPE **endptr, __locale_t loc) +{ + return INTERNAL (__STRTOD) (nptr, endptr, 0, loc); +} +weak_alias (__STRTOLD, STRTOLD) diff --git a/stdlib/strtoll.c b/stdlib/strtoll.c new file mode 100644 index 0000000000..60128df781 --- /dev/null +++ b/stdlib/strtoll.c @@ -0,0 +1,34 @@ +/* Function to parse a `long long int' from text. + Copyright (C) 1995, 1996, 1997, 1999, 2001 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#define QUAD 1 + +#include + +#ifdef _LIBC +# ifdef SHARED +# include + +# if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_2) +compat_symbol (libc, __strtoll_internal, __strtoq_internal, GLIBC_2_0); +# endif + +# endif +weak_alias (strtoll, strtoq) +#endif diff --git a/stdlib/strtoll_l.c b/stdlib/strtoll_l.c new file mode 100644 index 0000000000..7725035bd1 --- /dev/null +++ b/stdlib/strtoll_l.c @@ -0,0 +1,28 @@ +/* Convert string representing a number to integer value, using given locale. + Copyright (C) 1997, 2002, 2004 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Ulrich Drepper , 1997. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#define QUAD 1 + +#include + +extern long long int ____strtoll_l_internal (const char *, char **, int, int, + __locale_t); + +#include diff --git a/stdlib/strtoul.c b/stdlib/strtoul.c new file mode 100644 index 0000000000..0862950231 --- /dev/null +++ b/stdlib/strtoul.c @@ -0,0 +1,21 @@ +/* Copyright (C) 1991, 1997 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#define UNSIGNED 1 + +#include "strtol.c" diff --git a/stdlib/strtoul_l.c b/stdlib/strtoul_l.c new file mode 100644 index 0000000000..a8b980f48d --- /dev/null +++ b/stdlib/strtoul_l.c @@ -0,0 +1,28 @@ +/* Convert string representing a number to integer value, using given locale. + Copyright (C) 1997, 2002, 2004 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Ulrich Drepper , 1997. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#define UNSIGNED 1 + +#include + +extern unsigned long int ____strtoul_l_internal (const char *, char **, int, + int, __locale_t); + +#include "strtol_l.c" diff --git a/stdlib/strtoull.c b/stdlib/strtoull.c new file mode 100644 index 0000000000..accf5874a0 --- /dev/null +++ b/stdlib/strtoull.c @@ -0,0 +1,34 @@ +/* Function to parse an `unsigned long long int' from text. + Copyright (C) 1995, 1996, 1997, 1999, 2001 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#define QUAD 1 + +#include + +#ifdef _LIBC +# ifdef SHARED +# include + +# if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_2) +compat_symbol (libc, __strtoull_internal, __strtouq_internal, GLIBC_2_0); +# endif + +# endif +weak_alias (strtoull, strtouq) +#endif diff --git a/stdlib/strtoull_l.c b/stdlib/strtoull_l.c new file mode 100644 index 0000000000..68ad0d826e --- /dev/null +++ b/stdlib/strtoull_l.c @@ -0,0 +1,29 @@ +/* Convert string representing a number to integer value, using given locale. + Copyright (C) 1997, 2002, 2004 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Ulrich Drepper , 1997. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#define QUAD 1 +#define UNSIGNED 1 + +#include + +extern unsigned long long int ____strtoull_l_internal (const char *, char **, + int, int, __locale_t); + +#include diff --git a/stdlib/strtoumax.c b/stdlib/strtoumax.c new file mode 100644 index 0000000000..508cb19f8c --- /dev/null +++ b/stdlib/strtoumax.c @@ -0,0 +1 @@ +#error "The correct implementation must be chosen based on the `uintmax_t' type" diff --git a/stdlib/sub_n.c b/stdlib/sub_n.c new file mode 100644 index 0000000000..987ad91eb1 --- /dev/null +++ b/stdlib/sub_n.c @@ -0,0 +1,62 @@ +/* mpn_sub_n -- Subtract two limb vectors of equal, non-zero length. + +Copyright (C) 1992, 1993, 1994, 1996 Free Software Foundation, Inc. + +This file is part of the GNU MP Library. + +The GNU MP Library is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 2.1 of the License, or (at your +option) any later version. + +The GNU MP Library 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 Lesser General Public +License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with the GNU MP Library; see the file COPYING.LIB. If not, write to +the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, +MA 02111-1307, USA. */ + +#include +#include "gmp-impl.h" + +mp_limb_t +#if __STDC__ +mpn_sub_n (mp_ptr res_ptr, mp_srcptr s1_ptr, mp_srcptr s2_ptr, mp_size_t size) +#else +mpn_sub_n (res_ptr, s1_ptr, s2_ptr, size) + register mp_ptr res_ptr; + register mp_srcptr s1_ptr; + register mp_srcptr s2_ptr; + mp_size_t size; +#endif +{ + register mp_limb_t x, y, cy; + register mp_size_t j; + + /* The loop counter and index J goes from -SIZE to -1. This way + the loop becomes faster. */ + j = -size; + + /* Offset the base pointers to compensate for the negative indices. */ + s1_ptr -= j; + s2_ptr -= j; + res_ptr -= j; + + cy = 0; + do + { + y = s2_ptr[j]; + x = s1_ptr[j]; + y += cy; /* add previous carry to subtrahend */ + cy = (y < cy); /* get out carry from that addition */ + y = x - y; /* main subtract */ + cy = (y > x) + cy; /* get out carry from the subtract, combine */ + res_ptr[j] = y; + } + while (++j != 0); + + return cy; +} diff --git a/stdlib/submul_1.c b/stdlib/submul_1.c new file mode 100644 index 0000000000..3e7163a2a3 --- /dev/null +++ b/stdlib/submul_1.c @@ -0,0 +1,65 @@ +/* mpn_submul_1 -- multiply the S1_SIZE long limb vector pointed to by S1_PTR + by S2_LIMB, subtract the S1_SIZE least significant limbs of the product + from the limb vector pointed to by RES_PTR. Return the most significant + limb of the product, adjusted for carry-out from the subtraction. + +Copyright (C) 1992, 1993, 1994, 1996, 2005 Free Software Foundation, Inc. + +This file is part of the GNU MP Library. + +The GNU MP Library is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 2.1 of the License, or (at your +option) any later version. + +The GNU MP Library 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 Lesser General Public +License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with the GNU MP Library; see the file COPYING.LIB. If not, write to +the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, +MA 02111-1307, USA. */ + +#include +#include "gmp-impl.h" +#include "longlong.h" + +mp_limb_t +mpn_submul_1 (res_ptr, s1_ptr, s1_size, s2_limb) + register mp_ptr res_ptr; + register mp_srcptr s1_ptr; + mp_size_t s1_size; + register mp_limb_t s2_limb; +{ + register mp_limb_t cy_limb; + register mp_size_t j; + register mp_limb_t prod_high, prod_low; + register mp_limb_t x; + + /* The loop counter and index J goes from -SIZE to -1. This way + the loop becomes faster. */ + j = -s1_size; + + /* Offset the base pointers to compensate for the negative indices. */ + res_ptr -= j; + s1_ptr -= j; + + cy_limb = 0; + do + { + umul_ppmm (prod_high, prod_low, s1_ptr[j], s2_limb); + + prod_low += cy_limb; + cy_limb = (prod_low < cy_limb) + prod_high; + + x = res_ptr[j]; + prod_low = x - prod_low; + cy_limb += (prod_low > x); + res_ptr[j] = prod_low; + } + while (++j != 0); + + return cy_limb; +} diff --git a/stdlib/swapcontext.c b/stdlib/swapcontext.c new file mode 100644 index 0000000000..56b73f0d6c --- /dev/null +++ b/stdlib/swapcontext.c @@ -0,0 +1,33 @@ +/* Copyright (C) 1998 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#include +#include + +int +swapcontext (oucp, ucp) + ucontext_t *oucp; + const ucontext_t *ucp; +{ + __set_errno (ENOSYS); + return -1; +} + + +stub_warning (swapcontext) +#include diff --git a/stdlib/system.c b/stdlib/system.c new file mode 100644 index 0000000000..cd12128cd8 --- /dev/null +++ b/stdlib/system.c @@ -0,0 +1,38 @@ +/* Copyright (C) 1991, 1993, 1995, 1996, 1997, 2003 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#include +#include + + +/* Execute LINE as a shell command. */ +int +__libc_system (line) + const char *line; +{ + if (line == NULL) + return 0; /* This indicates no command processor. */ + + __set_errno (ENOSYS); + return -1; +} +weak_alias (__libc_system, system) + + +stub_warning (system) +#include diff --git a/stdlib/udiv_qrnnd.c b/stdlib/udiv_qrnnd.c new file mode 100644 index 0000000000..d32796c04d --- /dev/null +++ b/stdlib/udiv_qrnnd.c @@ -0,0 +1,10 @@ +/* For some machines GNU MP needs to define an auxiliary function: + + udiv_qrnnd (quotient, remainder, high_numerator, low_numerator, denominator) + + Divides a two-word unsigned integer, composed by the integers + HIGH_NUMERATOR and LOW_NUMERATOR, by DENOMINATOR and places the quotient + in QUOTIENT and the remainder in REMAINDER. HIGH_NUMERATOR must be less + than DENOMINATOR for correct operation. If, in addition, the most + significant bit of DENOMINATOR must be 1, then the pre-processor symbol + UDIV_NEEDS_NORMALIZATION is defined to 1. */ diff --git a/stdlib/wcstoimax.c b/stdlib/wcstoimax.c new file mode 100644 index 0000000000..f1de70f320 --- /dev/null +++ b/stdlib/wcstoimax.c @@ -0,0 +1 @@ +#error "The correct implementation must be chosen based on the `intmax_t' type" diff --git a/stdlib/wcstoumax.c b/stdlib/wcstoumax.c new file mode 100644 index 0000000000..508cb19f8c --- /dev/null +++ b/stdlib/wcstoumax.c @@ -0,0 +1 @@ +#error "The correct implementation must be chosen based on the `uintmax_t' type" -- cgit v1.2.3