// File: /workspace/github_cpp_makefile_star2_O2/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 $0x98, %rsp
movl %ecx, %ebx
movl %edx, %ebp
movq %rsi, %r14
movq %rdi, %r13
movl $0xc0, %edi
callq 0x43c0
movq %rax, %r15
movq %rax, %rdi
callq 0x18e9c
movzbl %bpl, %r12d
testl %ebx, %ebx
je 0x1808a
movzbl 0x21(%r13), %esi
fldz
fstpt 0x20(%rsp)
leaq 0x70(%rsp), %rbx
leaq 0x20(%rsp), %rdx
leaq 0x7(%rsp), %rcx
movq %rbx, %rdi
callq 0x18df8
leaq 0x30(%r15), %rdi
movq %rbx, %rsi
callq 0x1a1fc
movq %rbx, %rdi
callq 0x195d0
movzbl 0x21(%r13), %esi
fldz
fld %st(0)
fstpt 0x14(%rsp)
fstpt 0x20(%rsp)
leaq 0x70(%rsp), %rbx
leaq 0x20(%rsp), %rdx
leaq 0x7(%rsp), %rcx
movq %rbx, %rdi
callq 0x18df8
leaq 0x48(%r15), %rdi
movq %rbx, %rsi
callq 0x1a1fc
movq %rbx, %rdi
callq 0x195d0
movq 0x30(%r14), %rax
imulq $0xa0, %r12, %rcx
leaq (%rax,%rcx), %rsi
addq $0x60, %rsi
leaq 0x60(%r15), %rdi
callq 0x196f2
movq 0x78(%r15), %rax
leaq 0x68(%r15), %rcx
movq %rcx, 0x48(%rsp)
movq %r12, %rbx
cmpq 0x48(%rsp), %rax
je 0x1814f
movq 0x28(%rax), %rcx
movq 0x30(%rax), %rdx
cmpq %rdx, %rcx
je 0x18080
movb $0x0, (%rcx)
incq %rcx
jmp 0x18073
movq %rax, %rdi
callq 0x42d0
jmp 0x18060
movq 0x48(%r14), %rax
movb (%rax,%r12), %al
movb %al, (%r15)
movq 0x30(%r14), %rax
imulq $0xa0, %r12, %rbx
leaq (%rax,%rbx), %rsi
addq $0x20, %rsi
movq 0x38(%rsi), %rax
movq %rax, 0x68(%rsp)
xorl %ecx, %ecx
testq %rax, %rax
sets %cl
fildll 0x68(%rsp)
leaq 0x126d4(%rip), %rax     # 0x2a798
fadds (%rax,%rcx,4)
fstpt 0x10(%r15)
leaq 0x30(%r15), %rdi
callq 0x18efe
movq 0x30(%r14), %rax
leaq (%rax,%rbx), %rsi
addq $0x38, %rsi
leaq 0x48(%r15), %rdi
callq 0x18efe
movq 0x30(%r14), %rax
fldt 0x10(%rax,%rbx)
fstpt 0x20(%r15)
leaq (%rax,%rbx), %rsi
addq $0x60, %rsi
leaq 0x60(%r15), %rdi
callq 0x196f2
imulq $0x28, %r12, %rsi
addq 0x88(%r14), %rsi
movq %r15, %rdi
addq $0x90, %rdi
callq 0x18fc8
addq $0x60, %r14
movq %r14, %rdi
movq %r12, %rsi
callq 0x1905e
testq %rdx, (%rax)
setne 0xb8(%r15)
movq %r15, %rax
addq $0x98, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movq %r13, 0x40(%rsp)
leaq 0x60(%r14), %rax
movq %rax, 0x58(%rsp)
movq %r15, 0x8(%rsp)
movq %r15, %rbp
addq $0x90, %rbp
pushq $0x1
popq %r13
leaq 0x70(%rsp), %r15
movq %rbx, 0x50(%rsp)
movzbl 0x24(%r14), %eax
cmpq %rax, %r13
jae 0x1836e
cmpq %rbx, %r13
je 0x18366
movq 0x30(%r14), %rax
imulq $0xa0, %r13, %r12
cmpq $0x0, 0x58(%rax,%r12)
je 0x18366
movq 0x58(%rsp), %rdi
movq %r13, %rsi
callq 0x1905e
testq %rdx, (%rax)
jne 0x18366
movq 0x48(%r14), %rax
movq 0x8(%rsp), %rbx
movzbl (%rbx), %ecx
movq %r13, 0x38(%rsp)
movzbl (%rax,%r13), %eax
cmpb %al, %cl
cmoval %ecx, %eax
movb %al, (%rbx)
movq 0x30(%r14), %rax
movq 0x58(%rax,%r12), %rcx
movq %rcx, 0x60(%rsp)
xorl %edx, %edx
testq %rcx, %rcx
sets %dl
fildll 0x60(%rsp)
leaq 0x1259c(%rip), %rcx     # 0x2a798
fadds (%rcx,%rdx,4)
fldt 0x10(%rbx)
faddp %st, %st(1)
fstpt 0x10(%rbx)
movq 0x30(%rbx), %rcx
movq 0x38(%rbx), %rsi
movq 0x20(%rax,%r12), %rdx
movq %rcx, %rdi
callq 0x1907b
movq 0x48(%rbx), %rcx
movq 0x50(%rbx), %rsi
movq 0x30(%r14), %rax
movq 0x38(%rax,%r12), %rdx
movq %rcx, %rdi
callq 0x1907b
movq 0x78(%rbx), %rbx
cmpq 0x48(%rsp), %rbx
je 0x182a2
movl 0x20(%rbx), %eax
movl %eax, 0x70(%rsp)
xorl %eax, %eax
movl %eax, %r13d
movq 0x30(%r14), %rax
leaq (%rax,%r12), %rdi
addq $0x60, %rdi
movq %r15, %rsi
callq 0x1909a
movq 0x8(%rax), %rcx
subq (%rax), %rcx
cmpq %r13, %rcx
jbe 0x18295
movq 0x30(%r14), %rax
leaq (%rax,%r12), %rdi
addq $0x60, %rdi
movq %r15, %rsi
callq 0x1909a
movq (%rax), %rax
movb (%rax,%r13), %al
movq 0x28(%rbx), %rcx
orb %al, (%rcx,%r13)
leal 0x1(%r13), %eax
jmp 0x18249
movq %rbx, %rdi
callq 0x42d0
movq %rax, %rbx
jmp 0x18239
movq 0x30(%r14), %rax
fldt 0x10(%rax,%r12)
movq 0x8(%rsp), %rax
fldt 0x20(%rax)
faddp %st, %st(1)
fstpt 0x20(%rax)
movq 0x40(%rsp), %rax
movzbl 0x21(%rax), %esi
movb $0x0, 0x20(%rsp)
movq %r15, %rdi
leaq 0x20(%rsp), %rdx
leaq 0x7(%rsp), %rcx
callq 0x18aa6
movq %rbp, %rdi
movq %r15, %rsi
callq 0x18b0a
movq %r15, %rdi
callq 0x18b5c
imulq $0x28, 0x38(%rsp), %r12
xorl %ebx, %ebx
movq 0x40(%rsp), %rax
movzbl 0x21(%rax), %eax
cmpq %rax, %rbx
jae 0x18350
movq %rbp, %rdi
movq %rbx, %rsi
callq 0x1905e
movb $0x1, %r13b
testq %rdx, (%rax)
jne 0x1832d
movq 0x88(%r14), %rdi
addq %r12, %rdi
movq %rbx, %rsi
callq 0x1905e
testq %rdx, (%rax)
setne %r13b
movq %rbp, %rdi
movq %rbx, %rsi
callq 0x1905e
testb %r13b, %r13b
je 0x18342
orq (%rax), %rdx
jmp 0x18348
notq %rdx
andq (%rax), %rdx
movq %rdx, (%rax)
incq %rbx
jmp 0x182f3
fldt 0x14(%rsp)
fld1
faddp %st, %st(1)
fstpt 0x14(%rsp)
movq 0x50(%rsp), %rbx
movq 0x38(%rsp), %r13
incq %r13
jmp 0x1817a
movq 0x8(%rsp), %r15
movq 0x30(%r15), %rax
movq 0x38(%r15), %rcx
subq %rax, %rcx
sarq $0x4, %rcx
xorl %edx, %edx
movzbl %dl, %edx
cmpq %rdx, %rcx
jbe 0x183a1
movl %edx, %esi
shll $0x4, %esi
fldt (%rax,%rsi)
fldt 0x14(%rsp)
fdivrp %st, %st(1)
fstpt (%rax,%rsi)
incl %edx
jmp 0x18384
movq 0x48(%r15), %rax
movq 0x50(%r15), %rcx
subq %rax, %rcx
sarq $0x4, %rcx
xorl %edx, %edx
movzbl %dl, %edx
cmpq %rdx, %rcx
jbe 0x1813a
movl %edx, %esi
shll $0x4, %esi
fldt (%rax,%rsi)
fldt 0x14(%rsp)
fdivrp %st, %st(1)
fstpt (%rax,%rsi)
incl %edx
jmp 0x183b2
nop