// File: adamiaonr[P]rid-analytics/src/prob.cpp
// Function: Prob::calc_lm_prob(unsigned char, unsigned char, Prob::fp_data*, std::vector<long double, std::allocator<long double>>*)
int Prob::calc_lm_prob(
    uint8_t i, 
    uint8_t t,
    Prob::fp_data * iface_fp_data,
    std::vector<__float080> * lmp) {

    // aux. arrays used in fp rate calculation:
    //  - P(|FP| =/= f) = (1.0 - P(|FP| = f)) : prob of not having an fp match of size f
    std::vector<__float080> log_prob_fp_neq(n, 0.0);
    //  - P(|FP| <= f) : prob of fp match smaller than or equal to f
    std::vector<__float080> log_prob_fp_smeq(n + 1, 0.0);

    if (iface_fp_data->is_blocked) { (*lmp)[0] = 1.0; return 0; }
    if (iface_fp_data->num_entries < 1.0) { (*lmp)[0] = 1.0; return 0; }

    // fill P(|FP| =/= f) = (1.0 - P(|FP| = f)), for all f
    std::vector<__float080> lt_ratios = std::vector<__float080>(n, 1.0);
    calc_log_prob_fp_neq(iface_fp_data, log_prob_fp_neq, lt_ratios);
    // calc P(|FP| <= f), for all f
    for (int f = (int) (this->n - 1); f >= 0; f--)
        log_prob_fp_smeq[f] = log_prob_fp_smeq[f + 1] + log_prob_fp_neq[f];

    for (int f = (int) this->n; f >= 0; f--) {

        _calc_lm_prob(
            f, t, 
            iface_fp_data, 
            &log_prob_fp_neq, &log_prob_fp_smeq,
            lmp);
    }

    return 0;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x190, %rsp            # imm = 0x190
movb %dl, %al
movb %sil, %dl
movq %rdi, -0x10(%rbp)
movb %dl, -0x11(%rbp)
movb %al, -0x12(%rbp)
movq %rcx, -0x20(%rbp)
movq %r8, -0x28(%rbp)
movq -0x10(%rbp), %rax
movq %rax, -0x138(%rbp)
fldt 0x90(%rax)
flds 0x93f3(%rip)            # 0x635fc
fucomi %st(1), %st
setbe %al
fldz
fld %st(0)
fcmovbe %st(2), %st
fstp %st(2)
fxch %st(2)
fsubp %st, %st(1)
fnstcw -0x10a(%rbp)
movzwl -0x10a(%rbp), %ecx
orl $0xc00, %ecx            # imm = 0xC00
movw %cx, -0x10c(%rbp)
fldcw -0x10c(%rbp)
fistpll -0xf0(%rbp)
fldcw -0x10a(%rbp)
movzbl %al, %eax
movl %eax, %ecx
shlq $0x3f, %rcx
movq -0xf0(%rbp), %rax
xorq %rcx, %rax
movq %rax, -0x130(%rbp)
fstpt -0x50(%rbp)
leaq -0x51(%rbp), %rdi
movq %rdi, -0x128(%rbp)
callq 0x34a40
movq -0x130(%rbp), %rsi
movq -0x128(%rbp), %rcx
leaq -0x40(%rbp), %rdi
leaq -0x50(%rbp), %rdx
callq 0x34a60
jmp 0x5a290
leaq -0x51(%rbp), %rdi
callq 0x34b70
movq -0x138(%rbp), %rax
fldt 0x90(%rax)
fld1
faddp %st, %st(1)
flds 0x934c(%rip)            # 0x635fc
fxch %st(1)
fucomi %st(1), %st
fldz
fld %st(0)
fcmovnb %st(3), %st
fstp %st(3)
fxch %st(1)
fsubp %st, %st(2)
setae %al
fnstcw -0x10e(%rbp)
movzwl -0x10e(%rbp), %ecx
orl $0xc00, %ecx            # imm = 0xC00
movw %cx, -0x110(%rbp)
fldcw -0x110(%rbp)
fxch %st(1)
fistpll -0xf8(%rbp)
fldcw -0x10e(%rbp)
movzbl %al, %eax
movl %eax, %ecx
shlq $0x3f, %rcx
movq -0xf8(%rbp), %rax
xorq %rcx, %rax
movq %rax, -0x148(%rbp)
fstpt -0x90(%rbp)
leaq -0x91(%rbp), %rdi
movq %rdi, -0x140(%rbp)
callq 0x34a40
movq -0x148(%rbp), %rsi
movq -0x140(%rbp), %rcx
leaq -0x80(%rbp), %rdi
leaq -0x90(%rbp), %rdx
callq 0x34a60
jmp 0x5a344
leaq -0x91(%rbp), %rdi
callq 0x34b70
movq -0x20(%rbp), %rax
testb $0x1, 0xb8(%rax)
je 0x5a3bb
movq -0x28(%rbp), %rdi
xorl %eax, %eax
movl %eax, %esi
callq 0x34c70
fld1
fstpt (%rax)
movl $0x0, -0x4(%rbp)
movl $0x1, -0x98(%rbp)
jmp 0x5a6ae
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x60(%rbp)
movl %eax, -0x64(%rbp)
leaq -0x51(%rbp), %rdi
callq 0x34b70
jmp 0x5a6de
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x60(%rbp)
movl %eax, -0x64(%rbp)
leaq -0x91(%rbp), %rdi
callq 0x34b70
jmp 0x5a6d5
movq -0x20(%rbp), %rax
fldt 0x10(%rax)
fld1
fucompi %st(1), %st
fstp %st(0)
jbe 0x5a3f3
jmp 0x5a3cc
movq -0x28(%rbp), %rdi
xorl %eax, %eax
movl %eax, %esi
callq 0x34c70
fld1
fstpt (%rax)
movl $0x0, -0x4(%rbp)
movl $0x1, -0x98(%rbp)
jmp 0x5a6ae
movq -0x138(%rbp), %rax
fldt 0x90(%rax)
flds 0x91f6(%rip)            # 0x635fc
fucomi %st(1), %st
setbe %al
fldz
fcmovbe %st(1), %st
fstp %st(1)
fsubrp %st, %st(1)
fnstcw -0x112(%rbp)
movzwl -0x112(%rbp), %ecx
orl $0xc00, %ecx            # imm = 0xC00
movw %cx, -0x114(%rbp)
fldcw -0x114(%rbp)
fistpll -0x100(%rbp)
fldcw -0x112(%rbp)
movzbl %al, %eax
movl %eax, %ecx
shlq $0x3f, %rcx
movq -0x100(%rbp), %rax
xorq %rcx, %rax
movq %rax, -0x158(%rbp)
fld1
fstpt -0xc0(%rbp)
leaq -0xc1(%rbp), %rdi
movq %rdi, -0x150(%rbp)
callq 0x34a40
movq -0x158(%rbp), %rsi
movq -0x150(%rbp), %rcx
leaq -0xb0(%rbp), %rdi
leaq -0xc0(%rbp), %rdx
callq 0x34a60
jmp 0x5a497
leaq -0xc1(%rbp), %rdi
callq 0x34b70
movq -0x20(%rbp), %rax
movq %rax, -0x160(%rbp)
leaq -0xe0(%rbp), %rdi
leaq -0xb0(%rbp), %rsi
callq 0x36d30
jmp 0x5a4c3
movq -0x160(%rbp), %rsi
movq -0x138(%rbp), %rdi
leaq -0x40(%rbp), %rdx
leaq -0xe0(%rbp), %rcx
callq 0x59b60
jmp 0x5a4e3
leaq -0xe0(%rbp), %rdi
callq 0x34b10
movq -0x138(%rbp), %rax
fldt 0x90(%rax)
fld1
fchs
faddp %st, %st(1)
fnstcw -0x116(%rbp)
movzwl -0x116(%rbp), %eax
orl $0xc00, %eax            # imm = 0xC00
movw %ax, -0x118(%rbp)
fldcw -0x118(%rbp)
fistpl -0x104(%rbp)
fldcw -0x116(%rbp)
movl -0x104(%rbp), %eax
movl %eax, -0xe4(%rbp)
cmpl $0x0, -0xe4(%rbp)
jl 0x5a600
movl -0xe4(%rbp), %eax
incl %eax
movslq %eax, %rsi
leaq -0x80(%rbp), %rdi
movq %rdi, -0x178(%rbp)
callq 0x34c70
fldt (%rax)
fstpt -0x184(%rbp)
movslq -0xe4(%rbp), %rsi
leaq -0x40(%rbp), %rdi
callq 0x34c70
fldt -0x184(%rbp)
movq -0x178(%rbp), %rdi
fldt (%rax)
faddp %st, %st(1)
fstpt -0x16c(%rbp)
movslq -0xe4(%rbp), %rsi
callq 0x34c70
fldt -0x16c(%rbp)
fstpt (%rax)
movl -0xe4(%rbp), %eax
addl $-0x1, %eax
movl %eax, -0xe4(%rbp)
jmp 0x5a539
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x60(%rbp)
movl %eax, -0x64(%rbp)
leaq -0xc1(%rbp), %rdi
callq 0x34b70
jmp 0x5a6cc
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x60(%rbp)
movl %eax, -0x64(%rbp)
jmp 0x5a6a0
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x60(%rbp)
movl %eax, -0x64(%rbp)
leaq -0xe0(%rbp), %rdi
callq 0x34b10
jmp 0x5a6a0
movq -0x138(%rbp), %rax
fldt 0x90(%rax)
fnstcw -0x11a(%rbp)
movzwl -0x11a(%rbp), %eax
orl $0xc00, %eax            # imm = 0xC00
movw %ax, -0x11c(%rbp)
fldcw -0x11c(%rbp)
fistpl -0x108(%rbp)
fldcw -0x11a(%rbp)
movl -0x108(%rbp), %eax
movl %eax, -0xe8(%rbp)
cmpl $0x0, -0xe8(%rbp)
jl 0x5a681
movl -0xe8(%rbp), %edi
movzbl -0x12(%rbp), %esi
movq -0x20(%rbp), %rdx
movq -0x28(%rbp), %r9
leaq -0x40(%rbp), %rcx
leaq -0x80(%rbp), %r8
callq 0x5a050
jmp 0x5a66e
jmp 0x5a670
movl -0xe8(%rbp), %eax
addl $-0x1, %eax
movl %eax, -0xe8(%rbp)
jmp 0x5a644
movl $0x0, -0x4(%rbp)
movl $0x1, -0x98(%rbp)
leaq -0xb0(%rbp), %rdi
callq 0x34b10
jmp 0x5a6ae
leaq -0xb0(%rbp), %rdi
callq 0x34b10
jmp 0x5a6cc
leaq -0x80(%rbp), %rdi
callq 0x34b10
leaq -0x40(%rbp), %rdi
callq 0x34b10
movl -0x4(%rbp), %eax
addq $0x190, %rsp            # imm = 0x190
popq %rbp
retq
leaq -0x80(%rbp), %rdi
callq 0x34b10
leaq -0x40(%rbp), %rdi
callq 0x34b10
movq -0x60(%rbp), %rdi
callq 0x5920
nopw (%rax,%rax)