// File: /workspace/github_cpp_makefile_star2_O2/eniac[P]Mantis/src/compile/compile_p4.cpp
// Function: generateInitTableForIng(std::unordered_map<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>, int, 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, int>>>*, std::vector<AstNode*, std::allocator<AstNode*>>*, 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&, int, bool)
int generateInitTableForIng(unordered_map<string, int>* mblUsages,
                               vector<AstNode*>* newNodes,
                               const unordered_map<string,
                                                   P4RMalleableValueNode*>& mblValues,
                               const unordered_map<string,
                                                   P4RMalleableFieldNode*>& mblFields,
                               int iso_opt, bool forIng) {

    // As the set of mbls in practice is small, currently a monolithic init for ing or egr
    ostringstream oss;
    string p4rInitActionName;
    string p4rSetVarTblName;
    string p4rMetadataName;
    
    if(forIng) {
        p4rInitActionName = string(kP4rIngInitAction);
        p4rSetVarTblName = "__tiSetVars";
        p4rMetadataName = string(kP4rIngMetadataName);
    } else {
        p4rInitActionName = string(kP4rEgrInitAction);
        p4rSetVarTblName = "__teSetVars";
        p4rMetadataName = string(kP4rEgrMetadataName);
    }

    oss << "action " << p4rInitActionName << "(";
    bool first = true;
    bool has_var = false;
    int num_vars = 0;
    for (auto kv : mblValues) {
        if(forIng && mblUsages->at(kv.first)==USAGE::EGRESS) {
            continue;
        } 
        if(!forIng && mblUsages->at(kv.first)==USAGE::INGRESS) {
            continue;
        }  
        if (first) {
            first = false;
        } else {
            oss << ", ";
        }
        has_var = true;
        oss << "p__" << kv.first;
        num_vars += 1;
    }
    for (auto kv : mblFields) {
        if(forIng && mblUsages->at(kv.first)==USAGE::EGRESS) {
            continue;
        } 
        if(!forIng && mblUsages->at(kv.first)==USAGE::INGRESS) {
            continue;
        }         
        if (first) {
            first = false;
        } else {
            oss << ", ";
        }
        has_var = true;
        oss << "p__" << kv.first << kP4rIndexSuffix;
        num_vars += 1;
    }

    if(has_var && iso_opt != 0) {
        oss << ", ";
    }

    if(iso_opt == 1) {
        oss << "__mv";
        num_vars += 1;
    } else if(iso_opt == 2) {
        oss << "__vv";
        num_vars += 1;
    } else if (iso_opt == 3) {
        oss << "__mv , __vv";
        num_vars += 2;
    }
    if(forIng) {
        PRINT_VERBOSE("Number of ing vars to set in init: %d\n", num_vars);
    } else {
        PRINT_VERBOSE("Number of egr vars to set in init: %d\n", num_vars);
    }

    oss << ") {\n";

    for (auto kv : mblValues) {
        if(forIng && mblUsages->at(kv.first)==USAGE::EGRESS) {
            continue;
        } 
        if(!forIng && mblUsages->at(kv.first)==USAGE::INGRESS) {
            continue;
        }        
        oss << "  modify_field(" << p4rMetadataName << "." << kv.first
                                << ", p__" << kv.first << ");\n";
    }

    for (auto kv : mblFields) {
        if(forIng && mblUsages->at(kv.first)==USAGE::EGRESS) {
            continue;
        } 
        if(!forIng && mblUsages->at(kv.first)==USAGE::INGRESS) {
            continue;
        }         
        oss << "  modify_field(" << p4rMetadataName << "."
                                << kv.first << kP4rIndexSuffix
                                << ", p__" << kv.first << kP4rIndexSuffix
                                << ");\n";
    }

    if(((unsigned int)iso_opt) & 0b1) {
        oss << "  modify_field(" << p4rMetadataName << "."
                                << "__mv, __mv"
                                << ");\n";
    } 
    if (((unsigned int)iso_opt) & 0b10) {
        oss << "  modify_field(" << p4rMetadataName << "."
                                << "__vv, __vv"
                                << ");\n";
    } 

    // pragma stage 0 not required due to the match dependency of later tables matching on __vv, __mv, field_alt
    oss << "}\n\n"
        << "table "
        << p4rSetVarTblName
        << " {\n"
        << "  actions {\n"
        << "    " << p4rInitActionName << ";\n"
        << "  }\n"
        << "  size : 1;\n"
        << "}\n\n";

    string* codeStr = new string(oss.str());
    string* objType = new string("table");
    string* tableName = new string(p4rSetVarTblName);

    newNodes->push_back(new UnanchoredNode(codeStr, objType, tableName));

    return num_vars;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x228, %rsp            # imm = 0x228
movl %r9d, %r14d
movl %r8d, %r13d
movq %rcx, %rbx
movq %rdx, %r15
movq %rsi, %r12
movq %rdi, -0x40(%rbp)
leaq -0x250(%rbp), %rdi
callq 0x415a0
leaq -0xc8(%rbp), %rax
movq %rax, -0x10(%rax)
andq $0x0, -0x8(%rax)
xorl %ecx, %ecx
leaq -0xa8(%rbp), %rdx
movq %rdx, -0x10(%rdx)
andq $0x0, -0x8(%rdx)
leaq -0x80(%rbp), %rsi
movq %rsi, -0x10(%rsi)
andq $0x0, -0x8(%rsi)
movb %cl, (%rax)
movb %cl, (%rdx)
movb %cl, (%rsi)
movl %r14d, -0x38(%rbp)
testl %r14d, %r14d
je 0x70292
leaq 0xab0f(%rip), %rsi      # 0x7ad50
leaq -0x70(%rbp), %rdi
leaq -0x29(%rbp), %rdx
callq 0x411c0
leaq -0xd8(%rbp), %rdi
leaq -0x70(%rbp), %r14
movq %r14, %rsi
callq 0x41500
movq %r14, %rdi
callq 0x418c8
leaq 0xcbed(%rip), %rsi      # 0x7ce5d
leaq -0xb8(%rbp), %rdi
callq 0x41850
leaq 0xa958(%rip), %rsi      # 0x7abdb
leaq -0x70(%rbp), %rdi
leaq -0x29(%rbp), %rdx
callq 0x411c0
jmp 0x702e8
leaq 0xab0c(%rip), %rsi      # 0x7ada5
leaq -0x70(%rbp), %rdi
leaq -0x29(%rbp), %rdx
callq 0x411c0
leaq -0xd8(%rbp), %rdi
leaq -0x70(%rbp), %r14
movq %r14, %rsi
callq 0x41500
movq %r14, %rdi
callq 0x418c8
leaq 0xcba1(%rip), %rsi      # 0x7ce69
leaq -0xb8(%rbp), %rdi
callq 0x41850
leaq 0xa91e(%rip), %rsi      # 0x7abf9
leaq -0x70(%rbp), %rdi
leaq -0x29(%rbp), %rdx
callq 0x411c0
leaq -0x90(%rbp), %rdi
movq %r14, %rsi
callq 0x41500
movq %r14, %rdi
callq 0x418c8
leaq 0x8f8d(%rip), %rsi      # 0x79293
leaq -0x250(%rbp), %rdi
callq 0x413d0
leaq -0xd8(%rbp), %rsi
movq %rax, %rdi
callq 0x41380
leaq 0xc929(%rip), %rsi      # 0x7cc51
movq %rax, %rdi
callq 0x413d0
movl %r13d, -0x44(%rbp)
movq %r12, -0x98(%rbp)
addq $0x10, %r15
movb $0x1, %al
movl %eax, -0x34(%rbp)
movl $0x0, -0x30(%rbp)
movq %r15, %r13
xorl %r12d, %r12d
movq (%r13), %r13
testq %r13, %r13
je 0x703e7
leaq 0x8(%r13), %rsi
movq %r14, %rdi
callq 0x4f432
cmpb $0x0, -0x38(%rbp)
je 0x70383
movq -0x40(%rbp), %rdi
movq %r14, %rsi
callq 0x69226
cmpl $0x1, (%rax)
jne 0x70394
jmp 0x703da
movq -0x40(%rbp), %rdi
movq %r14, %rsi
callq 0x69226
cmpl $0x0, (%rax)
je 0x703da
testb $0x1, -0x34(%rbp)
je 0x703a3
movl $0x0, -0x34(%rbp)
jmp 0x703b6
leaq -0x250(%rbp), %rdi
leaq 0xabae(%rip), %rsi      # 0x7af5f
callq 0x413d0
leaq -0x250(%rbp), %rdi
leaq 0xcacf(%rip), %rsi      # 0x7ce93
callq 0x413d0
movq %rax, %rdi
movq %r14, %rsi
callq 0x41380
incl -0x30(%rbp)
movb $0x1, %r12b
movq %r14, %rdi
callq 0x418c8
jmp 0x70351
addq $0x10, %rbx
leaq -0x70(%rbp), %r14
movq %rbx, %r13
movq (%r13), %r13
testq %r13, %r13
je 0x70497
leaq 0x8(%r13), %rsi
movq %r14, %rdi
callq 0x4f6a2
cmpb $0x0, -0x38(%rbp)
je 0x70424
movq -0x40(%rbp), %rdi
movq %r14, %rsi
callq 0x69226
cmpl $0x1, (%rax)
jne 0x70435
jmp 0x7048a
movq -0x40(%rbp), %rdi
movq %r14, %rsi
callq 0x69226
cmpl $0x0, (%rax)
je 0x7048a
testb $0x1, -0x34(%rbp)
je 0x70444
movl $0x0, -0x34(%rbp)
jmp 0x70457
leaq -0x250(%rbp), %rdi
leaq 0xab0d(%rip), %rsi      # 0x7af5f
callq 0x413d0
leaq -0x250(%rbp), %rdi
leaq 0xca2e(%rip), %rsi      # 0x7ce93
callq 0x413d0
movq %rax, %rdi
movq %r14, %rsi
callq 0x41380
movq %rax, %rdi
leaq 0xaa9f(%rip), %rsi      # 0x7af1e
callq 0x413d0
incl -0x30(%rbp)
movb $0x1, %r12b
movq %r14, %rdi
callq 0x418c8
jmp 0x703f2
movl -0x44(%rbp), %r13d
testl %r13d, %r13d
setne %al
testb %r12b, %al
je 0x704b9
leaq 0xaab2(%rip), %rsi      # 0x7af5f
leaq -0x250(%rbp), %rdi
callq 0x413d0
cmpl $0x3, %r13d
je 0x704f8
cmpl $0x2, %r13d
je 0x704e0
cmpl $0x1, %r13d
jne 0x7050f
leaq 0xc9cb(%rip), %rsi      # 0x7ce9d
leaq -0x250(%rbp), %rdi
callq 0x413d0
jmp 0x704f3
leaq 0xc995(%rip), %rsi      # 0x7ce7c
leaq -0x250(%rbp), %rdi
callq 0x413d0
incl -0x30(%rbp)
jmp 0x7050f
leaq 0xc976(%rip), %rsi      # 0x7ce75
leaq -0x250(%rbp), %rdi
callq 0x413d0
addl $0x2, -0x30(%rbp)
leaq 0xc748(%rip), %rsi      # 0x7cc5e
leaq -0x250(%rbp), %rdi
callq 0x413d0
leaq -0x70(%rbp), %r14
leaq 0xc954(%rip), %r12      # 0x7ce81
movq (%r15), %r15
testq %r15, %r15
je 0x705dd
leaq 0x8(%r15), %rsi
movq %r14, %rdi
callq 0x4f432
cmpb $0x0, -0x38(%rbp)
je 0x7055e
movq -0x40(%rbp), %rdi
movq %r14, %rsi
callq 0x69226
cmpl $0x1, (%rax)
jne 0x7056f
jmp 0x705d0
movq -0x40(%rbp), %rdi
movq %r14, %rsi
callq 0x69226
cmpl $0x0, (%rax)
je 0x705d0
leaq -0x250(%rbp), %rdi
movq %r12, %rsi
callq 0x413d0
movq %rax, %rdi
leaq -0x90(%rbp), %rsi
callq 0x41380
movq %rax, %rdi
leaq 0xa372(%rip), %rsi      # 0x7a909
callq 0x413d0
movq %rax, %rdi
movq %r14, %rsi
callq 0x41380
movq %rax, %rdi
leaq 0xc8e0(%rip), %rsi      # 0x7ce91
callq 0x413d0
movq %rax, %rdi
movq %r14, %rsi
callq 0x41380
movq %rax, %rdi
leaq 0x8839(%rip), %rsi      # 0x78e04
callq 0x413d0
movq %r14, %rdi
callq 0x418c8
jmp 0x7052d
leaq -0x70(%rbp), %r15
leaq 0xc899(%rip), %r12      # 0x7ce81
leaq 0xa92f(%rip), %r14      # 0x7af1e
movq (%rbx), %rbx
testq %rbx, %rbx
je 0x706b8
leaq 0x8(%rbx), %rsi
movq %r15, %rdi
callq 0x4f6a2
cmpb $0x0, -0x38(%rbp)
je 0x70623
movq -0x40(%rbp), %rdi
movq %r15, %rsi
callq 0x69226
cmpl $0x1, (%rax)
jne 0x70634
jmp 0x706ab
movq -0x40(%rbp), %rdi
movq %r15, %rsi
callq 0x69226
cmpl $0x0, (%rax)
je 0x706ab
leaq -0x250(%rbp), %rdi
movq %r12, %rsi
callq 0x413d0
movq %rax, %rdi
leaq -0x90(%rbp), %rsi
callq 0x41380
movq %rax, %rdi
leaq 0xa2ad(%rip), %rsi      # 0x7a909
callq 0x413d0
movq %rax, %rdi
movq %r15, %rsi
callq 0x41380
movq %rax, %rdi
movq %r14, %rsi
callq 0x413d0
movq %rax, %rdi
leaq 0xc810(%rip), %rsi      # 0x7ce91
callq 0x413d0
movq %rax, %rdi
movq %r15, %rsi
callq 0x41380
movq %rax, %rdi
movq %r14, %rsi
callq 0x413d0
movq %rax, %rdi
leaq 0x875e(%rip), %rsi      # 0x78e04
callq 0x413d0
movq %r15, %rdi
callq 0x418c8
jmp 0x705ef
testb $0x1, %r13b
je 0x7070d
leaq 0xc7bc(%rip), %rsi      # 0x7ce81
leaq -0x250(%rbp), %rdi
callq 0x413d0
leaq -0x90(%rbp), %rsi
movq %rax, %rdi
callq 0x41380
leaq 0xa222(%rip), %rsi      # 0x7a909
movq %rax, %rdi
callq 0x413d0
leaq 0xc7a1(%rip), %rsi      # 0x7ce97
movq %rax, %rdi
callq 0x413d0
leaq 0x86ff(%rip), %rsi      # 0x78e04
movq %rax, %rdi
callq 0x413d0
testb $0x2, %r13b
je 0x70762
leaq 0xc767(%rip), %rsi      # 0x7ce81
leaq -0x250(%rbp), %rdi
callq 0x413d0
leaq -0x90(%rbp), %rsi
movq %rax, %rdi
callq 0x41380
leaq 0xa1cd(%rip), %rsi      # 0x7a909
movq %rax, %rdi
callq 0x413d0
leaq 0xc757(%rip), %rsi      # 0x7cea2
movq %rax, %rdi
callq 0x413d0
leaq 0x86aa(%rip), %rsi      # 0x78e04
movq %rax, %rdi
callq 0x413d0
leaq 0xc9b4(%rip), %rsi      # 0x7d11d
leaq -0x250(%rbp), %rdi
callq 0x413d0
leaq 0x862a(%rip), %rsi      # 0x78da6
movq %rax, %rdi
callq 0x413d0
leaq -0xb8(%rbp), %rsi
movq %rax, %rdi
callq 0x41380
leaq 0xc4c5(%rip), %rsi      # 0x7cc5f
movq %rax, %rdi
callq 0x413d0
leaq 0x860f(%rip), %rsi      # 0x78db8
movq %rax, %rdi
callq 0x413d0
leaq 0x85d6(%rip), %rsi      # 0x78d8e
movq %rax, %rdi
callq 0x413d0
leaq -0xd8(%rbp), %rsi
movq %rax, %rdi
callq 0x41380
leaq 0x862f(%rip), %rsi      # 0x78e05
movq %rax, %rdi
callq 0x413d0
leaq 0x9bb1(%rip), %rsi      # 0x7a396
movq %rax, %rdi
callq 0x413d0
leaq 0xc6b9(%rip), %rsi      # 0x7cead
movq %rax, %rdi
callq 0x413d0
leaq 0xc91a(%rip), %rsi      # 0x7d11d
movq %rax, %rdi
callq 0x413d0
pushq $0x20
popq %rdi
callq 0x413f0
movq %rax, %r14
leaq -0x248(%rbp), %rsi
movq %rax, %rdi
callq 0x416b0
pushq $0x20
popq %rdi
callq 0x413f0
movq %rax, %r15
leaq 0xc55a(%rip), %rsi      # 0x7cd91
leaq -0x70(%rbp), %rdx
movq %rax, %rdi
callq 0x411c0
pushq $0x20
popq %rdi
callq 0x413f0
movq %rax, %r12
leaq -0xb8(%rbp), %rsi
movq %rax, %rdi
callq 0x415b0
pushq $0x58
popq %rdi
callq 0x413f0
movq %rax, %r13
movq %rax, %rdi
movq %r14, %rsi
movq %r15, %rdx
movq %r12, %rcx
callq 0x4dd8e
leaq -0x70(%rbp), %rsi
movq %r13, (%rsi)
movq -0x98(%rbp), %rdi
callq 0x44d46
leaq -0x90(%rbp), %rdi
callq 0x418c8
leaq -0xb8(%rbp), %rdi
callq 0x418c8
leaq -0xd8(%rbp), %rdi
callq 0x418c8
leaq -0x250(%rbp), %rdi
callq 0x410e0
movl -0x30(%rbp), %eax
addq $0x228, %rsp            # imm = 0x228
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
jmp 0x70910
jmp 0x70910
jmp 0x70910
jmp 0x70910
movq %rax, %rbx
movq %r13, %rdi
jmp 0x708fb
movq %rax, %rbx
movq %r12, %rdi
jmp 0x708fb
jmp 0x70910
movq %rax, %rbx
movq %r15, %rdi
jmp 0x708fb
jmp 0x70910
movq %rax, %rbx
movq %r14, %rdi
callq 0x413a0
jmp 0x70927
jmp 0x70910
jmp 0x70910
jmp 0x70910
jmp 0x70910
jmp 0x70910
jmp 0x70910
jmp 0x70910
movq %rax, %rbx
jmp 0x70927
jmp 0x7091b
jmp 0x7091b
jmp 0x7091b
movq %rax, %rbx
leaq -0x70(%rbp), %rdi
callq 0x418c8
leaq -0x90(%rbp), %rdi
callq 0x418c8
leaq -0xb8(%rbp), %rdi
callq 0x418c8
leaq -0xd8(%rbp), %rdi
callq 0x418c8
leaq -0x250(%rbp), %rdi
callq 0x410e0
movq %rbx, %rdi
callq 0x41790