// File: msotoodeh[P]asymmetric-passwords/common/curve25519/curve25519_mehdi.c
// Function: ecp_WordMulAddReduce
void ecp_WordMulAddReduce(U32 *Z, const U32* Y, U32 b, const U32* X) 
{
    M64 c;
    ECP_MULADD_W0(Z[0], Y[0], b, X[0]);
    ECP_MULADD_W1(Z[1], Y[1], b, X[1]);
    ECP_MULADD_W1(Z[2], Y[2], b, X[2]);
    ECP_MULADD_W1(Z[3], Y[3], b, X[3]);
    ECP_MULADD_W1(Z[4], Y[4], b, X[4]);
    ECP_MULADD_W1(Z[5], Y[5], b, X[5]);
    ECP_MULADD_W1(Z[6], Y[6], b, X[6]);
    ECP_MULADD_W1(Z[7], Y[7], b, X[7]);

    /* Z += c.u32.hi * 38 */
    ECP_MULADD_W0(Z[0], Z[0], c.u32.hi, 38);
    ECP_ADD_C1(Z[1], Z[1]);
    ECP_ADD_C1(Z[2], Z[2]);
    ECP_ADD_C1(Z[3], Z[3]);
    ECP_ADD_C1(Z[4], Z[4]);
    ECP_ADD_C1(Z[5], Z[5]);
    ECP_ADD_C1(Z[6], Z[6]);
    ECP_ADD_C1(Z[7], Z[7]);

    /* One more time at most */
    ECP_MULADD_W0(Z[0], Z[0], c.u32.hi, 38);
    ECP_ADD_C1(Z[1], Z[1]);
    ECP_ADD_C1(Z[2], Z[2]);
    ECP_ADD_C1(Z[3], Z[3]);
    ECP_ADD_C1(Z[4], Z[4]);
    ECP_ADD_C1(Z[5], Z[5]);
    ECP_ADD_C1(Z[6], Z[6]);
    ECP_ADD_C1(Z[7], Z[7]);
}

// Assembly:
movq %rdi, -0x8(%rsp)
movq %rsi, -0x10(%rsp)
movl %edx, -0x14(%rsp)
movq %rcx, -0x20(%rsp)
movl -0x14(%rsp), %eax
movq -0x20(%rsp), %rcx
movl (%rcx), %ecx
imulq %rcx, %rax
movq -0x10(%rsp), %rcx
movl (%rcx), %ecx
addq %rcx, %rax
movq %rax, -0x28(%rsp)
movl -0x28(%rsp), %ecx
movq -0x8(%rsp), %rax
movl %ecx, (%rax)
movl -0x14(%rsp), %eax
movq -0x20(%rsp), %rcx
movl 0x4(%rcx), %ecx
imulq %rcx, %rax
movq -0x10(%rsp), %rcx
movl 0x4(%rcx), %ecx
addq %rcx, %rax
movl -0x24(%rsp), %ecx
addq %rcx, %rax
movq %rax, -0x28(%rsp)
movl -0x28(%rsp), %ecx
movq -0x8(%rsp), %rax
movl %ecx, 0x4(%rax)
movl -0x14(%rsp), %eax
movq -0x20(%rsp), %rcx
movl 0x8(%rcx), %ecx
imulq %rcx, %rax
movq -0x10(%rsp), %rcx
movl 0x8(%rcx), %ecx
addq %rcx, %rax
movl -0x24(%rsp), %ecx
addq %rcx, %rax
movq %rax, -0x28(%rsp)
movl -0x28(%rsp), %ecx
movq -0x8(%rsp), %rax
movl %ecx, 0x8(%rax)
movl -0x14(%rsp), %eax
movq -0x20(%rsp), %rcx
movl 0xc(%rcx), %ecx
imulq %rcx, %rax
movq -0x10(%rsp), %rcx
movl 0xc(%rcx), %ecx
addq %rcx, %rax
movl -0x24(%rsp), %ecx
addq %rcx, %rax
movq %rax, -0x28(%rsp)
movl -0x28(%rsp), %ecx
movq -0x8(%rsp), %rax
movl %ecx, 0xc(%rax)
movl -0x14(%rsp), %eax
movq -0x20(%rsp), %rcx
movl 0x10(%rcx), %ecx
imulq %rcx, %rax
movq -0x10(%rsp), %rcx
movl 0x10(%rcx), %ecx
addq %rcx, %rax
movl -0x24(%rsp), %ecx
addq %rcx, %rax
movq %rax, -0x28(%rsp)
movl -0x28(%rsp), %ecx
movq -0x8(%rsp), %rax
movl %ecx, 0x10(%rax)
movl -0x14(%rsp), %eax
movq -0x20(%rsp), %rcx
movl 0x14(%rcx), %ecx
imulq %rcx, %rax
movq -0x10(%rsp), %rcx
movl 0x14(%rcx), %ecx
addq %rcx, %rax
movl -0x24(%rsp), %ecx
addq %rcx, %rax
movq %rax, -0x28(%rsp)
movl -0x28(%rsp), %ecx
movq -0x8(%rsp), %rax
movl %ecx, 0x14(%rax)
movl -0x14(%rsp), %eax
movq -0x20(%rsp), %rcx
movl 0x18(%rcx), %ecx
imulq %rcx, %rax
movq -0x10(%rsp), %rcx
movl 0x18(%rcx), %ecx
addq %rcx, %rax
movl -0x24(%rsp), %ecx
addq %rcx, %rax
movq %rax, -0x28(%rsp)
movl -0x28(%rsp), %ecx
movq -0x8(%rsp), %rax
movl %ecx, 0x18(%rax)
movl -0x14(%rsp), %eax
movq -0x20(%rsp), %rcx
movl 0x1c(%rcx), %ecx
imulq %rcx, %rax
movq -0x10(%rsp), %rcx
movl 0x1c(%rcx), %ecx
addq %rcx, %rax
movl -0x24(%rsp), %ecx
addq %rcx, %rax
movq %rax, -0x28(%rsp)
movl -0x28(%rsp), %ecx
movq -0x8(%rsp), %rax
movl %ecx, 0x1c(%rax)
movl -0x24(%rsp), %eax
imulq $0x26, %rax, %rax
movq -0x8(%rsp), %rcx
movl (%rcx), %ecx
addq %rcx, %rax
movq %rax, -0x28(%rsp)
movl -0x28(%rsp), %ecx
movq -0x8(%rsp), %rax
movl %ecx, (%rax)
movq -0x8(%rsp), %rax
movl 0x4(%rax), %eax
movl -0x24(%rsp), %ecx
addq %rcx, %rax
movq %rax, -0x28(%rsp)
movl -0x28(%rsp), %ecx
movq -0x8(%rsp), %rax
movl %ecx, 0x4(%rax)
movq -0x8(%rsp), %rax
movl 0x8(%rax), %eax
movl -0x24(%rsp), %ecx
addq %rcx, %rax
movq %rax, -0x28(%rsp)
movl -0x28(%rsp), %ecx
movq -0x8(%rsp), %rax
movl %ecx, 0x8(%rax)
movq -0x8(%rsp), %rax
movl 0xc(%rax), %eax
movl -0x24(%rsp), %ecx
addq %rcx, %rax
movq %rax, -0x28(%rsp)
movl -0x28(%rsp), %ecx
movq -0x8(%rsp), %rax
movl %ecx, 0xc(%rax)
movq -0x8(%rsp), %rax
movl 0x10(%rax), %eax
movl -0x24(%rsp), %ecx
addq %rcx, %rax
movq %rax, -0x28(%rsp)
movl -0x28(%rsp), %ecx
movq -0x8(%rsp), %rax
movl %ecx, 0x10(%rax)
movq -0x8(%rsp), %rax
movl 0x14(%rax), %eax
movl -0x24(%rsp), %ecx
addq %rcx, %rax
movq %rax, -0x28(%rsp)
movl -0x28(%rsp), %ecx
movq -0x8(%rsp), %rax
movl %ecx, 0x14(%rax)
movq -0x8(%rsp), %rax
movl 0x18(%rax), %eax
movl -0x24(%rsp), %ecx
addq %rcx, %rax
movq %rax, -0x28(%rsp)
movl -0x28(%rsp), %ecx
movq -0x8(%rsp), %rax
movl %ecx, 0x18(%rax)
movq -0x8(%rsp), %rax
movl 0x1c(%rax), %eax
movl -0x24(%rsp), %ecx
addq %rcx, %rax
movq %rax, -0x28(%rsp)
movl -0x28(%rsp), %ecx
movq -0x8(%rsp), %rax
movl %ecx, 0x1c(%rax)
movl -0x24(%rsp), %eax
imulq $0x26, %rax, %rax
movq -0x8(%rsp), %rcx
movl (%rcx), %ecx
addq %rcx, %rax
movq %rax, -0x28(%rsp)
movl -0x28(%rsp), %ecx
movq -0x8(%rsp), %rax
movl %ecx, (%rax)
movq -0x8(%rsp), %rax
movl 0x4(%rax), %eax
movl -0x24(%rsp), %ecx
addq %rcx, %rax
movq %rax, -0x28(%rsp)
movl -0x28(%rsp), %ecx
movq -0x8(%rsp), %rax
movl %ecx, 0x4(%rax)
movq -0x8(%rsp), %rax
movl 0x8(%rax), %eax
movl -0x24(%rsp), %ecx
addq %rcx, %rax
movq %rax, -0x28(%rsp)
movl -0x28(%rsp), %ecx
movq -0x8(%rsp), %rax
movl %ecx, 0x8(%rax)
movq -0x8(%rsp), %rax
movl 0xc(%rax), %eax
movl -0x24(%rsp), %ecx
addq %rcx, %rax
movq %rax, -0x28(%rsp)
movl -0x28(%rsp), %ecx
movq -0x8(%rsp), %rax
movl %ecx, 0xc(%rax)
movq -0x8(%rsp), %rax
movl 0x10(%rax), %eax
movl -0x24(%rsp), %ecx
addq %rcx, %rax
movq %rax, -0x28(%rsp)
movl -0x28(%rsp), %ecx
movq -0x8(%rsp), %rax
movl %ecx, 0x10(%rax)
movq -0x8(%rsp), %rax
movl 0x14(%rax), %eax
movl -0x24(%rsp), %ecx
addq %rcx, %rax
movq %rax, -0x28(%rsp)
movl -0x28(%rsp), %ecx
movq -0x8(%rsp), %rax
movl %ecx, 0x14(%rax)
movq -0x8(%rsp), %rax
movl 0x18(%rax), %eax
movl -0x24(%rsp), %ecx
addq %rcx, %rax
movq %rax, -0x28(%rsp)
movl -0x28(%rsp), %ecx
movq -0x8(%rsp), %rax
movl %ecx, 0x18(%rax)
movq -0x8(%rsp), %rax
movl 0x1c(%rax), %eax
movl -0x24(%rsp), %ecx
addq %rcx, %rax
movq %rax, -0x28(%rsp)
movl -0x28(%rsp), %ecx
movq -0x8(%rsp), %rax
movl %ecx, 0x1c(%rax)
retq
nopw %cs:(%rax,%rax)