// File: attractivechaos[P]udb2/verstable/./verstable.h
// Function: intmap_t_insert_raw
static inline VT_CAT( NAME, _itr ) VT_CAT( NAME, _insert_raw )(
  NAME *table,
  KEY_TY key,
  #ifdef VAL_TY
  VAL_TY val,
  #endif
  bool unique,
  bool replace
)
{
  if( !table->bucket_count )
    return VT_CAT( NAME, _end_itr )( table );

  uint64_t hash = HASH_FN( key );
  size_t home_bucket = hash & ( table->bucket_count - 1 );
  uint16_t hashfrag = VT_HASH_FRAG( hash );

  // Case 1: The home bucket is empty or contains a key that doesn't belong there.
  if( !( table->metadata[ home_bucket ] & VT_IN_HOME_BUCKET_MASK ) )
  {
    if( table->key_count + 1 > table->bucket_count * MAX_LOAD )
      return VT_CAT( NAME, _end_itr )( table );

    if( table->metadata[ home_bucket ] != VT_EMPTY )
      if( !VT_CAT( NAME, _evict )( table, home_bucket ) )
        return VT_CAT( NAME, _end_itr )( table );

    table->buckets[ home_bucket ].key = key;
    #ifdef VAL_TY
    table->buckets[ home_bucket ].val = val;
    #endif
    table->metadata[ home_bucket ] = hashfrag | VT_IN_HOME_BUCKET_MASK | VT_DISPLACEMENT_MASK;

    ++table->key_count;

    VT_CAT( NAME, _itr ) itr = {
      table->buckets + home_bucket,
      table->metadata + home_bucket,
      table->metadata + table->bucket_count,
      home_bucket
    };
    return itr;
  }

  // Case 2: The home bucket contains the beginning of a chain.

  // Optionally, check the existing chain.
  if( !unique )
  {
    size_t bucket = home_bucket;
    while( true )
    {
      if(
        ( table->metadata[ bucket ] & VT_HASH_FRAG_MASK ) == hashfrag &&
        CMPR_FN( table->buckets[ bucket ].key, key )
      )
      {
        if( replace )
        {
          #ifdef KEY_DTOR_FN
          KEY_DTOR_FN( table->buckets[ bucket ].key );
          #endif
          table->buckets[ bucket ].key = key;

          #ifdef VAL_TY
          #ifdef VAL_DTOR_FN
          VAL_DTOR_FN( table->buckets[ bucket ].val );
          #endif
          table->buckets[ bucket ].val = val;
          #endif
        }

        VT_CAT( NAME, _itr ) itr = {
          table->buckets + bucket,
          table->metadata + bucket,
          table->metadata + table->bucket_count,
          home_bucket
        };
        return itr;
      }

      uint16_t displacement = table->metadata[ bucket ] & VT_DISPLACEMENT_MASK;
      if( displacement == VT_DISPLACEMENT_MASK )
        break;

      bucket = ( home_bucket + VT_QUADRATIC( displacement ) ) & ( table->bucket_count - 1 );
    }
  }

  if( table->key_count + 1 > table->bucket_count * MAX_LOAD )
    return VT_CAT( NAME, _end_itr )( table );

  // Find the earliest empty bucket, per quadratic probing.
  size_t empty;
  uint16_t displacement;
  if( !VT_CAT( NAME, _find_first_empty )( table, home_bucket, &empty, &displacement ) )
    return VT_CAT( NAME, _end_itr )( table );

  size_t prev = VT_CAT( NAME, _find_insert_location_in_chain )( table, home_bucket, displacement );

  // Insert the new key (and value) in the empty bucket and link it to the chain.
  table->buckets[ empty ].key = key;
  #ifdef VAL_TY
  table->buckets[ empty ].val = val;
  #endif
  table->metadata[ empty ] = hashfrag | ( table->metadata[ prev ] & VT_DISPLACEMENT_MASK );
  table->metadata[ prev ] = ( table->metadata[ prev ] & ~VT_DISPLACEMENT_MASK ) | displacement;

  ++table->key_count;


  VT_CAT( NAME, _itr ) itr = {
    table->buckets + empty,
    table->metadata + empty,
    table->metadata + table->bucket_count,
    home_bucket
  };
  return itr;
}

// Assembly:
subq $0x88, %rsp
movl %r8d, 0xc(%rsp)
movl %ecx, %eax
movl 0xc(%rsp), %ecx
movl %eax, 0x10(%rsp)
movl %edx, %eax
movl 0x10(%rsp), %edx
movl %eax, 0x14(%rsp)
movq %rsi, %rax
movl 0x14(%rsp), %esi
movq %rax, 0x18(%rsp)
movq %rdi, %r8
movq 0x18(%rsp), %rdi
movq %r8, 0x20(%rsp)
movb %r9b, %al
movq %r8, 0x28(%rsp)
movq %rdi, 0x80(%rsp)
movl %esi, 0x7c(%rsp)
movl %edx, 0x78(%rsp)
andb $0x1, %cl
movb %cl, 0x77(%rsp)
andb $0x1, %al
movb %al, 0x76(%rsp)
movq 0x80(%rsp), %rax
cmpq $0x0, 0x8(%rax)
jne 0x19f4
movq 0x20(%rsp), %rdi
movq 0x80(%rsp), %rsi
callq 0x2190
jmp 0x1f5f
movl 0x7c(%rsp), %edi
callq 0x21c0
movl %eax, %eax
movq %rax, 0x68(%rsp)
movq 0x68(%rsp), %rax
movq 0x80(%rsp), %rcx
movq 0x8(%rcx), %rcx
subq $0x1, %rcx
andq %rcx, %rax
movq %rax, 0x60(%rsp)
movq 0x68(%rsp), %rax
shrq $0x30, %rax
andq $0xf000, %rax           # imm = 0xF000
movw %ax, 0x5e(%rsp)
movq 0x80(%rsp), %rax
movq 0x10(%rax), %rax
movq 0x60(%rsp), %rcx
movzwl (%rax,%rcx,2), %eax
andl $0x800, %eax            # imm = 0x800
cmpl $0x0, %eax
jne 0x1bee
movq 0x80(%rsp), %rax
movq (%rax), %rcx
incq %rcx
movq %rcx, %xmm0
movaps 0x15be(%rip), %xmm3     # 0x3030
punpckldq %xmm3, %xmm0    # xmm0 = xmm0[0],xmm3[0],xmm0[1],xmm3[1]
movapd 0x15c2(%rip), %xmm2     # 0x3040
subpd %xmm2, %xmm0
movaps %xmm0, %xmm1
unpckhpd %xmm0, %xmm0            # xmm0 = xmm0[1,1]
addsd %xmm1, %xmm0
movq 0x8(%rax), %xmm1
punpckldq %xmm3, %xmm1    # xmm1 = xmm1[0],xmm3[0],xmm1[1],xmm3[1]
subpd %xmm2, %xmm1
movaps %xmm1, %xmm2
unpckhpd %xmm1, %xmm1            # xmm1 = xmm1[1,1]
addsd %xmm2, %xmm1
movsd 0x1573(%rip), %xmm2     # 0x3020
mulsd %xmm2, %xmm1
ucomisd %xmm1, %xmm0
jbe 0x1ace
movq 0x20(%rsp), %rdi
movq 0x80(%rsp), %rsi
callq 0x2190
jmp 0x1f5f
movq 0x80(%rsp), %rax
movq 0x10(%rax), %rax
movq 0x60(%rsp), %rcx
movzwl (%rax,%rcx,2), %eax
cmpl $0x0, %eax
je 0x1b17
movq 0x80(%rsp), %rdi
movq 0x60(%rsp), %rsi
callq 0x21d0
testb $0x1, %al
jne 0x1b15
movq 0x20(%rsp), %rdi
movq 0x80(%rsp), %rsi
callq 0x2190
jmp 0x1f5f
jmp 0x1b17
movq 0x20(%rsp), %rax
movl 0x7c(%rsp), %esi
movq 0x80(%rsp), %rcx
movq 0x18(%rcx), %rcx
movq 0x60(%rsp), %rdx
movl %esi, (%rcx,%rdx,8)
movl 0x78(%rsp), %esi
movq 0x80(%rsp), %rcx
movq 0x18(%rcx), %rcx
movq 0x60(%rsp), %rdx
movl %esi, 0x4(%rcx,%rdx,8)
movzwl 0x5e(%rsp), %ecx
orl $0x800, %ecx            # imm = 0x800
orl $0x7ff, %ecx            # imm = 0x7FF
movw %cx, %si
movq 0x80(%rsp), %rcx
movq 0x10(%rcx), %rcx
movq 0x60(%rsp), %rdx
movw %si, (%rcx,%rdx,2)
movq 0x80(%rsp), %rcx
movq (%rcx), %rdx
addq $0x1, %rdx
movq %rdx, (%rcx)
movq 0x80(%rsp), %rcx
movq 0x18(%rcx), %rcx
movq 0x60(%rsp), %rdx
shlq $0x3, %rdx
addq %rdx, %rcx
movq %rcx, (%rax)
movq 0x80(%rsp), %rcx
movq 0x10(%rcx), %rcx
movq 0x60(%rsp), %rdx
shlq %rdx
addq %rdx, %rcx
movq %rcx, 0x8(%rax)
movq 0x80(%rsp), %rcx
movq 0x10(%rcx), %rcx
movq 0x80(%rsp), %rdx
movq 0x8(%rdx), %rdx
shlq %rdx
addq %rdx, %rcx
movq %rcx, 0x10(%rax)
movq 0x60(%rsp), %rcx
movq %rcx, 0x18(%rax)
jmp 0x1f5f
testb $0x1, 0x77(%rsp)
jne 0x1d74
movq 0x60(%rsp), %rax
movq %rax, 0x50(%rsp)
movq 0x80(%rsp), %rax
movq 0x10(%rax), %rax
movq 0x50(%rsp), %rcx
movzwl (%rax,%rcx,2), %eax
andl $0xf000, %eax           # imm = 0xF000
movzwl 0x5e(%rsp), %ecx
cmpl %ecx, %eax
jne 0x1cf7
movq 0x80(%rsp), %rax
movq 0x18(%rax), %rax
movq 0x50(%rsp), %rcx
movl (%rax,%rcx,8), %eax
movl %eax, %edi
movl 0x7c(%rsp), %eax
movl %eax, %esi
callq 0x23f0
testb $0x1, %al
jne 0x1c54
jmp 0x1cf7
testb $0x1, 0x76(%rsp)
je 0x1c8c
movl 0x7c(%rsp), %edx
movq 0x80(%rsp), %rax
movq 0x18(%rax), %rax
movq 0x50(%rsp), %rcx
movl %edx, (%rax,%rcx,8)
movl 0x78(%rsp), %edx
movq 0x80(%rsp), %rax
movq 0x18(%rax), %rax
movq 0x50(%rsp), %rcx
movl %edx, 0x4(%rax,%rcx,8)
movq 0x20(%rsp), %rax
movq 0x80(%rsp), %rcx
movq 0x18(%rcx), %rcx
movq 0x50(%rsp), %rdx
shlq $0x3, %rdx
addq %rdx, %rcx
movq %rcx, (%rax)
movq 0x80(%rsp), %rcx
movq 0x10(%rcx), %rcx
movq 0x50(%rsp), %rdx
shlq %rdx
addq %rdx, %rcx
movq %rcx, 0x8(%rax)
movq 0x80(%rsp), %rcx
movq 0x10(%rcx), %rcx
movq 0x80(%rsp), %rdx
movq 0x8(%rdx), %rdx
shlq %rdx
addq %rdx, %rcx
movq %rcx, 0x10(%rax)
movq 0x60(%rsp), %rcx
movq %rcx, 0x18(%rax)
jmp 0x1f5f
movq 0x80(%rsp), %rax
movq 0x10(%rax), %rax
movq 0x50(%rsp), %rcx
movzwl (%rax,%rcx,2), %eax
andl $0x7ff, %eax            # imm = 0x7FF
movw %ax, 0x4e(%rsp)
movzwl 0x4e(%rsp), %eax
cmpl $0x7ff, %eax            # imm = 0x7FF
jne 0x1d24
jmp 0x1d72
movq 0x60(%rsp), %rax
movq %rax, (%rsp)
movzwl 0x4e(%rsp), %eax
movzwl 0x4e(%rsp), %ecx
imull %ecx, %eax
movzwl 0x4e(%rsp), %ecx
addl %ecx, %eax
movl $0x2, %ecx
cltd
idivl %ecx
movl %eax, %ecx
movq (%rsp), %rax
movslq %ecx, %rcx
addq %rcx, %rax
movq 0x80(%rsp), %rcx
movq 0x8(%rcx), %rcx
subq $0x1, %rcx
andq %rcx, %rax
movq %rax, 0x50(%rsp)
jmp 0x1c03
jmp 0x1d74
movq 0x80(%rsp), %rax
movq (%rax), %rcx
incq %rcx
movq %rcx, %xmm0
movaps 0x12a2(%rip), %xmm3     # 0x3030
punpckldq %xmm3, %xmm0    # xmm0 = xmm0[0],xmm3[0],xmm0[1],xmm3[1]
movapd 0x12a6(%rip), %xmm2     # 0x3040
subpd %xmm2, %xmm0
movaps %xmm0, %xmm1
unpckhpd %xmm0, %xmm0            # xmm0 = xmm0[1,1]
addsd %xmm1, %xmm0
movq 0x8(%rax), %xmm1
punpckldq %xmm3, %xmm1    # xmm1 = xmm1[0],xmm3[0],xmm1[1],xmm3[1]
subpd %xmm2, %xmm1
movaps %xmm1, %xmm2
unpckhpd %xmm1, %xmm1            # xmm1 = xmm1[1,1]
addsd %xmm2, %xmm1
movsd 0x1257(%rip), %xmm2     # 0x3020
mulsd %xmm2, %xmm1
ucomisd %xmm1, %xmm0
jbe 0x1dea
movq 0x20(%rsp), %rdi
movq 0x80(%rsp), %rsi
callq 0x2190
jmp 0x1f5f
movq 0x80(%rsp), %rdi
movq 0x60(%rsp), %rsi
leaq 0x40(%rsp), %rdx
leaq 0x3e(%rsp), %rcx
callq 0x2410
testb $0x1, %al
jne 0x1e21
movq 0x20(%rsp), %rdi
movq 0x80(%rsp), %rsi
callq 0x2190
jmp 0x1f5f
movq 0x80(%rsp), %rdi
movq 0x60(%rsp), %rsi
movzwl 0x3e(%rsp), %eax
movl %eax, %edx
callq 0x24c0
movq %rax, %rcx
movq 0x20(%rsp), %rax
movq %rcx, 0x30(%rsp)
movl 0x7c(%rsp), %esi
movq 0x80(%rsp), %rcx
movq 0x18(%rcx), %rcx
movq 0x40(%rsp), %rdx
movl %esi, (%rcx,%rdx,8)
movl 0x78(%rsp), %esi
movq 0x80(%rsp), %rcx
movq 0x18(%rcx), %rcx
movq 0x40(%rsp), %rdx
movl %esi, 0x4(%rcx,%rdx,8)
movzwl 0x5e(%rsp), %ecx
movq 0x80(%rsp), %rdx
movq 0x10(%rdx), %rdx
movq 0x30(%rsp), %rsi
movzwl (%rdx,%rsi,2), %edx
andl $0x7ff, %edx            # imm = 0x7FF
orl %edx, %ecx
movw %cx, %si
movq 0x80(%rsp), %rcx
movq 0x10(%rcx), %rcx
movq 0x40(%rsp), %rdx
movw %si, (%rcx,%rdx,2)
movq 0x80(%rsp), %rcx
movq 0x10(%rcx), %rcx
movq 0x30(%rsp), %rdx
movzwl (%rcx,%rdx,2), %ecx
andl $0xfffff800, %ecx       # imm = 0xFFFFF800
movzwl 0x3e(%rsp), %edx
orl %edx, %ecx
movw %cx, %si
movq 0x80(%rsp), %rcx
movq 0x10(%rcx), %rcx
movq 0x30(%rsp), %rdx
movw %si, (%rcx,%rdx,2)
movq 0x80(%rsp), %rcx
movq (%rcx), %rdx
addq $0x1, %rdx
movq %rdx, (%rcx)
movq 0x80(%rsp), %rcx
movq 0x18(%rcx), %rcx
movq 0x40(%rsp), %rdx
shlq $0x3, %rdx
addq %rdx, %rcx
movq %rcx, (%rax)
movq 0x80(%rsp), %rcx
movq 0x10(%rcx), %rcx
movq 0x40(%rsp), %rdx
shlq %rdx
addq %rdx, %rcx
movq %rcx, 0x8(%rax)
movq 0x80(%rsp), %rcx
movq 0x10(%rcx), %rcx
movq 0x80(%rsp), %rdx
movq 0x8(%rdx), %rdx
shlq %rdx
addq %rdx, %rcx
movq %rcx, 0x10(%rax)
movq 0x60(%rsp), %rcx
movq %rcx, 0x18(%rax)
movq 0x28(%rsp), %rax
addq $0x88, %rsp
retq
nopl (%rax)