// File: /workspace/github_cpp_makefile_star2_O1/adamiaonr[P]rid-analytics/src/rid-router.cpp
// Function: RID_Router::forward(unsigned char, std::map<int, std::vector<unsigned char, std::allocator<unsigned char>>, std::less<int>, std::allocator<std::pair<int const, std::vector<unsigned char, std::allocator<unsigned char>>>>>*, long double, std::vector<long double, std::allocator<long double>>*, std::vector<std::vector<long double, std::allocator<long double>>, std::allocator<std::vector<long double, std::allocator<long double>>>>&, std::vector<std::vector<long double, std::allocator<long double>>, std::allocator<std::vector<long double, std::allocator<long double>>>>&)
int RID_Router::forward(
    uint8_t ingress_iface,
    std::map<int, std::vector<uint8_t> > * tree_bitmasks,
    __float080 in_prob,
    std::vector<__float080> * in_fptree_prob,
    std::vector<std::vector<__float080> > & iface_probs,
    std::vector<std::vector<__float080> > & out_fptree_probs) {

    std::cout << "RID_Router::forward() : [INFO] *** forwarding *** " << 
        "\n\tfrom : " << this->get_next_hop(ingress_iface).router->get_id() << 
        "\n\tinto : " << this->get_id() << "[" << (int) ingress_iface << "]" << std::endl;

    // check which ifaces are eligible to be on prefix trees (of any size)
    for (uint8_t i = 0; i < this->iface_num; i++) {
        std::fill(this->iface_on_fptree[i].begin(), this->iface_on_fptree[i].end(), false);
        is_iface_on_fptree(i, tree_bitmasks);
    }

    // mark blocked ifaces for basic loop prevention
    // don't forward over ifaces w/ no entries associated w/ them
    for (uint8_t i = 0; i < this->iface_num; i++) {

        this->blocked_ifaces[i] = false;
        
        if (this->fwd_table[i].num_entries == 0)
            this->blocked_ifaces[i] = true;
    }
    // don't foward over ingress iface
    this->blocked_ifaces[ingress_iface] = true;

    std::cout << "RID_Router::forward() : [INFO] blocked ifaces {";
    for (uint8_t k = 0; k < this->blocked_ifaces.size(); k++) {
        std::cout << "[" << (int) k << "]:" << (int) this->blocked_ifaces[k] << ", ";        
    }
    std::cout << "}" << std::endl;

    // save the ingress probabilities for each diff. prefix tree size (i.e. 
    // the probability that a packet is already bound to a tree of size p)

    std::cout << "RID_Router::forward() : P(in) = " << in_prob << std::endl;
    std::cout << "RID_Router::forward() : P(in_fptree = p) :" << std::endl; 
    for (uint8_t fptree_size = 0; fptree_size <= this->req_size; fptree_size++)
        std::cout << "\tP(p = " << (int) fptree_size << "]) = " << (*in_fptree_prob)[fptree_size] << std::endl;

    // get the iface probs P(I = i), i.e. the probability of having iface i 
    // chosen as an egress iface 

    // as input, we pass: 
    //  - iface data from the fwd_table[] which has an influence in fp rate 
    //    and/or iface prob calculation
    //  - in_prob : probability of having a request forwarded 
    //              into this router by the previous router.
    //  - in_fptree_prob : probabilities of having the request coming into this 
    //                     router while 'bound' to a fp tree of size p
    std::vector<std::vector<Prob::fp_data *> > iface_fp_data(2);
    for (uint8_t i = 0; i < this->iface_num; i++) {

        iface_fp_data[0].push_back(get_fp_data(this, i));
        iface_fp_data[1].push_back(get_fp_data(this, i, true));
    }

    if (this->prob_mod->calc_probs(
        &(iface_fp_data),
        tree_bitmasks,
        in_prob,
        in_fptree_prob, 
        iface_probs, 
        out_fptree_probs) < 0) return -1;

    std::cout << "RID_Router::forward() : [INFO] iface probs :" << std::endl;
    for (uint8_t i = 0; i < this->iface_num; i++)
        std::cout << "\tP(I = " << (int) i << ") = " << iface_probs[i][0] << " : " << iface_probs[i][1] << " : " << iface_probs[i][2] << std::endl;

    for (uint8_t i = 0; i < iface_fp_data[0].size(); i++) {
        delete iface_fp_data[0][i];
    }

    for (uint8_t i = 0; i < iface_fp_data[0].size(); i++) {
        delete iface_fp_data[1][i];
    }

    return 0;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x88, %rsp
movq %r9, 0x80(%rsp)
movq %r8, 0x38(%rsp)
movq %rcx, 0x40(%rsp)
movq %rdx, 0x48(%rsp)
movl %esi, %r15d
movq %rdi, %r14
fldt 0xc0(%rsp)
fstpt 0x74(%rsp)
movq 0x22f88(%rip), %rbx     # 0x3ffb8
leaq 0x148de(%rip), %rsi     # 0x31915
movl $0x32, %edx
movq %rbx, %rdi
callq 0x4400
leaq 0x148fd(%rip), %rsi     # 0x31948
movl $0x9, %edx
movq %rbx, %rdi
callq 0x4400
movl %r15d, %ebp
movq 0x30(%r14), %rax
leaq (,%rbp,4), %rcx
addq %rbp, %rcx
shll $0x5, %ecx
movq 0x90(%rax,%rcx), %rax
leaq 0x20(%rsp), %r13
movq %r13, -0x10(%r13)
movq (%rax), %rsi
movq 0x8(%rax), %rdx
addq %rsi, %rdx
leaq 0x10(%rsp), %r12
movq %r12, %rdi
callq 0x1c27c
movq (%r12), %rsi
movq 0x8(%r12), %rdx
movq %rbx, %rdi
callq 0x4400
movq %rax, %rbx
leaq 0x148a2(%rip), %rsi     # 0x31952
movl $0x9, %edx
movq %rax, %rdi
callq 0x4400
leaq 0x60(%rsp), %r12
movq %r12, -0x10(%r12)
movq (%r14), %rsi
movq 0x8(%r14), %rdx
addq %rsi, %rdx
leaq 0x50(%rsp), %rdi
callq 0x1c27c
movq 0x50(%rsp), %rsi
movq 0x58(%rsp), %rdx
movq %rbx, %rdi
callq 0x4400
movq %rax, %rbx
leaq 0x154ac(%rip), %rsi     # 0x325a3
movl $0x1, %edx
movq %rax, %rdi
callq 0x4400
movzbl %r15b, %esi
movq %rbx, %rdi
callq 0x46d0
movq %rax, %rbx
leaq 0x11714(%rip), %rsi     # 0x2e82e
movl $0x1, %edx
movq %rax, %rdi
callq 0x4400
movq (%rbx), %rax
movq -0x18(%rax), %rdi
addq %rbx, %rdi
movl $0xa, %esi
callq 0x4370
movsbl %al, %esi
movq %rbx, %rdi
callq 0x4040
movq %rax, %rdi
callq 0x42a0
movq 0x50(%rsp), %rdi
cmpq %r12, %rdi
je 0x1d165
movq 0x60(%rsp), %rsi
incq %rsi
callq 0x43a0
movq 0x10(%rsp), %rdi
cmpq %r13, %rdi
je 0x1d17c
movq 0x20(%rsp), %rsi
incq %rsi
callq 0x43a0
movb 0x24(%r14), %cl
testb %cl, %cl
je 0x1d1f4
movl $0x18, %r12d
xorl %ebx, %ebx
movq 0x88(%r14), %rax
movq -0x18(%rax,%r12), %rdi
movq -0x8(%rax,%r12), %r13
movl (%rax,%r12), %r15d
cmpq %r13, %rdi
je 0x1d1b5
movq %r13, %rdx
subq %rdi, %rdx
xorl %esi, %esi
callq 0x4240
jmp 0x1d1b8
movq %rdi, %r13
testl %r15d, %r15d
je 0x1d1d4
negb %r15b
movq $-0x1, %rax
movl %r15d, %ecx
shrq %cl, %rax
notq %rax
andq %rax, (%r13)
movq %r14, %rdi
movl %ebx, %esi
movq 0x48(%rsp), %rdx
callq 0x1d7e2
incq %rbx
movzbl 0x24(%r14), %ecx
addq $0x28, %r12
cmpq %rcx, %rbx
jb 0x1d18c
testb %cl, %cl
je 0x1d242
movq 0x30(%r14), %rax
movq 0x60(%r14), %rdx
movzbl %cl, %esi
addq $0x58, %rax
xorl %ecx, %ecx
movl $0x1, %edi
shlq %cl, %rdi
movq %rcx, %r8
shrq $0x6, %r8
movq (%rdx,%r8,8), %r9
movq %r9, %r10
btrq %rcx, %r10
movq %r10, (%rdx,%r8,8)
cmpq $0x0, (%rax)
jne 0x1d234
orq %rdi, %r9
movq %r9, (%rdx,%r8,8)
incq %rcx
addq $0xa0, %rax
cmpq %rcx, %rsi
jne 0x1d209
movq 0x60(%r14), %rax
movl %ebp, %edx
movl $0x1, %esi
movl %ebp, %ecx
shlq %cl, %rsi
shrl $0x6, %edx
orq %rsi, (%rax,%rdx,8)
movq 0x22d58(%rip), %rbp     # 0x3ffb8
leaq 0x146f5(%rip), %rsi     # 0x3195c
movl $0x2f, %edx
movq %rbp, %rdi
callq 0x4400
movq 0x70(%r14), %rax
movl 0x78(%r14), %ecx
subq 0x60(%r14), %rax
shlq $0x3, %rax
addq %rcx, %rax
je 0x1d329
xorl %r12d, %r12d
movq 0x22d21(%rip), %r15     # 0x3ffb8
xorl %r13d, %r13d
movl $0x1, %edx
movq %r15, %rdi
leaq 0x152fa(%rip), %rsi     # 0x325a3
callq 0x4400
movzbl %r13b, %r13d
movq %r15, %rdi
movl %r13d, %esi
callq 0x46d0
movq %rax, %rbx
movl $0x2, %edx
movq %rax, %rdi
leaq 0x146bd(%rip), %rsi     # 0x3198c
callq 0x4400
movq 0x60(%r14), %rax
movq %r12, %rcx
shrq $0x6, %rcx
movq (%rax,%rcx,8), %rax
xorl %esi, %esi
btq %r12, %rax
setb %sil
movq %rbx, %rdi
callq 0x46d0
movl $0x2, %edx
movq %rax, %rdi
leaq 0x14404(%rip), %rsi     # 0x31708
callq 0x4400
incb %r13b
movzbl %r13b, %r12d
movq 0x70(%r14), %rax
movl 0x78(%r14), %ecx
subq 0x60(%r14), %rax
leaq (%rcx,%rax,8), %rax
cmpq %r12, %rax
ja 0x1d29a
leaq 0x1465f(%rip), %rsi     # 0x3198f
movl $0x1, %edx
movq %rbp, %rdi
callq 0x4400
movq (%rbp), %rax
movq -0x18(%rax), %rdi
addq %rbp, %rdi
movl $0xa, %esi
callq 0x4370
movsbl %al, %esi
movq %rbp, %rdi
callq 0x4040
movq %rax, %rdi
callq 0x42a0
leaq 0x14625(%rip), %rsi     # 0x31991
movl $0x20, %edx
movq %rbp, %rdi
callq 0x4400
fldt 0x74(%rsp)
fstpt (%rsp)
movq %rbp, %rdi
callq 0x41f0
movq %rax, %rbx
movq (%rax), %rax
movq -0x18(%rax), %rdi
addq %rbx, %rdi
movl $0xa, %esi
callq 0x4370
movsbl %al, %esi
movq %rbx, %rdi
callq 0x4040
movq %rax, %rdi
callq 0x42a0
leaq 0x145f9(%rip), %rsi     # 0x319b2
movl $0x2a, %edx
movq %rbp, %rdi
callq 0x4400
movq (%rbp), %rax
movq -0x18(%rax), %rdi
addq %rbp, %rdi
movl $0xa, %esi
callq 0x4370
movsbl %al, %esi
movq %rbp, %rdi
callq 0x4040
movq %rax, %rdi
callq 0x42a0
xorl %r15d, %r15d
leaq 0x145ed(%rip), %r12     # 0x319e5
movq %rbp, %rbx
movq 0x40(%rsp), %rbp
movzbl %r15b, %r15d
movl $0x7, %edx
movq %rbx, %rdi
leaq 0x145ca(%rip), %rsi     # 0x319dd
callq 0x4400
movq %rbx, %rdi
movl %r15d, %esi
callq 0x46d0
movq %rax, %r13
movl $0x5, %edx
movq %rax, %rdi
movq %r12, %rsi
callq 0x4400
movq (%rbp), %rax
movl %r15d, %ecx
shll $0x4, %ecx
fldt (%rax,%rcx)
fstpt (%rsp)
movq %r13, %rdi
callq 0x41f0
movq %rax, %r13
movq (%rax), %rax
movq -0x18(%rax), %rdi
addq %r13, %rdi
movl $0xa, %esi
callq 0x4370
movsbl %al, %esi
movq %r13, %rdi
callq 0x4040
movq %rax, %rdi
callq 0x42a0
incb %r15b
cmpb 0x21(%r14), %r15b
jbe 0x1d400
xorps %xmm0, %xmm0
movaps %xmm0, 0x10(%rsp)
movq $0x0, 0x20(%rsp)
movl $0x30, %edi
callq 0x4390
movq %rax, 0x10(%rsp)
movq %rax, 0x18(%rsp)
movq %rax, %rcx
addq $0x30, %rcx
movq %rcx, 0x20(%rsp)
xorps %xmm0, %xmm0
movups %xmm0, 0x20(%rax)
movups %xmm0, 0x10(%rax)
movups %xmm0, (%rax)
movq %rcx, 0x18(%rsp)
cmpb $0x0, 0x24(%r14)
movq 0x40(%rsp), %r13
je 0x1d539
xorl %r12d, %r12d
leaq 0x50(%rsp), %rbx
movq 0x10(%rsp), %r15
movzbl %r12b, %ebp
movq %r14, %rdi
movq %r14, %rsi
movl %ebp, %edx
xorl %ecx, %ecx
callq 0x1ca4c
movq %rax, 0x50(%rsp)
movq %r15, %rdi
movq %rbx, %rsi
callq 0x1f180
movq 0x10(%rsp), %r15
movq %r14, %rdi
movq %r14, %rsi
movl %ebp, %edx
movl $0x1, %ecx
callq 0x1ca4c
addq $0x18, %r15
movq %rax, 0x50(%rsp)
movq %r15, %rdi
movq %rbx, %rsi
callq 0x1f180
incb %r12b
cmpb 0x24(%r14), %r12b
jb 0x1d4dd
movq 0xa0(%r14), %rdi
fldt 0x74(%rsp)
fstpt (%rsp)
leaq 0x10(%rsp), %rsi
movq 0x48(%rsp), %rdx
movq %r13, %rcx
movq 0x38(%rsp), %r8
movq 0x80(%rsp), %r9
callq 0x2bb28
testl %eax, %eax
js 0x1d764
movq 0x22a43(%rip), %rbx     # 0x3ffb8
leaq 0x1446f(%rip), %rsi     # 0x319eb
movl $0x2c, %edx
movq %rbx, %rdi
callq 0x4400
movq (%rbx), %rax
addq -0x18(%rax), %rbx
movq %rbx, %rdi
movl $0xa, %esi
callq 0x4370
movsbl %al, %esi
movq 0x22a11(%rip), %rdi     # 0x3ffb8
callq 0x4040
movq %rax, %rdi
callq 0x42a0
cmpb $0x0, 0x24(%r14)
je 0x1d6bb
xorl %r13d, %r13d
movq 0x229ef(%rip), %r15     # 0x3ffb8
leaq 0x14cfd(%rip), %rbp     # 0x322cd
xorl %r12d, %r12d
movl $0x7, %edx
movq %r15, %rdi
leaq 0x14436(%rip), %rsi     # 0x31a18
callq 0x4400
movq %r15, %rdi
movl %r12d, %esi
callq 0x46d0
movq %rax, %rbx
movl $0x4, %edx
movq %rax, %rdi
leaq 0x143e2(%rip), %rsi     # 0x319e6
callq 0x4400
movq 0x38(%rsp), %rax
movq (%rax), %rax
movq (%rax,%r13), %rax
fldt (%rax)
fstpt (%rsp)
movq %rbx, %rdi
callq 0x41f0
movq %rax, %rbx
movl $0x3, %edx
movq %rax, %rdi
movq %rbp, %rsi
callq 0x4400
movq 0x38(%rsp), %rax
movq (%rax), %rax
movq (%rax,%r13), %rax
fldt 0x10(%rax)
fstpt (%rsp)
movq %rbx, %rdi
callq 0x41f0
movq %rax, %rbx
movl $0x3, %edx
movq %rax, %rdi
movq %rbp, %rsi
callq 0x4400
movq 0x38(%rsp), %rax
movq (%rax), %rax
movq (%rax,%r13), %rax
fldt 0x20(%rax)
fstpt (%rsp)
movq %rbx, %rdi
callq 0x41f0
movq %rax, %rbx
movq (%rax), %rax
movq -0x18(%rax), %rdi
addq %rbx, %rdi
movl $0xa, %esi
callq 0x4370
movsbl %al, %esi
movq %rbx, %rdi
callq 0x4040
movq %rax, %rdi
callq 0x42a0
incq %r12
movzbl 0x24(%r14), %eax
addq $0x18, %r13
cmpq %rax, %r12
jb 0x1d5d3
movq 0x10(%rsp), %rcx
movq (%rcx), %rax
cmpq %rax, 0x8(%rcx)
je 0x1d70d
movb $0x1, %bpl
xorl %ecx, %ecx
movq (%rax,%rcx,8), %rbx
testq %rbx, %rbx
je 0x1d6ec
movq %rbx, %rdi
callq 0x1e07a
movl $0xc0, %esi
movq %rbx, %rdi
callq 0x43a0
movzbl %bpl, %ecx
movq 0x10(%rsp), %rdx
movq (%rdx), %rax
movq 0x8(%rdx), %rdx
subq %rax, %rdx
sarq $0x3, %rdx
movl %ecx, %ebp
incb %bpl
cmpq %rcx, %rdx
ja 0x1d6ce
movq 0x10(%rsp), %rax
movq 0x8(%rax), %rcx
cmpq (%rax), %rcx
je 0x1d760
movb $0x1, %bpl
xorl %ecx, %ecx
movq 0x18(%rax), %rax
movq (%rax,%rcx,8), %rbx
testq %rbx, %rbx
je 0x1d742
movq %rbx, %rdi
callq 0x1e07a
movl $0xc0, %esi
movq %rbx, %rdi
callq 0x43a0
movzbl %bpl, %ecx
movq 0x10(%rsp), %rax
movq 0x8(%rax), %rdx
subq (%rax), %rdx
sarq $0x3, %rdx
movl %ecx, %ebp
incb %bpl
cmpq %rcx, %rdx
ja 0x1d720
xorl %ebx, %ebx
jmp 0x1d769
movl $0xffffffff, %ebx       # imm = 0xFFFFFFFF
leaq 0x10(%rsp), %rdi
callq 0x1e0c8
movl %ebx, %eax
addq $0x88, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movq %rax, %rbx
jmp 0x1d7d9
jmp 0x1d78e
movq %rax, %rbx
jmp 0x1d7af
jmp 0x1d7cc
movq %rax, %rbx
movq 0x50(%rsp), %rdi
cmpq %r12, %rdi
je 0x1d7af
movq 0x60(%rsp), %rsi
incq %rsi
callq 0x43a0
movq 0x10(%rsp), %rdi
cmpq %r13, %rdi
je 0x1d7d9
movq 0x20(%rsp), %rsi
incq %rsi
callq 0x43a0
jmp 0x1d7d9
jmp 0x1d7cc
jmp 0x1d7cc
movq %rax, %rbx
leaq 0x10(%rsp), %rdi
callq 0x1e0c8
movq %rbx, %rdi
callq 0x4700
nop