// File: eniac[P]Mantis/src/compile/find_nodes.cpp
// Function: findAllReactionArgSizes(std::vector<ReactionArgNode*, std::allocator<ReactionArgNode*>> const&, std::unordered_map<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>, std::vector<FieldDecNode*, std::allocator<FieldDecNode*>>*, std::hash<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>>, std::equal_to<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>>, std::allocator<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>> const, std::vector<FieldDecNode*, std::allocator<FieldDecNode*>>*>>> const&, std::unordered_map<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>, P4RMalleableValueNode*, std::hash<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>>, std::equal_to<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>>, std::allocator<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>> const, P4RMalleableValueNode*>>> const&, std::unordered_map<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>, P4RMalleableFieldNode*, std::hash<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>>, std::equal_to<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>>, std::allocator<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>> const, P4RMalleableFieldNode*>>> const&)
vector<pair<ReactionArgNode*, int> > findAllReactionArgSizes(
            const vector<ReactionArgNode*>& reactionArgs,
            const HeaderDecsMap& headerDecsMap,
            const unordered_map<string, P4RMalleableValueNode*>& mblValues,
            const unordered_map<string, P4RMalleableFieldNode*>& mblFields) {
    vector<pair<ReactionArgNode*, int> > argSizes;

    for (auto ra : reactionArgs) {
        switch (ra->argType_) {
        case ReactionArgNode::INGRESS_FIELD:
        case ReactionArgNode::EGRESS_FIELD:
        case ReactionArgNode::INGRESS_MBL_FIELD:
        case ReactionArgNode::EGRESS_MBL_FIELD:
            if (typeContains(ra->arg_, "FieldNode")) {
                // If it's a field node, grab from headerDecsMap
                auto fieldArg = dynamic_cast<FieldNode*>(ra->arg_);
                auto fieldDecs = headerDecsMap.at(*fieldArg->headerName_->word_);
                bool found = false;

                for (FieldDecNode* fd : *fieldDecs) {
                    if (*fd->name_->word_ == *fieldArg->fieldName_->word_) {
                        argSizes.emplace_back(ra, stoi(*fd->size_->word_));
                        found = true;
                        break;
                    }
                }
                assert(found);
            } else if (typeContains(ra->arg_, "MblRefNode")) {
                // If it's a var ref, find it
                auto varRefArg = dynamic_cast<MblRefNode*>(ra->arg_);
                if (mblValues.find(*varRefArg->name_->word_) != mblValues.end()) {
                    auto size = mblValues.at(*varRefArg->name_->word_)->varWidth_->val_->word_;
                    argSizes.emplace_back(ra, stoi(*size));
                } else {
                    auto size = mblFields.at(*varRefArg->name_->word_)->varWidth_->val_->word_;
                    argSizes.emplace_back(ra, stoi(*size));
                }
            } else {
                assert(false && "Should never happen.");
            }
            break;
        case ReactionArgNode::REGISTER:
            // Not taken into account when bin-packing
            break;
        }
    }

    return argSizes;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x150, %rsp            # imm = 0x150
movq %rdi, -0xe8(%rbp)
movq %rdi, %rax
movq %rax, -0xe0(%rbp)
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movq %rdx, -0x18(%rbp)
movq %rcx, -0x20(%rbp)
movq %r8, -0x28(%rbp)
movb $0x0, -0x29(%rbp)
callq 0x128950
movq -0x10(%rbp), %rax
movq %rax, -0x38(%rbp)
movq -0x38(%rbp), %rdi
callq 0x127ae0
movq %rax, -0x40(%rbp)
movq -0x38(%rbp), %rdi
callq 0x127b10
movq %rax, -0x48(%rbp)
leaq -0x40(%rbp), %rdi
leaq -0x48(%rbp), %rsi
callq 0x127b40
testb $0x1, %al
jne 0x12e131
jmp 0x12e564
leaq -0x40(%rbp), %rdi
callq 0x127b80
movq (%rax), %rax
movq %rax, -0x50(%rbp)
movq -0x50(%rbp), %rax
movl 0x3c(%rax), %eax
movl %eax, -0xec(%rbp)
subl $0x4, %eax
jb 0x12e169
jmp 0x12e155
movl -0xec(%rbp), %eax
subl $0x4, %eax
je 0x12e552
jmp 0x12e554
movq -0x50(%rbp), %rax
movq 0x40(%rax), %rdi
leaq 0xe084(%rip), %rsi      # 0x13c1fc
callq 0x12c730
movb %al, -0xed(%rbp)
jmp 0x12e185
movb -0xed(%rbp), %al
testb $0x1, %al
jne 0x12e194
jmp 0x12e342
movq -0x50(%rbp), %rax
movq 0x40(%rax), %rax
movq %rax, -0xf8(%rbp)
cmpq $0x0, %rax
je 0x12e1ed
movq -0xf8(%rbp), %rdi
leaq 0x44429(%rip), %rsi     # 0x1725e0
leaq 0x45192(%rip), %rdx     # 0x173350
xorl %eax, %eax
movl %eax, %ecx
callq 0xaa660
movq %rax, -0x100(%rbp)
jmp 0x12e1f8
movq -0xe8(%rbp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x58(%rbp)
movl %eax, -0x5c(%rbp)
callq 0xd09b0
jmp 0x12e58a
xorl %eax, %eax
movq %rax, -0x100(%rbp)
jmp 0x12e1f8
movq -0x100(%rbp), %rax
movq %rax, -0x68(%rbp)
movq -0x18(%rbp), %rdi
movq -0x68(%rbp), %rax
movq 0x40(%rax), %rax
movq 0x40(%rax), %rsi
callq 0x12fd50
movq %rax, -0x108(%rbp)
jmp 0x12e221
movq -0x108(%rbp), %rax
movq (%rax), %rax
movq %rax, -0x70(%rbp)
movb $0x0, -0x71(%rbp)
movq -0x70(%rbp), %rax
movq %rax, -0x80(%rbp)
movq -0x80(%rbp), %rdi
callq 0xb5470
movq %rax, -0x88(%rbp)
movq -0x80(%rbp), %rdi
callq 0xb5300
movq %rax, -0x90(%rbp)
leaq -0x88(%rbp), %rdi
leaq -0x90(%rbp), %rsi
callq 0xc0940
testb $0x1, %al
jne 0x12e277
jmp 0x12e316
leaq -0x88(%rbp), %rdi
callq 0xc0980
movq (%rax), %rax
movq %rax, -0x98(%rbp)
movq -0x98(%rbp), %rax
movq 0x40(%rax), %rax
movq 0x40(%rax), %rdi
movq -0x68(%rbp), %rax
movq 0x48(%rax), %rax
movq 0x40(%rax), %rsi
callq 0xfef60
testb $0x1, %al
jne 0x12e2b3
jmp 0x12e303
movq -0x98(%rbp), %rax
movq 0x48(%rax), %rax
movq 0x40(%rax), %rdi
xorl %eax, %eax
movl %eax, %esi
movl $0xa, %edx
callq 0xbff90
movl %eax, -0x10c(%rbp)
jmp 0x12e2d8
movq -0xe8(%rbp), %rdi
movl -0x10c(%rbp), %eax
movl %eax, -0x9c(%rbp)
leaq -0x50(%rbp), %rsi
leaq -0x9c(%rbp), %rdx
callq 0x12fd80
jmp 0x12e2fd
movb $0x1, -0x71(%rbp)
jmp 0x12e316
jmp 0x12e305
leaq -0x88(%rbp), %rdi
callq 0xc09a0
jmp 0x12e25b
testb $0x1, -0x71(%rbp)
je 0x12e31e
jmp 0x12e33d
leaq 0xb87c(%rip), %rdi      # 0x139ba1
leaq 0x103ad(%rip), %rsi     # 0x13e6d9
movl $0x111, %edx            # imm = 0x111
leaq 0x103bc(%rip), %rcx     # 0x13e6f4
callq 0xaa3d0
jmp 0x12e550
movq -0x50(%rbp), %rax
movq 0x40(%rax), %rdi
leaq 0xbacf(%rip), %rsi      # 0x139e20
callq 0x12c730
movb %al, -0x10d(%rbp)
jmp 0x12e35e
movb -0x10d(%rbp), %al
testb $0x1, %al
jne 0x12e36d
jmp 0x12e52f
movq -0x50(%rbp), %rax
movq 0x40(%rax), %rax
movq %rax, -0x118(%rbp)
cmpq $0x0, %rax
je 0x12e3a9
movq -0x118(%rbp), %rdi
leaq 0x44250(%rip), %rsi     # 0x1725e0
leaq 0x45091(%rip), %rdx     # 0x173428
xorl %eax, %eax
movl %eax, %ecx
callq 0xaa660
movq %rax, -0x120(%rbp)
jmp 0x12e3b4
xorl %eax, %eax
movq %rax, -0x120(%rbp)
jmp 0x12e3b4
movq -0x120(%rbp), %rax
movq %rax, -0xa8(%rbp)
movq -0x20(%rbp), %rdi
movq -0xa8(%rbp), %rax
movq 0x80(%rax), %rax
movq 0x40(%rax), %rsi
callq 0x127890
movq %rax, -0x128(%rbp)
jmp 0x12e3e6
movq -0x128(%rbp), %rax
movq %rax, -0xb0(%rbp)
movq -0x20(%rbp), %rdi
callq 0x1278c0
movq %rax, -0xb8(%rbp)
leaq -0xb0(%rbp), %rdi
leaq -0xb8(%rbp), %rsi
callq 0x127860
testb $0x1, %al
jne 0x12e420
jmp 0x12e4a8
movq -0x20(%rbp), %rdi
movq -0xa8(%rbp), %rax
movq 0x80(%rax), %rax
movq 0x40(%rax), %rsi
callq 0x12fe00
movq %rax, -0x130(%rbp)
jmp 0x12e444
movq -0x130(%rbp), %rax
movq (%rax), %rax
movq 0x48(%rax), %rax
movq 0x40(%rax), %rax
movq 0x40(%rax), %rax
movq %rax, -0xc0(%rbp)
movq -0xc0(%rbp), %rdi
xorl %eax, %eax
movl %eax, %esi
movl $0xa, %edx
callq 0xbff90
movl %eax, -0x134(%rbp)
jmp 0x12e47e
movq -0xe8(%rbp), %rdi
movl -0x134(%rbp), %eax
movl %eax, -0xc4(%rbp)
leaq -0x50(%rbp), %rsi
leaq -0xc4(%rbp), %rdx
callq 0x12fd80
jmp 0x12e4a3
jmp 0x12e52d
movq -0x28(%rbp), %rdi
movq -0xa8(%rbp), %rax
movq 0x80(%rax), %rax
movq 0x40(%rax), %rsi
callq 0x12fe30
movq %rax, -0x140(%rbp)
jmp 0x12e4cc
movq -0x140(%rbp), %rax
movq (%rax), %rax
movq 0x48(%rax), %rax
movq 0x40(%rax), %rax
movq 0x40(%rax), %rax
movq %rax, -0xd0(%rbp)
movq -0xd0(%rbp), %rdi
xorl %eax, %eax
movl %eax, %esi
movl $0xa, %edx
callq 0xbff90
movl %eax, -0x144(%rbp)
jmp 0x12e506
movq -0xe8(%rbp), %rdi
movl -0x144(%rbp), %eax
movl %eax, -0xd4(%rbp)
leaq -0x50(%rbp), %rsi
leaq -0xd4(%rbp), %rdx
callq 0x12fd80
jmp 0x12e52b
jmp 0x12e52d
jmp 0x12e54e
leaq 0x102a5(%rip), %rdi     # 0x13e7db
leaq 0x1019c(%rip), %rsi     # 0x13e6d9
movl $0x11d, %edx            # imm = 0x11D
leaq 0x101ab(%rip), %rcx     # 0x13e6f4
callq 0xaa3d0
jmp 0x12e550
jmp 0x12e554
jmp 0x12e554
jmp 0x12e556
leaq -0x40(%rbp), %rdi
callq 0x127ba0
jmp 0x12e11b
movb $0x1, -0x29(%rbp)
testb $0x1, -0x29(%rbp)
jne 0x12e57a
movq -0xe8(%rbp), %rdi
callq 0xd09b0
movq -0xe0(%rbp), %rax
addq $0x150, %rsp            # imm = 0x150
popq %rbp
retq
movq -0x58(%rbp), %rdi
callq 0xaaa60
nopw %cs:(%rax,%rax)