// File: /workspace/github_cpp_makefile_star2_O3/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, %r12d
movq %rsi, %r14
movq %rdi, %rbx
movl $0xc0, %edi
callq 0x4390
movq %rax, %r15
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, 0x8(%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 %r12b, %r13d
testl %ebp, %ebp
je 0x1ca8a
movzbl 0x21(%rbx), %esi
fstpt 0x20(%rsp)
leaq 0x40(%rsp), %r12
leaq 0x20(%rsp), %rdx
leaq 0x7(%rsp), %rcx
movq %r12, %rdi
callq 0x1d906
movq 0x30(%r15), %rdi
movq 0x40(%r15), %rsi
movaps (%r12), %xmm0
movups %xmm0, 0x30(%r15)
movq 0x10(%r12), %rax
movq %rax, 0x40(%r15)
xorps %xmm0, %xmm0
movaps %xmm0, (%r12)
movq $0x0, 0x10(%r12)
testq %rdi, %rdi
je 0x1c67c
subq %rdi, %rsi
callq 0x43a0
movq 0x40(%rsp), %rdi
testq %rdi, %rdi
je 0x1c67c
movq 0x50(%rsp), %rsi
subq %rdi, %rsi
callq 0x43a0
movzbl 0x21(%rbx), %esi
fldz
fstpt 0x20(%rsp)
leaq 0x40(%rsp), %r12
leaq 0x20(%rsp), %rdx
leaq 0x7(%rsp), %rcx
movq %r12, %rdi
callq 0x1d906
movq 0x48(%r15), %rdi
movq 0x58(%r15), %rsi
movaps (%r12), %xmm0
movups %xmm0, 0x48(%r15)
movq 0x10(%r12), %rax
movq %rax, 0x58(%r15)
xorps %xmm0, %xmm0
movaps %xmm0, (%r12)
movq $0x0, 0x10(%r12)
testq %rdi, %rdi
je 0x1c6ed
subq %rdi, %rsi
callq 0x43a0
movq 0x40(%rsp), %rdi
testq %rdi, %rdi
je 0x1c6ed
movq 0x50(%rsp), %rsi
subq %rdi, %rsi
callq 0x43a0
movq 0x30(%r14), %rax
leaq (,%r13,4), %rcx
addq %r13, %rcx
shll $0x5, %ecx
leaq (%rax,%rcx), %rsi
addq $0x60, %rsi
leaq 0x60(%r15), %rdi
callq 0x1e168
movq 0x78(%r15), %r12
cmpq 0x8(%rsp), %r12
je 0x1c746
movq 0x28(%r12), %rdi
movq 0x30(%r12), %rdx
cmpq %rdx, %rdi
je 0x1c734
subq %rdi, %rdx
xorl %esi, %esi
callq 0x4240
movq %r12, %rdi
callq 0x42b0
movq %rax, %r12
cmpq 0x8(%rsp), %rax
jne 0x1c71b
movb 0x24(%r14), %cl
cmpb $0x2, %cl
fldz
jb 0x1ca2f
fstp %st(0)
movq %r15, %rbp
addq $0x90, %rbp
fldz
movl $0x1, %r12d
movq %r15, 0x80(%rsp)
movq %r13, 0x78(%rsp)
movq %rbx, 0x70(%rsp)
movq %rbp, 0x88(%rsp)
movq %r14, 0x10(%rsp)
cmpq %r13, %r12
je 0x1ca20
movq 0x30(%r14), %r9
leaq (%r12,%r12,4), %r8
movq %r8, %rdx
shlq $0x5, %rdx
movq %rdx, 0x18(%rsp)
movq 0x58(%r9,%rdx), %rdx
testq %rdx, %rdx
je 0x1ca20
movq 0x60(%r14), %rsi
movq %r12, %rdi
shrq $0x6, %rdi
movq (%rsi,%rdi,8), %rsi
btq %r12, %rsi
jb 0x1ca20
fstpt 0xac(%rsp)
movq 0x48(%r14), %rcx
movzbl (%r15), %esi
movzbl (%rcx,%r12), %edi
cmpb %dil, %sil
cmoval %esi, %edi
movq 0x18(%rsp), %rcx
addq %r9, %rcx
movb %dil, (%r15)
movq %rdx, 0x98(%rsp)
xorl %esi, %esi
testq %rdx, %rdx
sets %sil
fildll 0x98(%rsp)
leaq 0x13dc8(%rip), %rdx     # 0x305d8
fadds (%rdx,%rsi,4)
fldt 0x10(%r15)
faddp %st, %st(1)
fstpt 0x10(%r15)
movq 0x30(%r15), %rdx
movq 0x38(%r15), %rsi
cmpq %rsi, %rdx
je 0x1c843
movq 0x20(%rcx), %rdi
fldt (%rdx)
fldt (%rdi)
faddp %st, %st(1)
fstpt (%rdx)
addq $0x10, %rdx
addq $0x10, %rdi
cmpq %rsi, %rdx
jne 0x1c82e
movq 0x48(%r15), %rdx
movq 0x50(%r15), %rsi
cmpq %rsi, %rdx
je 0x1c869
movq 0x38(%rcx), %rcx
fldt (%rdx)
fldt (%rcx)
faddp %st, %st(1)
fstpt (%rdx)
addq $0x10, %rdx
addq $0x10, %rcx
cmpq %rsi, %rdx
jne 0x1c854
movq %r8, 0x90(%rsp)
movq 0x78(%r15), %rax
cmpq 0x8(%rsp), %rax
leaq 0x40(%rsp), %r14
je 0x1c959
movq %r12, 0x30(%rsp)
movq %rax, 0x38(%rsp)
movl 0x20(%rax), %ecx
movl %ecx, 0x40(%rsp)
movq 0x10(%rsp), %r12
movq 0x30(%r12), %rdx
movq 0x18(%rsp), %rcx
leaq (%rdx,%rcx), %rdi
addq $0x60, %rdi
movq %r14, %rsi
callq 0x1db98
movq 0x8(%rax), %rcx
cmpq (%rax), %rcx
movq 0x30(%rsp), %rbp
je 0x1c924
movl $0x1, %r15d
xorl %ebx, %ebx
movq 0x30(%r12), %rax
movq %rbp, %rcx
shlq $0x5, %rcx
leaq (%rcx,%rcx,4), %r13
leaq (%rax,%r13), %rdi
addq $0x60, %rdi
movq %r14, %rsi
callq 0x1db98
movq (%rax), %rax
movb (%rax,%rbx), %al
movq 0x38(%rsp), %rcx
movq 0x28(%rcx), %rcx
orb %al, (%rcx,%rbx)
movl %r15d, %ebx
movq 0x30(%r12), %rax
leaq (%rax,%r13), %rdi
addq $0x60, %rdi
movq %r14, %rsi
callq 0x1db98
movq 0x8(%rax), %rcx
subq (%rax), %rcx
incl %r15d
cmpq %rbx, %rcx
ja 0x1c8cb
movq 0x38(%rsp), %rdi
callq 0x42b0
cmpq 0x8(%rsp), %rax
jne 0x1c88a
movq 0x10(%rsp), %rax
movq 0x30(%rax), %r9
movq 0x80(%rsp), %r15
movq 0x78(%rsp), %r13
movq 0x70(%rsp), %rbx
movq 0x30(%rsp), %r12
movq 0x18(%rsp), %rcx
fldt 0x10(%r9,%rcx)
fldt 0x20(%r15)
faddp %st, %st(1)
fstpt 0x20(%r15)
movzbl 0x21(%rbx), %esi
movb $0x0, 0x20(%rsp)
movq %r14, %rdi
leaq 0x20(%rsp), %rdx
leaq 0x7(%rsp), %rcx
callq 0x1d598
movq 0x88(%rsp), %rbp
movq %rbp, %rdi
callq 0x1e570
movq 0x60(%rsp), %rax
movq %rax, 0x20(%rbp)
movups 0x40(%rsp), %xmm0
movups 0x50(%rsp), %xmm1
movups %xmm1, 0x10(%rbp)
movups %xmm0, (%rbp)
movzbl 0x21(%rbx), %eax
testl %eax, %eax
fldt 0xac(%rsp)
movq 0x10(%rsp), %r14
movq 0x90(%rsp), %r10
je 0x1ca18
movq (%rbp), %rdx
xorl %ecx, %ecx
movl %ecx, %esi
movl $0x1, %r8d
shlq %cl, %r8
shrl $0x6, %esi
andl $0x3, %esi
movq (%rdx,%rsi,8), %rdi
btq %rcx, %rdi
jb 0x1ca01
movq 0x88(%r14), %r9
movq (%r9,%r10,8), %r9
testq %r8, (%r9,%rsi,8)
je 0x1ca10
orq %r8, %rdi
movq %rdi, (%rdx,%rsi,8)
incl %ecx
cmpl %ecx, %eax
jne 0x1c9d5
jmp 0x1ca18
notq %r8
andq %r8, %rdi
jmp 0x1ca04
fld1
faddp %st, %st(1)
movb 0x24(%r14), %cl
incq %r12
movzbl %cl, %eax
cmpq %rax, %r12
jb 0x1c788
movq 0x30(%r15), %rax
movq 0x38(%r15), %rcx
subq %rax, %rcx
je 0x1ca58
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 0x1ca42
movq 0x48(%r15), %rax
movq 0x50(%r15), %rcx
subq %rax, %rcx
je 0x1cb54
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 0x1ca6f
jmp 0x1cb54
fstp %st(0)
leaq 0x30(%r15), %rdi
movq 0x48(%r14), %rax
movb (%rax,%r13), %al
movb %al, (%r15)
movq 0x30(%r14), %rax
movl %r13d, %ecx
shll $0x5, %ecx
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 0x13b05(%rip), %rax     # 0x305d8
fadds (%rax,%rcx,4)
fstpt 0x10(%r15)
callq 0x1d9fa
movq 0x30(%r14), %rax
leaq (%rax,%rbx), %rsi
addq $0x38, %rsi
leaq 0x48(%r15), %rdi
callq 0x1d9fa
movq 0x30(%r14), %rax
fldt 0x10(%rax,%rbx)
fstpt 0x20(%r15)
leaq (%rax,%rbx), %rsi
addq $0x60, %rsi
leaq 0x60(%r15), %rdi
callq 0x1e168
leaq (,%r13,4), %rsi
addq %r13, %rsi
shll $0x3, %esi
addq 0x88(%r14), %rsi
movq %r15, %rdi
addq $0x90, %rdi
callq 0x1dade
movq 0x60(%r14), %rax
movl %r13d, %ecx
shrb $0x6, %cl
movzbl %cl, %ecx
movq (%rax,%rcx,8), %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 0x18b87
nop