// File: /workspace/github_cpp_makefile_star2_O1/adamiaonr[P]rid-analytics/src/rid-router.cpp
// Function: RID_Router::get_fp_data(RID_Router*, unsigned char, bool)
Prob::fp_data * RID_Router::get_fp_data(
    RID_Router * router, 
    uint8_t i,
    bool iface_complement) {

    Prob::fp_data * iface_fp_data = new Prob::fp_data();

    if (!iface_complement) {

        iface_fp_data->tp_size = router->tp_sizes[i];
        iface_fp_data->num_entries = (__float080) router->fwd_table[i].num_entries;
        iface_fp_data->f_distr = router->fwd_table[i].f_distr;
        iface_fp_data->f_r_distr = router->fwd_table[i].f_r_distr;
        iface_fp_data->entry_prop = router->fwd_table[i].iface_proportion;
        iface_fp_data->tree_bitmasks = router->fwd_table[i].tree_bitmasks;
        iface_fp_data->on_fptree = router->iface_on_fptree[i];
        iface_fp_data->is_blocked = router->blocked_ifaces[i];

    } else {

        iface_fp_data->f_distr = std::vector<__float080>(this->req_size, 0.0);
        iface_fp_data->f_r_distr = std::vector<__float080>(this->req_size, 0.0);
        iface_fp_data->tree_bitmasks = router->fwd_table[i].tree_bitmasks;
        // clear iface fp data's tree bitmask
        std::map<int, std::vector<uint8_t> >::iterator itr;
        for (itr = iface_fp_data->tree_bitmasks.begin(); itr != iface_fp_data->tree_bitmasks.end(); itr++)
            std::fill(itr->second.begin(), itr->second.end(), 0x00);

        // sum all the fp data, for all ifaces other than i
        __float080 num_valid_ifaces = 0.0;
        for (uint8_t k = 1; k < router->iface_num; k++) {

            // don't consider iface i, or blocked ifaces
            if ((k == i) || (router->fwd_table[k].num_entries < 1)) continue;
            if (router->blocked_ifaces[k]) continue;

            // the tp is the max of the ifaces other than i
            iface_fp_data->tp_size = std::max(iface_fp_data->tp_size, router->tp_sizes[k]);
            // keep adding up the nr of entries
            iface_fp_data->num_entries += (__float080) router->fwd_table[k].num_entries;

            // f_distr and f_r_distr vectors
            // use std::transform() to get the elementwise sum of 2 vectors 
            // (result saved in first vector)
            std::transform(
                iface_fp_data->f_distr.begin(), iface_fp_data->f_distr.end(), 
                router->fwd_table[k].f_distr.begin(), 
                iface_fp_data->f_distr.begin(), 
                std::plus<__float080>());

            std::transform(
                iface_fp_data->f_r_distr.begin(), iface_fp_data->f_r_distr.end(), 
                router->fwd_table[k].f_r_distr.begin(), 
                iface_fp_data->f_r_distr.begin(), 
                std::plus<__float080>());

            // fill the bitmask of ~i in the old fashioned way...
            for (itr = iface_fp_data->tree_bitmasks.begin(); itr != iface_fp_data->tree_bitmasks.end(); itr++) {
                int tb_size = itr->first;
                for (unsigned int j = 0; j < router->fwd_table[k].tree_bitmasks[tb_size].size(); j++)
                    itr->second[j] |= router->fwd_table[k].tree_bitmasks[tb_size][j];
            }

            iface_fp_data->entry_prop += router->fwd_table[k].iface_proportion;

            iface_fp_data->on_fptree = std::vector<bool>(this->req_size, false);
            for (unsigned int j = 0; j < this->req_size; j++) {
                // std::cout << "RID_Router::get_fp_data() : [INFO] " << 
                //     "\n\ton_fptree[~" << (int) i << "][" << j << "] : " << iface_fp_data->on_fptree[j] << 
                //     "\n\ton_fptree[" << (int) k << "][" << j << "] : " << router->iface_on_fptree[k][j] << std::endl;
                iface_fp_data->on_fptree[j] = (iface_fp_data->on_fptree[j] || router->iface_on_fptree[k][j]);
                // std::cout << "RID_Router::get_fp_data() : [INFO] " << 
                //     "\n\ton_fptree[~" << (int) i << "][" << j << "] : " << iface_fp_data->on_fptree[j] << std::endl;
            }

            num_valid_ifaces++;
        }

        // normalize the iface_fp_data->f_distr and iface_fp_data->f_r_distr vectors
        for (uint8_t k = 0; k < iface_fp_data->f_distr.size(); k++)
            iface_fp_data->f_distr[k] /= num_valid_ifaces;
        for (uint8_t k = 0; k < iface_fp_data->f_r_distr.size(); k++)
            iface_fp_data->f_r_distr[k] /= num_valid_ifaces;
    }

    return iface_fp_data;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0xb8, %rsp
movl %ecx, %ebp
movl %edx, %r13d
movq %rsi, %r14
movq %rdi, %r12
movl $0xc0, %edi
callq 0x4390
movq %rax, %r15
leaq 0x30(%rax), %rdi
leaq 0x68(%rax), %rcx
xorl %eax, %eax
movl %eax, 0x68(%r15)
movq %rax, 0x70(%r15)
xorps %xmm0, %xmm0
movaps %xmm0, 0x30(%r15)
movaps %xmm0, 0x40(%r15)
movaps %xmm0, 0x50(%r15)
movq %rcx, 0x78(%r15)
movq %rcx, 0x10(%rsp)
movq %rcx, 0x80(%r15)
movq %rax, 0xa0(%r15)
movl %eax, 0xa8(%r15)
movq %rax, 0xb0(%r15)
movb %al, (%r15)
fldz
fld %st(0)
fstpt 0x10(%r15)
fld %st(0)
fstpt 0x20(%r15)
movb %al, 0xb8(%r15)
movups %xmm0, 0x88(%r15)
movl %eax, 0x98(%r15)
movzbl %r13b, %ebx
testl %ebp, %ebp
je 0x1cf06
movzbl 0x21(%r12), %esi
fstpt 0x20(%rsp)
leaq 0x48(%rsp), %r13
leaq 0x20(%rsp), %rdx
leaq 0xf(%rsp), %rcx
movq %rdi, %rbp
movq %r13, %rdi
callq 0x1ddb8
movq %rbp, %rdi
movq %r13, %rsi
callq 0x1ed30
movq (%r13), %rdi
testq %rdi, %rdi
movq %r12, %r13
je 0x1cb39
movq 0x58(%rsp), %rsi
subq %rdi, %rsi
callq 0x43a0
movzbl 0x21(%r13), %esi
fldz
fstpt 0x20(%rsp)
leaq 0x48(%rsp), %r12
leaq 0x20(%rsp), %rdx
leaq 0xf(%rsp), %rcx
movq %r12, %rdi
callq 0x1ddb8
leaq 0x48(%r15), %rdi
movq %r12, %rsi
callq 0x1ed30
movq (%r12), %rdi
testq %rdi, %rdi
je 0x1cb7d
movq 0x58(%rsp), %rsi
subq %rdi, %rsi
callq 0x43a0
movq 0x30(%r14), %rax
leaq (%rbx,%rbx,4), %rcx
shll $0x5, %ecx
leaq (%rax,%rcx), %rsi
addq $0x60, %rsi
leaq 0x60(%r15), %rdi
callq 0x1e5e8
movq 0x78(%r15), %r12
cmpq 0x10(%rsp), %r12
je 0x1cbcf
movq 0x28(%r12), %rdi
movq 0x30(%r12), %rdx
cmpq %rdx, %rdi
je 0x1cbbd
subq %rdi, %rdx
xorl %esi, %esi
callq 0x4240
movq %r12, %rdi
callq 0x42b0
movq %rax, %r12
cmpq 0x10(%rsp), %rax
jne 0x1cba4
cmpb $0x2, 0x24(%r14)
fldz
jb 0x1ceab
fstp %st(0)
movq %r15, %rbp
addq $0x90, %rbp
fldz
movl $0x1, %edi
movq %r15, 0x88(%rsp)
movq %rbx, 0x70(%rsp)
movq %r13, 0x80(%rsp)
movq %rbp, 0x78(%rsp)
cmpq %rbx, %rdi
je 0x1ce9a
movq 0x30(%r14), %rax
leaq (%rdi,%rdi,4), %r8
movq %r8, %rcx
shlq $0x5, %rcx
movq %rcx, 0x18(%rsp)
movq 0x58(%rax,%rcx), %rcx
testq %rcx, %rcx
je 0x1ce9a
movq 0x60(%r14), %rdx
movq %rdi, %rsi
shrq $0x6, %rsi
movq (%rdx,%rsi,8), %rdx
btq %rdi, %rdx
jb 0x1ce9a
fstpt 0xac(%rsp)
addq 0x18(%rsp), %rax
movq 0x48(%r14), %rdx
movzbl (%r15), %esi
movzbl (%rdx,%rdi), %edx
cmpb %dl, %sil
cmoval %esi, %edx
movb %dl, (%r15)
movq %rcx, 0x98(%rsp)
xorl %edx, %edx
testq %rcx, %rcx
sets %dl
fildll 0x98(%rsp)
leaq 0x14b6c(%rip), %rcx     # 0x317f8
fadds (%rcx,%rdx,4)
fldt 0x10(%r15)
faddp %st, %st(1)
fstpt 0x10(%r15)
movq 0x30(%r15), %rcx
movq 0x38(%r15), %rdx
cmpq %rdx, %rcx
je 0x1ccbf
movq 0x20(%rax), %rsi
fldt (%rcx)
fldt (%rsi)
faddp %st, %st(1)
fstpt (%rcx)
addq $0x10, %rcx
addq $0x10, %rsi
cmpq %rdx, %rcx
jne 0x1ccaa
movq %rdi, 0x38(%rsp)
movq 0x48(%r15), %rcx
movq 0x50(%r15), %rdx
cmpq %rdx, %rcx
je 0x1ccea
movq 0x38(%rax), %rax
fldt (%rcx)
fldt (%rax)
faddp %st, %st(1)
fstpt (%rcx)
addq $0x10, %rcx
addq $0x10, %rax
cmpq %rdx, %rcx
jne 0x1ccd5
movq %r8, 0x90(%rsp)
movq 0x78(%r15), %rax
cmpq 0x10(%rsp), %rax
leaq 0x48(%rsp), %r12
je 0x1cdad
movq %rax, 0x40(%rsp)
movl 0x20(%rax), %eax
movl %eax, 0x48(%rsp)
movq 0x30(%r14), %rax
movq 0x18(%rsp), %rcx
leaq (%rax,%rcx), %rdi
addq $0x60, %rdi
movq %r12, %rsi
callq 0x1e016
movq 0x8(%rax), %rcx
cmpq (%rax), %rcx
movq 0x38(%rsp), %rbp
je 0x1cd98
movl $0x1, %r15d
xorl %ebx, %ebx
movq 0x30(%r14), %rax
movq %rbp, %rcx
shlq $0x5, %rcx
leaq (%rcx,%rcx,4), %r13
leaq (%rax,%r13), %rdi
addq $0x60, %rdi
movq %r12, %rsi
callq 0x1e016
movq (%rax), %rax
movb (%rax,%rbx), %al
movq 0x40(%rsp), %rcx
movq 0x28(%rcx), %rcx
orb %al, (%rcx,%rbx)
movl %r15d, %ebx
movq 0x30(%r14), %rax
leaq (%rax,%r13), %rdi
addq $0x60, %rdi
movq %r12, %rsi
callq 0x1e016
movq 0x8(%rax), %rcx
subq (%rax), %rcx
incl %r15d
cmpq %rbx, %rcx
ja 0x1cd41
movq 0x40(%rsp), %rdi
callq 0x42b0
cmpq 0x10(%rsp), %rax
jne 0x1cd06
movq 0x30(%r14), %rax
movq 0x18(%rsp), %rcx
fldt 0x10(%rax,%rcx)
movq 0x88(%rsp), %r15
fldt 0x20(%r15)
faddp %st, %st(1)
fstpt 0x20(%r15)
movq 0x80(%rsp), %r13
movzbl 0x21(%r13), %esi
movb $0x0, 0x20(%rsp)
movq %r12, %rdi
leaq 0x20(%rsp), %rdx
leaq 0xf(%rsp), %rcx
callq 0x1da4a
movq 0x78(%rsp), %rbp
movq %rbp, %rdi
callq 0x1e9f2
movq 0x68(%rsp), %rax
movq %rax, 0x20(%rbp)
movups 0x48(%rsp), %xmm0
movups 0x58(%rsp), %xmm1
movups %xmm1, 0x10(%rbp)
movups %xmm0, (%rbp)
movq $0x0, 0x58(%rsp)
movl $0x0, 0x60(%rsp)
movzbl 0x21(%r13), %eax
testq %rax, %rax
movq 0x70(%rsp), %rbx
fldt 0xac(%rsp)
movq 0x90(%rsp), %r10
je 0x1ce91
movq (%rbp), %rdx
xorl %ecx, %ecx
movl $0x1, %r8d
shlq %cl, %r8
movq %rcx, %rsi
shrq $0x6, %rsi
movq (%rdx,%rsi,8), %rdi
btq %rcx, %rdi
jb 0x1ce78
movq 0x88(%r14), %r9
movq (%r9,%r10,8), %r9
testq %r8, (%r9,%rsi,8)
je 0x1ce89
orq %r8, %rdi
movq %rdi, (%rdx,%rsi,8)
incq %rcx
cmpq %rcx, %rax
jne 0x1ce4d
jmp 0x1ce91
notq %r8
andq %r8, %rdi
jmp 0x1ce7b
fld1
faddp %st, %st(1)
movq 0x38(%rsp), %rdi
incq %rdi
movzbl 0x24(%r14), %eax
cmpq %rax, %rdi
jb 0x1cc09
movq 0x30(%r15), %rax
movq 0x38(%r15), %rcx
subq %rax, %rcx
je 0x1ced4
sarq $0x4, %rcx
movb $0x1, %dl
fldt (%rax)
fdiv %st(1), %st
fstpt (%rax)
movzbl %dl, %esi
addq $0x10, %rax
movl %esi, %edx
incb %dl
cmpq %rsi, %rcx
ja 0x1cebe
movq 0x48(%r15), %rax
movq 0x50(%r15), %rcx
subq %rax, %rcx
je 0x1cfd0
sarq $0x4, %rcx
movb $0x1, %dl
fldt (%rax)
fdiv %st(1), %st
fstpt (%rax)
movzbl %dl, %esi
addq $0x10, %rax
movl %esi, %edx
incb %dl
cmpq %rsi, %rcx
ja 0x1ceeb
jmp 0x1cfd0
fstp %st(0)
movq 0x48(%r14), %rax
movb (%rax,%rbx), %al
movb %al, (%r15)
movq 0x30(%r14), %rax
movl %ebx, %ecx
shll $0x5, %ecx
movq %rbx, %r13
leaq (%rcx,%rcx,4), %rbx
leaq (%rax,%rbx), %rsi
addq $0x20, %rsi
movq 0x38(%rsi), %rax
movq %rax, 0xa0(%rsp)
xorl %ecx, %ecx
testq %rax, %rax
sets %cl
fildll 0xa0(%rsp)
leaq 0x148ac(%rip), %rax     # 0x317f8
fadds (%rax,%rcx,4)
fstpt 0x10(%r15)
callq 0x1dea0
movq 0x30(%r14), %rax
leaq (%rax,%rbx), %rsi
addq $0x38, %rsi
leaq 0x48(%r15), %rdi
callq 0x1dea0
movq 0x30(%r14), %rax
fldt 0x10(%rax,%rbx)
fstpt 0x20(%r15)
leaq (%rax,%rbx), %rsi
addq $0x60, %rsi
leaq 0x60(%r15), %rdi
callq 0x1e5e8
leaq (,%r13,4), %rsi
addq %r13, %rsi
shll $0x3, %esi
addq 0x88(%r14), %rsi
movq %r15, %rdi
addq $0x90, %rdi
callq 0x1df76
movq 0x60(%r14), %rax
movl %r13d, %ecx
shrb $0x3, %cl
movzbl %cl, %ecx
andl $0x18, %ecx
movq (%rax,%rcx), %rax
btq %r13, %rax
setb 0xb8(%r15)
fldz
fstp %st(0)
movq %r15, %rax
addq $0xb8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movq %rax, %rdi
callq 0x1903b
nop