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

    //  - P(L_i | T_i = 0, A) and P(L_~i | T_~i = 0, A)
    std::vector<std::vector<__float080> > event_a(2, std::vector<__float080> ((this->n + 1), 0.0));
    calc_lm_prob(i, 0, (*iface_fp_data)[0][i], &event_a[0]);
    calc_lm_prob(i, 0, (*iface_fp_data)[1][i], &event_a[1]);

    // 1) calc P(L_i = l) and P(L_{~i} = l), for all l
    for (int f = this->n; f >= 0; f--) {

        // P(L_i, T_i = 0) is a special case, influenced by 2 mutually exclusive 
        // events, say A and B:
        //
        //  - A : a request comes into the router while *not* associated w/ 
        //        a tree of any size t. 
        //        in this case, none of the ifaces can be associated w/ 
        //        a fp tree of any size, yielding:
        //          - P(T_i = 0) = 1.0
        //          - P(T_i > 0) = 0.0
        //
        //        this can happen iff a TP match and no FP matches happened 
        //        in the previous router.
        //        
        //  - B : say the req. comes into the router associated w/ a tree of some size t (t > 0).
        //        in this this case iface i can either be associated or not 
        //        associated w/ a fp tree of size t > 0, yielding:
        //          - P(T_i = 0) = 1.0 - SUM {for all t > 0} [ srt[i][t] * P(T_in = t) ]
        //          - P(T_i > 0) = srt[i][t] * P(T_in = t)
        //         
        // finally, P(L_i, T_i = 0) = 
        //      P(T_in = 0) * (P(L_i | T_i = 0, A) * P(T_i = 0, A))         // event A
        //      + (1 - P(T_in = 0)) * (P(L_i | T_i = 0, B) * T_i = 0, B)    // event B

        // - P(L_i, T_i = 0)
        __float080 __joint_prob = 
            ((*in_fptree_prob)[0] * event_a[0][f] * (((*iface_fp_data)[0][i]->is_blocked && (f > 0)) ? 0.0 : 1.0))
            + ((1.0 - (*in_fptree_prob)[0]) * (this->lm_cond_prob[i][0][f] * this->fptree_prob[0][i][0]));
        lm_marg_prob[i][f] += __joint_prob;

        // if (__joint_prob > 0.0 || __joint_prob < 0.0) {

        //     std::cout << "\t[0] = " << (*in_fptree_prob)[0] << std::endl;
        //     std::cout << "\t[1] = " << event_a[0][f] << std::endl;
        //     std::cout << "\t[2] = " << (((*iface_fp_data)[0][i]->is_blocked && (f > 0)) ? 0.0 : 1.0) << std::endl;
        //     std::cout << "\t[3] = " << (1.0 - (*in_fptree_prob)[0]) << std::endl;
        //     std::cout << "\t[4] = " << (this->lm_cond_prob[i][0][f]) << std::endl;
        //     std::cout << "\t[5] = " << (this->fptree_prob[0][i][0]) << std::endl;
        // }

        // - P(L_~i, T_~i = 0)
        __joint_prob = 
            ((*in_fptree_prob)[0] * event_a[1][f])
            + ((1.0 - (*in_fptree_prob)[0]) * (this->lm_complement_cond_prob[i][0][f] * this->fptree_prob[1][i][0]));
        lm_complement_marg_prob[i][f] += __joint_prob;

        for (uint8_t t = 1; t < (this->n + 1); t++) {

            // - P(L_i = l, T_i = t)
            __float080 joint_prob = (1.0 - (*in_fptree_prob)[0]) * (this->lm_cond_prob[i][t][f] * this->fptree_prob[0][i][t]);
            // add joint P(L_i = l, T_i = t) to marginal P(L_i = l)
            lm_marg_prob[i][f] += joint_prob;

            // print if P(L_i = l, T_i = t) > 0.0
            // if (joint_prob > 0.0 || joint_prob < 0.0) {
            //     std::cout << "\t[" << (int) t << "] +" 
            //         << (joint_prob) << " (" << this->lm_cond_prob[i][t][f] << " x " << this->fptree_prob[0][i][t] << ")"
            //         << " to P(L_" << (int) i << " = " << (int) f << ") = " << lm_marg_prob[i][f] << std::endl;
            // }

            // - P(L_{~i} = l, T_{~i} = t)
            joint_prob = 
                    (1.0 - (*in_fptree_prob)[0])
                    * this->lm_complement_cond_prob[i][t][f]    // P(L_{~i} = l | T_{~i} = t)
                    * this->fptree_prob[1][i][t];               // P(T_{~i} = t)
            // add the joint P(L_{~i} = l, T_{~i} = t) to marginal P(L_{~i} = l)
            lm_complement_marg_prob[i][f] += joint_prob;
            // print if P(L_{~i} = l, T_{~i} = t) > 0.0
            // if (joint_prob > 0.0 || joint_prob < 0.0) {
            //     std::cout << "\t[" << (int) t << "] +" 
            //         << (joint_prob) << " (" << this->lm_complement_cond_prob[i][t][f] << " x " << this->fptree_prob[1][i][t] << ")"
            //         << " to P(L_{~" << (int) i << "} = " << f << ") = " << lm_complement_marg_prob[i][f] << std::endl;
            // }
        }
    }

    // std::cout << "Prob::calc_iface_prob() : P(L_" << (int) i << " = l) :" << std::endl; 
    // for (int f = 0; f < this->n + 1; f++)
    //     std::cout << "\tP(L_" << (int) i << " = " << (int) f << ") = " << lm_marg_prob[i][f] << std::endl;

    // std::cout << "Prob::calc_iface_prob() : P(L_{~" << (int) i << "} = l) :" << std::endl; 
    // for (int f = 0; f < this->n + 1; f++)
    //     std::cout << "\tP(L_{~" << (int) i << "} = " << (int) f << ") = " << lm_complement_marg_prob[i][f] << std::endl;


    // 2) calc P(L_i >= L_{~i})
    for (int f = this->n; f >= 0; f--) {

        __float080 prob[4] = {0.0, 0.0, 0.0, 0.0};

        for (uint8_t k = 0; k < f; k++) {

            // a) L_i > [ L_{~i} AND L_0]
            // [ i ][~i ][ 0 ]
            //   2    0    0
            //   2    0    1
            //   2    1    0
            //   2    1    1
            //   1    0    0
            __float080 _p = (lm_marg_prob[i][f] * lm_complement_marg_prob[i][k]);

            if (i > 0) {

                for (uint8_t j = 0; j < f; j++) {
                    // std::cout << "\t (a) [" << (int) f << "][" << (int) k << "][" << (int) j << "]" << std::endl;
                    prob[0] += _p * lm_marg_prob[0][j];
                }

                // b) L_i == L_0 > L_{~i}
                // [ i ][~i ][ 0 ]
                //   2    0    2
                //   2    1    2
                //   1    0    1
                // std::cout << "\t (b) [" << (int) f << "][" << (int) k << "][" << (int) f << "]" << std::endl;
                prob[1] += (_p * lm_marg_prob[0][f]);

            } else {
                prob[0] += _p;
            }
        }

        // std::cout << "Prob::calc_iface_prob() : L_" << (int) i << " > [ L~{" << (int) i << "} AND L_0 ] [" << f << "] = " << prob[0] << std::endl;
        // std::cout << "Prob::calc_iface_prob() : L_" << (int) i << " [ > L~{" << (int) i << "} ] AND  [ = L_0 ] [" << f << "] = " << prob[1] << std::endl;

        __float080 __p = (lm_marg_prob[i][f] * lm_complement_marg_prob[i][f]);

        if (i > 0) {

            for (uint8_t k = 0; k < f; k++) {
                // c) L_i == L_{~i} > L_0
                // [ i ][~i ][ 0 ]
                //   2    2    0
                //   2    2    1
                //   1    1    0
                // std::cout << "\t (c) [" << (int) f << "][" << (int) f << "][" << (int) k << "]" << std::endl;
                prob[2] += (__p * lm_marg_prob[0][k]);
            }

            // d) L_i == L_{~i} == L_0
            // [ i ][~i ][ 0 ]
            //   2    2    2
            //   1    1    1
            //   0    0    0
            // std::cout << "\t (d) [" << (int) f << "][" << (int) f << "][" << (int) f << "]" << std::endl;
            prob[3] = (__p  * lm_marg_prob[0][f]);

        } else {
            prob[3] = __p;
        }

        // std::cout << "Prob::calc_iface_prob() : L_" << (int) i << " = L~{" << (int) i << "} > L_0 [" << f << "] = " << prob[2] << std::endl;
        // std::cout << "Prob::calc_iface_prob() : L_" << (int) i << " = L~{" << (int) i << "} = L_0)[" << f << "] = " << prob[3] << std::endl;

        iface_prob[0] += (prob[0]);                                 // P(L_i >  L_{~i}) : SINGLE MATCH ONLY
        iface_prob[1] += (prob[0] + prob[2]);                       // P(L_i >= L_{~i}) : MULTIPLE MATCH (NO LOCAL MATCHES)
        iface_prob[2] += (prob[0] + prob[1] + prob[2] + prob[3]);   // P(L_i >= L_{~i}) : MULTIPLE MATCH (W/ LOCAL MATCHES)

        // for (int k = 0; k < 3; k++)
        //     std::cout << "Prob::calc_iface_prob() : iface_prob[" << (int) k << "] = " << iface_prob[k] << std::endl;

        if ((iface_prob[2] < iface_prob[0]) && (i > 0))
            std::cout << "Prob::calc_iface_prob() : [ERROR] P(L_i > L_{~i}) > P(L_i > L_{~i}/0)" << std::endl;            
    }

    return 0;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x390, %rsp            # imm = 0x390
movb %sil, %al
movq %rdi, -0x8(%rbp)
movb %al, -0x9(%rbp)
movq %rdx, -0x18(%rbp)
movq %rcx, -0x20(%rbp)
movq %r8, -0x28(%rbp)
movq -0x8(%rbp), %rax
movq %rax, -0x198(%rbp)
fldt 0x90(%rax)
fld1
faddp %st, %st(1)
flds 0x75f0(%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 -0x176(%rbp)
movzwl -0x176(%rbp), %ecx
orl $0xc00, %ecx            # imm = 0xC00
movw %cx, -0x178(%rbp)
fldcw -0x178(%rbp)
fxch %st(1)
fistpll -0x160(%rbp)
fldcw -0x176(%rbp)
movzbl %al, %eax
movl %eax, %ecx
shlq $0x3f, %rcx
movq -0x160(%rbp), %rax
xorq %rcx, %rax
movq %rax, -0x190(%rbp)
fstpt -0x70(%rbp)
leaq -0x71(%rbp), %rdi
movq %rdi, -0x188(%rbp)
callq 0x34a40
movq -0x190(%rbp), %rsi
movq -0x188(%rbp), %rcx
leaq -0x58(%rbp), %rdi
leaq -0x70(%rbp), %rdx
callq 0x34a60
jmp 0x5c097
leaq -0x85(%rbp), %rdi
movq %rdi, -0x1a0(%rbp)
callq 0x35a40
movq -0x1a0(%rbp), %rcx
leaq -0x40(%rbp), %rdi
movl $0x2, %esi
leaq -0x58(%rbp), %rdx
callq 0x35a60
jmp 0x5c0c5
leaq -0x85(%rbp), %rdi
callq 0x35b40
leaq -0x58(%rbp), %rdi
callq 0x34b10
leaq -0x71(%rbp), %rdi
callq 0x34b70
movzbl -0x9(%rbp), %eax
movl %eax, -0x1b0(%rbp)
movq -0x18(%rbp), %rdi
xorl %eax, %eax
movl %eax, -0x1ac(%rbp)
movl %eax, %esi
movq %rsi, -0x1b8(%rbp)
callq 0x35850
movq %rax, %rdi
movzbl -0x9(%rbp), %eax
movl %eax, %esi
callq 0x358e0
movq -0x1b8(%rbp), %rsi
movq (%rax), %rax
movq %rax, -0x1a8(%rbp)
leaq -0x40(%rbp), %rdi
callq 0x358a0
movq -0x198(%rbp), %rdi
movl -0x1b0(%rbp), %esi
movl -0x1ac(%rbp), %edx
movq -0x1a8(%rbp), %rcx
movq %rax, %r8
callq 0x5a1d0
jmp 0x5c153
movzbl -0x9(%rbp), %eax
movl %eax, -0x1c4(%rbp)
movq -0x18(%rbp), %rdi
movl $0x1, %esi
movq %rsi, -0x1d0(%rbp)
callq 0x35850
movq %rax, %rdi
movzbl -0x9(%rbp), %eax
movl %eax, %esi
callq 0x358e0
movq -0x1d0(%rbp), %rsi
movq (%rax), %rax
movq %rax, -0x1c0(%rbp)
leaq -0x40(%rbp), %rdi
callq 0x358a0
movq -0x198(%rbp), %rdi
movl -0x1c4(%rbp), %esi
movq -0x1c0(%rbp), %rcx
movq %rax, %r8
xorl %edx, %edx
callq 0x5a1d0
jmp 0x5c1ba
movq -0x198(%rbp), %rax
fldt 0x90(%rax)
fnstcw -0x17a(%rbp)
movzwl -0x17a(%rbp), %eax
orl $0xc00, %eax            # imm = 0xC00
movw %ax, -0x17c(%rbp)
fldcw -0x17c(%rbp)
fistpl -0x164(%rbp)
fldcw -0x17a(%rbp)
movl -0x164(%rbp), %eax
movl %eax, -0x8c(%rbp)
cmpl $0x0, -0x8c(%rbp)
jl 0x5c7b6
movq -0x20(%rbp), %rdi
xorl %eax, %eax
movl %eax, %esi
movq %rsi, -0x1f0(%rbp)
callq 0x34c70
movq -0x1f0(%rbp), %rsi
fldt (%rax)
fstpt -0x1e8(%rbp)
leaq -0x40(%rbp), %rdi
callq 0x358a0
movq %rax, %rdi
movslq -0x8c(%rbp), %rsi
callq 0x34c70
fldt -0x1e8(%rbp)
fldt (%rax)
fmulp %st, %st(1)
fstpt -0x1dc(%rbp)
movq -0x18(%rbp), %rdi
xorl %eax, %eax
movl %eax, %esi
callq 0x35850
movq %rax, %rdi
movzbl -0x9(%rbp), %eax
movl %eax, %esi
callq 0x358e0
movq (%rax), %rcx
xorl %eax, %eax
testb $0x1, 0xb8(%rcx)
movb %al, -0x1d1(%rbp)
je 0x5c295
cmpl $0x0, -0x8c(%rbp)
setg %al
movb %al, -0x1d1(%rbp)
movb -0x1d1(%rbp), %al
testb $0x1, %al
xorps %xmm0, %xmm0
movsd 0x2898(%rip), %xmm1     # 0x5eb40
movsd %xmm1, -0x200(%rbp)
movsd %xmm0, -0x1f8(%rbp)
jne 0x5c2ca
movsd -0x200(%rbp), %xmm0
movsd %xmm0, -0x1f8(%rbp)
movsd -0x1f8(%rbp), %xmm0
movsd %xmm0, -0x170(%rbp)
fldl -0x170(%rbp)
fstpt -0x27c(%rbp)
movq -0x20(%rbp), %rdi
xorl %eax, %eax
movl %eax, %esi
movq %rsi, -0x248(%rbp)
callq 0x34c70
movq -0x198(%rbp), %rdi
fldt (%rax)
fld1
fld %st(0)
fstpt -0x264(%rbp)
fsubp %st, %st(1)
fstpt -0x288(%rbp)
movzbl -0x9(%rbp), %eax
movl %eax, %esi
callq 0x5d910
movq -0x248(%rbp), %rsi
movq %rax, %rdi
callq 0x358a0
movq %rax, %rdi
movslq -0x8c(%rbp), %rsi
callq 0x34c70
movq -0x248(%rbp), %rsi
movq -0x198(%rbp), %rdi
fldt (%rax)
fstpt -0x294(%rbp)
addq $0x60, %rdi
movq %rdi, -0x258(%rbp)
callq 0x5d910
movq %rax, %rdi
movzbl -0x9(%rbp), %eax
movl %eax, %esi
callq 0x358a0
movq -0x248(%rbp), %rsi
movq %rax, %rdi
callq 0x34c70
fldt -0x294(%rbp)
fldt -0x288(%rbp)
fldt -0x27c(%rbp)
fldt -0x1dc(%rbp)
movq -0x198(%rbp), %rdi
fldt (%rax)
fmulp %st, %st(4)
fxch %st(2)
fmulp %st, %st(3)
fmulp %st, %st(1)
faddp %st, %st(1)
fstpt -0xa0(%rbp)
fldt -0xa0(%rbp)
fstpt -0x270(%rbp)
addq $0x30, %rdi
movzbl -0x9(%rbp), %eax
movl %eax, %esi
callq 0x358a0
movq %rax, %rdi
movslq -0x8c(%rbp), %rsi
callq 0x34c70
fldt -0x270(%rbp)
movq -0x248(%rbp), %rsi
fldt (%rax)
faddp %st, %st(1)
fstpt (%rax)
movq -0x20(%rbp), %rdi
callq 0x34c70
fldt (%rax)
fstpt -0x218(%rbp)
leaq -0x40(%rbp), %rdi
movl $0x1, %esi
movq %rsi, -0x250(%rbp)
callq 0x358a0
movq %rax, %rdi
movslq -0x8c(%rbp), %rsi
callq 0x34c70
movq -0x248(%rbp), %rsi
fldt (%rax)
fstpt -0x224(%rbp)
movq -0x20(%rbp), %rdi
callq 0x34c70
fldt -0x264(%rbp)
movq -0x198(%rbp), %rdi
fldt (%rax)
fsubrp %st, %st(1)
fstpt -0x230(%rbp)
addq $0x18, %rdi
movzbl -0x9(%rbp), %eax
movl %eax, %esi
callq 0x5d910
movq -0x248(%rbp), %rsi
movq %rax, %rdi
callq 0x358a0
movq %rax, %rdi
movslq -0x8c(%rbp), %rsi
callq 0x34c70
movq -0x258(%rbp), %rdi
movq -0x250(%rbp), %rsi
fldt (%rax)
fstpt -0x23c(%rbp)
callq 0x5d910
movq %rax, %rdi
movzbl -0x9(%rbp), %eax
movl %eax, %esi
callq 0x358a0
movq -0x248(%rbp), %rsi
movq %rax, %rdi
callq 0x34c70
fldt -0x23c(%rbp)
fldt -0x230(%rbp)
fldt -0x224(%rbp)
fldt -0x218(%rbp)
movq -0x198(%rbp), %rdi
fldt (%rax)
fmulp %st, %st(4)
fxch %st(2)
fmulp %st, %st(3)
fmulp %st, %st(1)
faddp %st, %st(1)
fstpt -0xa0(%rbp)
fldt -0xa0(%rbp)
fstpt -0x20c(%rbp)
addq $0x48, %rdi
movzbl -0x9(%rbp), %eax
movl %eax, %esi
callq 0x358a0
movq %rax, %rdi
movslq -0x8c(%rbp), %rsi
callq 0x34c70
fldt -0x20c(%rbp)
fldt (%rax)
faddp %st, %st(1)
fstpt (%rax)
movb $0x1, -0xa1(%rbp)
movq -0x198(%rbp), %rax
movzbl -0xa1(%rbp), %ecx
movl %ecx, -0x174(%rbp)
fildl -0x174(%rbp)
fldt 0x90(%rax)
fld1
faddp %st, %st(1)
fucompi %st(1), %st
fstp %st(0)
jbe 0x5c7a0
jmp 0x5c556
movq -0x20(%rbp), %rdi
xorl %eax, %eax
movl %eax, %esi
movq %rsi, -0x2d8(%rbp)
callq 0x34c70
movq -0x198(%rbp), %rdi
fldt (%rax)
fld1
fld %st(0)
fstpt -0x2d0(%rbp)
fsubp %st, %st(1)
fstpt -0x2f0(%rbp)
movzbl -0x9(%rbp), %eax
movl %eax, %esi
callq 0x5d910
movq %rax, %rdi
movzbl -0xa1(%rbp), %eax
movl %eax, %esi
callq 0x358a0
movq %rax, %rdi
movslq -0x8c(%rbp), %rsi
callq 0x34c70
movq -0x2d8(%rbp), %rsi
movq -0x198(%rbp), %rdi
fldt (%rax)
fstpt -0x2fc(%rbp)
addq $0x60, %rdi
movq %rdi, -0x2b8(%rbp)
callq 0x5d910
movq %rax, %rdi
movzbl -0x9(%rbp), %eax
movl %eax, %esi
callq 0x358a0
movq %rax, %rdi
movzbl -0xa1(%rbp), %eax
movl %eax, %esi
callq 0x34c70
fldt -0x2fc(%rbp)
fldt -0x2f0(%rbp)
movq -0x198(%rbp), %rdi
fldt (%rax)
fmulp %st, %st(2)
fmulp %st, %st(1)
fstpt -0xc0(%rbp)
fldt -0xc0(%rbp)
fstpt -0x2e4(%rbp)
addq $0x30, %rdi
movzbl -0x9(%rbp), %eax
movl %eax, %esi
callq 0x358a0
movq %rax, %rdi
movslq -0x8c(%rbp), %rsi
callq 0x34c70
fldt -0x2e4(%rbp)
movq -0x2d8(%rbp), %rsi
fldt (%rax)
faddp %st, %st(1)
fstpt (%rax)
movq -0x20(%rbp), %rdi
callq 0x34c70
fldt -0x2d0(%rbp)
movq -0x198(%rbp), %rdi
fldt (%rax)
fsubrp %st, %st(1)
fstpt -0x2c4(%rbp)
addq $0x18, %rdi
movzbl -0x9(%rbp), %eax
movl %eax, %esi
callq 0x5d910
movq %rax, %rdi
movzbl -0xa1(%rbp), %eax
movl %eax, %esi
callq 0x358a0
movq %rax, %rdi
movslq -0x8c(%rbp), %rsi
callq 0x34c70
fldt -0x2c4(%rbp)
movq -0x2b8(%rbp), %rdi
fldt (%rax)
fmulp %st, %st(1)
fstpt -0x2ac(%rbp)
movl $0x1, %esi
callq 0x5d910
movq %rax, %rdi
movzbl -0x9(%rbp), %eax
movl %eax, %esi
callq 0x358a0
movq %rax, %rdi
movzbl -0xa1(%rbp), %eax
movl %eax, %esi
callq 0x34c70
fldt -0x2ac(%rbp)
movq -0x198(%rbp), %rdi
fldt (%rax)
fmulp %st, %st(1)
fstpt -0xc0(%rbp)
fldt -0xc0(%rbp)
fstpt -0x2a0(%rbp)
addq $0x48, %rdi
movzbl -0x9(%rbp), %eax
movl %eax, %esi
callq 0x358a0
movq %rax, %rdi
movslq -0x8c(%rbp), %rsi
callq 0x34c70
fldt -0x2a0(%rbp)
fldt (%rax)
faddp %st, %st(1)
fstpt (%rax)
movb -0xa1(%rbp), %al
addb $0x1, %al
movb %al, -0xa1(%rbp)
jmp 0x5c526
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x80(%rbp)
movl %eax, -0x84(%rbp)
jmp 0x5c775
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x80(%rbp)
movl %eax, -0x84(%rbp)
leaq -0x85(%rbp), %rdi
callq 0x35b40
leaq -0x58(%rbp), %rdi
callq 0x34b10
leaq -0x71(%rbp), %rdi
callq 0x34b70
jmp 0x5cbf4
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x80(%rbp)
movl %eax, -0x84(%rbp)
leaq -0x40(%rbp), %rdi
callq 0x35ae0
jmp 0x5cbf4
jmp 0x5c7a2
movl -0x8c(%rbp), %eax
addl $-0x1, %eax
movl %eax, -0x8c(%rbp)
jmp 0x5c1fe
movq -0x198(%rbp), %rax
fldt 0x90(%rax)
fnstcw -0x17e(%rbp)
movzwl -0x17e(%rbp), %eax
orl $0xc00, %eax            # imm = 0xC00
movw %ax, -0x180(%rbp)
fldcw -0x180(%rbp)
fistpl -0x168(%rbp)
fldcw -0x17e(%rbp)
movl -0x168(%rbp), %eax
movl %eax, -0xc4(%rbp)
cmpl $0x0, -0xc4(%rbp)
jl 0x5cbe0
leaq -0x110(%rbp), %rdi
xorl %esi, %esi
movl $0x40, %edx
callq 0x5290
movb $0x0, -0x111(%rbp)
movzbl -0x111(%rbp), %eax
cmpl -0xc4(%rbp), %eax
jge 0x5c98a
movq -0x198(%rbp), %rdi
addq $0x30, %rdi
movzbl -0x9(%rbp), %eax
movl %eax, %esi
callq 0x358a0
movq %rax, %rdi
movslq -0xc4(%rbp), %rsi
callq 0x34c70
movq -0x198(%rbp), %rdi
fldt (%rax)
fstpt -0x308(%rbp)
addq $0x48, %rdi
movzbl -0x9(%rbp), %eax
movl %eax, %esi
callq 0x358a0
movq %rax, %rdi
movzbl -0x111(%rbp), %eax
movl %eax, %esi
callq 0x34c70
fldt -0x308(%rbp)
fldt (%rax)
fmulp %st, %st(1)
fstpt -0x130(%rbp)
movzbl -0x9(%rbp), %eax
cmpl $0x0, %eax
jle 0x5c961
movb $0x0, -0x131(%rbp)
movzbl -0x131(%rbp), %eax
cmpl -0xc4(%rbp), %eax
jge 0x5c916
movq -0x198(%rbp), %rdi
fldt -0x130(%rbp)
fstpt -0x314(%rbp)
addq $0x30, %rdi
xorl %eax, %eax
movl %eax, %esi
callq 0x358a0
movq %rax, %rdi
movzbl -0x131(%rbp), %eax
movl %eax, %esi
callq 0x34c70
fldt -0x314(%rbp)
fldt (%rax)
fldt -0x110(%rbp)
fxch %st(2)
fmulp %st, %st(1)
faddp %st, %st(1)
fstpt -0x110(%rbp)
movb -0x131(%rbp), %al
addb $0x1, %al
movb %al, -0x131(%rbp)
jmp 0x5c8ac
movq -0x198(%rbp), %rdi
fldt -0x130(%rbp)
fstpt -0x320(%rbp)
addq $0x30, %rdi
xorl %eax, %eax
movl %eax, %esi
callq 0x358a0
movq %rax, %rdi
movslq -0xc4(%rbp), %rsi
callq 0x34c70
fldt -0x320(%rbp)
fldt (%rax)
fldt -0x100(%rbp)
fxch %st(2)
fmulp %st, %st(1)
faddp %st, %st(1)
fstpt -0x100(%rbp)
jmp 0x5c975
fldt -0x130(%rbp)
fldt -0x110(%rbp)
faddp %st, %st(1)
fstpt -0x110(%rbp)
jmp 0x5c977
movb -0x111(%rbp), %al
addb $0x1, %al
movb %al, -0x111(%rbp)
jmp 0x5c821
movq -0x198(%rbp), %rdi
addq $0x30, %rdi
movzbl -0x9(%rbp), %eax
movl %eax, %esi
callq 0x358a0
movq %rax, %rdi
movslq -0xc4(%rbp), %rsi
callq 0x34c70
movq -0x198(%rbp), %rdi
fldt (%rax)
fstpt -0x32c(%rbp)
addq $0x48, %rdi
movzbl -0x9(%rbp), %eax
movl %eax, %esi
callq 0x358a0
movq %rax, %rdi
movslq -0xc4(%rbp), %rsi
callq 0x34c70
fldt -0x32c(%rbp)
fldt (%rax)
fmulp %st, %st(1)
fstpt -0x150(%rbp)
movzbl -0x9(%rbp), %eax
cmpl $0x0, %eax
jle 0x5caab
movb $0x0, -0x151(%rbp)
movzbl -0x151(%rbp), %eax
cmpl -0xc4(%rbp), %eax
jge 0x5ca6a
movq -0x198(%rbp), %rdi
fldt -0x150(%rbp)
fstpt -0x338(%rbp)
addq $0x30, %rdi
xorl %eax, %eax
movl %eax, %esi
callq 0x358a0
movq %rax, %rdi
movzbl -0x151(%rbp), %eax
movl %eax, %esi
callq 0x34c70
fldt -0x338(%rbp)
fldt (%rax)
fldt -0xf0(%rbp)
fxch %st(2)
fmulp %st, %st(1)
faddp %st, %st(1)
fstpt -0xf0(%rbp)
movb -0x151(%rbp), %al
addb $0x1, %al
movb %al, -0x151(%rbp)
jmp 0x5ca00
movq -0x198(%rbp), %rdi
fldt -0x150(%rbp)
fstpt -0x344(%rbp)
addq $0x30, %rdi
xorl %eax, %eax
movl %eax, %esi
callq 0x358a0
movq %rax, %rdi
movslq -0xc4(%rbp), %rsi
callq 0x34c70
fldt -0x344(%rbp)
fldt (%rax)
fmulp %st, %st(1)
fstpt -0xe0(%rbp)
jmp 0x5cab7
fldt -0x150(%rbp)
fstpt -0xe0(%rbp)
fldt -0x110(%rbp)
fstpt -0x384(%rbp)
movq -0x28(%rbp), %rdi
xorl %eax, %eax
movl %eax, %esi
movq %rsi, -0x358(%rbp)
callq 0x34c70
fldt -0x384(%rbp)
fldt (%rax)
faddp %st, %st(1)
fstpt (%rax)
fldt -0x110(%rbp)
fldt -0xf0(%rbp)
faddp %st, %st(1)
fstpt -0x378(%rbp)
movq -0x28(%rbp), %rdi
movl $0x1, %esi
callq 0x34c70
fldt -0x378(%rbp)
fldt (%rax)
faddp %st, %st(1)
fstpt (%rax)
fldt -0x110(%rbp)
fldt -0x100(%rbp)
faddp %st, %st(1)
fldt -0xf0(%rbp)
faddp %st, %st(1)
fldt -0xe0(%rbp)
faddp %st, %st(1)
fstpt -0x36c(%rbp)
movq -0x28(%rbp), %rdi
movl $0x2, %esi
movq %rsi, -0x360(%rbp)
callq 0x34c70
fldt -0x36c(%rbp)
movq -0x360(%rbp), %rsi
fldt (%rax)
faddp %st, %st(1)
fstpt (%rax)
movq -0x28(%rbp), %rdi
callq 0x34c70
movq -0x358(%rbp), %rsi
fldt (%rax)
fstpt -0x350(%rbp)
movq -0x28(%rbp), %rdi
callq 0x34c70
fldt -0x350(%rbp)
fldt (%rax)
fucompi %st(1), %st
fstp %st(0)
jbe 0x5cbca
jmp 0x5cb8e
movzbl -0x9(%rbp), %eax
cmpl $0x0, %eax
jle 0x5cbca
movq 0x2541a(%rip), %rdi     # 0x81fb8
leaq 0x78ef(%rip), %rsi      # 0x64494
callq 0x5480
movq %rax, -0x390(%rbp)
jmp 0x5cbb3
movq -0x390(%rbp), %rdi
movq 0x253cf(%rip), %rsi     # 0x81f90
callq 0x54f0
jmp 0x5cbc8
jmp 0x5cbca
jmp 0x5cbcc
movl -0xc4(%rbp), %eax
addl $-0x1, %eax
movl %eax, -0xc4(%rbp)
jmp 0x5c7fa
leaq -0x40(%rbp), %rdi
callq 0x35ae0
xorl %eax, %eax
addq $0x390, %rsp            # imm = 0x390
popq %rbp
retq
movq -0x80(%rbp), %rdi
callq 0x5920
nopl (%rax)