// File: /workspace/github_cpp_makefile_star2_O1/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 0x34c03
movq %rcx, %r15
movq %rdx, %r11
movl %esi, %r14d
leal -0x1(%r14), %eax
testl %eax, %esi
jne 0x34c11
movslq %r14d, %rax
leaq (%rax,%rax,4), %rax
leaq 0x35d8(%rip), %rcx      # 0x38130
movq 0x18(%rcx,%rax,8), %rsi
leaq -0x1(%r15), %rdi
movq -0x8(%r11,%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
subl %edx, %r9d
movl %edi, %r10d
shll $0x6, %r10d
testl %edx, %edx
cmovel %edx, %r9d
movl $0xffffffff, %eax       # imm = 0xFFFFFFFF
movl %esi, %ecx
shll %cl, %eax
subl %r10d, %r9d
addl %r9d, %r15d
notl %eax
movq %rbx, %r12
subl %esi, %r15d
js 0x34bc6
movq %r8, %rdx
movl %r15d, %ecx
shrq %cl, %rdx
andl %eax, %edx
movb %dl, (%r12)
incq %r12
jmp 0x34bad
testq %rdi, %rdi
jle 0x34c8f
movl %r15d, %ecx
negb %cl
shlq %cl, %r8
movl %eax, %edx
andl %r8d, %edx
movq -0x8(%r11,%rdi,8), %r8
decq %rdi
movl %r15d, %r9d
addl $0x40, %r9d
movq %r8, %r10
movl %r15d, %ecx
shrq %cl, %r10
orl %edx, %r10d
movb %r10b, (%r12)
incq %r12
movl %r9d, %r15d
jmp 0x34bad
movb $0x0, (%rbx)
movl $0x1, %r12d
jmp 0x34f35
cmpq $0x1c, %r15
jle 0x34c79
movq %r11, 0x28(%rsp)
leaq 0x68(%rsp), %rdi
movq $0x0, (%rdi)
leaq 0x400(,%r15,8), %rsi
callq 0x30170
movq %rax, %r13
movslq %r14d, %rax
leaq (%rax,%rax,4), %rdx
leaq 0x34ea(%rip), %rsi      # 0x38130
movq 0x8(%rsi,%rdx,8), %rax
movq 0x18(%rsi,%rdx,8), %rcx
movq %rcx, 0x20(%rsp)
movslq (%rsi,%rdx,8), %rdi
movq %r15, %rdx
shlq $0x6, %rdx
movq %rdx, 0x60(%rsp)
mulq 0x60(%rsp)
cmpq %rdi, %rdx
movq %rbx, 0x30(%rsp)
jae 0x34c97
xorl %r8d, %r8d
jmp 0x34cbc
movq %rbx, %rdi
xorl %esi, %esi
movq %r11, %rdx
movq %r15, %rcx
movl %r14d, %r8d
callq 0x34f56
movq %rax, %r12
subq %rbx, %r12
jmp 0x34f35
xorl %r8d, %r8d
movq %rdx, %rax
xorl %edx, %edx
divq %rdi
incq %rax
movq %rax, 0xa70(%rsp,%r8,8)
incq %r8
incq %rax
sarq %rax
cmpq $0x1, %rax
jne 0x34ca5
movl $0x1, %edx
movq %rdx, 0xa70(%rsp,%r8,8)
leaq 0x20(%rsp), %rsi
movq %rsi, 0x70(%rsp)
movq %rdx, 0x78(%rsp)
movq %rdi, 0x88(%rsp)
movl %r14d, 0x90(%rsp)
xorl %eax, %eax
movq %rax, 0x80(%rsp)
movq %r13, 0x98(%rsp)
movq %rcx, (%r13)
movq %rdx, 0xa0(%rsp)
movq %rdi, 0x8(%rsp)
movq %rdi, 0xb0(%rsp)
movq %r14, 0x40(%rsp)
movl %r14d, 0xb8(%rsp)
movq %rax, 0xa8(%rsp)
cmpq $0x3, %r8
movq %r8, 0x10(%rsp)
jb 0x34e7c
leaq 0x80(%r15), %rax
leaq (,%rax,8), %rax
addq %r13, %rax
movq %rax, 0x38(%rsp)
addq $0x10, %r13
movl $0x1, %edi
movl $0x2, %r12d
xorl %r14d, %r14d
movq 0x8(%rsp), %rdx
movl $0x1, %ebp
movq %rbp, %rax
shlq $0x4, %rax
addq %r13, %rax
addq $0x10, %rax
cmpq 0x38(%rsp), %rax
jae 0x34f4a
movq %rax, 0x48(%rsp)
leaq (,%rbp,2), %rbx
movq %rdi, 0x18(%rsp)
movq %r13, %rdi
movq %r12, 0x50(%rsp)
movq %rdx, %r12
movq %rbp, %rdx
callq 0x1da3c
movq 0x18(%rsp), %rdi
movq %r12, %rdx
movq 0x50(%rsp), %r12
movq 0x10(%rsp), %r8
addq %rdx, %rdx
cmpq $0x1, -0x8(%r13,%rbx,8)
movq %rbx, %rbp
sbbq $0x0, %rbp
leaq 0x1(,%rdi,2), %rbx
movq %r8, %rax
subq %r12, %rax
cmpq 0xa70(%rsp,%rax,8), %rbx
jge 0x34e1b
addq 0x8(%rsp), %rdx
movq %rdx, 0x18(%rsp)
movq 0x20(%rsp), %rcx
movq %r13, %rdi
movq %r13, %rsi
movq %rbp, %rdx
callq 0x1c386
movq 0x18(%rsp), %rdx
movq 0x10(%rsp), %r8
movq %rax, (%r13,%rbp,8)
cmpq $0x1, %rax
sbbq $-0x1, %rbp
movq %rbx, %rdi
jmp 0x34e1e
addq %rdi, %rdi
addq %r14, %r14
cmpq $0x0, (%r13)
je 0x34e2d
movq %r13, %rsi
jmp 0x34e41
leaq 0x8(%r13), %rsi
decq %rbp
incq %r14
cmpq $0x0, 0x8(%r13)
movq %rsi, %r13
je 0x34e2d
leaq (%r12,%r12,4), %rax
movq %rsi, 0x70(%rsp,%rax,8)
movq %rbp, 0x78(%rsp,%rax,8)
movq %rdx, 0x88(%rsp,%rax,8)
movq 0x40(%rsp), %rcx
movl %ecx, 0x90(%rsp,%rax,8)
movq %r14, 0x80(%rsp,%rax,8)
incq %r12
movq 0x48(%rsp), %r13
cmpq %r8, %r12
jne 0x34d6a
cmpq $0x2, %r8
movl $0x1, %ebx
jb 0x34eeb
leaq 0xb0(%rsp), %rbx
leaq -0x1(%r8), %r14
movq 0x8(%rsp), %rbp
movq -0x18(%rbx), %r13
movq -0x10(%rbx), %r12
movq 0x20(%rsp), %rcx
movq %r13, %rdi
movq %r13, %rsi
movq %r12, %rdx
callq 0x1c386
movq %rax, (%r13,%r12,8)
cmpq $0x1, %rax
sbbq $-0x1, %r12
cmpq $0x0, (%r13)
jne 0x34ed6
addq $0x8, %r13
movq %r13, -0x18(%rbx)
decq %r12
incq -0x8(%rbx)
movq %r12, -0x10(%rbx)
addq %rbp, (%rbx)
addq $0x28, %rbx
decq %r14
jne 0x34e98
movq 0x10(%rsp), %rbx
leaq 0x200(,%r15,8), %rsi
leaq 0x68(%rsp), %r13
movq %r13, %rdi
callq 0x30170
leaq (%rbx,%rbx,4), %rcx
leaq (%rsp,%rcx,8), %r8
addq $0x48, %r8
movq 0x30(%rsp), %rbx
movq %rbx, %rdi
xorl %esi, %esi
movq 0x28(%rsp), %rdx
movq %r15, %rcx
movq %rax, %r9
callq 0x3525d
movq %rax, %r12
subq %rbx, %r12
movq (%r13), %rdi
testq %rdi, %rdi
jne 0x34f4f
movq %r12, %rax
addq $0xc78, %rsp            # imm = 0xC78
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
callq 0x75c4
callq 0x301a3
jmp 0x34f35