// File: /workspace/github_cpp_makefile_star2_O3/lvandeve[P]lodepng/lodepng_unittest.cpp
// Function: md5sum(unsigned char const*, unsigned long, unsigned int*, unsigned int*, unsigned int*, unsigned int*)
void md5sum(const unsigned char* in, size_t size, unsigned* a0, unsigned* b0, unsigned* c0, unsigned* d0) {
  ASSERT_EQUALS(4, sizeof(unsigned));
  // per-round shift amounts
  static const unsigned s[64] = {
    7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, 5,  9, 14, 20, 5,  9, 14, 20, 5,  9, 14, 20, 5,  9, 14, 20,
    4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21,
  };
  // precomputed table from sines
  static const unsigned k[64] = {
    0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee, 0xf57c0faf, 0x4787c62a, 0xa8304613, 0xfd469501,
    0x698098d8, 0x8b44f7af, 0xffff5bb1, 0x895cd7be, 0x6b901122, 0xfd987193, 0xa679438e, 0x49b40821,
    0xf61e2562, 0xc040b340, 0x265e5a51, 0xe9b6c7aa, 0xd62f105d, 0x02441453, 0xd8a1e681, 0xe7d3fbc8,
    0x21e1cde6, 0xc33707d6, 0xf4d50d87, 0x455a14ed, 0xa9e3e905, 0xfcefa3f8, 0x676f02d9, 0x8d2a4c8a,
    0xfffa3942, 0x8771f681, 0x6d9d6122, 0xfde5380c, 0xa4beea44, 0x4bdecfa9, 0xf6bb4b60, 0xbebfbc70,
    0x289b7ec6, 0xeaa127fa, 0xd4ef3085, 0x04881d05, 0xd9d4d039, 0xe6db99e5, 0x1fa27cf8, 0xc4ac5665,
    0xf4292244, 0x432aff97, 0xab9423a7, 0xfc93a039, 0x655b59c3, 0x8f0ccc92, 0xffeff47d, 0x85845dd1,
    0x6fa87e4f, 0xfe2ce6e0, 0xa3014314, 0x4e0811a1, 0xf7537e82, 0xbd3af235, 0x2ad7d2bb, 0xeb86d391,
  };

  *a0 = 0x67452301;
  *b0 = 0xefcdab89;
  *c0 = 0x98badcfe;
  *d0 = 0x10325476;

  // append bit, padding and size to input
  std::vector<unsigned char> data(in, in + size);
  data.resize(((size + 1 + 8 + 63) / 64) * 64, 0);
  data[size] = 128; // append 1 bit (msb)
  size_t bitsize = size * 8; // append the size (shifts > 31 are avoided)
  data[data.size() - 1] = ((bitsize >> 28u) >> 28u) & 255u;
  data[data.size() - 2] = ((bitsize >> 24u) >> 24u) & 255u;
  data[data.size() - 3] = ((bitsize >> 20u) >> 20u) & 255u;
  data[data.size() - 4] = ((bitsize >> 16u) >> 16u) & 255u;
  data[data.size() - 5] = (bitsize >> 24u) & 255u;
  data[data.size() - 6] = (bitsize >> 16u) & 255u;
  data[data.size() - 7] = (bitsize >> 8u) & 255u;
  data[data.size() - 8] = bitsize & 255u;

  // per chunk
  for(size_t i = 0; i < data.size(); i += 64) {
    unsigned a = *a0;
    unsigned b = *b0;
    unsigned c = *c0;
    unsigned d = *d0;

    for(size_t j = 0; j < 64; j++) {
      unsigned f, g;
      if(j <= 15u) {
        f = (b & c) | (~b & d);
        g = j;
      } else if(j <= 31u) {
        f = (d & b) | (~d & c);
        g = (5u * j + 1u) & 15u;
      } else if(j <= 47u) {
        f = b ^ c ^ d;
        g = (3u * j + 5u) & 15u;
      } else {
        f = c ^ (b | ~d);
        g = (7u * j) & 15u;
      }
      unsigned m = (unsigned)(data[i + g * 4 + 3] << 24u) | (unsigned)(data[i + g * 4 + 2] << 16u)
                 | (unsigned)(data[i + g * 4 + 1] << 8u) | (unsigned)data[i + g * 4];
      f += a + k[j] + m;
      a = d;
      d = c;
      c = b;
      b += leftrotate(f, s[j]);
    }
    *a0 += a;
    *b0 += b;
    *c0 += c;
    *d0 += d;
  }
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x58, %rsp
movq %r8, %rbx
movq %rcx, %r14
movq %rsi, %r13
movq %rdi, %rsi
movq %rdx, 0x30(%rsp)
movl $0x67452301, (%rdx)     # imm = 0x67452301
movl $0xefcdab89, (%rcx)     # imm = 0xEFCDAB89
movl $0x98badcfe, (%r8)      # imm = 0x98BADCFE
movq %r9, 0x38(%rsp)
movl $0x10325476, (%r9)      # imm = 0x10325476
leaq (%rdi,%r13), %rdx
leaq 0x10(%rsp), %rbp
leaq 0xf(%rsp), %rcx
movq %rbp, %rdi
callq 0x14dac
leaq 0x48(%r13), %rsi
andq $-0x40, %rsi
movq %rbp, %rdi
xorl %edx, %edx
callq 0x1078a
movq 0x10(%rsp), %rax
movb $-0x80, (%rax,%r13)
leal (,%r13,8), %eax
movq %r13, %rcx
shrq $0x35, %rcx
movq 0x18(%rsp), %rdx
movb %cl, -0x1(%rdx)
movl %r13d, %ecx
shrl $0x15, %ecx
movq %r13, %rdx
shrq $0x2d, %rdx
movq 0x18(%rsp), %rsi
movb %dl, -0x2(%rsi)
movq %r13, %rdx
shrq $0x25, %rdx
movq 0x18(%rsp), %rsi
movb %dl, -0x3(%rsi)
movl %r13d, %edx
shrl $0xd, %edx
movq %r13, %rsi
shrq $0x1d, %rsi
movq 0x18(%rsp), %rdi
movb %sil, -0x4(%rdi)
movq 0x18(%rsp), %rsi
movb %cl, -0x5(%rsi)
movq 0x18(%rsp), %rcx
movb %dl, -0x6(%rcx)
shrl $0x5, %r13d
movq 0x18(%rsp), %rcx
movb %r13b, -0x7(%rcx)
movq 0x18(%rsp), %rcx
movb %al, -0x8(%rcx)
movq 0x10(%rsp), %rdi
movq 0x18(%rsp), %rax
subq %rdi, %rax
movq %rax, 0x50(%rsp)
je 0x16788
movq 0x38(%rsp), %rax
movl (%rax), %ebp
xorl %edx, %edx
leaq 0x88a58(%rip), %r8      # 0x9f0d0
movq 0x30(%rsp), %rcx
movq %rbx, 0x48(%rsp)
movq %r14, 0x40(%rsp)
movl (%rcx), %r9d
movl (%r14), %r15d
movl (%rbx), %ebx
movl $0x5, %r10d
movl $0x1, %r11d
xorl %r13d, %r13d
xorl %eax, %eax
xorl %r14d, %r14d
movl %r9d, 0x2c(%rsp)
movl %r9d, %ecx
movl %r15d, %esi
movl %ebx, %r12d
movl %ebp, %r9d
cmpq $0xf, %r14
ja 0x166cb
movl %r12d, %r15d
xorl %r9d, %r15d
andl %esi, %r15d
xorl %r9d, %r15d
movq %r14, %rbp
jmp 0x16708
cmpq $0x1f, %r14
ja 0x166e2
movl %esi, %r15d
xorl %r12d, %r15d
andl %r9d, %r15d
xorl %r12d, %r15d
movl %r11d, %ebp
jmp 0x16705
cmpq $0x2f, %r14
ja 0x166f6
movl %r12d, %r15d
xorl %esi, %r15d
xorl %r9d, %r15d
movl %r10d, %ebp
jmp 0x16705
movl %r9d, %r15d
notl %r15d
orl %esi, %r15d
xorl %r12d, %r15d
movl %r13d, %ebp
andl $0xf, %ebp
addl %ecx, %r15d
leaq (%rdx,%rbp,4), %rcx
leaq 0x88aba(%rip), %rbx     # 0x9f1d0
addl (%rax,%rbx), %r15d
addl (%rdi,%rcx), %r15d
movb (%rax,%r8), %cl
roll %cl, %r15d
addl %esi, %r15d
incq %r14
addq $0x3, %r10
addq $0x4, %rax
addq $0x5, %r11
addq $0x7, %r13
movl %r12d, %ebp
movl %esi, %ebx
cmpq $0xc5, %r10
jne 0x166a8
addl 0x2c(%rsp), %r9d
movq 0x30(%rsp), %rcx
movl %r9d, (%rcx)
movq 0x40(%rsp), %r14
addl %r15d, (%r14)
movq 0x48(%rsp), %rbx
addl %esi, (%rbx)
movq 0x38(%rsp), %rax
addl (%rax), %r12d
movl %r12d, (%rax)
addq $0x40, %rdx
movl %r12d, %ebp
cmpq 0x50(%rsp), %rdx
jb 0x16687
jmp 0x1678d
testq %rdi, %rdi
je 0x16792
callq 0x2210
addq $0x58, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movq %rax, %rbx
movq 0x10(%rsp), %rdi
testq %rdi, %rdi
je 0x167b3
callq 0x2210
movq %rbx, %rdi
callq 0x23c0