// File: eniac[P]Mantis/src/compile/compile_p4.cpp
// Function: transformMalleableRefs(std::vector<MblRefNode*, std::allocator<MblRefNode*>>*, 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&, std::vector<AstNode*, std::allocator<AstNode*>>*)
void transformMalleableRefs(
            vector<MblRefNode*>* mblRefs,
            const unordered_map<string, P4RMalleableValueNode*>& mblValues,
            const unordered_map<string, P4RMalleableFieldNode*>& mblFields,
            vector<AstNode*>* nodeArray) {
    while (!mblRefs->empty()) {
        MblRefNode* varRef = mblRefs->front();
        mblRefs->erase(mblRefs->begin());

        if (varRef->transformed_) {
            // We must have processed this variable reference in a previous pass
            // e.g., multiple references in the same action
            continue;
        }

        string* varName = varRef->name_->word_;

        if (mblValues.find(*varName) != mblValues.end()) {
            // we should treat variable value references in reaction and others differently
            bool is_in_reaction = false;
            AstNode* parent = varRef->parent_;
            while (parent != NULL) {
                if (typeContains(parent, "P4RReactionNode")) {
                    is_in_reaction = true;
                    break;
                }
                parent = parent->parent_;
            }
            if (is_in_reaction) {
                // For c code, we skip the transformation
                varRef->inReaction_ = true;
            } else {
                // Otherwise, transform it to valid meta data
                varRef->transform(string(kP4rIngMetadataName), *varRef->name_->word_);
            }
        } else if (mblFields.find(*varName) != mblFields.end()) {
            // Reference to a variable field
            transformMalleableFieldRef(varRef, mblRefs, nodeArray,
                                      *mblFields.find(*varName)->second);
        } else {
            PANIC("Unknown malleable ref!");
        }
    }
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0xf0, %rsp
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movq %rdx, -0x18(%rbp)
movq %rcx, -0x20(%rbp)
movq -0x8(%rbp), %rdi
callq 0x127560
xorb $-0x1, %al
testb $0x1, %al
jne 0x11914f
jmp 0x1193d9
movq -0x8(%rbp), %rdi
callq 0x1275a0
movq (%rax), %rax
movq %rax, -0x28(%rbp)
movq -0x8(%rbp), %rax
movq %rax, -0xc0(%rbp)
movq -0x8(%rbp), %rdi
callq 0x127640
movq %rax, -0x38(%rbp)
leaq -0x30(%rbp), %rdi
leaq -0x38(%rbp), %rsi
callq 0x127670
movq -0xc0(%rbp), %rdi
movq -0x30(%rbp), %rsi
callq 0x1275d0
movq %rax, -0x40(%rbp)
movq -0x28(%rbp), %rax
testb $0x1, 0x39(%rax)
je 0x1191a4
jmp 0x11913b
movq -0x28(%rbp), %rax
movq 0x80(%rax), %rax
movq 0x40(%rax), %rax
movq %rax, -0x48(%rbp)
movq -0x10(%rbp), %rdi
movq -0x48(%rbp), %rsi
callq 0x127890
movq %rax, -0x50(%rbp)
movq -0x10(%rbp), %rdi
callq 0x1278c0
movq %rax, -0x58(%rbp)
leaq -0x50(%rbp), %rdi
leaq -0x58(%rbp), %rsi
callq 0x127860
testb $0x1, %al
jne 0x1191eb
jmp 0x1192ff
movb $0x0, -0x59(%rbp)
movq -0x28(%rbp), %rax
movq 0x30(%rax), %rax
movq %rax, -0x68(%rbp)
cmpq $0x0, -0x68(%rbp)
je 0x11922c
movq -0x68(%rbp), %rdi
leaq 0x24ccd(%rip), %rsi     # 0x13deda
callq 0x12c730
testb $0x1, %al
jne 0x119218
jmp 0x11921e
movb $0x1, -0x59(%rbp)
jmp 0x11922c
movq -0x68(%rbp), %rax
movq 0x30(%rax), %rax
movq %rax, -0x68(%rbp)
jmp 0x1191fb
testb $0x1, -0x59(%rbp)
je 0x11923f
movq -0x28(%rbp), %rax
movb $0x1, 0x3a(%rax)
jmp 0x1192fa
movq -0x28(%rbp), %rax
movq %rax, -0xd0(%rbp)
leaq -0x89(%rbp), %rdi
movq %rdi, -0xc8(%rbp)
callq 0xaaa70
movq -0xc8(%rbp), %rdx
leaq 0x22c58(%rip), %rsi     # 0x13bec3
leaq -0x88(%rbp), %rdi
callq 0xaa7d0
jmp 0x119279
movq -0xd0(%rbp), %rdi
movq -0x28(%rbp), %rax
movq 0x80(%rax), %rax
movq 0x40(%rax), %rdx
leaq -0x88(%rbp), %rsi
callq 0xcac20
jmp 0x11929d
leaq -0x88(%rbp), %rdi
callq 0xaabe8
leaq -0x89(%rbp), %rdi
callq 0xaa5f0
jmp 0x1192fa
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x98(%rbp)
movl %eax, -0x9c(%rbp)
jmp 0x1192e9
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x98(%rbp)
movl %eax, -0x9c(%rbp)
leaq -0x88(%rbp), %rdi
callq 0xaabe8
leaq -0x89(%rbp), %rdi
callq 0xaa5f0
jmp 0x1193e2
jmp 0x1193d4
movq -0x18(%rbp), %rdi
movq -0x48(%rbp), %rsi
callq 0x127920
movq %rax, -0xa8(%rbp)
movq -0x18(%rbp), %rdi
callq 0x127950
movq %rax, -0xb0(%rbp)
leaq -0xa8(%rbp), %rdi
leaq -0xb0(%rbp), %rsi
callq 0x1278f0
testb $0x1, %al
jne 0x11933c
jmp 0x11939d
movq -0x28(%rbp), %rax
movq %rax, -0xe8(%rbp)
movq -0x8(%rbp), %rax
movq %rax, -0xe0(%rbp)
movq -0x20(%rbp), %rax
movq %rax, -0xd8(%rbp)
movq -0x18(%rbp), %rdi
movq -0x48(%rbp), %rsi
callq 0x127920
movq %rax, -0xb8(%rbp)
leaq -0xb8(%rbp), %rdi
callq 0x127980
movq -0xe8(%rbp), %rdi
movq -0xe0(%rbp), %rsi
movq -0xd8(%rbp), %rdx
movq 0x20(%rax), %rcx
callq 0x1193f0
jmp 0x1193d2
movq 0x5ac0c(%rip), %rax     # 0x173fb0
movq (%rax), %rdi
leaq 0x24b3c(%rip), %rsi     # 0x13deea
leaq 0x249a2(%rip), %rdx     # 0x13dd57
movl $0x1dd, %ecx            # imm = 0x1DD
leaq 0x24b51(%rip), %r8      # 0x13df12
movb $0x0, %al
callq 0xaa850
movl $0x1, %edi
callq 0xaa6c0
jmp 0x1193d4
jmp 0x11913b
addq $0xf0, %rsp
popq %rbp
retq
movq -0x98(%rbp), %rdi
callq 0xaaa60
nop