// File: eniac[P]Mantis/src/compile/compile_p4.cpp
// Function: generateMetadata(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, int)
void generateMetadata(vector<AstNode*>* newNodes,
                      const unordered_map<string,
                                          P4RMalleableValueNode*>& mblValues,
                      const unordered_map<string,
                                          P4RMalleableFieldNode*>& mblFields,
                      int ing_iso_opt, int egr_iso_opt) {
    ostringstream oss;
    // Ing
    oss << "header_type "<< kP4rIngMetadataType << " {\n"
        << "  fields {\n";
    if (((unsigned int)ing_iso_opt) & 0b1) {
        oss << "  __mv : 1;\n";
    } 
    if (((unsigned int)ing_iso_opt) & 0b10) {
        oss << "  __vv : 1;\n";        
    }

    // Presume malleables at ing
    for (auto kv : mblValues){
        // Values need to be as wide as specified
        VarWidthNode* widthNode =
                dynamic_cast<VarWidthNode*>(kv.second->varWidth_);
        string varWidth = widthNode->val_->toString();
        oss << "  " << kv.first << " : " << varWidth << ";" << endl;
    }
    for (auto kv : mblFields){
        // Ref-vars only need to be wide enough to store an index
        auto alts = findAllAlts(*kv.second);
        int indexWidth = 1;
        if(alts.size()!=1) {
            indexWidth = int(ceil(log2(alts.size())));
        }
        oss << "  " << kv.first << kP4rIndexSuffix << " : "
            << indexWidth << ";" << endl;
    }

    oss << " }" << endl;
    oss << "}" << endl;
    oss << "metadata " << kP4rIngMetadataType << " "
                       << kP4rIngMetadataName << ";\n\n";

    newNodes->push_back(new UnanchoredNode(new string(oss.str()),
                                           new string("metadata"),
                                           new string(kP4rIngMetadataName)));
    // Egr
    oss.str("");
    oss << "header_type "<< kP4rEgrMetadataType << " {\n"
        << "  fields {\n";
    if (((unsigned int)egr_iso_opt) & 0b1) {
        oss << "  __mv : 1;\n";
    }

    oss << "  }" << endl;
    oss << "}" << endl;
    oss << "metadata " << kP4rEgrMetadataType << " "
                       << kP4rEgrMetadataName << ";\n\n";

    newNodes->push_back(new UnanchoredNode(new string(oss.str()),
                                           new string("metadata"),
                                           new string(kP4rEgrMetadataName)));    
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x430, %rsp            # imm = 0x430
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movq %rdx, -0x18(%rbp)
movl %ecx, -0x1c(%rbp)
movl %r8d, -0x20(%rbp)
leaq -0x198(%rbp), %rdi
movq %rdi, -0x2c8(%rbp)
callq 0xaa7b0
movq -0x2c8(%rbp), %rdi
leaq 0x169e6(%rip), %rsi     # 0x139df5
callq 0xaa540
movq %rax, -0x2c0(%rbp)
jmp 0x12341d
movq -0x2c0(%rbp), %rdi
leaq 0x1ad2e(%rip), %rsi     # 0x13e159
callq 0xaa540
movq %rax, -0x2d0(%rbp)
jmp 0x123439
movq -0x2d0(%rbp), %rdi
leaq 0x1ab50(%rip), %rsi     # 0x13df97
callq 0xaa540
movq %rax, -0x2d8(%rbp)
jmp 0x123455
movq -0x2d8(%rbp), %rdi
leaq 0x1699f(%rip), %rsi     # 0x139e02
callq 0xaa540
jmp 0x12346a
movl -0x1c(%rbp), %eax
andl $0x1, %eax
cmpl $0x0, %eax
je 0x1234a3
leaq 0x1acec(%rip), %rsi     # 0x13e168
leaq -0x198(%rbp), %rdi
callq 0xaa540
jmp 0x12348a
jmp 0x1234a3
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x1a0(%rbp)
movl %eax, -0x1a4(%rbp)
jmp 0x123fa7
movl -0x1c(%rbp), %eax
andl $0x2, %eax
cmpl $0x0, %eax
je 0x1234c5
leaq 0x1acc0(%rip), %rsi     # 0x13e175
leaq -0x198(%rbp), %rdi
callq 0xaa540
jmp 0x1234c3
jmp 0x1234c5
movq -0x10(%rbp), %rax
movq %rax, -0x1b0(%rbp)
movq -0x1b0(%rbp), %rdi
callq 0x127e60
movq %rax, -0x1b8(%rbp)
movq -0x1b0(%rbp), %rdi
callq 0x1278c0
movq %rax, -0x1c0(%rbp)
leaq -0x1b8(%rbp), %rdi
leaq -0x1c0(%rbp), %rsi
callq 0x127860
testb $0x1, %al
jne 0x123512
jmp 0x12366a
leaq -0x1b8(%rbp), %rdi
callq 0x127e90
movq %rax, %rsi
leaq -0x1e8(%rbp), %rdi
callq 0xcf880
jmp 0x12352f
movq -0x1c8(%rbp), %rax
movq 0x48(%rax), %rax
movq %rax, -0x1f0(%rbp)
movq -0x1f0(%rbp), %rax
movq 0x40(%rax), %rsi
movq (%rsi), %rax
movq (%rax), %rax
leaq -0x210(%rbp), %rdi
callq *%rax
jmp 0x12355d
leaq 0x18dd4(%rip), %rsi     # 0x13c338
leaq -0x198(%rbp), %rdi
callq 0xaa540
movq %rax, -0x2e0(%rbp)
jmp 0x123579
movq -0x2e0(%rbp), %rdi
leaq -0x1e8(%rbp), %rsi
callq 0xaa4c0
movq %rax, -0x2e8(%rbp)
jmp 0x123595
movq -0x2e8(%rbp), %rdi
leaq 0x1ab61(%rip), %rsi     # 0x13e104
callq 0xaa540
movq %rax, -0x2f0(%rbp)
jmp 0x1235b1
movq -0x2f0(%rbp), %rdi
leaq -0x210(%rbp), %rsi
callq 0xaa4c0
movq %rax, -0x2f8(%rbp)
jmp 0x1235cd
movq -0x2f8(%rbp), %rdi
leaq 0x1741a(%rip), %rsi     # 0x13a9f5
callq 0xaa540
movq %rax, -0x300(%rbp)
jmp 0x1235e9
movq -0x300(%rbp), %rdi
movq 0x50971(%rip), %rsi     # 0x173f68
callq 0xaa5b0
jmp 0x1235fe
leaq -0x210(%rbp), %rdi
callq 0xaabe8
leaq -0x1e8(%rbp), %rdi
callq 0xcd9c0
leaq -0x1b8(%rbp), %rdi
callq 0x127ec0
jmp 0x1234f6
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x1a0(%rbp)
movl %eax, -0x1a4(%rbp)
jmp 0x123659
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x1a0(%rbp)
movl %eax, -0x1a4(%rbp)
leaq -0x210(%rbp), %rdi
callq 0xaabe8
leaq -0x1e8(%rbp), %rdi
callq 0xcd9c0
jmp 0x123fa7
movq -0x18(%rbp), %rax
movq %rax, -0x218(%rbp)
movq -0x218(%rbp), %rdi
callq 0x127ef0
movq %rax, -0x220(%rbp)
movq -0x218(%rbp), %rdi
callq 0x127950
movq %rax, -0x228(%rbp)
leaq -0x220(%rbp), %rdi
leaq -0x228(%rbp), %rsi
callq 0x1278f0
testb $0x1, %al
jne 0x1236b7
jmp 0x12386c
leaq -0x220(%rbp), %rdi
callq 0x127f20
movq %rax, %rsi
leaq -0x250(%rbp), %rdi
callq 0xd01f0
jmp 0x1236d4
movq -0x230(%rbp), %rsi
leaq -0x268(%rbp), %rdi
callq 0x12d7e0
jmp 0x1236e9
movl $0x1, -0x26c(%rbp)
leaq -0x268(%rbp), %rdi
callq 0xb7cd0
cmpq $0x1, %rax
je 0x123776
leaq -0x268(%rbp), %rdi
callq 0xb7cd0
movq %rax, %rdi
callq 0x127f50
movsd %xmm0, -0x308(%rbp)
jmp 0x123723
movsd -0x308(%rbp), %xmm0
callq 0xaa0c0
cvttsd2si %xmm0, %eax
movl %eax, -0x26c(%rbp)
jmp 0x123776
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x1a0(%rbp)
movl %eax, -0x1a4(%rbp)
jmp 0x12385b
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x1a0(%rbp)
movl %eax, -0x1a4(%rbp)
leaq -0x268(%rbp), %rdi
callq 0x127f90
jmp 0x12385b
leaq 0x18bbb(%rip), %rsi     # 0x13c338
leaq -0x198(%rbp), %rdi
callq 0xaa540
movq %rax, -0x310(%rbp)
jmp 0x123792
movq -0x310(%rbp), %rdi
leaq -0x250(%rbp), %rsi
callq 0xaa4c0
movq %rax, -0x318(%rbp)
jmp 0x1237ae
movq -0x318(%rbp), %rdi
leaq 0x18a4a(%rip), %rsi     # 0x13c206
callq 0xaa540
movq %rax, -0x320(%rbp)
jmp 0x1237ca
movq -0x320(%rbp), %rdi
leaq 0x1a92c(%rip), %rsi     # 0x13e104
callq 0xaa540
movq %rax, -0x328(%rbp)
jmp 0x1237e6
movq -0x328(%rbp), %rdi
movl -0x26c(%rbp), %esi
callq 0xaaa20
movq %rax, -0x330(%rbp)
jmp 0x123801
movq -0x330(%rbp), %rdi
leaq 0x171e6(%rip), %rsi     # 0x13a9f5
callq 0xaa540
movq %rax, -0x338(%rbp)
jmp 0x12381d
movq -0x338(%rbp), %rdi
movq 0x5073d(%rip), %rsi     # 0x173f68
callq 0xaa5b0
jmp 0x123832
leaq -0x268(%rbp), %rdi
callq 0x127f90
leaq -0x250(%rbp), %rdi
callq 0xcdfe0
leaq -0x220(%rbp), %rdi
callq 0x127ff0
jmp 0x12369b
leaq -0x250(%rbp), %rdi
callq 0xcdfe0
jmp 0x123fa7
leaq 0x1a91f(%rip), %rsi     # 0x13e192
leaq -0x198(%rbp), %rdi
callq 0xaa540
movq %rax, -0x340(%rbp)
jmp 0x123888
movq -0x340(%rbp), %rdi
movq 0x506d2(%rip), %rsi     # 0x173f68
callq 0xaa5b0
jmp 0x12389d
leaq 0x186f4(%rip), %rsi     # 0x13bf98
leaq -0x198(%rbp), %rdi
callq 0xaa540
movq %rax, -0x348(%rbp)
jmp 0x1238b9
movq -0x348(%rbp), %rdi
movq 0x506a1(%rip), %rsi     # 0x173f68
callq 0xaa5b0
jmp 0x1238ce
leaq 0x16541(%rip), %rsi     # 0x139e16
leaq -0x198(%rbp), %rdi
callq 0xaa540
movq %rax, -0x350(%rbp)
jmp 0x1238ea
movq -0x350(%rbp), %rdi
leaq 0x1a861(%rip), %rsi     # 0x13e159
callq 0xaa540
movq %rax, -0x358(%rbp)
jmp 0x123906
movq -0x358(%rbp), %rdi
leaq 0x18a25(%rip), %rsi     # 0x13c339
callq 0xaa540
movq %rax, -0x360(%rbp)
jmp 0x123922
movq -0x360(%rbp), %rdi
leaq 0x18593(%rip), %rsi     # 0x13bec3
callq 0xaa540
movq %rax, -0x368(%rbp)
jmp 0x12393e
movq -0x368(%rbp), %rdi
leaq 0x17b50(%rip), %rsi     # 0x13b49c
callq 0xaa540
jmp 0x123953
movq -0x8(%rbp), %rax
movq %rax, -0x378(%rbp)
movl $0x58, %edi
callq 0xaa560
movq %rax, -0x370(%rbp)
jmp 0x123971
movb $0x1, -0x27d(%rbp)
movl $0x20, %edi
callq 0xaa560
movq %rax, -0x380(%rbp)
jmp 0x12398b
movq -0x380(%rbp), %rdi
leaq -0x198(%rbp), %rsi
callq 0xaa580
jmp 0x1239a0
movl $0x20, %edi
callq 0xaa560
movq %rax, -0x388(%rbp)
jmp 0x1239b3
movb $0x1, -0x27a(%rbp)
leaq -0x279(%rbp), %rdi
movq %rdi, -0x390(%rbp)
callq 0xaaa70
movq -0x388(%rbp), %rdi
movq -0x390(%rbp), %rdx
leaq 0x1a726(%rip), %rsi     # 0x13e108
callq 0xaa7d0
jmp 0x1239e9
movb $0x0, -0x27a(%rbp)
movl $0x20, %edi
callq 0xaa560
movq %rax, -0x398(%rbp)
jmp 0x123a03
movb $0x1, -0x27c(%rbp)
leaq -0x27b(%rbp), %rdi
movq %rdi, -0x3a0(%rbp)
callq 0xaaa70
movq -0x398(%rbp), %rdi
movq -0x3a0(%rbp), %rdx
leaq 0x18491(%rip), %rsi     # 0x13bec3
callq 0xaa7d0
jmp 0x123a39
movq -0x398(%rbp), %rcx
movq -0x388(%rbp), %rdx
movq -0x380(%rbp), %rsi
movq -0x370(%rbp), %rdi
movb $0x0, -0x27c(%rbp)
callq 0xcaee0
jmp 0x123a63
movq -0x378(%rbp), %rdi
movq -0x370(%rbp), %rax
movb $0x0, -0x27d(%rbp)
movq %rax, -0x278(%rbp)
leaq -0x278(%rbp), %rsi
callq 0xb2540
jmp 0x123a8d
leaq -0x27b(%rbp), %rdi
callq 0xaa5f0
leaq -0x279(%rbp), %rdi
callq 0xaa5f0
leaq -0x2a1(%rbp), %rdi
movq %rdi, -0x3a8(%rbp)
callq 0xaaa70
movq -0x3a8(%rbp), %rdx
leaq 0x180dd(%rip), %rsi     # 0x13bba3
leaq -0x2a0(%rbp), %rdi
callq 0xaa7d0
jmp 0x123ad4
leaq -0x198(%rbp), %rdi
leaq -0x2a0(%rbp), %rsi
callq 0xaa2c0
jmp 0x123ae9
leaq -0x2a0(%rbp), %rdi
callq 0xaabe8
leaq -0x2a1(%rbp), %rdi
callq 0xaa5f0
leaq 0x162ed(%rip), %rsi     # 0x139df5
leaq -0x198(%rbp), %rdi
callq 0xaa540
movq %rax, -0x3b0(%rbp)
jmp 0x123b1d
movq -0x3b0(%rbp), %rdi
leaq 0x1a657(%rip), %rsi     # 0x13e182
callq 0xaa540
movq %rax, -0x3b8(%rbp)
jmp 0x123b39
movq -0x3b8(%rbp), %rdi
leaq 0x1a450(%rip), %rsi     # 0x13df97
callq 0xaa540
movq %rax, -0x3c0(%rbp)
jmp 0x123b55
movq -0x3c0(%rbp), %rdi
leaq 0x1629f(%rip), %rsi     # 0x139e02
callq 0xaa540
jmp 0x123b6a
movl -0x20(%rbp), %eax
andl $0x1, %eax
cmpl $0x0, %eax
je 0x123c99
leaq 0x1a5e8(%rip), %rsi     # 0x13e168
leaq -0x198(%rbp), %rdi
callq 0xaa540
jmp 0x123b8e
jmp 0x123c99
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x1a0(%rbp)
movl %eax, -0x1a4(%rbp)
jmp 0x123c3a
movq -0x380(%rbp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x1a0(%rbp)
movl %eax, -0x1a4(%rbp)
callq 0xaa4e0
jmp 0x123c3a
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x1a0(%rbp)
movl %eax, -0x1a4(%rbp)
jmp 0x123c15
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x1a0(%rbp)
movl %eax, -0x1a4(%rbp)
leaq -0x27b(%rbp), %rdi
callq 0xaa5f0
testb $0x1, -0x27c(%rbp)
jne 0x123c07
jmp 0x123c13
movq -0x398(%rbp), %rdi
callq 0xaa4e0
jmp 0x123c15
leaq -0x279(%rbp), %rdi
callq 0xaa5f0
testb $0x1, -0x27a(%rbp)
jne 0x123c2c
jmp 0x123c38
movq -0x388(%rbp), %rdi
callq 0xaa4e0
jmp 0x123c3a
testb $0x1, -0x27d(%rbp)
jne 0x123c45
jmp 0x123c51
movq -0x370(%rbp), %rdi
callq 0xaa4e0
jmp 0x123fa7
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x1a0(%rbp)
movl %eax, -0x1a4(%rbp)
jmp 0x123c88
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x1a0(%rbp)
movl %eax, -0x1a4(%rbp)
leaq -0x2a0(%rbp), %rdi
callq 0xaabe8
leaq -0x2a1(%rbp), %rdi
callq 0xaa5f0
jmp 0x123fa7
leaq 0x1a4f1(%rip), %rsi     # 0x13e191
leaq -0x198(%rbp), %rdi
callq 0xaa540
movq %rax, -0x3c8(%rbp)
jmp 0x123cb5
movq -0x3c8(%rbp), %rdi
movq 0x502a5(%rip), %rsi     # 0x173f68
callq 0xaa5b0
jmp 0x123cca
leaq 0x182c7(%rip), %rsi     # 0x13bf98
leaq -0x198(%rbp), %rdi
callq 0xaa540
movq %rax, -0x3d0(%rbp)
jmp 0x123ce6
movq -0x3d0(%rbp), %rdi
movq 0x50274(%rip), %rsi     # 0x173f68
callq 0xaa5b0
jmp 0x123cfb
leaq 0x16114(%rip), %rsi     # 0x139e16
leaq -0x198(%rbp), %rdi
callq 0xaa540
movq %rax, -0x3d8(%rbp)
jmp 0x123d17
movq -0x3d8(%rbp), %rdi
leaq 0x1a45d(%rip), %rsi     # 0x13e182
callq 0xaa540
movq %rax, -0x3e0(%rbp)
jmp 0x123d33
movq -0x3e0(%rbp), %rdi
leaq 0x185f8(%rip), %rsi     # 0x13c339
callq 0xaa540
movq %rax, -0x3e8(%rbp)
jmp 0x123d4f
movq -0x3e8(%rbp), %rdi
leaq 0x18184(%rip), %rsi     # 0x13bee1
callq 0xaa540
movq %rax, -0x3f0(%rbp)
jmp 0x123d6b
movq -0x3f0(%rbp), %rdi
leaq 0x17723(%rip), %rsi     # 0x13b49c
callq 0xaa540
jmp 0x123d80
movq -0x8(%rbp), %rax
movq %rax, -0x400(%rbp)
movl $0x58, %edi
callq 0xaa560
movq %rax, -0x3f8(%rbp)
jmp 0x123d9e
movb $0x1, -0x2b5(%rbp)
movl $0x20, %edi
callq 0xaa560
movq %rax, -0x408(%rbp)
jmp 0x123db8
movq -0x408(%rbp), %rdi
leaq -0x198(%rbp), %rsi
callq 0xaa580
jmp 0x123dcd
movl $0x20, %edi
callq 0xaa560
movq %rax, -0x410(%rbp)
jmp 0x123de0
movb $0x1, -0x2b2(%rbp)
leaq -0x2b1(%rbp), %rdi
movq %rdi, -0x418(%rbp)
callq 0xaaa70
movq -0x410(%rbp), %rdi
movq -0x418(%rbp), %rdx
leaq 0x1a2f9(%rip), %rsi     # 0x13e108
callq 0xaa7d0
jmp 0x123e16
movb $0x0, -0x2b2(%rbp)
movl $0x20, %edi
callq 0xaa560
movq %rax, -0x420(%rbp)
jmp 0x123e30
movb $0x1, -0x2b4(%rbp)
leaq -0x2b3(%rbp), %rdi
movq %rdi, -0x428(%rbp)
callq 0xaaa70
movq -0x420(%rbp), %rdi
movq -0x428(%rbp), %rdx
leaq 0x18082(%rip), %rsi     # 0x13bee1
callq 0xaa7d0
jmp 0x123e66
movq -0x420(%rbp), %rcx
movq -0x410(%rbp), %rdx
movq -0x408(%rbp), %rsi
movq -0x3f8(%rbp), %rdi
movb $0x0, -0x2b4(%rbp)
callq 0xcaee0
jmp 0x123e90
movq -0x400(%rbp), %rdi
movq -0x3f8(%rbp), %rax
movb $0x0, -0x2b5(%rbp)
movq %rax, -0x2b0(%rbp)
leaq -0x2b0(%rbp), %rsi
callq 0xb2540
jmp 0x123eba
leaq -0x2b3(%rbp), %rdi
callq 0xaa5f0
leaq -0x2b1(%rbp), %rdi
callq 0xaa5f0
leaq -0x198(%rbp), %rdi
callq 0xaa130
addq $0x430, %rsp            # imm = 0x430
popq %rbp
retq
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x1a0(%rbp)
movl %eax, -0x1a4(%rbp)
jmp 0x123f8e
movq -0x408(%rbp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x1a0(%rbp)
movl %eax, -0x1a4(%rbp)
callq 0xaa4e0
jmp 0x123f8e
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x1a0(%rbp)
movl %eax, -0x1a4(%rbp)
jmp 0x123f69
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x1a0(%rbp)
movl %eax, -0x1a4(%rbp)
leaq -0x2b3(%rbp), %rdi
callq 0xaa5f0
testb $0x1, -0x2b4(%rbp)
jne 0x123f5b
jmp 0x123f67
movq -0x420(%rbp), %rdi
callq 0xaa4e0
jmp 0x123f69
leaq -0x2b1(%rbp), %rdi
callq 0xaa5f0
testb $0x1, -0x2b2(%rbp)
jne 0x123f80
jmp 0x123f8c
movq -0x410(%rbp), %rdi
callq 0xaa4e0
jmp 0x123f8e
testb $0x1, -0x2b5(%rbp)
jne 0x123f99
jmp 0x123fa5
movq -0x3f8(%rbp), %rdi
callq 0xaa4e0
jmp 0x123fa7
leaq -0x198(%rbp), %rdi
callq 0xaa130
movq -0x1a0(%rbp), %rdi
callq 0xaaa60
nop