// File: /workspace/github_c_makefile_star2_O2/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, %rbx
movq %rdi, 0x8(%rsp)
testq %rdx, %rdx
je 0x1197b
movq %rdx, %r15
xorl %eax, %eax
movq 0x8(%rsp), %r14
cmpq $0x3f, %rax
ja 0x1197b
movq %rax, 0x10(%rsp)
xorl %r12d, %r12d
cmpq $0x10, %r12
je 0x1190c
movzbl (%r14,%r12), %ebp
movl %ebp, %eax
shrl $0x4, %eax
leaq 0x3a92(%rip), %r13      # 0x15370
movsbl (%rax,%r13), %edi
movq %r15, %rsi
callq 0x3410
andl $0xf, %ebp
movsbl (%rbp,%r13), %edi
movq %r15, %rsi
callq 0x3410
pushq $0x20
popq %rdi
movq %r15, %rsi
callq 0x3410
incq %r12
jmp 0x118c7
leaq 0x3a6e(%rip), %rdi      # 0x15381
movq %r15, %rsi
callq 0x33a0
xorl %ebp, %ebp
cmpq $0x10, %rbp
je 0x1195e
movzbl (%r14,%rbp), %r12d
movl %r12d, %edi
callq 0x3350
testl %eax, %eax
jne 0x1194e
movl %r12d, %edi
callq 0x3630
movl %r12d, %ecx
testl %eax, %eax
jne 0x11946
pushq $0x2e
popq %rcx
cmpl $0x20, %r12d
cmovnel %ecx, %r12d
movl %r12d, %edi
movq %r15, %rsi
callq 0x3410
incq %rbp
jmp 0x1191d
pushq $0xa
popq %rdi
movq %r15, %rsi
callq 0x3410
movq 0x10(%rsp), %rax
addq $0x10, %rax
addq $0x10, %r14
jmp 0x118b5
movb $0x1, %al
movdqa 0x399b(%rip), %xmm0     # 0x15320
movdqa 0x39a3(%rip), %xmm1     # 0x15330
movq 0x8(%rsp), %rcx
testb $0x1, %al
je 0x11a02
xorl %eax, %eax
cmpq $0x40, %rax
je 0x119fb
movdqu (%rcx,%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 (%rbx,%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, (%rbx,%rax)
addq $0x10, %rax
jmp 0x11998
addq %rax, %rcx
xorl %eax, %eax
jmp 0x11992
addq $0x18, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq