// File: /workspace/github_cpp_makefile_star2_O3/occivink[P]pyct/monocypher.cpp
// Function: invsqrt(int*, int const*)
static int invsqrt(fe isr, const fe x)
{
    fe t0, t1, t2;

    // t0 = x^((p-5)/8)
    // Can be achieved with a simple double & add ladder,
    // but it would be slower.
    fe_sq(t0, x);
    fe_sq(t1,t0);                   fe_sq(t1, t1);  fe_mul(t1, x, t1);
    fe_mul(t0, t0, t1);
    fe_sq(t0, t0);                                  fe_mul(t0, t1, t0);
    fe_sq(t1, t0);  FOR (i, 1,   5) fe_sq(t1, t1);  fe_mul(t0, t1, t0);
    fe_sq(t1, t0);  FOR (i, 1,  10) fe_sq(t1, t1);  fe_mul(t1, t1, t0);
    fe_sq(t2, t1);  FOR (i, 1,  20) fe_sq(t2, t2);  fe_mul(t1, t2, t1);
    fe_sq(t1, t1);  FOR (i, 1,  10) fe_sq(t1, t1);  fe_mul(t0, t1, t0);
    fe_sq(t1, t0);  FOR (i, 1,  50) fe_sq(t1, t1);  fe_mul(t1, t1, t0);
    fe_sq(t2, t1);  FOR (i, 1, 100) fe_sq(t2, t2);  fe_mul(t1, t2, t1);
    fe_sq(t1, t1);  FOR (i, 1,  50) fe_sq(t1, t1);  fe_mul(t0, t1, t0);
    fe_sq(t0, t0);  FOR (i, 1,   2) fe_sq(t0, t0);  fe_mul(t0, t0, x);

    // quartic = x^((p-1)/4)
    i32 *quartic = t1;
    fe_sq (quartic, t0);
    fe_mul(quartic, quartic, x);

    i32 *check = t2;
    fe_0  (check);          int z0 = fe_isequal(x      , check);
    fe_1  (check);          int p1 = fe_isequal(quartic, check);
    fe_neg(check, check );  int m1 = fe_isequal(quartic, check);
    fe_neg(check, sqrtm1);  int ms = fe_isequal(quartic, check);

    // if quartic == -1 or sqrt(-1)
    // then  isr = x^((p-1)/4) * sqrt(-1)
    // else  isr = x^((p-1)/4)
    fe_mul(isr, t0, sqrtm1);
    fe_ccopy(isr, t0, 1 - (m1 | ms));

    WIPE_BUFFER(t0);
    WIPE_BUFFER(t1);
    WIPE_BUFFER(t2);
    return p1 | m1 | z0;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r12
pushq %rbx
subq $0x90, %rsp
movq %rsi, %r14
movq %rdi, %rbx
leaq 0x60(%rsp), %r12
movq %r12, %rdi
callq 0x82b2
movq %rsp, %r15
movq %r15, %rdi
movq %r12, %rsi
callq 0x82b2
movq %r15, %rdi
movq %r15, %rsi
callq 0x82b2
movq %r15, %rdi
movq %r14, %rsi
movq %r15, %rdx
callq 0x7075
movq %r12, %rdi
movq %r12, %rsi
movq %r15, %rdx
callq 0x7075
movq %r12, %rdi
movq %r12, %rsi
callq 0x82b2
movq %r12, %rdi
movq %r15, %rsi
movq %r12, %rdx
callq 0x7075
movq %r15, %rdi
movq %r12, %rsi
callq 0x82b2
movl $0x4, %r12d
movq %r15, %rdi
movq %r15, %rsi
callq 0x82b2
decq %r12
jne 0x8814
movq %rsp, %r15
leaq 0x60(%rsp), %r12
movq %r12, %rdi
movq %r15, %rsi
movq %r12, %rdx
callq 0x7075
movq %r15, %rdi
movq %r12, %rsi
callq 0x82b2
movl $0x9, %r12d
movq %r15, %rdi
movq %r15, %rsi
callq 0x82b2
decq %r12
jne 0x884b
movq %rsp, %r12
leaq 0x60(%rsp), %rdx
movq %r12, %rdi
movq %r12, %rsi
callq 0x7075
leaq 0x30(%rsp), %r15
movq %r15, %rdi
movq %r12, %rsi
callq 0x82b2
movl $0x13, %r12d
movq %r15, %rdi
movq %r15, %rsi
callq 0x82b2
decq %r12
jne 0x8884
leaq 0x30(%rsp), %rsi
movq %rsp, %r15
movq %r15, %rdi
movq %r15, %rdx
callq 0x7075
movq %r15, %rdi
movq %r15, %rsi
callq 0x82b2
movl $0x9, %r12d
movq %r15, %rdi
movq %r15, %rsi
callq 0x82b2
decq %r12
jne 0x88b8
movq %rsp, %r15
leaq 0x60(%rsp), %r12
movq %r12, %rdi
movq %r15, %rsi
movq %r12, %rdx
callq 0x7075
movq %r15, %rdi
movq %r12, %rsi
callq 0x82b2
movl $0x31, %r12d
movq %r15, %rdi
movq %r15, %rsi
callq 0x82b2
decq %r12
jne 0x88ef
movq %rsp, %r12
leaq 0x60(%rsp), %rdx
movq %r12, %rdi
movq %r12, %rsi
callq 0x7075
leaq 0x30(%rsp), %r15
movq %r15, %rdi
movq %r12, %rsi
callq 0x82b2
movl $0x63, %r12d
movq %r15, %rdi
movq %r15, %rsi
callq 0x82b2
decq %r12
jne 0x8928
leaq 0x30(%rsp), %rsi
movq %rsp, %r15
movq %r15, %rdi
movq %r15, %rdx
callq 0x7075
movq %r15, %rdi
movq %r15, %rsi
callq 0x82b2
movl $0x31, %r12d
movq %r15, %rdi
movq %r15, %rsi
callq 0x82b2
decq %r12
jne 0x895c
movq %rsp, %r15
leaq 0x60(%rsp), %r12
movq %r12, %rdi
movq %r15, %rsi
movq %r12, %rdx
callq 0x7075
movq %r12, %rdi
movq %r12, %rsi
callq 0x82b2
movq %r12, %rdi
movq %r12, %rsi
callq 0x82b2
movq %r12, %rdi
movq %r12, %rsi
movq %r14, %rdx
callq 0x7075
movq %r15, %rdi
movq %r12, %rsi
callq 0x82b2
movq %r15, %rdi
movq %r15, %rsi
movq %r14, %rdx
callq 0x7075
xorps %xmm0, %xmm0
leaq 0x30(%rsp), %r12
movaps %xmm0, 0x10(%r12)
movaps %xmm0, (%r12)
movq $0x0, 0x20(%r12)
movq %r14, %rdi
movq %r12, %rsi
callq 0x9dbf
movl %eax, %ebp
movl $0x1, (%r12)
xorps %xmm0, %xmm0
movups %xmm0, 0x4(%r12)
movups %xmm0, 0x14(%r12)
movl $0x0, 0x24(%r12)
movq %r15, %rdi
movq %r12, %rsi
callq 0x9dbf
movl %eax, %r14d
xorl %eax, %eax
negl 0x30(%rsp,%rax,4)
incq %rax
cmpq $0xa, %rax
jne 0x8a18
movq %rsp, %rdi
leaq 0x30(%rsp), %rsi
callq 0x9dbf
movl %eax, %r15d
xorl %eax, %eax
leaq 0x4732(%rip), %rcx      # 0xd170
xorl %edx, %edx
subl (%rax,%rcx), %edx
movl %edx, 0x30(%rsp,%rax)
addq $0x4, %rax
cmpq $0x28, %rax
jne 0x8a3e
movq %rsp, %rdi
leaq 0x30(%rsp), %rsi
callq 0x9dbf
movl %eax, %r12d
leaq 0x4708(%rip), %rdx      # 0xd170
leaq 0x60(%rsp), %rsi
movq %rbx, %rdi
callq 0x7075
orl %r15d, %r12d
xorl %eax, %eax
testl %r12d, %r12d
leaq (%rbx,%rax,4), %rcx
leaq 0x60(%rsp,%rax,4), %rdx
cmovneq %rcx, %rdx
movl (%rdx), %edx
movl %edx, (%rcx)
incq %rax
cmpq $0xa, %rax
jne 0x8a7a
xorl %eax, %eax
movb $0x0, 0x60(%rsp,%rax)
incq %rax
cmpq $0x28, %rax
jne 0x8a99
xorl %eax, %eax
movb $0x0, (%rsp,%rax)
incq %rax
cmpq $0x28, %rax
jne 0x8aa9
xorl %eax, %eax
movb $0x0, 0x30(%rsp,%rax)
incq %rax
cmpq $0x28, %rax
jne 0x8ab8
orl %ebp, %r14d
orl %r15d, %r14d
movl %r14d, %eax
addq $0x90, %rsp
popq %rbx
popq %r12
popq %r14
popq %r15
popq %rbp
retq