// File: /workspace/github_cpp_makefile_star2_O2/eniac[P]Mantis/src/compile/compile_c.cpp
// Function: generateDialogueEnd(std::vector<AstNode*, std::allocator<AstNode*>>, std::__cxx11::basic_ostringstream<char, std::char_traits<char>, std::allocator<char>>&, int, int)
void generateDialogueEnd(std::vector<AstNode*> nodeArray, ostringstream& oss_reaction_update, int ing_iso_opt, int egr_iso_opt) {

    // __vv points to shallow copy under isolation, now update version bit commit together with other mbls)
    oss_reaction_update << "\n  __mantis__mod_vars_ing;\n";
    oss_reaction_update << "\n  __mantis__mod_vars_egr;\n";

    // Flip __vv to point to shallow copy
    if(((unsigned int)ing_iso_opt) & 0b10) {
        oss_reaction_update << "\n  __mantis__flip_vv_ing;\n\n";
    }
    if(((unsigned int)egr_iso_opt) & 0b10) {
        oss_reaction_update << "\n  __mantis__flip_vv_egr;\n\n";
    }

    // Under isolation, call mirror macros to mirror shallow copies for mbl table operations
    // Get the reaction string and find all user macros
    P4RReactionNode * react_node = findReaction(nodeArray);
    string p4r_reaction_user_str = "";
    if (react_node != 0) {
        p4r_reaction_user_str = react_node->body_->toString();
    }

    // No need to check isolation opt and ing/egr, just mirror user-specified operations in prepare
    for (auto node : nodeArray) {
        // For each mbl table
        if(typeContains(node, "P4RMalleableTableNode")) {
            TableNode* table = dynamic_cast<P4RMalleableTableNode*>(node)->table_;
            string table_name = *(table->name_->word_);

            TableActionStmtsNode* actions = table->actions_;

            // Mbl tables are always with With matches (at least match on __vv)
            // For each action
            for (TableActionStmtNode* tas : *actions->list_) {
                string action_name = *tas->name_->word_;

                string str_prepare_macro_func;
                string str_mirror_macro_func;

                std::smatch result;

                // Construct match regrex for add
                str_prepare_macro_func = table_name + "_add_" + action_name;
                std::regex e_add (str_prepare_macro_func+"\\s*\\("+"([^\\)]*)"+"\\)");   // matches words beginning by "sub"

                // Stop after first match
                while (std::regex_search (p4r_reaction_user_str, result, e_add)) {
                    
                    str_prepare_macro_func = result[0];
                    str_mirror_macro_func = "__mantis__mirror_" + str_prepare_macro_func;
                    // Call corresponding mirror macros
                    oss_reaction_update << "\n  "
                                        << str_mirror_macro_func
                                        << ";\n\n";

                    // Search remaining string of p4r_reaction_user_str
                    p4r_reaction_user_str = result.suffix().str();
                }
                // Mod
                str_prepare_macro_func = table_name + "_mod_" + action_name;
                std::regex e_mod (str_prepare_macro_func+"\\s*\\("+"([^\\)]*)"+"\\)");   // matches words beginning by "sub"
                while (std::regex_search (p4r_reaction_user_str, result, e_mod)) {
                    str_prepare_macro_func = result[0];
                    str_mirror_macro_func = "__mantis__mirror_" + str_prepare_macro_func;
                    oss_reaction_update << "\n  "
                                        << str_mirror_macro_func
                                        << ";\n\n";
                    p4r_reaction_user_str = result.suffix().str();
                }
                // Del
                str_prepare_macro_func = table_name + "_del_" + action_name;
                std::regex e_del (str_prepare_macro_func+"\\s*\\("+"([^\\)]*)"+"\\)");   // matches words beginning by "sub"
                while (std::regex_search (p4r_reaction_user_str, result, e_del)) {
                    str_prepare_macro_func = result[0];
                    str_mirror_macro_func = "__mantis__mirror_" + str_prepare_macro_func;
                    oss_reaction_update << "\n  "
                                        << str_mirror_macro_func
                                        << ";\n\n";
                    p4r_reaction_user_str = result.suffix().str();
                }
            }   
        }
    }

    // Point __vv back to working copy for next dialogue
    if(((unsigned int)ing_iso_opt) & 0b10) {
        oss_reaction_update << "\n  __mantis__flip_vv_ing;\n\n";
    }
    if(((unsigned int)egr_iso_opt) & 0b10) {
        oss_reaction_update << "\n  __mantis__flip_vv_egr;\n\n";
    }
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x1c8, %rsp            # imm = 0x1C8
movl %ecx, %r15d
movl %edx, %r12d
movq %rsi, %r14
movq %rdi, %rbx
leaq 0x225b7(%rip), %rsi     # 0x7a7f5
movq %r14, %rdi
callq 0x413d0
leaq 0x22620(%rip), %rsi     # 0x7a86d
movq %r14, -0x30(%rbp)
movq %r14, %rdi
callq 0x413d0
testb $0x2, %r12b
je 0x5826f
leaq 0x222f2(%rip), %rsi     # 0x7a558
movq -0x30(%rbp), %rdi
callq 0x413d0
testb $0x2, %r15b
je 0x58285
leaq 0x222f8(%rip), %rsi     # 0x7a574
movq -0x30(%rbp), %rdi
callq 0x413d0
leaq -0x1d0(%rbp), %r14
movq %r14, %rdi
movq %rbx, %rsi
callq 0x4486c
movq %r14, %rdi
callq 0x72600
movq %rax, %r14
leaq -0x1d0(%rbp), %rdi
callq 0x44be0
leaq 0x22606(%rip), %rsi     # 0x7a8bb
leaq -0xb8(%rbp), %rdi
leaq -0xd8(%rbp), %rdx
callq 0x411c0
testq %r14, %r14
je 0x582fb
movq 0x50(%r14), %rsi
movq (%rsi), %rax
leaq -0xd8(%rbp), %rdi
callq *(%rax)
leaq -0xb8(%rbp), %rdi
leaq -0xd8(%rbp), %r14
movq %r14, %rsi
callq 0x41500
movq %r14, %rdi
callq 0x418c8
movl %r12d, -0x58(%rbp)
movl %r15d, -0x54(%rbp)
movq (%rbx), %rax
movq 0x8(%rbx), %rcx
movq %rcx, -0xe0(%rbp)
leaq -0x1b8(%rbp), %r12
leaq -0x158(%rbp), %r13
leaq -0x178(%rbp), %r14
cmpq -0xe0(%rbp), %rax
je 0x58995
movq %rax, -0xe8(%rbp)
movq (%rax), %rbx
movq %rbx, %rdi
leaq 0x2287e(%rip), %rsi     # 0x7abc5
callq 0x71cf8
testb %al, %al
je 0x58985
movq %rbx, %rdi
leaq 0x3c332(%rip), %rsi     # 0x94690
leaq 0x3d0cb(%rip), %rdx     # 0x95430
xorl %ecx, %ecx
callq 0x41480
movq 0x40(%rax), %rbx
movq 0x40(%rbx), %rax
movq 0x40(%rax), %rsi
leaq -0xd8(%rbp), %rdi
callq 0x415b0
movq 0x50(%rbx), %rax
movq 0x40(%rax), %rax
movq (%rax), %rcx
movq 0x8(%rax), %rax
movq %rax, -0xf0(%rbp)
cmpq -0xf0(%rbp), %rcx
je 0x58979
movq %rcx, -0xf8(%rbp)
movq (%rcx), %rax
movq 0x40(%rax), %rax
movq 0x40(%rax), %rsi
leaq -0x138(%rbp), %rdi
callq 0x415b0
leaq -0x88(%rbp), %rax
movq %rax, -0x98(%rbp)
andq $0x0, -0x90(%rbp)
leaq -0x68(%rbp), %rax
movq %rax, -0x78(%rbp)
andq $0x0, -0x70(%rbp)
xorl %eax, %eax
movb %al, -0x88(%rbp)
movb %al, -0x68(%rbp)
xorps %xmm0, %xmm0
movaps %xmm0, -0x40(%rbp)
movaps %xmm0, -0x50(%rbp)
movq %r12, %rdi
leaq -0xd8(%rbp), %rsi
leaq 0x2262f(%rip), %rdx     # 0x7aa3e
callq 0x4df81
leaq -0x198(%rbp), %r15
movq %r15, %rdi
movq %r12, %rsi
leaq -0x138(%rbp), %rdx
callq 0x4df58
leaq -0x98(%rbp), %rbx
movq %rbx, %rdi
movq %r15, %rsi
callq 0x41500
movq %r15, %rdi
callq 0x418c8
movq %r12, %rdi
callq 0x418c8
movq %r13, %rdi
movq %rbx, %rsi
leaq 0x22be1(%rip), %rdx     # 0x7b03d
callq 0x4df81
movq %r14, %rdi
movq %r13, %rsi
leaq 0x22bd5(%rip), %rdx     # 0x7b043
callq 0x4ed31
movq %r12, %rdi
movq %r14, %rsi
leaq 0x22bcc(%rip), %rdx     # 0x7b04c
callq 0x4ed31
leaq -0x198(%rbp), %rdi
movq %r12, %rsi
pushq $0x10
popq %rdx
callq 0x58d60
movq %r12, %rdi
callq 0x418c8
movq %r14, %rdi
callq 0x418c8
movq %r13, %rdi
callq 0x418c8
leaq -0xb8(%rbp), %rbx
movq %rbx, %rdi
leaq -0x50(%rbp), %rsi
leaq -0x198(%rbp), %rdx
xorl %ecx, %ecx
callq 0x58e56
testb %al, %al
je 0x585b4
movq -0x50(%rbp), %rax
movq -0x48(%rbp), %rcx
movq %rcx, %rdx
subq %rax, %rdx
leaq -0x48(%rcx), %rdi
cmpq $0x48, %rdx
movq %rax, %rsi
cmoveq %rdi, %rsi
cmpq %rax, %rcx
cmoveq %rdi, %rsi
movq %r12, %rdi
callq 0x58f2c
leaq -0x98(%rbp), %rbx
movq %rbx, %rdi
movq %r12, %rsi
callq 0x41500
movq %r12, %rdi
callq 0x418c8
movq %r12, %rdi
leaq 0x22744(%rip), %rsi     # 0x7ac67
movq %rbx, %rdx
callq 0x58eb6
leaq -0x78(%rbp), %rdi
movq %r12, %rsi
callq 0x41500
movq %r12, %rdi
callq 0x418c8
movq -0x30(%rbp), %rdi
leaq 0x22b05(%rip), %rsi     # 0x7b04f
callq 0x413d0
movq %rax, %rdi
leaq -0x78(%rbp), %rsi
callq 0x41380
movq %rax, %rdi
leaq 0x21c4f(%rip), %rsi     # 0x7a1b4
callq 0x413d0
movq -0x48(%rbp), %rsi
movq %rsi, %rax
subq -0x50(%rbp), %rax
cqto
pushq $0x18
popq %rcx
idivq %rcx
cmpq $0x4, %rax
jb 0x58589
addq $-0x18, %rsi
jmp 0x5858d
addq $-0x48, %rsi
movq %r12, %rdi
callq 0x58f2c
leaq -0xb8(%rbp), %rbx
movq %rbx, %rdi
movq %r12, %rsi
callq 0x41500
movq %r12, %rdi
callq 0x418c8
jmp 0x584b6
movq %r14, %rdi
leaq -0xd8(%rbp), %rsi
leaq 0x22561(%rip), %rdx     # 0x7ab26
callq 0x4df81
movq %r12, %rdi
movq %r14, %rsi
leaq -0x138(%rbp), %rdx
callq 0x4df58
leaq -0x98(%rbp), %r15
movq %r15, %rdi
movq %r12, %rsi
callq 0x41500
movq %r12, %rdi
callq 0x418c8
movq %r14, %rdi
callq 0x418c8
leaq -0x118(%rbp), %rbx
movq %rbx, %rdi
movq %r15, %rsi
leaq 0x22a2b(%rip), %rdx     # 0x7b03d
callq 0x4df81
movq %r13, %rdi
movq %rbx, %rsi
leaq 0x22a1f(%rip), %rdx     # 0x7b043
callq 0x4ed31
movq %r14, %rdi
movq %r13, %rsi
leaq 0x22a16(%rip), %rdx     # 0x7b04c
callq 0x4ed31
movq %r12, %rdi
movq %r14, %rsi
pushq $0x10
popq %rdx
callq 0x58d60
movq %r14, %rdi
callq 0x418c8
movq %r13, %rdi
callq 0x418c8
leaq -0x118(%rbp), %rdi
callq 0x418c8
leaq -0xb8(%rbp), %rbx
movq %rbx, %rdi
leaq -0x50(%rbp), %rsi
movq %r12, %rdx
xorl %ecx, %ecx
callq 0x58e56
testb %al, %al
je 0x58766
movq -0x50(%rbp), %rax
movq -0x48(%rbp), %rcx
movq %rcx, %rdx
subq %rax, %rdx
leaq -0x48(%rcx), %rdi
cmpq $0x48, %rdx
movq %rax, %rsi
cmoveq %rdi, %rsi
cmpq %rax, %rcx
cmoveq %rdi, %rsi
movq %r14, %rdi
callq 0x58f2c
leaq -0x98(%rbp), %rbx
movq %rbx, %rdi
movq %r14, %rsi
callq 0x41500
movq %r14, %rdi
callq 0x418c8
movq %r14, %rdi
leaq 0x22592(%rip), %rsi     # 0x7ac67
movq %rbx, %rdx
callq 0x58eb6
leaq -0x78(%rbp), %rdi
movq %r14, %rsi
callq 0x41500
movq %r14, %rdi
callq 0x418c8
movq -0x30(%rbp), %rdi
leaq 0x22953(%rip), %rsi     # 0x7b04f
callq 0x413d0
movq %rax, %rdi
leaq -0x78(%rbp), %rsi
callq 0x41380
movq %rax, %rdi
leaq 0x21a9d(%rip), %rsi     # 0x7a1b4
callq 0x413d0
movq -0x48(%rbp), %rsi
movq %rsi, %rax
subq -0x50(%rbp), %rax
cqto
pushq $0x18
popq %rcx
idivq %rcx
cmpq $0x4, %rax
jb 0x5873b
addq $-0x18, %rsi
jmp 0x5873f
addq $-0x48, %rsi
movq %r14, %rdi
callq 0x58f2c
leaq -0xb8(%rbp), %rbx
movq %rbx, %rdi
movq %r14, %rsi
callq 0x41500
movq %r14, %rdi
callq 0x418c8
jmp 0x5866c
movq %r13, %rdi
leaq -0xd8(%rbp), %rsi
leaq 0x22336(%rip), %rdx     # 0x7aaad
callq 0x4df81
movq %r14, %rdi
movq %r13, %rsi
leaq -0x138(%rbp), %rdx
callq 0x4df58
leaq -0x98(%rbp), %rbx
movq %rbx, %rdi
movq %r14, %rsi
callq 0x41500
movq %r14, %rdi
callq 0x418c8
movq %r13, %rdi
callq 0x418c8
leaq -0x1f0(%rbp), %r15
movq %r15, %rdi
movq %rbx, %rsi
leaq 0x22879(%rip), %rdx     # 0x7b03d
callq 0x4df81
leaq -0x118(%rbp), %rbx
movq %rbx, %rdi
movq %r15, %rsi
leaq 0x22866(%rip), %rdx     # 0x7b043
callq 0x4ed31
movq %r13, %rdi
movq %rbx, %rsi
leaq 0x2285d(%rip), %rdx     # 0x7b04c
callq 0x4ed31
movq %r14, %rdi
movq %r13, %rsi
pushq $0x10
popq %rdx
callq 0x58d60
movq %r13, %rdi
callq 0x418c8
leaq -0x118(%rbp), %rdi
callq 0x418c8
leaq -0x1f0(%rbp), %rdi
callq 0x418c8
leaq -0xb8(%rbp), %rbx
movq %rbx, %rdi
leaq -0x50(%rbp), %rsi
movq %r14, %rdx
xorl %ecx, %ecx
callq 0x58e56
testb %al, %al
je 0x58923
movq -0x50(%rbp), %rax
movq -0x48(%rbp), %rcx
movq %rcx, %rdx
subq %rax, %rdx
leaq -0x48(%rcx), %rdi
cmpq $0x48, %rdx
movq %rax, %rsi
cmoveq %rdi, %rsi
cmpq %rax, %rcx
cmoveq %rdi, %rsi
movq %r13, %rdi
callq 0x58f2c
leaq -0x98(%rbp), %rbx
movq %rbx, %rdi
movq %r13, %rsi
callq 0x41500
movq %r13, %rdi
callq 0x418c8
movq %r13, %rdi
leaq 0x223d5(%rip), %rsi     # 0x7ac67
movq %rbx, %rdx
callq 0x58eb6
leaq -0x78(%rbp), %rdi
movq %r13, %rsi
callq 0x41500
movq %r13, %rdi
callq 0x418c8
movq -0x30(%rbp), %rdi
leaq 0x22796(%rip), %rsi     # 0x7b04f
callq 0x413d0
movq %rax, %rdi
leaq -0x78(%rbp), %rsi
callq 0x41380
movq %rax, %rdi
leaq 0x218e0(%rip), %rsi     # 0x7a1b4
callq 0x413d0
movq -0x48(%rbp), %rsi
movq %rsi, %rax
subq -0x50(%rbp), %rax
cqto
pushq $0x18
popq %rcx
idivq %rcx
cmpq $0x4, %rax
jb 0x588f8
addq $-0x18, %rsi
jmp 0x588fc
addq $-0x48, %rsi
movq %r13, %rdi
callq 0x58f2c
leaq -0xb8(%rbp), %rbx
movq %rbx, %rdi
movq %r13, %rsi
callq 0x41500
movq %r13, %rdi
callq 0x418c8
jmp 0x58829
movq %r14, %rdi
callq 0x58e18
movq %r12, %rdi
callq 0x58e18
leaq -0x198(%rbp), %rdi
callq 0x58e18
leaq -0x50(%rbp), %rdi
callq 0x59518
leaq -0x78(%rbp), %rdi
callq 0x418c8
leaq -0x98(%rbp), %rdi
callq 0x418c8
leaq -0x138(%rbp), %rdi
callq 0x418c8
movq -0xf8(%rbp), %rcx
addq $0x8, %rcx
jmp 0x5839a
leaq -0xd8(%rbp), %rdi
callq 0x418c8
movq -0xe8(%rbp), %rax
addq $0x8, %rax
jmp 0x58326
testb $0x2, -0x58(%rbp)
je 0x589ab
leaq 0x21bb6(%rip), %rsi     # 0x7a558
movq -0x30(%rbp), %rdi
callq 0x413d0
testb $0x2, -0x54(%rbp)
je 0x589c1
leaq 0x21bbc(%rip), %rsi     # 0x7a574
movq -0x30(%rbp), %rdi
callq 0x413d0
leaq -0xb8(%rbp), %rdi
callq 0x418c8
addq $0x1c8, %rsp            # imm = 0x1C8
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
jmp 0x58a01
jmp 0x58a01
movq %rax, %rbx
jmp 0x58b74
movq %rax, %rbx
leaq -0x1d0(%rbp), %rdi
callq 0x44be0
jmp 0x58b74
jmp 0x58a01
movq %rax, %rbx
jmp 0x58b68
movq %rax, %rbx
jmp 0x58a33
movq %rax, %rbx
jmp 0x58a27
jmp 0x58b12
movq %rax, %rbx
leaq -0x158(%rbp), %rdi
callq 0x418c8
leaq -0x118(%rbp), %rdi
callq 0x418c8
leaq -0x1f0(%rbp), %rdi
jmp 0x58a46
movq %rax, %rbx
leaq -0x158(%rbp), %rdi
callq 0x418c8
jmp 0x58b15
jmp 0x58b12
jmp 0x58b23
movq %rax, %rbx
jmp 0x58a7f
movq %rax, %rbx
jmp 0x58a73
movq %rax, %rbx
leaq -0x178(%rbp), %rdi
callq 0x418c8
leaq -0x158(%rbp), %rdi
callq 0x418c8
leaq -0x118(%rbp), %rdi
jmp 0x58a97
jmp 0x58b23
movq %rax, %rbx
leaq -0x178(%rbp), %rdi
callq 0x418c8
jmp 0x58b26
jmp 0x58ad9
movq %rax, %rbx
jmp 0x58ad0
movq %rax, %rbx
jmp 0x58ac4
movq %rax, %rbx
jmp 0x58b5c
movq %rax, %rbx
leaq -0x1b8(%rbp), %rdi
callq 0x418c8
leaq -0x178(%rbp), %rdi
callq 0x418c8
leaq -0x158(%rbp), %rdi
jmp 0x58ae8
movq %rax, %rbx
jmp 0x58b32
movq %rax, %rbx
leaq -0x1b8(%rbp), %rdi
callq 0x418c8
jmp 0x58b32
jmp 0x58b01
jmp 0x58b01
jmp 0x58b01
jmp 0x58b12
jmp 0x58b12
jmp 0x58b12
jmp 0x58b23
jmp 0x58b23
jmp 0x58b23
movq %rax, %rbx
leaq -0x178(%rbp), %rdi
callq 0x58e18
jmp 0x58b15
movq %rax, %rbx
leaq -0x1b8(%rbp), %rdi
callq 0x58e18
jmp 0x58b26
movq %rax, %rbx
leaq -0x198(%rbp), %rdi
callq 0x58e18
leaq -0x50(%rbp), %rdi
callq 0x59518
leaq -0x78(%rbp), %rdi
callq 0x418c8
leaq -0x98(%rbp), %rdi
callq 0x418c8
leaq -0x138(%rbp), %rdi
callq 0x418c8
leaq -0xd8(%rbp), %rdi
callq 0x418c8
leaq -0xb8(%rbp), %rdi
callq 0x418c8
movq %rbx, %rdi
callq 0x41790