// File: 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, -0x10(%rsp)
movq %rsi, -0x18(%rsp)
movl %edx, -0x1c(%rsp)
movq -0x10(%rsp), %rax
shrq $0x10, %rax
andq $0xffff, %rax           # imm = 0xFFFF
movq %rax, -0x28(%rsp)
movq -0x10(%rsp), %rax
andq $0xffff, %rax           # imm = 0xFFFF
movq %rax, -0x10(%rsp)
cmpl $0x1, -0x1c(%rsp)
jne 0x1314ab
movq -0x18(%rsp), %rax
movzbl (%rax), %eax
addq -0x10(%rsp), %rax
movq %rax, -0x10(%rsp)
cmpq $0xfff1, -0x10(%rsp)    # imm = 0xFFF1
jb 0x131466
movq -0x10(%rsp), %rax
subq $0xfff1, %rax           # imm = 0xFFF1
movq %rax, -0x10(%rsp)
movq -0x10(%rsp), %rax
addq -0x28(%rsp), %rax
movq %rax, -0x28(%rsp)
cmpq $0xfff1, -0x28(%rsp)    # imm = 0xFFF1
jb 0x131490
movq -0x28(%rsp), %rax
subq $0xfff1, %rax           # imm = 0xFFF1
movq %rax, -0x28(%rsp)
movq -0x10(%rsp), %rax
movq -0x28(%rsp), %rcx
shlq $0x10, %rcx
orq %rcx, %rax
movq %rax, -0x8(%rsp)
jmp 0x131ac2
cmpq $0x0, -0x18(%rsp)
jne 0x1314c1
movq $0x1, -0x8(%rsp)
jmp 0x131ac2
cmpl $0x10, -0x1c(%rsp)
jae 0x131559
jmp 0x1314ce
movl -0x1c(%rsp), %eax
movl %eax, %ecx
addl $-0x1, %ecx
movl %ecx, -0x1c(%rsp)
cmpl $0x0, %eax
je 0x13150f
movq -0x18(%rsp), %rax
movq %rax, %rcx
addq $0x1, %rcx
movq %rcx, -0x18(%rsp)
movzbl (%rax), %eax
addq -0x10(%rsp), %rax
movq %rax, -0x10(%rsp)
movq -0x10(%rsp), %rax
addq -0x28(%rsp), %rax
movq %rax, -0x28(%rsp)
jmp 0x1314ce
cmpq $0xfff1, -0x10(%rsp)    # imm = 0xFFF1
jb 0x13152a
movq -0x10(%rsp), %rax
subq $0xfff1, %rax           # imm = 0xFFF1
movq %rax, -0x10(%rsp)
movq -0x28(%rsp), %rax
movl $0xfff1, %ecx           # imm = 0xFFF1
xorl %edx, %edx
divq %rcx
movq %rdx, -0x28(%rsp)
movq -0x10(%rsp), %rax
movq -0x28(%rsp), %rcx
shlq $0x10, %rcx
orq %rcx, %rax
movq %rax, -0x8(%rsp)
jmp 0x131ac2
jmp 0x13155b
cmpl $0x15b0, -0x1c(%rsp)    # imm = 0x15B0
jb 0x1317ec
movl -0x1c(%rsp), %eax
subl $0x15b0, %eax           # imm = 0x15B0
movl %eax, -0x1c(%rsp)
movl $0x15b, -0x2c(%rsp)     # imm = 0x15B
movq -0x18(%rsp), %rax
movzbl (%rax), %eax
addq -0x10(%rsp), %rax
movq %rax, -0x10(%rsp)
movq -0x10(%rsp), %rax
addq -0x28(%rsp), %rax
movq %rax, -0x28(%rsp)
movq -0x18(%rsp), %rax
movzbl 0x1(%rax), %eax
addq -0x10(%rsp), %rax
movq %rax, -0x10(%rsp)
movq -0x10(%rsp), %rax
addq -0x28(%rsp), %rax
movq %rax, -0x28(%rsp)
movq -0x18(%rsp), %rax
movzbl 0x2(%rax), %eax
addq -0x10(%rsp), %rax
movq %rax, -0x10(%rsp)
movq -0x10(%rsp), %rax
addq -0x28(%rsp), %rax
movq %rax, -0x28(%rsp)
movq -0x18(%rsp), %rax
movzbl 0x3(%rax), %eax
addq -0x10(%rsp), %rax
movq %rax, -0x10(%rsp)
movq -0x10(%rsp), %rax
addq -0x28(%rsp), %rax
movq %rax, -0x28(%rsp)
movq -0x18(%rsp), %rax
movzbl 0x4(%rax), %eax
addq -0x10(%rsp), %rax
movq %rax, -0x10(%rsp)
movq -0x10(%rsp), %rax
addq -0x28(%rsp), %rax
movq %rax, -0x28(%rsp)
movq -0x18(%rsp), %rax
movzbl 0x5(%rax), %eax
addq -0x10(%rsp), %rax
movq %rax, -0x10(%rsp)
movq -0x10(%rsp), %rax
addq -0x28(%rsp), %rax
movq %rax, -0x28(%rsp)
movq -0x18(%rsp), %rax
movzbl 0x6(%rax), %eax
addq -0x10(%rsp), %rax
movq %rax, -0x10(%rsp)
movq -0x10(%rsp), %rax
addq -0x28(%rsp), %rax
movq %rax, -0x28(%rsp)
movq -0x18(%rsp), %rax
movzbl 0x7(%rax), %eax
addq -0x10(%rsp), %rax
movq %rax, -0x10(%rsp)
movq -0x10(%rsp), %rax
addq -0x28(%rsp), %rax
movq %rax, -0x28(%rsp)
movq -0x18(%rsp), %rax
movzbl 0x8(%rax), %eax
addq -0x10(%rsp), %rax
movq %rax, -0x10(%rsp)
movq -0x10(%rsp), %rax
addq -0x28(%rsp), %rax
movq %rax, -0x28(%rsp)
movq -0x18(%rsp), %rax
movzbl 0x9(%rax), %eax
addq -0x10(%rsp), %rax
movq %rax, -0x10(%rsp)
movq -0x10(%rsp), %rax
addq -0x28(%rsp), %rax
movq %rax, -0x28(%rsp)
movq -0x18(%rsp), %rax
movzbl 0xa(%rax), %eax
addq -0x10(%rsp), %rax
movq %rax, -0x10(%rsp)
movq -0x10(%rsp), %rax
addq -0x28(%rsp), %rax
movq %rax, -0x28(%rsp)
movq -0x18(%rsp), %rax
movzbl 0xb(%rax), %eax
addq -0x10(%rsp), %rax
movq %rax, -0x10(%rsp)
movq -0x10(%rsp), %rax
addq -0x28(%rsp), %rax
movq %rax, -0x28(%rsp)
movq -0x18(%rsp), %rax
movzbl 0xc(%rax), %eax
addq -0x10(%rsp), %rax
movq %rax, -0x10(%rsp)
movq -0x10(%rsp), %rax
addq -0x28(%rsp), %rax
movq %rax, -0x28(%rsp)
movq -0x18(%rsp), %rax
movzbl 0xd(%rax), %eax
addq -0x10(%rsp), %rax
movq %rax, -0x10(%rsp)
movq -0x10(%rsp), %rax
addq -0x28(%rsp), %rax
movq %rax, -0x28(%rsp)
movq -0x18(%rsp), %rax
movzbl 0xe(%rax), %eax
addq -0x10(%rsp), %rax
movq %rax, -0x10(%rsp)
movq -0x10(%rsp), %rax
addq -0x28(%rsp), %rax
movq %rax, -0x28(%rsp)
movq -0x18(%rsp), %rax
movzbl 0xf(%rax), %eax
addq -0x10(%rsp), %rax
movq %rax, -0x10(%rsp)
movq -0x10(%rsp), %rax
addq -0x28(%rsp), %rax
movq %rax, -0x28(%rsp)
movq -0x18(%rsp), %rax
addq $0x10, %rax
movq %rax, -0x18(%rsp)
movl -0x2c(%rsp), %eax
addl $-0x1, %eax
movl %eax, -0x2c(%rsp)
cmpl $0x0, %eax
jne 0x13157e
movq -0x10(%rsp), %rax
movl $0xfff1, %ecx           # imm = 0xFFF1
xorl %edx, %edx
divq %rcx
movq %rdx, -0x10(%rsp)
movq -0x28(%rsp), %rax
movl $0xfff1, %ecx           # imm = 0xFFF1
xorl %edx, %edx
divq %rcx
movq %rdx, -0x28(%rsp)
jmp 0x13155b
cmpl $0x0, -0x1c(%rsp)
je 0x131aac
jmp 0x1317f9
cmpl $0x10, -0x1c(%rsp)
jb 0x131a41
movl -0x1c(%rsp), %eax
subl $0x10, %eax
movl %eax, -0x1c(%rsp)
movq -0x18(%rsp), %rax
movzbl (%rax), %eax
addq -0x10(%rsp), %rax
movq %rax, -0x10(%rsp)
movq -0x10(%rsp), %rax
addq -0x28(%rsp), %rax
movq %rax, -0x28(%rsp)
movq -0x18(%rsp), %rax
movzbl 0x1(%rax), %eax
addq -0x10(%rsp), %rax
movq %rax, -0x10(%rsp)
movq -0x10(%rsp), %rax
addq -0x28(%rsp), %rax
movq %rax, -0x28(%rsp)
movq -0x18(%rsp), %rax
movzbl 0x2(%rax), %eax
addq -0x10(%rsp), %rax
movq %rax, -0x10(%rsp)
movq -0x10(%rsp), %rax
addq -0x28(%rsp), %rax
movq %rax, -0x28(%rsp)
movq -0x18(%rsp), %rax
movzbl 0x3(%rax), %eax
addq -0x10(%rsp), %rax
movq %rax, -0x10(%rsp)
movq -0x10(%rsp), %rax
addq -0x28(%rsp), %rax
movq %rax, -0x28(%rsp)
movq -0x18(%rsp), %rax
movzbl 0x4(%rax), %eax
addq -0x10(%rsp), %rax
movq %rax, -0x10(%rsp)
movq -0x10(%rsp), %rax
addq -0x28(%rsp), %rax
movq %rax, -0x28(%rsp)
movq -0x18(%rsp), %rax
movzbl 0x5(%rax), %eax
addq -0x10(%rsp), %rax
movq %rax, -0x10(%rsp)
movq -0x10(%rsp), %rax
addq -0x28(%rsp), %rax
movq %rax, -0x28(%rsp)
movq -0x18(%rsp), %rax
movzbl 0x6(%rax), %eax
addq -0x10(%rsp), %rax
movq %rax, -0x10(%rsp)
movq -0x10(%rsp), %rax
addq -0x28(%rsp), %rax
movq %rax, -0x28(%rsp)
movq -0x18(%rsp), %rax
movzbl 0x7(%rax), %eax
addq -0x10(%rsp), %rax
movq %rax, -0x10(%rsp)
movq -0x10(%rsp), %rax
addq -0x28(%rsp), %rax
movq %rax, -0x28(%rsp)
movq -0x18(%rsp), %rax
movzbl 0x8(%rax), %eax
addq -0x10(%rsp), %rax
movq %rax, -0x10(%rsp)
movq -0x10(%rsp), %rax
addq -0x28(%rsp), %rax
movq %rax, -0x28(%rsp)
movq -0x18(%rsp), %rax
movzbl 0x9(%rax), %eax
addq -0x10(%rsp), %rax
movq %rax, -0x10(%rsp)
movq -0x10(%rsp), %rax
addq -0x28(%rsp), %rax
movq %rax, -0x28(%rsp)
movq -0x18(%rsp), %rax
movzbl 0xa(%rax), %eax
addq -0x10(%rsp), %rax
movq %rax, -0x10(%rsp)
movq -0x10(%rsp), %rax
addq -0x28(%rsp), %rax
movq %rax, -0x28(%rsp)
movq -0x18(%rsp), %rax
movzbl 0xb(%rax), %eax
addq -0x10(%rsp), %rax
movq %rax, -0x10(%rsp)
movq -0x10(%rsp), %rax
addq -0x28(%rsp), %rax
movq %rax, -0x28(%rsp)
movq -0x18(%rsp), %rax
movzbl 0xc(%rax), %eax
addq -0x10(%rsp), %rax
movq %rax, -0x10(%rsp)
movq -0x10(%rsp), %rax
addq -0x28(%rsp), %rax
movq %rax, -0x28(%rsp)
movq -0x18(%rsp), %rax
movzbl 0xd(%rax), %eax
addq -0x10(%rsp), %rax
movq %rax, -0x10(%rsp)
movq -0x10(%rsp), %rax
addq -0x28(%rsp), %rax
movq %rax, -0x28(%rsp)
movq -0x18(%rsp), %rax
movzbl 0xe(%rax), %eax
addq -0x10(%rsp), %rax
movq %rax, -0x10(%rsp)
movq -0x10(%rsp), %rax
addq -0x28(%rsp), %rax
movq %rax, -0x28(%rsp)
movq -0x18(%rsp), %rax
movzbl 0xf(%rax), %eax
addq -0x10(%rsp), %rax
movq %rax, -0x10(%rsp)
movq -0x10(%rsp), %rax
addq -0x28(%rsp), %rax
movq %rax, -0x28(%rsp)
movq -0x18(%rsp), %rax
addq $0x10, %rax
movq %rax, -0x18(%rsp)
jmp 0x1317f9
jmp 0x131a43
movl -0x1c(%rsp), %eax
movl %eax, %ecx
addl $-0x1, %ecx
movl %ecx, -0x1c(%rsp)
cmpl $0x0, %eax
je 0x131a84
movq -0x18(%rsp), %rax
movq %rax, %rcx
addq $0x1, %rcx
movq %rcx, -0x18(%rsp)
movzbl (%rax), %eax
addq -0x10(%rsp), %rax
movq %rax, -0x10(%rsp)
movq -0x10(%rsp), %rax
addq -0x28(%rsp), %rax
movq %rax, -0x28(%rsp)
jmp 0x131a43
movq -0x10(%rsp), %rax
movl $0xfff1, %ecx           # imm = 0xFFF1
xorl %edx, %edx
divq %rcx
movq %rdx, -0x10(%rsp)
movq -0x28(%rsp), %rax
movl $0xfff1, %ecx           # imm = 0xFFF1
xorl %edx, %edx
divq %rcx
movq %rdx, -0x28(%rsp)
movq -0x10(%rsp), %rax
movq -0x28(%rsp), %rcx
shlq $0x10, %rcx
orq %rcx, %rax
movq %rax, -0x8(%rsp)
movq -0x8(%rsp), %rax
retq
nopl (%rax,%rax)