// File: /workspace/github_c_makefile_star2_O3/deplinenoise[P]tundra/src/HashFast.cpp
// Function: t2::HashBlock(unsigned char const*, t2::HashStateImpl*, void*)
void HashBlock(const uint8_t* block, HashStateImpl* state, void* debug_file_)
{
  const uint32_t* p = (const uint32_t*) block;
  const size_t buffer_size = sizeof(HashState().m_Buffer);

  if (FILE* debug_file = (FILE*) debug_file_)
  {
    const size_t line_size = 16;

    for (size_t i = 0; i < buffer_size; i += line_size)
    {
      for (size_t x = 0; x < line_size; ++x)
      {
        int ch = block[x + i];
        static const char hex[] = "0123456789ABCDEF";
        fputc(hex[(ch & 0xf0) >> 4], debug_file);
        fputc(hex[(ch & 0x0f)     ], debug_file);
        fputc(' ', debug_file);
      }

      fputs(" | ", debug_file);

      for (size_t x = 0; x < line_size; ++x)
      {
        int ch = block[x + i];
        if (isalnum(ch) || ispunct(ch) || ' ' == ch)
          fputc(ch, debug_file);
        else
          fputc('.', debug_file);
      }
      fputc('\n', debug_file);
    }
  }

  static_assert((buffer_size & 63) == 0, "buffer must be multiple of 64 bytes");

  for (size_t i = 0; i < buffer_size/64; ++i)
  {
    for (int v = 0; v < 4; ++v)
    {
      uint32_t v0 = state->m_V[v][0];
      uint32_t v1 = state->m_V[v][1];
      uint32_t v2 = state->m_V[v][2];
      uint32_t v3 = state->m_V[v][3];

      v0 += *p++ * kPrime32_2; v0 = RotateLeft(v0, 13); v0 *= kPrime32_1;
      v1 += *p++ * kPrime32_2; v1 = RotateLeft(v1, 13); v1 *= kPrime32_1;
      v2 += *p++ * kPrime32_2; v2 = RotateLeft(v2, 13); v2 *= kPrime32_1;
      v3 += *p++ * kPrime32_2; v3 = RotateLeft(v3, 13); v3 *= kPrime32_1;

      state->m_V[v][0] = v0;
      state->m_V[v][1] = v1;
      state->m_V[v][2] = v2;
      state->m_V[v][3] = v3;
    }
  }
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x18, %rsp
movq %rsi, 0x10(%rsp)
movq %rdi, 0x8(%rsp)
testq %rdx, %rdx
je 0x13292
movq %rdx, %r15
xorl %r12d, %r12d
leaq 0x41a2(%rip), %r13      # 0x17380
movq 0x8(%rsp), %r14
xorl %ebx, %ebx
movzbl (%r14,%rbx), %ebp
movl %ebp, %eax
shrl $0x4, %eax
movsbl (%rax,%r13), %edi
movq %r15, %rsi
callq 0x3410
andl $0xf, %ebp
movsbl (%rbp,%r13), %edi
movq %r15, %rsi
callq 0x3410
movl $0x20, %edi
movq %r15, %rsi
callq 0x3410
incq %rbx
cmpq $0x10, %rbx
jne 0x131e5
leaq 0x4167(%rip), %rdi      # 0x17391
movq %r15, %rsi
callq 0x33a0
xorl %ebx, %ebx
movzbl (%r14,%rbx), %ebp
movl %ebp, %edi
callq 0x3350
testl %eax, %eax
jne 0x1325c
movl %ebp, %edi
callq 0x3630
movl %ebp, %ecx
testl %eax, %eax
jne 0x13256
movl $0x2e, %ecx
cmpl $0x20, %ebp
cmovnel %ecx, %ebp
movl %ebp, %edi
movq %r15, %rsi
callq 0x3410
incq %rbx
cmpq $0x10, %rbx
jne 0x13234
movl $0xa, %edi
movq %r15, %rsi
callq 0x3410
leaq 0x10(%r12), %rax
addq $0x10, %r14
cmpq $0x30, %r12
movq %rax, %r12
jb 0x131e3
xorl %eax, %eax
movdqa 0x4094(%rip), %xmm0     # 0x17330
movdqa 0x409c(%rip), %xmm1     # 0x17340
movq 0x10(%rsp), %rcx
movq 0x8(%rsp), %rdx
movdqu (%rdx,%rax), %xmm2
pshufd $0xf5, %xmm2, %xmm3     # xmm3 = xmm2[1,1,3,3]
pmuludq %xmm0, %xmm2
pshufd $0xe8, %xmm2, %xmm2     # xmm2 = xmm2[0,2,2,3]
pmuludq %xmm0, %xmm3
pshufd $0xe8, %xmm3, %xmm3     # xmm3 = xmm3[0,2,2,3]
punpckldq %xmm3, %xmm2    # xmm2 = xmm2[0],xmm3[0],xmm2[1],xmm3[1]
paddd (%rcx,%rax), %xmm2
movdqa %xmm2, %xmm3
psrld $0x13, %xmm3
pslld $0xd, %xmm2
por %xmm3, %xmm2
pshufd $0xf5, %xmm2, %xmm3     # xmm3 = xmm2[1,1,3,3]
pmuludq %xmm1, %xmm2
pshufd $0xe8, %xmm2, %xmm2     # xmm2 = xmm2[0,2,2,3]
pmuludq %xmm1, %xmm3
pshufd $0xe8, %xmm3, %xmm3     # xmm3 = xmm3[0,2,2,3]
punpckldq %xmm3, %xmm2    # xmm2 = xmm2[0],xmm3[0],xmm2[1],xmm3[1]
movdqa %xmm2, (%rcx,%rax)
addq $0x10, %rax
cmpq $0x40, %rax
jne 0x132ae
addq $0x18, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq