// File: /workspace/github_c_makefile_star2_O1/FastFilter[P]BlockBloomSimulator/src/softblockmodel.h
// Function: simulate_soft
sim_stats_t simulate_soft(size_t HowManyKeys, softmodel_t model, size_t howmanytests,
                     bitset_t *b) {
  if((model.BlockSizeInBits % 64)!=0) {
      printf("block size should be divisible by 64 bits");
      abort();
  }
  size_t wordsperblock = model.BlockSizeInBits / 64;
  bitset_resize(b, model.BlockSizeInBits * model.NumberOfBlocks, true);
  bitset_clear(b);
  for (size_t i = 0; i < HowManyKeys; i++) {
    size_t blockindex = random_integer(model.NumberOfBlocks);
    for(size_t j = 0; j < wordsperblock; j++) {
        uint64_t w = random_word64();
        for(size_t k = 0; k < model.FoldCount; k++) {
            w &= random_word64();
        }
        w = w | bitset_get_word(b, blockindex * wordsperblock + j);
        bitset_set_word(b, w, blockindex * wordsperblock + j);
    }
  }
  size_t matches = 0;
  for (size_t i = 0; i < howmanytests; i++) {
    size_t blockindex = random_integer(model.NumberOfBlocks);
    bool is_matched = true;
    for(size_t j = 0; j < wordsperblock; j++) {
        uint64_t w = random_word64();
        for(size_t k = 0; k < model.FoldCount; k++) {
            w &= random_word64();;
        }
        uint64_t tw = bitset_get_word(b, blockindex * wordsperblock + j);
        if( (tw & w) != w) {
            is_matched = false; 
        }
    }
    if (is_matched)
      matches++;
  }
  sim_stats_t answer;
  answer.collision_rate = matches * 1.0 / howmanytests;
  answer.density = bitset_count(b) * 1.0 /  (model.BlockSizeInBits * model.NumberOfBlocks) ;
  return answer;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x48, %rsp
movq %rsi, 0x10(%rsp)
movq 0x88(%rsp), %rbp
testb $0x3f, %bpl
jne 0x22fc
movq %rdx, %rbx
movq %rdi, %r13
leaq 0x80(%rsp), %rcx
movabsq $0x5851f42d4c957f2d, %r15 # imm = 0x5851F42D4C957F2D
movq %rbp, %rax
shrq $0x6, %rax
movq %rax, (%rsp)
movq 0x10(%rcx), %rsi
movq %rsi, 0x20(%rsp)
imulq %rbp, %rsi
movq %rdx, %rdi
movq %rsi, 0x30(%rsp)
movl $0x1, %edx
callq 0x29aa
movq %rbx, %rdi
callq 0x2891
testq %r13, %r13
je 0x20f8
leaq 0x80(%rsp), %rax
movq (%rax), %r14
xorl %r12d, %r12d
movq 0x20(%rsp), %rdi
callq 0x1220
testq %rbp, %rbp
je 0x20ec
imulq (%rsp), %rax
xorl %edx, %edx
movq 0x5049(%rip), %rcx      # 0x7080
imulq %r15, %rcx
movq 0x5046(%rip), %rdi      # 0x7088
addq %rdi, %rcx
movq %rcx, %r8
movq %rcx, %rsi
shrq $0x2d, %rsi
movq %rcx, %r9
shrq $0x1b, %r9
xorl %r9d, %esi
shrq $0x3b, %rcx
rorl %cl, %esi
imulq %r15, %r8
addq %rdi, %r8
movq %r8, 0x5013(%rip)       # 0x7080
testq %r14, %r14
je 0x20b7
movq 0x5007(%rip), %r8       # 0x7080
movq %r14, %r9
imulq %r15, %r8
movq %r8, %rcx
addq %rdi, %rcx
movq %rcx, %r8
movq %rcx, %r10
shrq $0x2d, %r10
movq %rcx, %r11
shrq $0x1b, %r11
xorl %r11d, %r10d
shrq $0x3b, %rcx
rorl %cl, %r10d
imulq %r15, %r8
addq %rdi, %r8
andl %r10d, %esi
decq %r9
jne 0x207c
movq %r8, 0x4fc9(%rip)       # 0x7080
leaq (%rdx,%rax), %rcx
movq 0x8(%rbx), %rdi
cmpq %rcx, %rdi
jbe 0x20cd
movq (%rbx), %r8
movq (%r8,%rcx,8), %r8
jmp 0x20d0
xorl %r8d, %r8d
cmpq %rcx, %rdi
jbe 0x20df
orq %rsi, %r8
movq (%rbx), %rsi
movq %r8, (%rsi,%rcx,8)
incq %rdx
cmpq (%rsp), %rdx
jne 0x2030
incq %r12
cmpq %r13, %r12
jne 0x2016
cmpq $0x0, 0x10(%rsp)
je 0x2261
movq (%rsp), %r13
cmpq $0x1, %r13
adcq $0x0, %r13
leaq 0x80(%rsp), %rax
movq (%rax), %r12
xorl %edx, %edx
xorl %eax, %eax
movq %rbp, 0x38(%rsp)
movq %rdx, 0x18(%rsp)
movq %rax, 0x40(%rsp)
movq 0x20(%rsp), %rdi
callq 0x1220
testq %rbp, %rbp
je 0x2216
movq 0x4f38(%rip), %r10      # 0x7080
movq 0x4f39(%rip), %rsi      # 0x7088
imulq (%rsp), %rax
movq 0x8(%rbx), %r8
movb $0x1, %dil
xorl %r9d, %r9d
imulq %r15, %r10
addq %rsi, %r10
movq %r10, %r11
imulq %r15, %r11
addq %rsi, %r11
movq %r10, %rbp
shrq $0x2d, %rbp
movq %r10, %rcx
shrq $0x1b, %rcx
xorl %ecx, %ebp
shrq $0x3b, %r10
movl %r10d, %ecx
rorl %cl, %ebp
movq %r11, 0x4ef1(%rip)      # 0x7080
movq %r11, %r10
movq %r12, %r11
testq %r12, %r12
je 0x21d7
imulq %r15, %r10
movq %r10, %rdx
addq %rsi, %rdx
movq %rdx, %r10
movq %rdx, %r14
shrq $0x2d, %r14
movq %rdx, %rcx
shrq $0x1b, %rcx
xorl %ecx, %r14d
shrq $0x3b, %rdx
movl %edx, %ecx
rorl %cl, %r14d
imulq %r15, %r10
addq %rsi, %r10
andl %r14d, %ebp
decq %r11
jne 0x219a
movq %r10, 0x4ea9(%rip)      # 0x7080
leaq (%r9,%rax), %rcx
cmpq %rcx, %r8
jbe 0x21e9
movq (%rbx), %r11
movq (%r11,%rcx,8), %rcx
jmp 0x21eb
xorl %ecx, %ecx
notl %ecx
testl %ecx, %ebp
movzbl %dil, %edi
movl $0x0, %ecx
cmovnel %ecx, %edi
incq %r9
cmpq %r13, %r9
jne 0x215e
andb $0x1, %dil
movzbl %dil, %eax
movq 0x38(%rsp), %rbp
jmp 0x221b
movl $0x1, %eax
movq 0x18(%rsp), %rdx
movq 0x40(%rsp), %rcx
addq %rax, %rcx
movq %rcx, %rax
incq %rdx
cmpq 0x10(%rsp), %rdx
jne 0x2124
movq %rax, %xmm0
punpckldq 0x1dca(%rip), %xmm0 # xmm0 = xmm0[0],mem[0],xmm0[1],mem[1]
subpd 0x1dd2(%rip), %xmm0     # 0x4020
movapd %xmm0, %xmm1
unpckhpd %xmm0, %xmm1            # xmm1 = xmm1[1],xmm0[1]
addsd %xmm0, %xmm1
movapd %xmm1, (%rsp)
jmp 0x226a
xorpd %xmm0, %xmm0
movapd %xmm0, (%rsp)
movq 0x30(%rsp), %xmm0
movq 0x10(%rsp), %xmm1
punpcklqdq %xmm0, %xmm1    # xmm1 = xmm1[0],xmm0[0]
movdqa 0x1dae(%rip), %xmm0     # 0x4030
pand %xmm1, %xmm0
por 0x1db2(%rip), %xmm0     # 0x4040
psrlq $0x20, %xmm1
por 0x1db5(%rip), %xmm1     # 0x4050
subpd 0x1dbd(%rip), %xmm1     # 0x4060
addpd %xmm0, %xmm1
movapd %xmm1, 0x20(%rsp)
movq %rbx, %rdi
callq 0x2b06
movq %rax, %xmm0
punpckldq 0x1d4e(%rip), %xmm0 # xmm0 = xmm0[0],mem[0],xmm0[1],mem[1]
subpd 0x1d56(%rip), %xmm0     # 0x4020
movapd %xmm0, %xmm1
unpckhpd %xmm0, %xmm1            # xmm1 = xmm1[1],xmm0[1]
addpd %xmm0, %xmm1
movapd (%rsp), %xmm0
unpcklpd %xmm1, %xmm0            # xmm0 = xmm0[0],xmm1[0]
divpd 0x20(%rsp), %xmm0
movapd %xmm0, %xmm1
unpckhpd %xmm0, %xmm1            # xmm1 = xmm1[1],xmm0[1]
addq $0x48, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
leaq 0x1ffc(%rip), %rdi      # 0x42ff
xorl %eax, %eax
callq 0x1080
callq 0x1060