// File: adamiaonr[P]rid-analytics/src/rid-router.cpp
// Function: RID_Router::add_fwd_table_entry(int, long double, std::map<int, long double, std::less<int>, std::allocator<std::pair<int const, long double>>>*, 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>>>>>*, RID_Router*, int)
int RID_Router::add_fwd_table_entry(
    int i, 
    __float080 iface_proportion, 
    std::map<int, __float080> * f_distr,
    std::map<int, std::vector<uint8_t> > * tree_bitmasks,
    RID_Router * next_hop_router,
    int next_hop_iface) {

    if ((i < 0) || (i > (this->iface_num - 1))) {
        std::cerr << "RID_Router::add_fwd_table_entry() : [ERROR] invalid iface index: "
            << i << " vs. " << (int) this->iface_num << std::endl;
        return -1;
    }

    this->fwd_table[i].num_entries = (__float080) this->fwd_table_size * iface_proportion;
    std::cout << "RID_Router::add_fwd_table_entry() : [INFO] iface[" << i 
        << "].num_entries = " << this->fwd_table[i].num_entries << std::endl;
    
    this->fwd_table[i].iface = i;
    // iface_proportion : % of table entries associated w/ this iface
    this->fwd_table[i].iface_proportion = iface_proportion;
    // distribution of sizes among the entries associated w/ this iface
    this->fwd_table[i].f_distr = std::vector<__float080>(this->req_size, 0.0);

    for (int f = 0; f < this->req_size; f++) {
        this->fwd_table[i].f_distr[f] = (*f_distr)[f + 1];
        // set bit in the bitmask of fwd entry sizes if f_distr[f] > 0.0
        if (this->fwd_table[i].f_distr[f] > 0.0)
            this->fwd_table[i].f_bitmask |= (1 << f);
    }

    // copy the map of tree bitmasks into the router's iface
    this->fwd_table[i].tree_bitmasks = (*tree_bitmasks);

    // next hop information: remote router pointer and iface
    this->fwd_table[i].next_hop.router = next_hop_router;
    this->fwd_table[i].next_hop.iface = next_hop_iface;

    return 0;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x140, %rsp            # imm = 0x140
fldt 0x10(%rbp)
movq %rdi, -0x10(%rbp)
movl %esi, -0x14(%rbp)
fstpt -0x30(%rbp)
movq %rdx, -0x38(%rbp)
movq %rcx, -0x40(%rbp)
movq %r8, -0x48(%rbp)
movl %r9d, -0x4c(%rbp)
movq -0x10(%rbp), %rax
movq %rax, -0xc0(%rbp)
cmpl $0x0, -0x14(%rbp)
jl 0x325be
movq -0xc0(%rbp), %rcx
movl -0x14(%rbp), %eax
movzbl 0x24(%rcx), %ecx
subl $0x1, %ecx
cmpl %ecx, %eax
jle 0x32619
movq 0x4fa2b(%rip), %rdi     # 0x81ff0
leaq 0x310c2(%rip), %rsi     # 0x6368e
callq 0x5480
movq %rax, %rdi
movl -0x14(%rbp), %esi
callq 0x58f0
movq %rax, %rdi
leaq 0x310ea(%rip), %rsi     # 0x636d0
callq 0x5480
movq %rax, %rdi
movq -0xc0(%rbp), %rax
movzbl 0x24(%rax), %esi
callq 0x58f0
movq %rax, %rdi
movq 0x4f988(%rip), %rsi     # 0x81f90
callq 0x54f0
movl $0xffffffff, -0x4(%rbp) # imm = 0xFFFFFFFF
jmp 0x329af
movq -0xc0(%rbp), %rdi
movq 0x28(%rdi), %rax
movq %rax, -0xb0(%rbp)
testq %rax, %rax
sets %al
movzbl %al, %eax
movl %eax, %ecx
fildll -0xb0(%rbp)
leaq 0x30fbd(%rip), %rax     # 0x63600
flds (%rax,%rcx,4)
faddp %st, %st(1)
fldt -0x30(%rbp)
fmulp %st, %st(1)
flds 0x30fa9(%rip)           # 0x635fc
fxch %st(1)
fucomi %st(1), %st
fldz
fld %st(0)
fstpt -0xdc(%rbp)
fcmovnb %st(2), %st
fstp %st(2)
fsubp %st, %st(1)
setae %al
fnstcw -0xb2(%rbp)
movzwl -0xb2(%rbp), %ecx
orl $0xc00, %ecx            # imm = 0xC00
movw %cx, -0xb4(%rbp)
fldcw -0xb4(%rbp)
fistpll -0xa8(%rbp)
fldcw -0xb2(%rbp)
movzbl %al, %eax
movl %eax, %ecx
shlq $0x3f, %rcx
movq -0xa8(%rbp), %rax
xorq %rcx, %rax
movq %rax, -0x108(%rbp)
addq $0x30, %rdi
movq %rdi, -0xf0(%rbp)
movslq -0x14(%rbp), %rsi
callq 0x34a20
movq -0x108(%rbp), %rcx
movq %rcx, 0x58(%rax)
movq 0x4f8e2(%rip), %rdi     # 0x81fb8
leaq 0x30ff9(%rip), %rsi     # 0x636d6
callq 0x5480
movq %rax, %rdi
movl -0x14(%rbp), %esi
callq 0x58f0
movq %rax, %rdi
leaq 0x31011(%rip), %rsi     # 0x63708
callq 0x5480
movq -0xf0(%rbp), %rdi
movq %rax, -0x100(%rbp)
movslq -0x14(%rbp), %rsi
callq 0x34a20
movq -0x100(%rbp), %rdi
movq 0x58(%rax), %rsi
callq 0x5140
movq %rax, %rdi
movq 0x4f863(%rip), %rsi     # 0x81f90
callq 0x54f0
movq -0xf0(%rbp), %rdi
movslq -0x14(%rbp), %rsi
movb %sil, %al
movb %al, -0xf1(%rbp)
callq 0x34a20
movb -0xf1(%rbp), %cl
movq -0xf0(%rbp), %rdi
movb %cl, (%rax)
fldt -0x30(%rbp)
fstpt -0xe8(%rbp)
movslq -0x14(%rbp), %rsi
callq 0x34a20
fldt -0xe8(%rbp)
fldt -0xdc(%rbp)
movq %rax, %rcx
movq -0xc0(%rbp), %rax
fxch %st(1)
fstpt 0x10(%rcx)
movzbl 0x21(%rax), %eax
movq %rax, -0xd0(%rbp)
fstpt -0x80(%rbp)
leaq -0x81(%rbp), %rdi
movq %rdi, -0xc8(%rbp)
callq 0x34a40
movq -0xd0(%rbp), %rsi
movq -0xc8(%rbp), %rcx
leaq -0x68(%rbp), %rdi
leaq -0x80(%rbp), %rdx
callq 0x34a60
jmp 0x327c5
movq -0xc0(%rbp), %rdi
addq $0x30, %rdi
movslq -0x14(%rbp), %rsi
callq 0x34a20
movq %rax, %rdi
addq $0x20, %rdi
leaq -0x68(%rbp), %rsi
callq 0x34ae0
leaq -0x68(%rbp), %rdi
callq 0x34b10
leaq -0x81(%rbp), %rdi
callq 0x34b70
movl $0x0, -0x98(%rbp)
movq -0xc0(%rbp), %rcx
movl -0x98(%rbp), %eax
movzbl 0x21(%rcx), %ecx
cmpl %ecx, %eax
jge 0x32920
movq -0x38(%rbp), %rdi
movl -0x98(%rbp), %eax
incl %eax
movl %eax, -0x9c(%rbp)
leaq -0x9c(%rbp), %rsi
callq 0x34b90
movq -0xc0(%rbp), %rdi
fldt (%rax)
fstpt -0x11c(%rbp)
addq $0x30, %rdi
movq %rdi, -0x110(%rbp)
movslq -0x14(%rbp), %rsi
callq 0x34a20
movq %rax, %rdi
addq $0x20, %rdi
movslq -0x98(%rbp), %rsi
callq 0x34c70
fldt -0x11c(%rbp)
movq -0x110(%rbp), %rdi
fstpt (%rax)
movslq -0x14(%rbp), %rsi
callq 0x34a20
movq %rax, %rdi
addq $0x20, %rdi
movslq -0x98(%rbp), %rsi
callq 0x34c70
fldt (%rax)
fldz
fxch %st(1)
fucompi %st(1), %st
fstp %st(0)
jbe 0x3290a
jmp 0x328ae
movq -0xc0(%rbp), %rdi
movl -0x98(%rbp), %ecx
movl $0x1, %eax
shll %cl, %eax
movl %eax, -0x120(%rbp)
addq $0x30, %rdi
movslq -0x14(%rbp), %rsi
callq 0x34a20
movl -0x120(%rbp), %edx
movzwl 0x50(%rax), %ecx
orl %edx, %ecx
movw %cx, 0x50(%rax)
jmp 0x3290a
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x90(%rbp)
movl %eax, -0x94(%rbp)
leaq -0x81(%rbp), %rdi
callq 0x34b70
jmp 0x329bb
jmp 0x3290c
movl -0x98(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x98(%rbp)
jmp 0x32808
movq -0xc0(%rbp), %rdi
movq -0x40(%rbp), %rax
movq %rax, -0x138(%rbp)
addq $0x30, %rdi
movslq -0x14(%rbp), %rsi
callq 0x34a20
movq -0x138(%rbp), %rsi
movq %rax, %rdi
addq $0x60, %rdi
callq 0x34c90
movq -0xc0(%rbp), %rdi
movq -0x48(%rbp), %rax
movq %rax, -0x130(%rbp)
addq $0x30, %rdi
movslq -0x14(%rbp), %rsi
callq 0x34a20
movq -0x130(%rbp), %rcx
movq -0xc0(%rbp), %rdi
movq %rcx, 0x90(%rax)
movl -0x4c(%rbp), %eax
movb %al, -0x121(%rbp)
addq $0x30, %rdi
movslq -0x14(%rbp), %rsi
callq 0x34a20
movb -0x121(%rbp), %cl
movb %cl, 0x98(%rax)
movl $0x0, -0x4(%rbp)
movl -0x4(%rbp), %eax
addq $0x140, %rsp            # imm = 0x140
popq %rbp
retq
movq -0x90(%rbp), %rdi
callq 0x5920
nopw (%rax,%rax)