// File: /workspace/github_cpp_makefile_star2_O2/jstaursky[P]hutch/src/Sleigh/address.cc
// Function: power2Divide(int, unsigned long, unsigned long&, unsigned long&)
int4 power2Divide(int4 n,uint8 divisor,uint8 &q,uint8 &r)

{
  if (divisor == 0) return 2;
  uint8 power = 1;
  if (n < 64) {
    power <<= n;
    q = power / divisor;
    r = power % divisor;
    return 0;
  }
  // Divide numerand and divisor by 2^(n-63) to get approximation of result
  uint8 y = divisor >> (n-64);	// Most of the way on divisor
  if (y == 0) return 1;		// Check if result will be too big
  y >>= 1;			// Divide divisor by final bit
  power <<= 63;
  uint8 max;
  if (y == 0) {
    max = 0;
    max -= 1;			// Could be maximal
    // Check if divisor is a power of 2
    if ((((uint8)1) << (n-64)) == divisor)
      return 1;
  }
  else
    max = power / y + 1;
  uint8 min = power / (y+1);
  if (min != 0)
    min -= 1;
  uint8 fullpower[2];
  fullpower[1] = ((uint8)1)<<(n-64);
  fullpower[0] = 0;
  uint8 mult[2];
  mult[0] = 0;
  mult[1] = 0;
  uint8 tmpq = 0;
  while(max > min+1) {
    tmpq = max + min;
    if (tmpq < min) {
      tmpq = (tmpq>>1) + 0x8000000000000000L;
    }
    else
      tmpq >>= 1;
    mult64to128(mult,divisor,tmpq);
    if (unsignedCompare128(fullpower,mult) < 0)
      max = tmpq-1;
    else
      min = tmpq;
  }
  // min is now our putative quotient
  if (tmpq != min)
    mult64to128(mult,divisor,min);
  unsignedSubtract128(fullpower,mult); // Calculate remainder
  // min might be 1 too small
  if (fullpower[1] != 0 || fullpower[0] >= divisor) {
    q = min + 1;
    r = fullpower[0] - divisor;
  }
  else {
    q = min;
    r = fullpower[0];
  }
  return 0;
}

// Assembly:
testq %rsi, %rsi
je 0x53338
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x28, %rsp
movq %rcx, %r9
movq %rdx, %r10
movq %rsi, %r15
cmpl $0x3f, %edi
jg 0x5333c
pushq $0x1
popq %rax
movl %edi, %ecx
shlq %cl, %rax
xorl %edx, %edx
divq %r15
movq %rax, %rcx
xorl %eax, %eax
movq %rcx, (%r10)
movq %rdx, (%r9)
jmp 0x53489
pushq $0x2
popq %rax
retq
movq %r15, %rdx
movl %edi, %ecx
shrq %cl, %rdx
pushq $0x1
popq %rax
testq %rdx, %rdx
je 0x53489
addl $-0x40, %edi
movq %rdx, %r8
shrq %r8
cmpq $0x1, %rdx
jne 0x53380
pushq $0x1
popq %r14
movl %edi, %ecx
shlq %cl, %r14
cmpq %r15, %r14
je 0x53489
movq %r10, (%rsp)
movq %r9, 0x8(%rsp)
pushq $-0x1
popq %r13
jmp 0x533a7
movq %r10, (%rsp)
movq %r9, 0x8(%rsp)
movabsq $-0x8000000000000000, %rax # imm = 0x8000000000000000
xorl %edx, %edx
divq %r8
movq %rax, %r13
incq %r13
pushq $0x1
popq %r14
movl %edi, %ecx
shlq %cl, %r14
incq %r8
xorl %esi, %esi
movabsq $-0x8000000000000000, %rax # imm = 0x8000000000000000
xorl %edx, %edx
divq %r8
movq %rax, %r12
decq %r12
xorps %xmm0, %xmm0
leaq 0x10(%rsp), %rax
movaps %xmm0, (%rax)
xorl %ecx, %ecx
xorl %ebx, %ebx
leaq 0x1(%r12), %rbp
cmpq %rbp, %r13
jbe 0x53430
leaq (%r12,%r13), %rax
shrq %rax
movq %rax, %rbx
btsq $0x3f, %rbx
movq %r12, %rcx
addq %r13, %rcx
cmovaeq %rax, %rbx
leaq 0x10(%rsp), %rdi
movq %r15, %rsi
movq %rbx, %rdx
callq 0x4e590
movq 0x10(%rsp), %rcx
movq 0x18(%rsp), %rsi
xorl %eax, %eax
testq %rcx, %rcx
setne %al
xorl %edx, %edx
cmpq %rsi, %r14
setb %dl
cmovnel %edx, %eax
leaq -0x1(%rbx), %rdx
testb %al, %al
cmovneq %rdx, %r13
cmoveq %rbx, %r12
jmp 0x533d0
cmpq %r12, %rbx
je 0x5344f
leaq 0x10(%rsp), %rbx
movq %rbx, %rdi
movq %r15, %rsi
movq %r12, %rdx
callq 0x4e590
movq (%rbx), %rcx
movq 0x8(%rbx), %rsi
xorl %eax, %eax
negq %rcx
movl $0x0, %edx
sbbq %rdx, %rdx
subq %rsi, %rdx
addq %r14, %rdx
sete %dl
cmpq %r15, %rcx
setb %sil
testb %dl, %sil
cmovneq %r12, %rbp
cmovneq %rax, %r15
subq %r15, %rcx
movq (%rsp), %rdx
movq %rbp, (%rdx)
movq 0x8(%rsp), %rdx
movq %rcx, (%rdx)
addq $0x28, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq