// File: eniac[P]Mantis/src/compile/compile_p4.cpp
// Function: runBinPackForIng(std::vector<std::pair<ReactionArgNode*, int>, std::allocator<std::pair<ReactionArgNode*, int>>>*, std::vector<AstNode*, std::allocator<AstNode*>>, bool)
static vector<ReactionArgBin> runBinPackForIng(
            vector<pair<ReactionArgNode*, int> >* argSizes, vector<AstNode*> nodeArray, bool forIng) {

    sort(argSizes->begin(), argSizes->end(),
            [](const pair<ReactionArgNode*, int>& l,
               const pair<ReactionArgNode*, int>& r) {
                if (l.second != r.second) {
                    return l.second > r.second;
                }
                return l.first > r.first;
            });

    vector<ReactionArgBin> bins;
    for (const pair<ReactionArgNode*, int>& p : *argSizes) {
        assert(p.second <= REGISTER_SIZE);

        // Packing
        if(forIng) {
            if(p.first->argType_!=ReactionArgNode::INGRESS_FIELD && p.first->argType_!=ReactionArgNode::INGRESS_MBL_FIELD) {
                continue;
            }
        } else {
            if(p.first->argType_!=ReactionArgNode::EGRESS_FIELD && p.first->argType_!=ReactionArgNode::EGRESS_MBL_FIELD) {
                continue;
            }
        }

        bool added = false;
        for (ReactionArgBin& bin : bins) {
            if (p.second + bin.second <= REGISTER_SIZE) {
                bin.first.push_back(p);
                bin.second += p.second;
                added = true;
                break;
            }
        }

        if (!added) {
            vector<ReactionArgSize> newBin;
            newBin.push_back(p);
            bins.emplace_back(move(newBin), p.second);
        }
    }

    return bins;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0xc0, %rsp
movq %rdi, -0xb0(%rbp)
movb %cl, %al
movq %rdi, %rcx
movq %rcx, -0xb8(%rbp)
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movq %rdx, -0x18(%rbp)
andb $0x1, %al
movb %al, -0x19(%rbp)
movq -0x10(%rbp), %rdi
callq 0x128740
movq %rax, -0x28(%rbp)
movq -0x10(%rbp), %rdi
callq 0x128770
movq %rax, -0x30(%rbp)
movq -0x28(%rbp), %rdi
movq -0x30(%rbp), %rsi
callq 0x126550
movq -0xb0(%rbp), %rdi
movb $0x0, -0x32(%rbp)
callq 0xcc7d0
movq -0x10(%rbp), %rax
movq %rax, -0x40(%rbp)
movq -0x40(%rbp), %rdi
callq 0x128740
movq %rax, -0x48(%rbp)
movq -0x40(%rbp), %rdi
callq 0x128770
movq %rax, -0x50(%rbp)
leaq -0x48(%rbp), %rdi
leaq -0x50(%rbp), %rsi
callq 0x1287a0
testb $0x1, %al
jne 0x12009e
jmp 0x12024a
leaq -0x48(%rbp), %rdi
callq 0x1287e0
movq %rax, -0x58(%rbp)
movq -0x58(%rbp), %rax
cmpl $0x20, 0x8(%rax)
jg 0x1200b7
jmp 0x1200d6
leaq 0x1e1c9(%rip), %rdi     # 0x13e287
leaq 0x1dc92(%rip), %rsi     # 0x13dd57
movl $0x354, %edx            # imm = 0x354
leaq 0x1e1d0(%rip), %rcx     # 0x13e2a1
callq 0xaa3d0
testb $0x1, -0x19(%rbp)
je 0x1200fd
movq -0x58(%rbp), %rax
movq (%rax), %rax
cmpl $0x0, 0x3c(%rax)
je 0x1200fb
movq -0x58(%rbp), %rax
movq (%rax), %rax
cmpl $0x2, 0x3c(%rax)
je 0x1200fb
jmp 0x12023c
jmp 0x12011e
movq -0x58(%rbp), %rax
movq (%rax), %rax
cmpl $0x1, 0x3c(%rax)
je 0x12011c
movq -0x58(%rbp), %rax
movq (%rax), %rax
cmpl $0x3, 0x3c(%rax)
je 0x12011c
jmp 0x12023c
jmp 0x12011e
movq -0xb0(%rbp), %rax
movb $0x0, -0x59(%rbp)
movq %rax, -0x68(%rbp)
movq -0x68(%rbp), %rdi
callq 0x128800
movq %rax, -0x70(%rbp)
movq -0x68(%rbp), %rdi
callq 0x128830
movq %rax, -0x78(%rbp)
leaq -0x70(%rbp), %rdi
leaq -0x78(%rbp), %rsi
callq 0x128860
testb $0x1, %al
jne 0x12015a
jmp 0x1201c4
leaq -0x70(%rbp), %rdi
callq 0x1288a0
movq %rax, -0x80(%rbp)
movq -0x58(%rbp), %rax
movl 0x8(%rax), %eax
movq -0x80(%rbp), %rcx
addl 0x18(%rcx), %eax
cmpl $0x20, %eax
jg 0x1201b7
movq -0x80(%rbp), %rdi
movq -0x58(%rbp), %rsi
callq 0x1288c0
jmp 0x120189
movq -0x58(%rbp), %rax
movl 0x8(%rax), %ecx
movq -0x80(%rbp), %rax
addl 0x18(%rax), %ecx
movl %ecx, 0x18(%rax)
movb $0x1, -0x59(%rbp)
jmp 0x1201c4
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x88(%rbp)
movl %eax, -0x8c(%rbp)
jmp 0x120270
jmp 0x1201b9
leaq -0x70(%rbp), %rdi
callq 0x128930
jmp 0x120147
testb $0x1, -0x59(%rbp)
jne 0x12023a
leaq -0xa8(%rbp), %rdi
movq %rdi, -0xc0(%rbp)
callq 0x128950
movq -0xc0(%rbp), %rdi
movq -0x58(%rbp), %rsi
callq 0x1288c0
jmp 0x1201ef
movq -0xb0(%rbp), %rdi
movq -0x58(%rbp), %rdx
addq $0x8, %rdx
leaq -0xa8(%rbp), %rsi
callq 0x128970
jmp 0x12020c
leaq -0xa8(%rbp), %rdi
callq 0xd09b0
jmp 0x12023a
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x88(%rbp)
movl %eax, -0x8c(%rbp)
leaq -0xa8(%rbp), %rdi
callq 0xd09b0
jmp 0x120270
jmp 0x12023c
leaq -0x48(%rbp), %rdi
callq 0x1289f0
jmp 0x120088
movb $0x1, -0x32(%rbp)
testb $0x1, -0x32(%rbp)
jne 0x120260
movq -0xb0(%rbp), %rdi
callq 0xcc7f0
movq -0xb8(%rbp), %rax
addq $0xc0, %rsp
popq %rbp
retq
movq -0xb0(%rbp), %rdi
callq 0xcc7f0
movq -0x88(%rbp), %rdi
callq 0xaaa60
nopl (%rax,%rax)