// File: /workspace/github_c_makefile_star2_O0/ioerror[P]csidh-reference-implementation/mont.c
// Function: xISOG
void xISOG(proj *A, proj *P, proj const *K, uint64_t k)
{
    assert (k >= 3);
    assert (k % 2 == 1);

    fp tmp0, tmp1;
    fp T[4] = {K->z, K->x, K->x, K->z};
    proj Q;

    fp_mul3(&Q.x,  &P->x, &K->x);
    fp_mul3(&tmp0, &P->z, &K->z);
    fp_sub2(&Q.x,  &tmp0);

    fp_mul3(&Q.z,  &P->x, &K->z);
    fp_mul3(&tmp0, &P->z, &K->x);
    fp_sub2(&Q.z,  &tmp0);

    proj M[3] = {*K};
    xDBL(&M[1], A, K);

    for (uint64_t i = 1; i < k / 2; ++i) {

        if (i >= 2)
            xADD(&M[i % 3], &M[(i - 1) % 3], K, &M[(i - 2) % 3]);

        fp_mul3(&tmp0, &M[i % 3].x, &T[0]);
        fp_mul3(&tmp1, &M[i % 3].z, &T[1]);
        fp_add3(&T[0], &tmp0, &tmp1);

        fp_mul2(&T[1], &M[i % 3].x);

        fp_mul3(&tmp0, &M[i % 3].z, &T[2]);
        fp_mul3(&tmp1, &M[i % 3].x, &T[3]);
        fp_add3(&T[2], &tmp0, &tmp1);

        fp_mul2(&T[3], &M[i % 3].z);


        fp_mul3(&tmp0, &P->x, &M[i % 3].x);
        fp_mul3(&tmp1, &P->z, &M[i % 3].z);
        fp_sub2(&tmp0, &tmp1);
        fp_mul2(&Q.x,  &tmp0);

        fp_mul3(&tmp0, &P->x, &M[i % 3].z);
        fp_mul3(&tmp1, &P->z, &M[i % 3].x);
        fp_sub2(&tmp0, &tmp1);
        fp_mul2(&Q.z,  &tmp0);
    }

    fp_mul2(&T[0], &T[1]);
    fp_add2(&T[0], &T[0]); /* multiplication by 2 */

    fp_sq1(&T[1]);

    fp_mul2(&T[2], &T[3]);
    fp_add2(&T[2], &T[2]); /* multiplication by 2 */

    fp_sq1(&T[3]);

    /* Ax := T[1] * T[3] * Ax - 3 * Az * (T[1] * T[2] - T[0] * T[3]) */
    fp_mul3(&tmp0, &T[1], &T[2]);
    fp_mul3(&tmp1, &T[0], &T[3]);
    fp_sub2(&tmp0, &tmp1);
    fp_mul2(&tmp0, &A->z);
    fp_add3(&tmp1, &tmp0, &tmp0); fp_add2(&tmp0, &tmp1); /* multiplication by 3 */

    fp_mul3(&tmp1, &T[1], &T[3]);
    fp_mul2(&tmp1, &A->x);

    fp_sub3(&A->x, &tmp1, &tmp0);

    /* Az := Az * T[3]^2 */
    fp_sq1(&T[3]);
    fp_mul2(&A->z, &T[3]);

    /* X := X * Xim^2, Z := Z * Zim^2 */
    fp_sq1(&Q.x);
    fp_sq1(&Q.z);
    fp_mul2(&P->x, &Q.x);
    fp_mul2(&P->z, &Q.z);
}

// Assembly:
subq $0x3d8, %rsp            # imm = 0x3D8
movq %rdi, 0x3d0(%rsp)
movq %rsi, 0x3c8(%rsp)
movq %rdx, 0x3c0(%rsp)
movq %rcx, 0x3b8(%rsp)
cmpq $0x3, 0x3b8(%rsp)
jb 0x2d34
jmp 0x2d53
leaq 0x24ea(%rip), %rdi      # 0x5225
leaq 0x24ea(%rip), %rsi      # 0x522c
movl $0x6d, %edx
leaq 0x24e5(%rip), %rcx      # 0x5233
callq 0x1050
movq 0x3b8(%rsp), %rax
andq $0x1, %rax
cmpq $0x1, %rax
jne 0x2d67
jmp 0x2d86
leaq 0x24f8(%rip), %rdi      # 0x5266
leaq 0x24b7(%rip), %rsi      # 0x522c
movl $0x6e, %edx
leaq 0x24b2(%rip), %rcx      # 0x5233
callq 0x1050
movq 0x3c0(%rsp), %rsi
addq $0x40, %rsi
leaq 0x230(%rsp), %rdi
movl $0x40, %edx
callq 0x1090
leaq 0x230(%rsp), %rdi
addq $0x40, %rdi
movq 0x3c0(%rsp), %rsi
movl $0x40, %edx
callq 0x1090
leaq 0x230(%rsp), %rdi
addq $0x80, %rdi
movq 0x3c0(%rsp), %rsi
movl $0x40, %edx
callq 0x1090
leaq 0x230(%rsp), %rdi
addq $0xc0, %rdi
movq 0x3c0(%rsp), %rsi
addq $0x40, %rsi
movl $0x40, %edx
callq 0x1090
leaq 0x1b0(%rsp), %rdi
movq 0x3c8(%rsp), %rsi
movq 0x3c0(%rsp), %rdx
callq 0x166d
movq 0x3c8(%rsp), %rsi
addq $0x40, %rsi
movq 0x3c0(%rsp), %rdx
addq $0x40, %rdx
leaq 0x378(%rsp), %rdi
callq 0x166d
leaq 0x1b0(%rsp), %rdi
leaq 0x378(%rsp), %rsi
callq 0x164a
leaq 0x1b0(%rsp), %rdi
addq $0x40, %rdi
movq 0x3c8(%rsp), %rsi
movq 0x3c0(%rsp), %rdx
addq $0x40, %rdx
callq 0x166d
movq 0x3c8(%rsp), %rsi
addq $0x40, %rsi
movq 0x3c0(%rsp), %rdx
leaq 0x378(%rsp), %rdi
callq 0x166d
leaq 0x1b0(%rsp), %rdi
addq $0x40, %rdi
leaq 0x378(%rsp), %rsi
callq 0x164a
movq 0x3c0(%rsp), %rsi
leaq 0x30(%rsp), %rdi
movl $0x80, %edx
callq 0x1090
leaq 0x30(%rsp), %rax
addq $0x80, %rax
leaq 0x30(%rsp), %rcx
addq $0x180, %rcx            # imm = 0x180
movq %rcx, 0x18(%rsp)
movq %rax, 0x20(%rsp)
movq 0x20(%rsp), %rdi
movq %rdi, 0x10(%rsp)
xorl %esi, %esi
movl $0x80, %edx
callq 0x1060
movq 0x10(%rsp), %rax
movq 0x18(%rsp), %rcx
addq $0x80, %rax
cmpq %rcx, %rax
movq %rax, 0x20(%rsp)
jne 0x2ef6
leaq 0x30(%rsp), %rdi
addq $0x80, %rdi
movq 0x3d0(%rsp), %rsi
movq 0x3c0(%rsp), %rdx
callq 0x2830
movq $0x1, 0x28(%rsp)
movq 0x28(%rsp), %rax
movq 0x3b8(%rsp), %rcx
shrq %rcx
cmpq %rcx, %rax
jae 0x32a5
cmpq $0x2, 0x28(%rsp)
jb 0x2fe4
movq 0x28(%rsp), %rax
movl $0x3, %ecx
xorl %edx, %edx
divq %rcx
leaq 0x30(%rsp), %rdi
shlq $0x7, %rdx
addq %rdx, %rdi
movq 0x28(%rsp), %rax
subq $0x1, %rax
movl $0x3, %ecx
xorl %edx, %edx
divq %rcx
leaq 0x30(%rsp), %rsi
shlq $0x7, %rdx
addq %rdx, %rsi
movq 0x3c0(%rsp), %rax
movq %rax, 0x8(%rsp)
movq 0x28(%rsp), %rax
subq $0x2, %rax
movl $0x3, %ecx
xorl %edx, %edx
divq %rcx
movq %rdx, %rax
movq 0x8(%rsp), %rdx
leaq 0x30(%rsp), %rcx
shlq $0x7, %rax
addq %rax, %rcx
callq 0x2990
movq 0x28(%rsp), %rax
movl $0x3, %ecx
xorl %edx, %edx
divq %rcx
leaq 0x30(%rsp), %rsi
shlq $0x7, %rdx
addq %rdx, %rsi
leaq 0x230(%rsp), %rdx
leaq 0x378(%rsp), %rdi
callq 0x166d
movq 0x28(%rsp), %rax
movl $0x3, %ecx
xorl %edx, %edx
divq %rcx
leaq 0x30(%rsp), %rsi
shlq $0x7, %rdx
addq %rdx, %rsi
addq $0x40, %rsi
leaq 0x230(%rsp), %rdx
addq $0x40, %rdx
leaq 0x338(%rsp), %rdi
callq 0x166d
leaq 0x230(%rsp), %rdi
leaq 0x378(%rsp), %rsi
leaq 0x338(%rsp), %rdx
callq 0x15b7
leaq 0x230(%rsp), %rdi
addq $0x40, %rdi
movq 0x28(%rsp), %rax
movl $0x3, %ecx
xorl %edx, %edx
divq %rcx
leaq 0x30(%rsp), %rsi
shlq $0x7, %rdx
addq %rdx, %rsi
callq 0x2246
movq 0x28(%rsp), %rax
movl $0x3, %ecx
xorl %edx, %edx
divq %rcx
leaq 0x30(%rsp), %rsi
shlq $0x7, %rdx
addq %rdx, %rsi
addq $0x40, %rsi
leaq 0x230(%rsp), %rdx
addq $0x80, %rdx
leaq 0x378(%rsp), %rdi
callq 0x166d
movq 0x28(%rsp), %rax
movl $0x3, %ecx
xorl %edx, %edx
divq %rcx
leaq 0x30(%rsp), %rsi
shlq $0x7, %rdx
addq %rdx, %rsi
leaq 0x230(%rsp), %rdx
addq $0xc0, %rdx
leaq 0x338(%rsp), %rdi
callq 0x166d
leaq 0x230(%rsp), %rdi
addq $0x80, %rdi
leaq 0x378(%rsp), %rsi
leaq 0x338(%rsp), %rdx
callq 0x15b7
leaq 0x230(%rsp), %rdi
addq $0xc0, %rdi
movq 0x28(%rsp), %rax
movl $0x3, %ecx
xorl %edx, %edx
divq %rcx
leaq 0x30(%rsp), %rsi
shlq $0x7, %rdx
addq %rdx, %rsi
addq $0x40, %rsi
callq 0x2246
movq 0x3c8(%rsp), %rsi
movq 0x28(%rsp), %rax
movl $0x3, %ecx
xorl %edx, %edx
divq %rcx
movq %rdx, %rax
leaq 0x30(%rsp), %rdx
shlq $0x7, %rax
addq %rax, %rdx
leaq 0x378(%rsp), %rdi
callq 0x166d
movq 0x3c8(%rsp), %rsi
addq $0x40, %rsi
movq 0x28(%rsp), %rax
movl $0x3, %ecx
xorl %edx, %edx
divq %rcx
movq %rdx, %rax
leaq 0x30(%rsp), %rdx
shlq $0x7, %rax
addq %rax, %rdx
addq $0x40, %rdx
leaq 0x338(%rsp), %rdi
callq 0x166d
leaq 0x378(%rsp), %rdi
leaq 0x338(%rsp), %rsi
callq 0x164a
leaq 0x1b0(%rsp), %rdi
leaq 0x378(%rsp), %rsi
callq 0x2246
movq 0x3c8(%rsp), %rsi
movq 0x28(%rsp), %rax
movl $0x3, %ecx
xorl %edx, %edx
divq %rcx
movq %rdx, %rax
leaq 0x30(%rsp), %rdx
shlq $0x7, %rax
addq %rax, %rdx
addq $0x40, %rdx
leaq 0x378(%rsp), %rdi
callq 0x166d
movq 0x3c8(%rsp), %rsi
addq $0x40, %rsi
movq 0x28(%rsp), %rax
movl $0x3, %ecx
xorl %edx, %edx
divq %rcx
movq %rdx, %rax
leaq 0x30(%rsp), %rdx
shlq $0x7, %rax
addq %rax, %rdx
leaq 0x338(%rsp), %rdi
callq 0x166d
leaq 0x378(%rsp), %rdi
leaq 0x338(%rsp), %rsi
callq 0x164a
leaq 0x1b0(%rsp), %rdi
addq $0x40, %rdi
leaq 0x378(%rsp), %rsi
callq 0x2246
movq 0x28(%rsp), %rax
addq $0x1, %rax
movq %rax, 0x28(%rsp)
jmp 0x2f50
leaq 0x230(%rsp), %rdi
leaq 0x230(%rsp), %rsi
addq $0x40, %rsi
callq 0x2246
leaq 0x230(%rsp), %rdi
leaq 0x230(%rsp), %rsi
callq 0x15c3
leaq 0x230(%rsp), %rdi
addq $0x40, %rdi
callq 0x2256
leaq 0x230(%rsp), %rdi
addq $0x80, %rdi
leaq 0x230(%rsp), %rsi
addq $0xc0, %rsi
callq 0x2246
leaq 0x230(%rsp), %rdi
addq $0x80, %rdi
leaq 0x230(%rsp), %rsi
addq $0x80, %rsi
callq 0x15c3
leaq 0x230(%rsp), %rdi
addq $0xc0, %rdi
callq 0x2256
leaq 0x230(%rsp), %rsi
addq $0x40, %rsi
leaq 0x230(%rsp), %rdx
addq $0x80, %rdx
leaq 0x378(%rsp), %rdi
callq 0x166d
leaq 0x230(%rsp), %rsi
leaq 0x230(%rsp), %rdx
addq $0xc0, %rdx
leaq 0x338(%rsp), %rdi
callq 0x166d
leaq 0x378(%rsp), %rdi
leaq 0x338(%rsp), %rsi
callq 0x164a
movq 0x3d0(%rsp), %rsi
addq $0x40, %rsi
leaq 0x378(%rsp), %rdi
callq 0x2246
leaq 0x338(%rsp), %rdi
leaq 0x378(%rsp), %rdx
movq %rdx, %rsi
callq 0x15b7
leaq 0x378(%rsp), %rdi
leaq 0x338(%rsp), %rsi
callq 0x15c3
leaq 0x230(%rsp), %rsi
addq $0x40, %rsi
leaq 0x230(%rsp), %rdx
addq $0xc0, %rdx
leaq 0x338(%rsp), %rdi
callq 0x166d
movq 0x3d0(%rsp), %rsi
leaq 0x338(%rsp), %rdi
callq 0x2246
movq 0x3d0(%rsp), %rdi
leaq 0x338(%rsp), %rsi
leaq 0x378(%rsp), %rdx
callq 0x15cb
leaq 0x230(%rsp), %rdi
addq $0xc0, %rdi
callq 0x2256
movq 0x3d0(%rsp), %rdi
addq $0x40, %rdi
leaq 0x230(%rsp), %rsi
addq $0xc0, %rsi
callq 0x2246
leaq 0x1b0(%rsp), %rdi
callq 0x2256
leaq 0x1b0(%rsp), %rdi
addq $0x40, %rdi
callq 0x2256
movq 0x3c8(%rsp), %rdi
leaq 0x1b0(%rsp), %rsi
callq 0x2246
movq 0x3c8(%rsp), %rdi
addq $0x40, %rdi
leaq 0x1b0(%rsp), %rsi
addq $0x40, %rsi
callq 0x2246
addq $0x3d8, %rsp            # imm = 0x3D8
retq
nopl (%rax,%rax)