// File: /workspace/github_cpp_makefile_star2_O2/marxn[P]pupp/3rdparty/gmp/mpn/get_str.c
// Function: _gmpn_get_str
size_t
mpn_get_str (unsigned char *str, int base, mp_ptr up, mp_size_t un)
{
  mp_ptr powtab_mem, powtab_mem_ptr;
  mp_limb_t big_base;
  size_t digits_in_base;
  powers_t powtab[GMP_LIMB_BITS];
  int pi;
  mp_size_t n;
  mp_ptr p, t;
  size_t out_len;
  mp_ptr tmp;
  TMP_DECL;

  /* Special case zero, as the code below doesn't handle it.  */
  if (un == 0)
    {
      str[0] = 0;
      return 1;
    }

  if (POW2_P (base))
    {
      /* The base is a power of 2.  Convert from most significant end.  */
      mp_limb_t n1, n0;
      int bits_per_digit = mp_bases[base].big_base;
      int cnt;
      int bit_pos;
      mp_size_t i;
      unsigned char *s = str;
      mp_bitcnt_t bits;

      n1 = up[un - 1];
      count_leading_zeros (cnt, n1);

      /* BIT_POS should be R when input ends in least significant nibble,
	 R + bits_per_digit * n when input ends in nth least significant
	 nibble. */

      bits = (mp_bitcnt_t) GMP_NUMB_BITS * un - cnt + GMP_NAIL_BITS;
      cnt = bits % bits_per_digit;
      if (cnt != 0)
	bits += bits_per_digit - cnt;
      bit_pos = bits - (mp_bitcnt_t) (un - 1) * GMP_NUMB_BITS;

      /* Fast loop for bit output.  */
      i = un - 1;
      for (;;)
	{
	  bit_pos -= bits_per_digit;
	  while (bit_pos >= 0)
	    {
	      *s++ = (n1 >> bit_pos) & ((1 << bits_per_digit) - 1);
	      bit_pos -= bits_per_digit;
	    }
	  i--;
	  if (i < 0)
	    break;
	  n0 = (n1 << -bit_pos) & ((1 << bits_per_digit) - 1);
	  n1 = up[i];
	  bit_pos += GMP_NUMB_BITS;
	  *s++ = n0 | (n1 >> bit_pos);
	}

      return s - str;
    }

  /* General case.  The base is not a power of 2.  */

  if (BELOW_THRESHOLD (un, GET_STR_PRECOMPUTE_THRESHOLD))
    return mpn_sb_get_str (str, (size_t) 0, up, un, base) - str;

  TMP_MARK;

  /* Allocate one large block for the powers of big_base.  */
  powtab_mem = TMP_BALLOC_LIMBS (mpn_dc_get_str_powtab_alloc (un));
  powtab_mem_ptr = powtab_mem;

  /* Compute a table of powers, were the largest power is >= sqrt(U).  */

  big_base = mp_bases[base].big_base;
  digits_in_base = mp_bases[base].chars_per_limb;

  {
    mp_size_t n_pows, xn, pn, exptab[GMP_LIMB_BITS], bexp;
    mp_limb_t cy;
    mp_size_t shift;
    size_t ndig;

    DIGITS_IN_BASE_PER_LIMB (ndig, un, base);
    xn = 1 + ndig / mp_bases[base].chars_per_limb; /* FIXME: scalar integer division */

    n_pows = 0;
    for (pn = xn; pn != 1; pn = (pn + 1) >> 1)
      {
	exptab[n_pows] = pn;
	n_pows++;
      }
    exptab[n_pows] = 1;

    powtab[0].p = &big_base;
    powtab[0].n = 1;
    powtab[0].digits_in_base = digits_in_base;
    powtab[0].base = base;
    powtab[0].shift = 0;

    powtab[1].p = powtab_mem_ptr;  powtab_mem_ptr += 2;
    powtab[1].p[0] = big_base;
    powtab[1].n = 1;
    powtab[1].digits_in_base = digits_in_base;
    powtab[1].base = base;
    powtab[1].shift = 0;

    n = 1;
    p = &big_base;
    bexp = 1;
    shift = 0;
    for (pi = 2; pi < n_pows; pi++)
      {
	t = powtab_mem_ptr;
	powtab_mem_ptr += 2 * n + 2;

	ASSERT_ALWAYS (powtab_mem_ptr < powtab_mem + mpn_dc_get_str_powtab_alloc (un));

	mpn_sqr (t, p, n);

	digits_in_base *= 2;
	n *= 2;  n -= t[n - 1] == 0;
	bexp *= 2;

	if (bexp + 1 < exptab[n_pows - pi])
	  {
	    digits_in_base += mp_bases[base].chars_per_limb;
	    cy = mpn_mul_1 (t, t, n, big_base);
	    t[n] = cy;
	    n += cy != 0;
	    bexp += 1;
	  }
	shift *= 2;
	/* Strip low zero limbs.  */
	while (t[0] == 0)
	  {
	    t++;
	    n--;
	    shift++;
	  }
	p = t;
	powtab[pi].p = p;
	powtab[pi].n = n;
	powtab[pi].digits_in_base = digits_in_base;
	powtab[pi].base = base;
	powtab[pi].shift = shift;
      }

    for (pi = 1; pi < n_pows; pi++)
      {
	t = powtab[pi].p;
	n = powtab[pi].n;
	cy = mpn_mul_1 (t, t, n, big_base);
	t[n] = cy;
	n += cy != 0;
	if (t[0] == 0)
	  {
	    powtab[pi].p = t + 1;
	    n--;
	    powtab[pi].shift++;
	  }
	powtab[pi].n = n;
	powtab[pi].digits_in_base += mp_bases[base].chars_per_limb;
      }

#if 0
    { int i;
      printf ("Computed table values for base=%d, un=%d, xn=%d:\n", base, un, xn);
      for (i = 0; i < n_pows; i++)
	printf ("%2d: %10ld %10ld %11ld %ld\n", i, exptab[n_pows-i], powtab[i].n, powtab[i].digits_in_base, powtab[i].shift);
    }
#endif
  }

  /* Using our precomputed powers, now in powtab[], convert our number.  */
  tmp = TMP_BALLOC_LIMBS (mpn_dc_get_str_itch (un));
  out_len = mpn_dc_get_str (str, 0, up, un, powtab + (pi - 1), tmp) - str;
  TMP_FREE;

  return out_len;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0xc78, %rsp            # imm = 0xC78
movq %rdi, %rbx
testq %rcx, %rcx
je 0x2de30
movq %rcx, %r15
movq %rdx, %r13
movl %esi, %ebp
leal -0x1(%rbp), %eax
testl %eax, %esi
jne 0x2de3c
movslq %ebp, %rax
imulq $0x28, %rax, %rax
leaq 0x33aa(%rip), %rcx      # 0x31120
movq 0x18(%rcx,%rax), %rsi
leaq -0x1(%r15), %rdi
movq -0x8(%r13,%r15,8), %r8
movq %r8, 0x58(%rsp)
bsrq 0x58(%rsp), %rax
shlq $0x6, %r15
cltq
xorq $0x3f, %rax
subq %rax, %r15
movslq %esi, %r9
movq %r15, %rax
xorl %edx, %edx
divq %r9
movl %r9d, %eax
subl %edx, %eax
movl %edi, %ecx
shll $0x6, %ecx
testl %edx, %edx
cmovel %edx, %eax
subl %ecx, %eax
addl %eax, %r15d
pushq $-0x1
popq %rax
movl %esi, %ecx
shll %cl, %eax
notl %eax
negl %r9d
movq %rbx, %rdx
negq %rdx
addl %r9d, %r15d
leaq (%rdx,%rbx), %r12
incq %rbx
testl %r15d, %r15d
js 0x2ddf5
movq %r8, %r10
movl %r15d, %ecx
shrq %cl, %r10
movl %eax, %ecx
andl %r10d, %ecx
movb %cl, -0x1(%rbx)
subl %esi, %r15d
incq %r12
jmp 0x2ddd4
testq %rdi, %rdi
jle 0x2e121
movl %r15d, %ecx
negb %cl
shlq %cl, %r8
movl %eax, %r10d
andl %r8d, %r10d
movq -0x8(%r13,%rdi,8), %r8
decq %rdi
movl %r15d, %r11d
movq %r8, %r14
movl %r15d, %ecx
shrq %cl, %r14
addl $0x40, %r11d
orl %r10d, %r14d
movb %r14b, -0x1(%rbx)
movl %r11d, %r15d
jmp 0x2ddcd
movb $0x0, (%rbx)
pushq $0x1
popq %r12
jmp 0x2e121
cmpq $0x1c, %r15
jle 0x2dec8
movq %r13, 0x28(%rsp)
leaq 0x68(%rsp), %rdi
andq $0x0, (%rdi)
leaq 0x80(%r15), %r14
leaq 0x400(,%r15,8), %rsi
callq 0x29dc0
movq %rax, %r13
movslq %ebp, %rax
imulq $0x28, %rax, %rdx
leaq 0x32a7(%rip), %rsi      # 0x31120
movq 0x8(%rsi,%rdx), %rax
movq 0x18(%rsi,%rdx), %rcx
movq %rcx, 0x18(%rsp)
movslq (%rsi,%rdx), %rsi
movq %r15, %rdx
shlq $0x6, %rdx
movq %rdx, 0x60(%rsp)
mulq 0x60(%rsp)
movq %rdx, %rax
xorl %edi, %edi
xorl %edx, %edx
movq %rsi, 0x8(%rsp)
divq %rsi
incq %rax
cmpq $0x1, %rax
je 0x2dee6
movq %rax, 0xa70(%rsp,%rdi,8)
incq %rdi
incq %rax
sarq %rax
jmp 0x2deaf
movq %rbx, %rdi
xorl %esi, %esi
movq %r13, %rdx
movq %r15, %rcx
movl %ebp, %r8d
callq 0x2e155
movq %rax, %r12
subq %rbx, %r12
jmp 0x2e121
pushq $0x1
popq %rdx
leaq 0x18(%rsp), %rsi
movq %rsi, 0x70(%rsp)
movq %rdx, 0x78(%rsp)
movq 0x8(%rsp), %rax
movq %rax, 0x88(%rsp)
movl %ebp, 0x90(%rsp)
andq $0x0, 0x80(%rsp)
movq %r13, 0x98(%rsp)
movq %rdx, 0xa0(%rsp)
movq %rax, 0xb0(%rsp)
movl %ebp, 0xb8(%rsp)
andq $0x0, 0xa8(%rsp)
movq %rdx, 0xa70(%rsp,%rdi,8)
movq %rcx, (%r13)
leaq (,%r14,8), %rcx
addq %r13, %rcx
movq %rcx, 0x38(%rsp)
addq $0x10, %r13
pushq $0x2
popq %rcx
xorl %r14d, %r14d
movq %rdx, %r9
movq %rax, %r8
movq %rdi, 0x20(%rsp)
movq %rbp, 0x30(%rsp)
movq %rdi, %r12
subq %rcx, %r12
jbe 0x2e078
movq %rdx, %rax
shlq $0x4, %rax
addq %r13, %rax
addq $0x10, %rax
cmpq 0x38(%rsp), %rax
jae 0x2e136
movq %rax, 0x48(%rsp)
movq %rcx, 0x50(%rsp)
leaq (%rdx,%rdx), %rbp
movq %r13, %rdi
movq %r8, 0x10(%rsp)
movq %r9, 0x40(%rsp)
callq 0x196c0
movq 0x40(%rsp), %r9
movq 0x10(%rsp), %r8
addq %r8, %r8
cmpq $0x1, -0x8(%r13,%rbp,8)
sbbq $0x0, %rbp
leaq 0x1(,%r9,2), %rax
cmpq 0xa70(%rsp,%r12,8), %rax
jge 0x2e018
addq 0x8(%rsp), %r8
movq %r8, 0x10(%rsp)
movq 0x18(%rsp), %rcx
movq %r13, %rdi
movq %r13, %rsi
movq %rbp, %rdx
movq %rax, %r12
callq 0x18086
movq %r12, %r9
movq 0x10(%rsp), %r8
movq %rax, (%r13,%rbp,8)
cmpq $0x1, %rax
sbbq $-0x1, %rbp
jmp 0x2e01b
addq %r9, %r9
addq %r14, %r14
movq %rbp, %rdx
movq 0x20(%rsp), %rdi
movq 0x30(%rsp), %rbp
movq 0x50(%rsp), %rcx
cmpq $0x0, (%r13)
jne 0x2e043
addq $0x8, %r13
decq %rdx
incq %r14
jmp 0x2e030
imulq $0x28, %rcx, %rax
movq %r13, 0x70(%rsp,%rax)
movq %rdx, 0x78(%rsp,%rax)
movq %r8, 0x88(%rsp,%rax)
movl %ebp, 0x90(%rsp,%rax)
movq %r14, 0x80(%rsp,%rax)
incq %rcx
movq %r13, %rsi
movq 0x48(%rsp), %r13
jmp 0x2df73
pushq $0x1
popq %r14
leaq 0x70(%rsp), %r12
cmpq %r14, %rdi
jbe 0x2e0e5
movq 0x28(%r12), %rbp
movq 0x30(%r12), %r13
movq 0x18(%rsp), %rcx
movq %rbp, %rdi
movq %rbp, %rsi
movq %r13, %rdx
callq 0x18086
movq %rax, (%rbp,%r13,8)
cmpq $0x1, %rax
sbbq $-0x1, %r13
cmpq $0x0, (%rbp)
jne 0x2e0c8
addq $0x8, %rbp
movq %rbp, 0x28(%r12)
decq %r13
incq 0x38(%r12)
movq %r13, 0x30(%r12)
movq 0x8(%rsp), %rax
addq %rax, 0x40(%r12)
incq %r14
addq $0x28, %r12
movq 0x20(%rsp), %rdi
jmp 0x2e081
leaq 0x200(,%r15,8), %rsi
leaq 0x68(%rsp), %r13
movq %r13, %rdi
callq 0x29dc0
movq %rbx, %rdi
xorl %esi, %esi
movq 0x28(%rsp), %rdx
movq %r15, %rcx
movq %r12, %r8
movq %rax, %r9
callq 0x2e3ab
movq %rax, %r12
subq %rbx, %r12
movq (%r13), %rdi
testq %rdi, %rdi
jne 0x2e14e
movq %r12, %rax
addq $0xc78, %rsp            # imm = 0xC78
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
leaq 0x6783(%rip), %rdi      # 0x348c0
leaq 0x6786(%rip), %rdx      # 0x348ca
movl $0x1e9, %esi            # imm = 0x1E9
callq 0x29ce6
callq 0x29df3
jmp 0x2e121