// File: /workspace/github_c_makefile_star2_O0/LoupVaillant[P]Monocypher-Utils/src/monocypher.c
// Function: crypto_poly1305_final
void crypto_poly1305_final(crypto_poly1305_ctx *ctx, u8 mac[16])
{
    // Process the last block (if any)
    if (ctx->c_idx != 0) {
        // move the final 1 according to remaining input length
        // (We may add less than 2^130 to the last input block)
        ctx->c[4] = 0;
        poly_take_input(ctx, 1);
        // one last hash update
        poly_block(ctx);
    }

    // check if we should subtract 2^130-5 by performing the
    // corresponding carry propagation.
    const u64 u0 = (u64)5     + ctx->h[0]; // <= 1_00000004
    const u64 u1 = (u0 >> 32) + ctx->h[1]; // <= 1_00000000
    const u64 u2 = (u1 >> 32) + ctx->h[2]; // <= 1_00000000
    const u64 u3 = (u2 >> 32) + ctx->h[3]; // <= 1_00000000
    const u64 u4 = (u3 >> 32) + ctx->h[4]; // <=          5
    // u4 indicates how many times we should subtract 2^130-5 (0 or 1)

    // h + pad, minus 2^130-5 if u4 exceeds 3
    const u64 uu0 = (u4 >> 2) * 5 + ctx->h[0] + ctx->pad[0]; // <= 2_00000003
    const u64 uu1 = (uu0 >> 32)   + ctx->h[1] + ctx->pad[1]; // <= 2_00000000
    const u64 uu2 = (uu1 >> 32)   + ctx->h[2] + ctx->pad[2]; // <= 2_00000000
    const u64 uu3 = (uu2 >> 32)   + ctx->h[3] + ctx->pad[3]; // <= 2_00000000

    store32_le(mac     , (u32)uu0);
    store32_le(mac +  4, (u32)uu1);
    store32_le(mac +  8, (u32)uu2);
    store32_le(mac + 12, (u32)uu3);

    WIPE_CTX(ctx);
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x60, %rsp
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movq -0x8(%rbp), %rax
cmpq $0x0, 0x48(%rax)
je 0x2ddd
movq -0x8(%rbp), %rax
movl $0x0, 0x34(%rax)
movq -0x8(%rbp), %rdi
movl $0x1, %esi
callq 0x2f30
movq -0x8(%rbp), %rdi
callq 0x2a60
movq -0x8(%rbp), %rax
movl 0x10(%rax), %eax
addq $0x5, %rax
movq %rax, -0x18(%rbp)
movq -0x18(%rbp), %rax
shrq $0x20, %rax
movq -0x8(%rbp), %rcx
movl 0x14(%rcx), %ecx
addq %rcx, %rax
movq %rax, -0x20(%rbp)
movq -0x20(%rbp), %rax
shrq $0x20, %rax
movq -0x8(%rbp), %rcx
movl 0x18(%rcx), %ecx
addq %rcx, %rax
movq %rax, -0x28(%rbp)
movq -0x28(%rbp), %rax
shrq $0x20, %rax
movq -0x8(%rbp), %rcx
movl 0x1c(%rcx), %ecx
addq %rcx, %rax
movq %rax, -0x30(%rbp)
movq -0x30(%rbp), %rax
shrq $0x20, %rax
movq -0x8(%rbp), %rcx
movl 0x20(%rcx), %ecx
addq %rcx, %rax
movq %rax, -0x38(%rbp)
movq -0x38(%rbp), %rax
shrq $0x2, %rax
imulq $0x5, %rax, %rax
movq -0x8(%rbp), %rcx
movl 0x10(%rcx), %ecx
addq %rcx, %rax
movq -0x8(%rbp), %rcx
movl 0x38(%rcx), %ecx
addq %rcx, %rax
movq %rax, -0x40(%rbp)
movq -0x40(%rbp), %rax
shrq $0x20, %rax
movq -0x8(%rbp), %rcx
movl 0x14(%rcx), %ecx
addq %rcx, %rax
movq -0x8(%rbp), %rcx
movl 0x3c(%rcx), %ecx
addq %rcx, %rax
movq %rax, -0x48(%rbp)
movq -0x48(%rbp), %rax
shrq $0x20, %rax
movq -0x8(%rbp), %rcx
movl 0x18(%rcx), %ecx
addq %rcx, %rax
movq -0x8(%rbp), %rcx
movl 0x40(%rcx), %ecx
addq %rcx, %rax
movq %rax, -0x50(%rbp)
movq -0x50(%rbp), %rax
shrq $0x20, %rax
movq -0x8(%rbp), %rcx
movl 0x1c(%rcx), %ecx
addq %rcx, %rax
movq -0x8(%rbp), %rcx
movl 0x44(%rcx), %ecx
addq %rcx, %rax
movq %rax, -0x58(%rbp)
movq -0x10(%rbp), %rdi
movq -0x40(%rbp), %rax
movl %eax, %esi
callq 0x22b0
movq -0x10(%rbp), %rdi
addq $0x4, %rdi
movq -0x48(%rbp), %rax
movl %eax, %esi
callq 0x22b0
movq -0x10(%rbp), %rdi
addq $0x8, %rdi
movq -0x50(%rbp), %rax
movl %eax, %esi
callq 0x22b0
movq -0x10(%rbp), %rdi
addq $0xc, %rdi
movq -0x58(%rbp), %rax
movl %eax, %esi
callq 0x22b0
movq -0x8(%rbp), %rdi
movl $0x50, %esi
callq 0x1b40
addq $0x60, %rsp
popq %rbp
retq
nopw %cs:(%rax,%rax)