summary refs log tree commit diff
path: root/stdlib
diff options
context:
space:
mode:
authorUlrich Drepper <drepper@redhat.com>2005-12-14 15:06:39 +0000
committerUlrich Drepper <drepper@redhat.com>2005-12-14 15:06:39 +0000
commit9d13fb2413921c713f83efe331e8e4d219c62c6b (patch)
tree2d44d7ac45ab2d147eb8361bbff880c365aa8ad5 /stdlib
parentb6ab06cef4670e02756bcdd4d2c33a49369a4346 (diff)
downloadglibc-9d13fb2413921c713f83efe331e8e4d219c62c6b.tar.gz
glibc-9d13fb2413921c713f83efe331e8e4d219c62c6b.tar.xz
glibc-9d13fb2413921c713f83efe331e8e4d219c62c6b.zip
Moved to csu/errno-loc.c.
Diffstat (limited to 'stdlib')
-rw-r--r--stdlib/getcontext.c32
-rw-r--r--stdlib/getenv.c98
-rw-r--r--stdlib/inlines.c3
-rw-r--r--stdlib/labs.c29
-rw-r--r--stdlib/ldbl2mpn.c1
-rw-r--r--stdlib/ldiv.c54
-rw-r--r--stdlib/llabs.c31
-rw-r--r--stdlib/lldiv.c57
-rw-r--r--stdlib/lshift.c87
-rw-r--r--stdlib/makecontext.c30
-rw-r--r--stdlib/mod_1.c197
-rw-r--r--stdlib/mp_clz_tab.c37
-rw-r--r--stdlib/mpn2dbl.c30
-rw-r--r--stdlib/mpn2flt.c30
-rw-r--r--stdlib/mpn2ldbl.c1
-rw-r--r--stdlib/mul.c152
-rw-r--r--stdlib/mul_1.c59
-rw-r--r--stdlib/mul_n.c401
-rw-r--r--stdlib/putenv.c72
-rw-r--r--stdlib/rshift.c88
-rw-r--r--stdlib/setcontext.c32
-rw-r--r--stdlib/setenv.c353
-rw-r--r--stdlib/strtoimax.c1
-rw-r--r--stdlib/strtol.c111
-rw-r--r--stdlib/strtol_l.c557
-rw-r--r--stdlib/strtold_l.c58
-rw-r--r--stdlib/strtoll.c34
-rw-r--r--stdlib/strtoll_l.c28
-rw-r--r--stdlib/strtoul.c21
-rw-r--r--stdlib/strtoul_l.c28
-rw-r--r--stdlib/strtoull.c34
-rw-r--r--stdlib/strtoull_l.c29
-rw-r--r--stdlib/strtoumax.c1
-rw-r--r--stdlib/sub_n.c62
-rw-r--r--stdlib/submul_1.c65
-rw-r--r--stdlib/swapcontext.c33
-rw-r--r--stdlib/system.c38
-rw-r--r--stdlib/udiv_qrnnd.c10
-rw-r--r--stdlib/wcstoimax.c1
-rw-r--r--stdlib/wcstoumax.c1
40 files changed, 2986 insertions, 0 deletions
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 <errno.h>
+#include <ucontext.h>
+
+int
+getcontext (ucp)
+     ucontext_t *ucp;
+{
+  __set_errno (ENOSYS);
+  return -1;
+}
+
+
+stub_warning (getcontext)
+#include <stub-tag.h>
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 <endian.h>
+#include <errno.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+
+/* 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 <gmp.h>
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 <stdlib.h>
+
+#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 <stdlib.h>
+
+
+/* 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 <stdlib.h>
+
+#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 <stdlib.h>
+
+
+/* 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 <gmp.h>
+#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 <errno.h>
+#include <ucontext.h>
+
+void
+makecontext (ucontext_t *ucp, void (*func) (void), int argc, ...)
+{
+  __set_errno (ENOSYS);
+}
+
+
+stub_warning (makecontext)
+#include <stub-tag.h>
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 <gmp.h>
+#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 <gmp.h>
+#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 <gmp.h>
+#include "gmp-impl.h"
+#include <float.h>
+
+/* 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 <float.h>
+
+/* 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 <gmp.h>
+#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 <gmp.h>
+#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 <gmp.h>
+#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 <config.h>
+#endif
+
+#if _LIBC || HAVE_STDLIB_H
+# include <stdlib.h>
+#endif
+#if _LIBC || HAVE_STRING_H
+# include <string.h>
+#endif
+
+#if !__GNU_LIBRARY__ && !HAVE_STRCHR
+# define strchr index
+#endif
+
+#ifndef _LIBC
+# ifdef HAVE_ALLOCA_H
+#  include <alloca.h>
+# 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 <gmp.h>
+#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 <errno.h>
+#include <ucontext.h>
+
+int
+setcontext (ucp)
+     const ucontext_t *ucp;
+{
+  __set_errno (ENOSYS);
+  return -1;
+}
+
+
+stub_warning (setcontext)
+#include <stub-tag.h>
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 <config.h>
+#endif
+
+#include <errno.h>
+#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 <stdlib.h>
+#endif
+#if _LIBC || HAVE_STRING_H
+# include <string.h>
+#endif
+#if _LIBC || HAVE_UNISTD_H
+# include <unistd.h>
+#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 <bits/libc-lock.h>
+__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 <search.h>
+
+/* 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 <stdlib.h>
+#include <wchar.h>
+#include <locale/localeinfo.h>
+
+#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 <drepper@cygnus.com>, 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 <config.h>
+#endif
+
+#ifdef _LIBC
+# define USE_NUMBER_GROUPING
+# define STDC_HEADERS
+# define HAVE_LIMITS_H
+#endif
+
+#include <ctype.h>
+#include <errno.h>
+#ifndef __set_errno
+# define __set_errno(Val) errno = (Val)
+#endif
+
+#ifdef HAVE_LIMITS_H
+# include <limits.h>
+#endif
+
+#include <stddef.h>
+#include <stdlib.h>
+#include <string.h>
+#include <locale.h>
+#include <xlocale.h>
+#include <bits/wordsize.h>
+
+#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 <wchar.h>
+#endif
+
+#ifdef USE_WIDE_CHAR
+# include <wctype.h>
+# 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 <locale.h>.  */
+  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 <math.h>
+#include <stdlib.h>
+#include <xlocale.h>
+
+#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 <strtol.c>
+
+#ifdef _LIBC
+# ifdef SHARED
+#  include <shlib-compat.h>
+
+#  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 <drepper@cygnus.com>, 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 <xlocale.h>
+
+extern long long int ____strtoll_l_internal (const char *, char **, int, int,
+					     __locale_t);
+
+#include <strtol_l.c>
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 <drepper@cygnus.com>, 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 <xlocale.h>
+
+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 <strtoul.c>
+
+#ifdef _LIBC
+# ifdef SHARED
+#  include <shlib-compat.h>
+
+#  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 <drepper@cygnus.com>, 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 <xlocale.h>
+
+extern unsigned long long int ____strtoull_l_internal (const char *, char **,
+						       int, int, __locale_t);
+
+#include <strtol_l.c>
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 <gmp.h>
+#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 <gmp.h>
+#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 <errno.h>
+#include <ucontext.h>
+
+int
+swapcontext (oucp, ucp)
+     ucontext_t *oucp;
+     const ucontext_t *ucp;
+{
+  __set_errno (ENOSYS);
+  return -1;
+}
+
+
+stub_warning (swapcontext)
+#include <stub-tag.h>
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 <errno.h>
+#include <stdlib.h>
+
+
+/* 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 <stub-tag.h>
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"