// File: /workspace/github_cpp_makefile_star2_O3/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, 0x18(%rsp)
movq %rcx, 0x40(%rsp)
movq %rdx, 0x48(%rsp)
movl %esi, %r15d
movq %rdi, %r14
fldt 0xc0(%rsp)
fstpt 0x74(%rsp)
movq 0x22404(%rip), %rbx     # 0x3efb8
leaq 0x13b3a(%rip), %rsi     # 0x306f5
movl $0x32, %edx
movq %rbx, %rdi
callq 0x4400
leaq 0x13b59(%rip), %rsi     # 0x30728
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 0x30(%rsp), %r13
movq %r13, -0x10(%r13)
movq (%rax), %rsi
movq 0x8(%rax), %rdx
addq %rsi, %rdx
leaq 0x20(%rsp), %r12
movq %r12, %rdi
callq 0x1bdb4
movq (%r12), %rsi
movq 0x8(%r12), %rdx
movq %rbx, %rdi
callq 0x4400
movq %rax, %rbx
leaq 0x13afe(%rip), %rsi     # 0x30732
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 0x1bdb4
movq 0x50(%rsp), %rsi
movq 0x58(%rsp), %rdx
movq %rbx, %rdi
callq 0x4400
movq %rax, %rbx
leaq 0x14708(%rip), %rsi     # 0x31383
movl $0x1, %edx
movq %rax, %rdi
callq 0x4400
movzbl %r15b, %esi
movq %rbx, %rdi
callq 0x46d0
movq %rax, %rbx
leaq 0x10bc0(%rip), %rsi     # 0x2d85e
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 0x1cce9
movq 0x60(%rsp), %rsi
incq %rsi
callq 0x43a0
movq 0x20(%rsp), %rdi
cmpq %r13, %rdi
je 0x1cd00
movq 0x30(%rsp), %rsi
incq %rsi
callq 0x43a0
cmpb $0x0, 0x24(%r14)
je 0x1cdcc
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 0x1cd3c
movq %r13, %rdx
subq %rdi, %rdx
xorl %esi, %esi
callq 0x4240
jmp 0x1cd3f
movq %rdi, %r13
testl %r15d, %r15d
je 0x1cd5b
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 0x1d34c
incq %rbx
movzbl 0x24(%r14), %edx
addq $0x28, %r12
cmpq %rdx, %rbx
jb 0x1cd13
testq %rdx, %rdx
je 0x1cdcc
movq 0x30(%r14), %rsi
movq 0x60(%r14), %rax
addq $0x58, %rsi
xorl %ecx, %ecx
movl %ecx, %edi
movl $0x1, %r8d
shlq %cl, %r8
shrl $0x6, %edi
andl $0x3, %edi
movq (%rax,%rdi,8), %r9
movq %r9, %r10
btrq %rcx, %r10
movq %r10, (%rax,%rdi,8)
cmpq $0x0, (%rsi)
jne 0x1cdbb
orq %r8, %r9
movq %r9, (%rax,%rdi,8)
incq %rcx
addq $0xa0, %rsi
cmpq %rcx, %rdx
jne 0x1cd8e
jmp 0x1cdd0
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 0x221ce(%rip), %rbp     # 0x3efb8
leaq 0x1394b(%rip), %rsi     # 0x3073c
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 0x1ceb5
xorl %r12d, %r12d
movq 0x22197(%rip), %r15     # 0x3efb8
xorl %r13d, %r13d
movl $0x1, %edx
movq %r15, %rdi
leaq 0x14550(%rip), %rsi     # 0x31383
callq 0x4400
movzbl %r13b, %r13d
movq %r15, %rdi
movl %r13d, %esi
callq 0x46d0
movq %rax, %rbx
movl $0x2, %edx
movq %rax, %rdi
leaq 0x13913(%rip), %rsi     # 0x3076c
callq 0x4400
movq 0x60(%r14), %rax
movl %r13d, %ecx
shrb $0x6, %cl
movzbl %cl, %ecx
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 0x13658(%rip), %rsi     # 0x304e8
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 0x1ce24
leaq 0x138b3(%rip), %rsi     # 0x3076f
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 0x13879(%rip), %rsi     # 0x30771
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 0x1384d(%rip), %rsi     # 0x30792
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 %ebx, %ebx
leaq 0x13842(%rip), %r12     # 0x307c5
movq %rbp, %r15
movq 0x40(%rsp), %rbp
movzbl %bl, %ebx
movl $0x7, %edx
movq %r15, %rdi
leaq 0x13820(%rip), %rsi     # 0x307bd
callq 0x4400
movq %r15, %rdi
movl %ebx, %esi
callq 0x46d0
movq %rax, %r13
movl $0x5, %edx
movq %rax, %rdi
movq %r12, %rsi
callq 0x4400
movq (%rbp), %rax
movl %ebx, %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 %bl
cmpb 0x21(%r14), %bl
jbe 0x1cf8b
movl $0x30, %edi
callq 0x4390
movq %rax, 0x20(%rsp)
movq %rax, %rcx
addq $0x30, %rcx
movq %rcx, 0x30(%rsp)
xorps %xmm0, %xmm0
movups %xmm0, 0x20(%rax)
movups %xmm0, 0x10(%rax)
movups %xmm0, (%rax)
movq %rcx, 0x28(%rsp)
cmpb $0x0, 0x24(%r14)
movq 0x40(%rsp), %r13
je 0x1d0a6
xorl %r12d, %r12d
leaq 0x50(%rsp), %rbx
movq 0x20(%rsp), %r15
movzbl %r12b, %ebp
movq %r14, %rdi
movq %r14, %rsi
movl %ebp, %edx
xorl %ecx, %ecx
callq 0x1c56c
movq %rax, 0x50(%rsp)
movq %r15, %rdi
movq %rbx, %rsi
callq 0x1ecba
movq 0x20(%rsp), %r15
movq %r14, %rdi
movq %r14, %rsi
movl %ebp, %edx
movl $0x1, %ecx
callq 0x1c56c
addq $0x18, %r15
movq %rax, 0x50(%rsp)
movq %r15, %rdi
movq %rbx, %rsi
callq 0x1ecba
incb %r12b
cmpb 0x24(%r14), %r12b
jb 0x1d04a
movq 0xa0(%r14), %rdi
fldt 0x74(%rsp)
fstpt (%rsp)
leaq 0x20(%rsp), %rsi
movq 0x48(%rsp), %rdx
movq %r13, %rcx
movq 0x18(%rsp), %r8
movq 0x80(%rsp), %r9
callq 0x2b5f6
testl %eax, %eax
js 0x1d2cf
movq 0x21ed6(%rip), %rbx     # 0x3efb8
leaq 0x136e2(%rip), %rsi     # 0x307cb
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 0x21ea4(%rip), %rdi     # 0x3efb8
callq 0x4040
movq %rax, %rdi
callq 0x42a0
cmpb $0x0, 0x24(%r14)
je 0x1d228
xorl %r13d, %r13d
movq 0x21e82(%rip), %r15     # 0x3efb8
leaq 0x13f70(%rip), %rbp     # 0x310ad
xorl %r12d, %r12d
movl $0x7, %edx
movq %r15, %rdi
leaq 0x136a9(%rip), %rsi     # 0x307f8
callq 0x4400
movq %r15, %rdi
movl %r12d, %esi
callq 0x46d0
movq %rax, %rbx
movl $0x4, %edx
movq %rax, %rdi
leaq 0x13655(%rip), %rsi     # 0x307c6
callq 0x4400
movq 0x18(%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 0x18(%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 0x18(%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 0x1d140
movq 0x20(%rsp), %rax
movq (%rax), %rcx
cmpq %rcx, 0x8(%rax)
je 0x1d2cb
movb $0x1, %bpl
xorl %edx, %edx
movq (%rcx,%rdx,8), %rbx
testq %rbx, %rbx
je 0x1d250
movq %rbx, %rdi
callq 0x1dbfe
movl $0xc0, %esi
movq %rbx, %rdi
callq 0x43a0
movzbl %bpl, %edx
movq 0x20(%rsp), %rax
movq (%rax), %rcx
movq 0x8(%rax), %rsi
movq %rsi, %rdi
subq %rcx, %rdi
sarq $0x3, %rdi
movl %edx, %ebp
incb %bpl
cmpq %rdx, %rdi
ja 0x1d23f
cmpq %rcx, %rsi
je 0x1d2cb
movb $0x1, %bpl
xorl %ecx, %ecx
movq 0x18(%rax), %rax
movq (%rax,%rcx,8), %rbx
testq %rbx, %rbx
je 0x1d2a0
movq %rbx, %rdi
callq 0x1dbfe
movl $0xc0, %esi
movq %rbx, %rdi
callq 0x43a0
movzbl %bpl, %ecx
movq 0x20(%rsp), %rax
movq 0x8(%rax), %rdx
subq (%rax), %rdx
sarq $0x3, %rdx
movl %ecx, %ebp
incb %bpl
cmpq %rcx, %rdx
ja 0x1d28b
xorl %ebx, %ebx
jmp 0x1d2d4
movl $0xffffffff, %ebx       # imm = 0xFFFFFFFF
leaq 0x20(%rsp), %rdi
callq 0x1dc4c
movl %ebx, %eax
addq $0x88, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movq %rax, %rbx
jmp 0x1d344
jmp 0x1d2f9
movq %rax, %rbx
jmp 0x1d31a
jmp 0x1d337
movq %rax, %rbx
movq 0x50(%rsp), %rdi
cmpq %r12, %rdi
je 0x1d31a
movq 0x60(%rsp), %rsi
incq %rsi
callq 0x43a0
movq 0x20(%rsp), %rdi
cmpq %r13, %rdi
je 0x1d344
movq 0x30(%rsp), %rsi
incq %rsi
callq 0x43a0
jmp 0x1d344
jmp 0x1d337
jmp 0x1d337
movq %rax, %rbx
leaq 0x20(%rsp), %rdi
callq 0x1dc4c
movq %rbx, %rdi
callq 0x4700