// File: /workspace/github_cpp_makefile_star2_O3/tomfunkhouser[P]gaps/pkgs/png/adler32.c
// Function: adler32
uLong ZEXPORT adler32(adler, buf, len)
    uLong adler;
    const Bytef *buf;
    uInt len;
{
    unsigned long sum2;
    unsigned n;

    /* split Adler-32 into component sums */
    sum2 = (adler >> 16) & 0xffff;
    adler &= 0xffff;

    /* in case user likes doing a byte at a time, keep it fast */
    if (len == 1) {
        adler += buf[0];
        if (adler >= BASE)
            adler -= BASE;
        sum2 += adler;
        if (sum2 >= BASE)
            sum2 -= BASE;
        return adler | (sum2 << 16);
    }

    /* initial Adler-32 value (deferred check for len == 1 speed) */
    if (buf == Z_NULL)
        return 1L;

    /* in case short lengths are provided, keep it somewhat fast */
    if (len < 16) {
        while (len--) {
            adler += *buf++;
            sum2 += adler;
        }
        if (adler >= BASE)
            adler -= BASE;
        MOD4(sum2);             /* only added so many BASE's */
        return adler | (sum2 << 16);
    }

    /* do length NMAX blocks -- requires just one modulo operation */
    while (len >= NMAX) {
        len -= NMAX;
        n = NMAX / 16;          /* NMAX is divisible by 16 */
        do {
            DO16(buf);          /* 16 sums unrolled */
            buf += 16;
        } while (--n);
        MOD(adler);
        MOD(sum2);
    }

    /* do remaining bytes (less than NMAX, still just one modulo) */
    if (len) {                  /* avoid modulos if none remaining */
        while (len >= 16) {
            len -= 16;
            DO16(buf);
            buf += 16;
        }
        while (len--) {
            adler += *buf++;
            sum2 += adler;
        }
        MOD(adler);
        MOD(sum2);
    }

    /* return recombined sums */
    return adler | (sum2 << 16);
}

// Assembly:
movq %rdi, %rcx
movzwl %cx, %edi
shrl $0x10, %ecx
cmpl $0x1, %edx
jne 0xa0c36
movzbl (%rsi), %eax
leaq (%rdi,%rax), %rdx
movl $0xfff1, %esi           # imm = 0xFFF1
cmpq %rsi, %rdx
leaq -0xfff1(%rdi,%rax), %rax
cmovbq %rdx, %rax
addq %rax, %rcx
movq %rcx, %rdx
shlq $0x10, %rdx
movabsq $-0xfff10000, %rdi      # imm = 0xFFFFFFFF000F0000
addq %rdx, %rdi
cmpq %rsi, %rcx
cmovbq %rdx, %rdi
orq %rax, %rdi
movq %rdi, %rcx
jmp 0xa0f0c
testq %rsi, %rsi
je 0xa0c9f
movl %edx, %r8d
cmpl $0x10, %edx
jae 0xa0ca9
testl %r8d, %r8d
je 0xa0c5f
movl %r8d, %eax
xorl %edx, %edx
movzbl (%rsi,%rdx), %r8d
addq %r8, %rdi
addq %rdi, %rcx
incq %rdx
cmpl %edx, %eax
jne 0xa0c4d
leaq -0xfff1(%rdi), %rsi
cmpq $0xfff1, %rdi           # imm = 0xFFF1
cmovbq %rdi, %rsi
movabsq $0xf00e10d2fc5cd, %rdx  # imm = 0xF00E10D2FC5CD
movq %rcx, %rax
mulq %rdx
movl %ecx, %eax
subl %edx, %eax
shrl %eax
addl %edx, %eax
shrl $0xf, %eax
imull $0xfff1, %eax, %eax     # imm = 0xFFF1
subl %eax, %ecx
shll $0x10, %ecx
orq %rsi, %rcx
jmp 0xa0f0c
movl $0x1, %ecx
jmp 0xa0f0c
cmpl $0x15b0, %r8d           # imm = 0x15B0
jb 0xa0dee
movabsq $0xf00e10d2fc5cd, %r9   # imm = 0xF00E10D2FC5CD
addl $0xffffea50, %r8d       # imm = 0xFFFFEA50
xorl %eax, %eax
movzbl (%rsi,%rax), %edx
addq %rdi, %rdx
addq %rdx, %rcx
movzbl 0x1(%rsi,%rax), %edi
addq %rdx, %rdi
addq %rdi, %rcx
movzbl 0x2(%rsi,%rax), %edx
addq %rdi, %rdx
addq %rdx, %rcx
movzbl 0x3(%rsi,%rax), %edi
addq %rdx, %rdi
addq %rdi, %rcx
movzbl 0x4(%rsi,%rax), %edx
addq %rdi, %rdx
addq %rdx, %rcx
movzbl 0x5(%rsi,%rax), %edi
addq %rdx, %rdi
addq %rdi, %rcx
movzbl 0x6(%rsi,%rax), %edx
addq %rdi, %rdx
addq %rdx, %rcx
movzbl 0x7(%rsi,%rax), %edi
addq %rdx, %rdi
addq %rdi, %rcx
movzbl 0x8(%rsi,%rax), %edx
addq %rdi, %rdx
addq %rdx, %rcx
movzbl 0x9(%rsi,%rax), %edi
addq %rdx, %rdi
addq %rdi, %rcx
movzbl 0xa(%rsi,%rax), %edx
addq %rdi, %rdx
addq %rdx, %rcx
movzbl 0xb(%rsi,%rax), %edi
addq %rdx, %rdi
addq %rdi, %rcx
movzbl 0xc(%rsi,%rax), %edx
addq %rdi, %rdx
addq %rdx, %rcx
movzbl 0xd(%rsi,%rax), %edi
addq %rdx, %rdi
addq %rdi, %rcx
movzbl 0xe(%rsi,%rax), %edx
addq %rdi, %rdx
addq %rdx, %rcx
movzbl 0xf(%rsi,%rax), %edi
addq %rdx, %rdi
addq %rdi, %rcx
addq $0x10, %rax
cmpl $0x15b0, %eax           # imm = 0x15B0
jne 0xa0cc9
addq $0x15b0, %rsi           # imm = 0x15B0
movq %rdi, %rax
mulq %r9
movq %rdi, %rax
subq %rdx, %rax
shrq %rax
addq %rdx, %rax
shrq $0xf, %rax
imulq $0xfff1, %rax, %rax     # imm = 0xFFF1
subq %rax, %rdi
movq %rcx, %rax
mulq %r9
movq %rcx, %rax
subq %rdx, %rax
shrq %rax
addq %rdx, %rax
shrq $0xf, %rax
imulq $0xfff1, %rax, %rax     # imm = 0xFFF1
subq %rax, %rcx
cmpl $0x15af, %r8d           # imm = 0x15AF
ja 0xa0cc0
testl %r8d, %r8d
je 0xa0f05
cmpl $0x10, %r8d
jb 0xa0ea4
addl $-0x10, %r8d
movzbl (%rsi), %eax
addq %rdi, %rax
addq %rax, %rcx
movzbl 0x1(%rsi), %edx
addq %rax, %rdx
addq %rdx, %rcx
movzbl 0x2(%rsi), %eax
addq %rdx, %rax
addq %rax, %rcx
movzbl 0x3(%rsi), %edx
addq %rax, %rdx
addq %rdx, %rcx
movzbl 0x4(%rsi), %eax
addq %rdx, %rax
addq %rax, %rcx
movzbl 0x5(%rsi), %edx
addq %rax, %rdx
addq %rdx, %rcx
movzbl 0x6(%rsi), %eax
addq %rdx, %rax
addq %rax, %rcx
movzbl 0x7(%rsi), %edx
addq %rax, %rdx
addq %rdx, %rcx
movzbl 0x8(%rsi), %eax
addq %rdx, %rax
addq %rax, %rcx
movzbl 0x9(%rsi), %edx
addq %rax, %rdx
addq %rdx, %rcx
movzbl 0xa(%rsi), %eax
addq %rdx, %rax
addq %rax, %rcx
movzbl 0xb(%rsi), %edx
addq %rax, %rdx
addq %rdx, %rcx
movzbl 0xc(%rsi), %eax
addq %rdx, %rax
addq %rax, %rcx
movzbl 0xd(%rsi), %edx
addq %rax, %rdx
addq %rdx, %rcx
movzbl 0xe(%rsi), %eax
addq %rdx, %rax
addq %rax, %rcx
movzbl 0xf(%rsi), %edi
addq %rax, %rdi
addq %rdi, %rcx
addq $0x10, %rsi
cmpl $0xf, %r8d
ja 0xa0dee
testl %r8d, %r8d
je 0xa0ebb
movl %r8d, %eax
xorl %edx, %edx
movzbl (%rsi,%rdx), %r8d
addq %r8, %rdi
addq %rdi, %rcx
incq %rdx
cmpl %edx, %eax
jne 0xa0ea9
movabsq $0xf00e10d2fc5cd, %rsi  # imm = 0xF00E10D2FC5CD
movq %rdi, %rax
mulq %rsi
movq %rdi, %rax
subq %rdx, %rax
shrq %rax
addq %rdx, %rax
shrq $0xf, %rax
imulq $0xfff1, %rax, %rax     # imm = 0xFFF1
subq %rax, %rdi
movq %rcx, %rax
mulq %rsi
movq %rcx, %rax
subq %rdx, %rax
shrq %rax
addq %rdx, %rax
shrq $0xf, %rax
imulq $0xfff1, %rax, %rax     # imm = 0xFFF1
subq %rax, %rcx
shlq $0x10, %rcx
orq %rdi, %rcx
movq %rcx, %rax
retq