// File: /workspace/github_c_makefile_star2_O0/janmojzis[P]mcencrypt/poly1305.c
// Function: poly1305_final
void poly1305_final(poly1305_ctx *ctx, unsigned char *o) {

    unsigned long long f;
    unsigned long c, mask;
    unsigned long h0 = ctx->h[0];
    unsigned long h1 = ctx->h[1];
    unsigned long h2 = ctx->h[2];
    unsigned long h3 = ctx->h[3];
    unsigned long h4 = ctx->h[4];
    unsigned long r0 = ctx->r[0];
    unsigned long r1 = ctx->r[1];
    unsigned long r2 = ctx->r[2];
    unsigned long r3 = ctx->r[3];
    unsigned long r4 = ctx->r[4];

    /* fully carry h */
                 c = h1 >> 26; h1 = h1 & 0x3ffffff;
    h2 +=     c; c = h2 >> 26; h2 = h2 & 0x3ffffff;
    h3 +=     c; c = h3 >> 26; h3 = h3 & 0x3ffffff;
    h4 +=     c; c = h4 >> 26; h4 = h4 & 0x3ffffff;
    h0 += c * 5; c = h0 >> 26; h0 = h0 & 0x3ffffff;
    h1 +=     c;

    /* compute h + -p */
    r0 = h0 + 5; c = r0 >> 26; r0 &= 0x3ffffff;
    r1 = h1 + c; c = r1 >> 26; r1 &= 0x3ffffff;
    r2 = h2 + c; c = r2 >> 26; r2 &= 0x3ffffff;
    r3 = h3 + c; c = r3 >> 26; r3 &= 0x3ffffff;
    r4 = h4 + c - (1 << 26);

    /* select h if h < p, or h + -p if h >= p */
    mask = (r4 >> ((sizeof(unsigned long) * 8) - 1)) - 1;
    r0 &= mask;
    r1 &= mask;
    r2 &= mask;
    r3 &= mask;
    r4 &= mask;
    mask = ~mask;
    h0 = (h0 & mask) | r0;
    h1 = (h1 & mask) | r1;
    h2 = (h2 & mask) | r2;
    h3 = (h3 & mask) | r3;
    h4 = (h4 & mask) | r4;

    /* h = h % (2^128) */
    h0 = ((h0      ) | (h1 << 26)) & 0xffffffff;
    h1 = ((h1 >>  6) | (h2 << 20)) & 0xffffffff;
    h2 = ((h2 >> 12) | (h3 << 14)) & 0xffffffff;
    h3 = ((h3 >> 18) | (h4 <<  8)) & 0xffffffff;

    /* mac = (h + pad) % (2^128) */
    f = (unsigned long long)h0 + ctx->pad[0]            ; h0 = (unsigned long)f;
    f = (unsigned long long)h1 + ctx->pad[1] + (f >> 32); h1 = (unsigned long)f;
    f = (unsigned long long)h2 + ctx->pad[2] + (f >> 32); h2 = (unsigned long)f;
    f = (unsigned long long)h3 + ctx->pad[3] + (f >> 32); h3 = (unsigned long)f;

    pack(o +  0, h0);
    pack(o +  4, h1);
    pack(o +  8, h2);
    pack(o + 12, h3);
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x80, %rsp
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movq -0x8(%rbp), %rax
movq (%rax), %rax
movq %rax, -0x30(%rbp)
movq -0x8(%rbp), %rax
movq 0x8(%rax), %rax
movq %rax, -0x38(%rbp)
movq -0x8(%rbp), %rax
movq 0x10(%rax), %rax
movq %rax, -0x40(%rbp)
movq -0x8(%rbp), %rax
movq 0x18(%rax), %rax
movq %rax, -0x48(%rbp)
movq -0x8(%rbp), %rax
movq 0x20(%rax), %rax
movq %rax, -0x50(%rbp)
movq -0x8(%rbp), %rax
movq 0x28(%rax), %rax
movq %rax, -0x58(%rbp)
movq -0x8(%rbp), %rax
movq 0x30(%rax), %rax
movq %rax, -0x60(%rbp)
movq -0x8(%rbp), %rax
movq 0x38(%rax), %rax
movq %rax, -0x68(%rbp)
movq -0x8(%rbp), %rax
movq 0x40(%rax), %rax
movq %rax, -0x70(%rbp)
movq -0x8(%rbp), %rax
movq 0x48(%rax), %rax
movq %rax, -0x78(%rbp)
movq -0x38(%rbp), %rax
shrq $0x1a, %rax
movq %rax, -0x20(%rbp)
movq -0x38(%rbp), %rax
andq $0x3ffffff, %rax        # imm = 0x3FFFFFF
movq %rax, -0x38(%rbp)
movq -0x20(%rbp), %rax
addq -0x40(%rbp), %rax
movq %rax, -0x40(%rbp)
movq -0x40(%rbp), %rax
shrq $0x1a, %rax
movq %rax, -0x20(%rbp)
movq -0x40(%rbp), %rax
andq $0x3ffffff, %rax        # imm = 0x3FFFFFF
movq %rax, -0x40(%rbp)
movq -0x20(%rbp), %rax
addq -0x48(%rbp), %rax
movq %rax, -0x48(%rbp)
movq -0x48(%rbp), %rax
shrq $0x1a, %rax
movq %rax, -0x20(%rbp)
movq -0x48(%rbp), %rax
andq $0x3ffffff, %rax        # imm = 0x3FFFFFF
movq %rax, -0x48(%rbp)
movq -0x20(%rbp), %rax
addq -0x50(%rbp), %rax
movq %rax, -0x50(%rbp)
movq -0x50(%rbp), %rax
shrq $0x1a, %rax
movq %rax, -0x20(%rbp)
movq -0x50(%rbp), %rax
andq $0x3ffffff, %rax        # imm = 0x3FFFFFF
movq %rax, -0x50(%rbp)
imulq $0x5, -0x20(%rbp), %rax
addq -0x30(%rbp), %rax
movq %rax, -0x30(%rbp)
movq -0x30(%rbp), %rax
shrq $0x1a, %rax
movq %rax, -0x20(%rbp)
movq -0x30(%rbp), %rax
andq $0x3ffffff, %rax        # imm = 0x3FFFFFF
movq %rax, -0x30(%rbp)
movq -0x20(%rbp), %rax
addq -0x38(%rbp), %rax
movq %rax, -0x38(%rbp)
movq -0x30(%rbp), %rax
addq $0x5, %rax
movq %rax, -0x58(%rbp)
movq -0x58(%rbp), %rax
shrq $0x1a, %rax
movq %rax, -0x20(%rbp)
movq -0x58(%rbp), %rax
andq $0x3ffffff, %rax        # imm = 0x3FFFFFF
movq %rax, -0x58(%rbp)
movq -0x38(%rbp), %rax
addq -0x20(%rbp), %rax
movq %rax, -0x60(%rbp)
movq -0x60(%rbp), %rax
shrq $0x1a, %rax
movq %rax, -0x20(%rbp)
movq -0x60(%rbp), %rax
andq $0x3ffffff, %rax        # imm = 0x3FFFFFF
movq %rax, -0x60(%rbp)
movq -0x40(%rbp), %rax
addq -0x20(%rbp), %rax
movq %rax, -0x68(%rbp)
movq -0x68(%rbp), %rax
shrq $0x1a, %rax
movq %rax, -0x20(%rbp)
movq -0x68(%rbp), %rax
andq $0x3ffffff, %rax        # imm = 0x3FFFFFF
movq %rax, -0x68(%rbp)
movq -0x48(%rbp), %rax
addq -0x20(%rbp), %rax
movq %rax, -0x70(%rbp)
movq -0x70(%rbp), %rax
shrq $0x1a, %rax
movq %rax, -0x20(%rbp)
movq -0x70(%rbp), %rax
andq $0x3ffffff, %rax        # imm = 0x3FFFFFF
movq %rax, -0x70(%rbp)
movq -0x50(%rbp), %rax
addq -0x20(%rbp), %rax
subq $0x4000000, %rax        # imm = 0x4000000
movq %rax, -0x78(%rbp)
movq -0x78(%rbp), %rax
shrq $0x3f, %rax
subq $0x1, %rax
movq %rax, -0x28(%rbp)
movq -0x28(%rbp), %rax
andq -0x58(%rbp), %rax
movq %rax, -0x58(%rbp)
movq -0x28(%rbp), %rax
andq -0x60(%rbp), %rax
movq %rax, -0x60(%rbp)
movq -0x28(%rbp), %rax
andq -0x68(%rbp), %rax
movq %rax, -0x68(%rbp)
movq -0x28(%rbp), %rax
andq -0x70(%rbp), %rax
movq %rax, -0x70(%rbp)
movq -0x28(%rbp), %rax
andq -0x78(%rbp), %rax
movq %rax, -0x78(%rbp)
movq -0x28(%rbp), %rax
xorq $-0x1, %rax
movq %rax, -0x28(%rbp)
movq -0x30(%rbp), %rax
andq -0x28(%rbp), %rax
orq -0x58(%rbp), %rax
movq %rax, -0x30(%rbp)
movq -0x38(%rbp), %rax
andq -0x28(%rbp), %rax
orq -0x60(%rbp), %rax
movq %rax, -0x38(%rbp)
movq -0x40(%rbp), %rax
andq -0x28(%rbp), %rax
orq -0x68(%rbp), %rax
movq %rax, -0x40(%rbp)
movq -0x48(%rbp), %rax
andq -0x28(%rbp), %rax
orq -0x70(%rbp), %rax
movq %rax, -0x48(%rbp)
movq -0x50(%rbp), %rax
andq -0x28(%rbp), %rax
orq -0x78(%rbp), %rax
movq %rax, -0x50(%rbp)
movq -0x30(%rbp), %rax
movq -0x38(%rbp), %rcx
shlq $0x1a, %rcx
orq %rcx, %rax
movabsq $0xffffffff, %rcx       # imm = 0xFFFFFFFF
andq %rcx, %rax
movq %rax, -0x30(%rbp)
movq -0x38(%rbp), %rax
shrq $0x6, %rax
movq -0x40(%rbp), %rcx
shlq $0x14, %rcx
orq %rcx, %rax
movabsq $0xffffffff, %rcx       # imm = 0xFFFFFFFF
andq %rcx, %rax
movq %rax, -0x38(%rbp)
movq -0x40(%rbp), %rax
shrq $0xc, %rax
movq -0x48(%rbp), %rcx
shlq $0xe, %rcx
orq %rcx, %rax
movabsq $0xffffffff, %rcx       # imm = 0xFFFFFFFF
andq %rcx, %rax
movq %rax, -0x40(%rbp)
movq -0x48(%rbp), %rax
shrq $0x12, %rax
movq -0x50(%rbp), %rcx
shlq $0x8, %rcx
orq %rcx, %rax
movabsq $0xffffffff, %rcx       # imm = 0xFFFFFFFF
andq %rcx, %rax
movq %rax, -0x48(%rbp)
movq -0x30(%rbp), %rax
movq -0x8(%rbp), %rcx
addq 0x78(%rcx), %rax
movq %rax, -0x18(%rbp)
movq -0x18(%rbp), %rax
movq %rax, -0x30(%rbp)
movq -0x38(%rbp), %rax
movq -0x8(%rbp), %rcx
addq 0x80(%rcx), %rax
movq -0x18(%rbp), %rcx
shrq $0x20, %rcx
addq %rcx, %rax
movq %rax, -0x18(%rbp)
movq -0x18(%rbp), %rax
movq %rax, -0x38(%rbp)
movq -0x40(%rbp), %rax
movq -0x8(%rbp), %rcx
addq 0x88(%rcx), %rax
movq -0x18(%rbp), %rcx
shrq $0x20, %rcx
addq %rcx, %rax
movq %rax, -0x18(%rbp)
movq -0x18(%rbp), %rax
movq %rax, -0x40(%rbp)
movq -0x48(%rbp), %rax
movq -0x8(%rbp), %rcx
addq 0x90(%rcx), %rax
movq -0x18(%rbp), %rcx
shrq $0x20, %rcx
addq %rcx, %rax
movq %rax, -0x18(%rbp)
movq -0x18(%rbp), %rax
movq %rax, -0x48(%rbp)
movq -0x10(%rbp), %rdi
movq -0x30(%rbp), %rsi
callq 0xd250
movq -0x10(%rbp), %rdi
addq $0x4, %rdi
movq -0x38(%rbp), %rsi
callq 0xd250
movq -0x10(%rbp), %rdi
addq $0x8, %rdi
movq -0x40(%rbp), %rsi
callq 0xd250
movq -0x10(%rbp), %rdi
addq $0xc, %rdi
movq -0x48(%rbp), %rsi
callq 0xd250
addq $0x80, %rsp
popq %rbp
retq
nopw (%rax,%rax)