Revert "Remove gmp from AOS"

This reverts commit f37c97684f0910a3f241394549392f00145ab0f7.

We need gmp for SymEngine for symbolicmanipultion in C++

Change-Id: Ia13216d1715cf96944f7b4f422b7a799f921d4a4
Signed-off-by: Austin Schuh <austin.linux@gmail.com>
diff --git a/third_party/gmp/mpf/set_str.c b/third_party/gmp/mpf/set_str.c
new file mode 100644
index 0000000..c7bfe0b
--- /dev/null
+++ b/third_party/gmp/mpf/set_str.c
@@ -0,0 +1,412 @@
+/* mpf_set_str (dest, string, base) -- Convert the string STRING
+   in base BASE to a float in dest.  If BASE is zero, the leading characters
+   of STRING is used to figure out the base.
+
+Copyright 1993-1997, 2000-2003, 2005, 2007, 2008, 2011, 2013, 2019 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 either:
+
+  * the GNU Lesser General Public License as published by the Free
+    Software Foundation; either version 3 of the License, or (at your
+    option) any later version.
+
+or
+
+  * the GNU General Public License as published by the Free Software
+    Foundation; either version 2 of the License, or (at your option) any
+    later version.
+
+or both in parallel, as here.
+
+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 General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library.  If not,
+see https://www.gnu.org/licenses/.  */
+
+/*
+  This still needs work, as suggested by some FIXME comments.
+  1. Don't depend on superfluous mantissa digits.
+  2. Allocate temp space more cleverly.
+  3. Use mpn_div_q instead of mpn_lshift+mpn_divrem.
+*/
+
+#define _GNU_SOURCE    /* for DECIMAL_POINT in langinfo.h */
+
+#include "config.h"
+
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+
+#if HAVE_LANGINFO_H
+#include <langinfo.h>  /* for nl_langinfo */
+#endif
+
+#if HAVE_LOCALE_H
+#include <locale.h>    /* for localeconv */
+#endif
+
+#include "gmp-impl.h"
+#include "longlong.h"
+
+
+#define digit_value_tab __gmp_digit_value_tab
+
+/* Compute base^exp and return the most significant prec limbs in rp[].
+   Put the count of omitted low limbs in *ign.
+   Return the actual size (which might be less than prec).  */
+static mp_size_t
+mpn_pow_1_highpart (mp_ptr rp, mp_size_t *ignp,
+		    mp_limb_t base, mp_exp_t exp,
+		    mp_size_t prec, mp_ptr tp)
+{
+  mp_size_t ign;		/* counts number of ignored low limbs in r */
+  mp_size_t off;		/* keeps track of offset where value starts */
+  mp_ptr passed_rp = rp;
+  mp_size_t rn;
+  int cnt;
+  int i;
+
+  rp[0] = base;
+  rn = 1;
+  off = 0;
+  ign = 0;
+  count_leading_zeros (cnt, exp);
+  for (i = GMP_LIMB_BITS - cnt - 2; i >= 0; i--)
+    {
+      mpn_sqr (tp, rp + off, rn);
+      rn = 2 * rn;
+      rn -= tp[rn - 1] == 0;
+      ign <<= 1;
+
+      off = 0;
+      if (rn > prec)
+	{
+	  ign += rn - prec;
+	  off = rn - prec;
+	  rn = prec;
+	}
+      MP_PTR_SWAP (rp, tp);
+
+      if (((exp >> i) & 1) != 0)
+	{
+	  mp_limb_t cy;
+	  cy = mpn_mul_1 (rp, rp + off, rn, base);
+	  rp[rn] = cy;
+	  rn += cy != 0;
+	  off = 0;
+	}
+    }
+
+  if (rn > prec)
+    {
+      ign += rn - prec;
+      rp += rn - prec;
+      rn = prec;
+    }
+
+  MPN_COPY_INCR (passed_rp, rp + off, rn);
+  *ignp = ign;
+  return rn;
+}
+
+int
+mpf_set_str (mpf_ptr x, const char *str, int base)
+{
+  size_t str_size;
+  char *s, *begs;
+  size_t i, j;
+  int c;
+  int negative;
+  char *dotpos;
+  const char *expptr;
+  int exp_base;
+  const char  *point = GMP_DECIMAL_POINT;
+  size_t      pointlen = strlen (point);
+  const unsigned char *digit_value;
+  int incr;
+  size_t n_zeros_skipped;
+
+  TMP_DECL;
+
+  c = (unsigned char) *str;
+
+  /* Skip whitespace.  */
+  while (isspace (c))
+    c = (unsigned char) *++str;
+
+  negative = 0;
+  if (c == '-')
+    {
+      negative = 1;
+      c = (unsigned char) *++str;
+    }
+
+  /* Default base to decimal.  */
+  if (base == 0)
+    base = 10;
+
+  exp_base = base;
+
+  if (base < 0)
+    {
+      exp_base = 10;
+      base = -base;
+    }
+
+  digit_value = digit_value_tab;
+  if (base > 36)
+    {
+      /* For bases > 36, use the collating sequence
+	 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz.  */
+      digit_value += 208;
+      if (base > 62)
+	return -1;		/* too large base */
+    }
+
+  /* Require at least one digit, possibly after an initial decimal point.  */
+  if (digit_value[c] >= base)
+    {
+      /* not a digit, must be a decimal point */
+      for (i = 0; i < pointlen; i++)
+	if (str[i] != point[i])
+	  return -1;
+      if (digit_value[(unsigned char) str[pointlen]] >= base)
+	return -1;
+    }
+
+  /* Locate exponent part of the input.  Look from the right of the string,
+     since the exponent is usually a lot shorter than the mantissa.  */
+  expptr = NULL;
+  str_size = strlen (str);
+  for (i = str_size - 1; i > 0; i--)
+    {
+      c = (unsigned char) str[i];
+      if (c == '@' || (base <= 10 && (c == 'e' || c == 'E')))
+	{
+	  expptr = str + i + 1;
+	  str_size = i;
+	  break;
+	}
+    }
+
+  TMP_MARK;
+  s = begs = (char *) TMP_ALLOC (str_size + 1);
+
+  incr = 0;
+  n_zeros_skipped = 0;
+  dotpos = NULL;
+
+  /* Loop through mantissa, converting it from ASCII to raw byte values.  */
+  for (i = 0; i < str_size; i++)
+    {
+      c = (unsigned char) *str;
+      if (!isspace (c))
+	{
+	  int dig;
+
+	  for (j = 0; j < pointlen; j++)
+	    if (str[j] != point[j])
+	      goto not_point;
+	  if (1)
+	    {
+	      if (dotpos != 0)
+		{
+		  /* already saw a decimal point, another is invalid */
+		  TMP_FREE;
+		  return -1;
+		}
+	      dotpos = s;
+	      str += pointlen - 1;
+	      i += pointlen - 1;
+	    }
+	  else
+	    {
+	    not_point:
+	      dig = digit_value[c];
+	      if (dig >= base)
+		{
+		  TMP_FREE;
+		  return -1;
+		}
+	      *s = dig;
+	      incr |= dig != 0;
+	      s += incr;	/* Increment after first non-0 digit seen. */
+	      if (dotpos != NULL)
+		/* Count skipped zeros between radix point and first non-0
+		   digit. */
+		n_zeros_skipped += 1 - incr;
+	    }
+	}
+      c = (unsigned char) *++str;
+    }
+
+  str_size = s - begs;
+
+  {
+    long exp_in_base;
+    mp_size_t ra, ma, rn, mn;
+    int cnt;
+    mp_ptr mp, tp, rp;
+    mp_exp_t exp_in_limbs;
+    mp_size_t prec = PREC(x) + 1;
+    int divflag;
+    mp_size_t madj, radj;
+
+#if 0
+    size_t n_chars_needed;
+
+    /* This needs careful testing.  Leave disabled for now.  */
+    /* Just consider the relevant leading digits of the mantissa.  */
+    LIMBS_PER_DIGIT_IN_BASE (n_chars_needed, prec, base);
+    if (str_size > n_chars_needed)
+      str_size = n_chars_needed;
+#endif
+
+    if (str_size == 0)
+      {
+	SIZ(x) = 0;
+	EXP(x) = 0;
+	TMP_FREE;
+	return 0;
+      }
+
+    LIMBS_PER_DIGIT_IN_BASE (ma, str_size, base);
+    mp = TMP_ALLOC_LIMBS (ma);
+    mn = mpn_set_str (mp, (unsigned char *) begs, str_size, base);
+
+    madj = 0;
+    /* Ignore excess limbs in MP,MSIZE.  */
+    if (mn > prec)
+      {
+	madj = mn - prec;
+	mp += mn - prec;
+	mn = prec;
+      }
+
+    if (expptr != 0)
+      {
+	/* Scan and convert the exponent, in base exp_base.  */
+	long dig, minus, plusminus;
+	c = (unsigned char) *expptr;
+	minus = -(long) (c == '-');
+	plusminus = minus | -(long) (c == '+');
+	expptr -= plusminus;			/* conditional increment */
+	c = (unsigned char) *expptr++;
+	dig = digit_value[c];
+	if (dig >= exp_base)
+	  {
+	    TMP_FREE;
+	    return -1;
+	  }
+	exp_in_base = dig;
+	c = (unsigned char) *expptr++;
+	dig = digit_value[c];
+	while (dig < exp_base)
+	  {
+	    exp_in_base = exp_in_base * exp_base;
+	    exp_in_base += dig;
+	    c = (unsigned char) *expptr++;
+	    dig = digit_value[c];
+	  }
+	exp_in_base = (exp_in_base ^ minus) - minus; /* conditional negation */
+      }
+    else
+      exp_in_base = 0;
+    if (dotpos != 0)
+      exp_in_base -= s - dotpos + n_zeros_skipped;
+    divflag = exp_in_base < 0;
+    exp_in_base = ABS (exp_in_base);
+
+    if (exp_in_base == 0)
+      {
+	MPN_COPY (PTR(x), mp, mn);
+	SIZ(x) = negative ? -mn : mn;
+	EXP(x) = mn + madj;
+	TMP_FREE;
+	return 0;
+      }
+
+    ra = 2 * (prec + 1);
+    TMP_ALLOC_LIMBS_2 (rp, ra, tp, ra);
+    rn = mpn_pow_1_highpart (rp, &radj, (mp_limb_t) base, exp_in_base, prec, tp);
+
+    if (divflag)
+      {
+#if 0
+	/* FIXME: Should use mpn_div_q here.  */
+	...
+	mpn_div_q (tp, mp, mn, rp, rn, scratch);
+	...
+#else
+	mp_ptr qp;
+	mp_limb_t qlimb;
+	if (mn < rn)
+	  {
+	    /* Pad out MP,MSIZE for current divrem semantics.  */
+	    mp_ptr tmp = TMP_ALLOC_LIMBS (rn + 1);
+	    MPN_ZERO (tmp, rn - mn);
+	    MPN_COPY (tmp + rn - mn, mp, mn);
+	    mp = tmp;
+	    madj -= rn - mn;
+	    mn = rn;
+	  }
+	if ((rp[rn - 1] & GMP_NUMB_HIGHBIT) == 0)
+	  {
+	    mp_limb_t cy;
+	    count_leading_zeros (cnt, rp[rn - 1]);
+	    cnt -= GMP_NAIL_BITS;
+	    mpn_lshift (rp, rp, rn, cnt);
+	    cy = mpn_lshift (mp, mp, mn, cnt);
+	    if (cy)
+	      mp[mn++] = cy;
+	  }
+
+	qp = TMP_ALLOC_LIMBS (prec + 1);
+	qlimb = mpn_divrem (qp, prec - (mn - rn), mp, mn, rp, rn);
+	tp = qp;
+	exp_in_limbs = qlimb + (mn - rn) + (madj - radj);
+	rn = prec;
+	if (qlimb != 0)
+	  {
+	    tp[prec] = qlimb;
+	    /* Skip the least significant limb not to overrun the destination
+	       variable.  */
+	    tp++;
+	  }
+#endif
+      }
+    else
+      {
+	tp = TMP_ALLOC_LIMBS (rn + mn);
+	if (rn > mn)
+	  mpn_mul (tp, rp, rn, mp, mn);
+	else
+	  mpn_mul (tp, mp, mn, rp, rn);
+	rn += mn;
+	rn -= tp[rn - 1] == 0;
+	exp_in_limbs = rn + madj + radj;
+
+	if (rn > prec)
+	  {
+	    tp += rn - prec;
+	    rn = prec;
+	    exp_in_limbs += 0;
+	  }
+      }
+
+    MPN_COPY (PTR(x), tp, rn);
+    SIZ(x) = negative ? -rn : rn;
+    EXP(x) = exp_in_limbs;
+    TMP_FREE;
+    return 0;
+  }
+}