// File: /workspace/github_cpp_makefile_star2_O3/eniac[P]Mantis/src/compile/compile.cpp
// Function: compileP4Code(std::vector<AstNode*, std::allocator<AstNode*>>*)
vector<AstNode*> compileP4Code(vector<AstNode*>* nodeArray) {

    ing_iso_opt = inferIsoOptForIng(nodeArray, true);
    egr_iso_opt = inferIsoOptForIng(nodeArray, false);

    transformPragma(nodeArray);

    findAndRemoveMalleables(&mblValues, &mblFields, &mblTables, *nodeArray);

    vector<MblRefNode*> mblRefs;
    findMalleableRefs(&mblRefs, *nodeArray);

    // Visitor pass to find the corresponding usage
    findMalleableUsage(mblRefs, mblValues, mblFields, nodeArray, &mblUsages);

    // Transform all references to mbls into references to the appropriate metadata
    transformMalleableRefs(&mblRefs, mblValues, mblFields, nodeArray);

    transformMalleableTables(&mblTables, *nodeArray, ing_iso_opt, egr_iso_opt);

    auto newNodes = vector<AstNode*>();

    generateMetadata(&newNodes, mblValues, mblFields, ing_iso_opt, egr_iso_opt);
    num_init_mbls_ing = generateInitTableForIng(&mblUsages, &newNodes, mblValues, mblFields, ing_iso_opt, true);
    num_init_mbls_egr = generateInitTableForIng(&mblUsages, &newNodes, mblValues, mblFields, egr_iso_opt, false);

    generateSetvarControl(&newNodes);

    // Measurement code
    HeaderDecsMap headerDecsMap = findHeaderDecs(*nodeArray);
    vector<ReactionArgNode*> reaction_args = findReactionArgs(*nodeArray);

    global_ing_bins = generateIngDigestPacking(&newNodes, reaction_args, headerDecsMap,
                    mblValues, mblFields, *nodeArray, &ing_iso_opt);
    global_egr_bins = generateEgrDigestPacking(&newNodes, reaction_args, headerDecsMap,
                    mblValues, mblFields, *nodeArray, &egr_iso_opt);    

    // After packing, iso_opt is firm
    augmentRegisterArgProgForIng(&newNodes, nodeArray, reaction_args, ing_iso_opt, true);   
    augmentRegisterArgProgForIng(&newNodes, nodeArray, reaction_args, egr_iso_opt, false);  

    generateDupRegArgProg(&newNodes, nodeArray, reaction_args, ing_iso_opt, egr_iso_opt);

    generateRegArgGateControl(&newNodes, nodeArray, reaction_args, ing_iso_opt, egr_iso_opt);

    generateExportControl(&newNodes, global_ing_bins, global_egr_bins);

    // Finally, assemble ingress/egress
    augmentIngress(nodeArray);
    augmentEgress(nodeArray); 

    return newNodes;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
pushq %r15
pushq %r14
pushq %rbx
subq $0x148, %rsp            # imm = 0x148
movq %rsi, %r14
movq %rdi, %rbx
movq %rsi, %rdi
movl $0x1, %esi
callq 0x63262
movl %eax, 0x50037(%rip)     # 0x8e434
movq %r14, %rdi
xorl %esi, %esi
callq 0x63262
movl %eax, 0x5002b(%rip)     # 0x8e438
movq %r14, %rdi
callq 0x631c8
leaq 0x505bc(%rip), %rdi     # 0x8e9d8
leaq 0x505ed(%rip), %rsi     # 0x8ea10
leaq 0x5061e(%rip), %rdx     # 0x8ea48
movq %r14, %rcx
callq 0x6ee24
xorps %xmm0, %xmm0
leaq -0x50(%rbp), %rdi
movaps %xmm0, (%rdi)
movq $0x0, 0x10(%rdi)
movq %r14, %rsi
callq 0x6ef6d
leaq -0xa0(%rbp), %rdi
leaq -0x50(%rbp), %rsi
callq 0x3f60e
xorl %eax, %eax
leaq -0x160(%rbp), %rdi
movq %rax, (%rdi)
leaq 0x50569(%rip), %rsi     # 0x8e9d8
movq 0x5056a(%rip), %rcx     # 0x8e9e0
movq %rcx, 0x8(%rdi)
movq %rax, 0x10(%rdi)
movq 0x5056b(%rip), %rcx     # 0x8e9f0
movq %rcx, 0x18(%rdi)
movups 0x50568(%rip), %xmm0    # 0x8e9f8
movups %xmm0, 0x20(%rdi)
movq %rax, 0x30(%rdi)
leaq -0xd8(%rbp), %rdx
movq %rdi, (%rdx)
callq 0x3fa44
xorl %eax, %eax
leaq -0x128(%rbp), %rdi
movq %rax, (%rdi)
leaq 0x50556(%rip), %rsi     # 0x8ea10
movq 0x50557(%rip), %rcx     # 0x8ea18
movq %rcx, 0x8(%rdi)
movq %rax, 0x10(%rdi)
movq 0x50558(%rip), %rcx     # 0x8ea28
movq %rcx, 0x18(%rdi)
movups 0x50555(%rip), %xmm0    # 0x8ea30
movups %xmm0, 0x20(%rdi)
movq %rax, 0x30(%rdi)
leaq -0xd8(%rbp), %rdx
movq %rdi, (%rdx)
callq 0x3fc0c
leaq 0x504a7(%rip), %r8      # 0x8e9a0
leaq -0xa0(%rbp), %rdi
leaq -0x160(%rbp), %rsi
leaq -0x128(%rbp), %rdx
movq %r14, %rcx
callq 0x63e2c
leaq -0x128(%rbp), %rdi
callq 0x3f85c
leaq -0x160(%rbp), %rdi
callq 0x3f7bc
movq -0xa0(%rbp), %rdi
testq %rdi, %rdi
je 0x3e53f
callq 0x2e360
leaq 0x50492(%rip), %rsi     # 0x8e9d8
leaq 0x504c3(%rip), %rdx     # 0x8ea10
leaq -0x50(%rbp), %rdi
movq %r14, %rcx
callq 0x64330
leaq -0x88(%rbp), %rdi
movq %r14, %rsi
callq 0x32ac0
movl 0x4fec6(%rip), %edx     # 0x8e434
movl 0x4fec4(%rip), %ecx     # 0x8e438
leaq 0x504cd(%rip), %rdi     # 0x8ea48
leaq -0x88(%rbp), %rsi
callq 0x64fe6
movq -0x88(%rbp), %rdi
testq %rdi, %rdi
je 0x3e598
callq 0x2e360
xorps %xmm0, %xmm0
movups %xmm0, (%rbx)
movq $0x0, 0x10(%rbx)
movl 0x4fe88(%rip), %ecx     # 0x8e434
movl 0x4fe85(%rip), %r8d     # 0x8e438
leaq 0x5041e(%rip), %rsi     # 0x8e9d8
leaq 0x5044f(%rip), %rdx     # 0x8ea10
movq %rbx, %rdi
callq 0x6c2ef
movl 0x4fe64(%rip), %r8d     # 0x8e434
leaq 0x503c9(%rip), %rdi     # 0x8e9a0
leaq 0x503fa(%rip), %rdx     # 0x8e9d8
leaq 0x5042b(%rip), %rcx     # 0x8ea10
movq %rbx, %rsi
movl $0x1, %r9d
callq 0x6cb6f
movl %eax, 0x4fe43(%rip)     # 0x8e43c
movl 0x4fe38(%rip), %r8d     # 0x8e438
leaq 0x50399(%rip), %rdi     # 0x8e9a0
leaq 0x503ca(%rip), %rdx     # 0x8e9d8
leaq 0x503fb(%rip), %rcx     # 0x8ea10
movq %rbx, %rsi
xorl %r9d, %r9d
callq 0x6cb6f
movl %eax, 0x4fe1a(%rip)     # 0x8e440
movq %rbx, %rdi
callq 0x6d678
leaq -0xd8(%rbp), %rdi
movq %r14, %rsi
callq 0x6f634
leaq -0x30(%rbp), %rdi
movq %r14, %rsi
callq 0x6f575
leaq 0x4fde4(%rip), %rax     # 0x8e434
leaq 0x50381(%rip), %r8      # 0x8e9d8
leaq 0x503b2(%rip), %r9      # 0x8ea10
leaq -0x70(%rbp), %rdi
leaq -0x30(%rbp), %rdx
leaq -0xd8(%rbp), %rcx
movq %rbx, %rsi
pushq %rax
pushq %r14
callq 0x694f3
addq $0x10, %rsp
movups 0x502ed(%rip), %xmm0    # 0x8e970
movq 0x502f6(%rip), %rax     # 0x8e980
leaq -0x70(%rbp), %r15
movaps (%r15), %xmm1
movups %xmm1, 0x502d7(%rip)    # 0x8e970
movq 0x10(%r15), %rcx
movq %rcx, 0x502dc(%rip)     # 0x8e980
leaq -0xf0(%rbp), %rdi
movups %xmm0, (%rdi)
movq %rax, 0x10(%rdi)
xorps %xmm0, %xmm0
movaps %xmm0, (%r15)
movq $0x0, 0x10(%r15)
callq 0x3f588
movq %r15, %rdi
callq 0x3f588
leaq 0x4fd63(%rip), %rax     # 0x8e438
leaq 0x502fc(%rip), %r8      # 0x8e9d8
leaq 0x5032d(%rip), %r9      # 0x8ea10
leaq -0x70(%rbp), %rdi
leaq -0x30(%rbp), %rdx
leaq -0xd8(%rbp), %rcx
movq %rbx, %rsi
pushq %rax
pushq %r14
callq 0x6c0ad
addq $0x10, %rsp
movups 0x50280(%rip), %xmm0    # 0x8e988
movq 0x50289(%rip), %rax     # 0x8e998
movaps (%r15), %xmm1
movups %xmm1, 0x5026e(%rip)    # 0x8e988
movq 0x10(%r15), %rcx
movq %rcx, 0x50273(%rip)     # 0x8e998
leaq -0xf0(%rbp), %rdi
movups %xmm0, (%rdi)
movq %rax, 0x10(%rdi)
xorps %xmm0, %xmm0
movaps %xmm0, (%r15)
movq $0x0, 0x10(%r15)
callq 0x3f588
movq %r15, %rdi
callq 0x3f588
movl 0x4fcdf(%rip), %ecx     # 0x8e434
leaq -0x30(%rbp), %rdx
movq %rbx, %rdi
movq %r14, %rsi
movl $0x1, %r8d
callq 0x67f9d
movl 0x4fcc8(%rip), %ecx     # 0x8e438
leaq -0x30(%rbp), %rdx
movq %rbx, %rdi
movq %r14, %rsi
xorl %r8d, %r8d
callq 0x67f9d
movl 0x4fcac(%rip), %ecx     # 0x8e434
movl 0x4fca9(%rip), %r8d     # 0x8e438
leaq -0x30(%rbp), %rdx
movq %rbx, %rdi
movq %r14, %rsi
callq 0x65f58
movl 0x4fc90(%rip), %ecx     # 0x8e434
movl 0x4fc8d(%rip), %r8d     # 0x8e438
leaq -0x30(%rbp), %rdx
movq %rbx, %rdi
movq %r14, %rsi
callq 0x657a4
leaq 0x501af(%rip), %rsi     # 0x8e970
leaq 0x501c0(%rip), %rdx     # 0x8e988
movq %rbx, %rdi
callq 0x65320
movq %r14, %rdi
callq 0x6384c
movq %r14, %rdi
callq 0x63b3c
movq -0x30(%rbp), %rdi
testq %rdi, %rdi
je 0x3e7ee
callq 0x2e360
leaq -0xd8(%rbp), %rdi
callq 0x3fdb6
movq -0x50(%rbp), %rdi
testq %rdi, %rdi
je 0x3e808
callq 0x2e360
movq %rbx, %rax
addq $0x148, %rsp            # imm = 0x148
popq %rbx
popq %r14
popq %r15
popq %rbp
retq
jmp 0x3e872
jmp 0x3e872
movq %rax, %r14
jmp 0x3e883
jmp 0x3e868
movq %rax, %r14
movq -0x88(%rbp), %rdi
testq %rdi, %rdi
je 0x3e89c
jmp 0x3e897
movq %rax, %r14
leaq -0x128(%rbp), %rdi
callq 0x3f85c
jmp 0x3e849
movq %rax, %r14
leaq -0x160(%rbp), %rdi
callq 0x3f7bc
jmp 0x3e85a
movq %rax, %r14
movq -0xa0(%rbp), %rdi
testq %rdi, %rdi
je 0x3e89c
jmp 0x3e897
movq %rax, %r14
jmp 0x3e88f
movq %rax, %r14
jmp 0x3e89c
movq %rax, %r14
movq -0x30(%rbp), %rdi
testq %rdi, %rdi
je 0x3e883
callq 0x2e360
leaq -0xd8(%rbp), %rdi
callq 0x3fdb6
movq (%rbx), %rdi
testq %rdi, %rdi
je 0x3e89c
callq 0x2e360
movq -0x50(%rbp), %rdi
testq %rdi, %rdi
je 0x3e8aa
callq 0x2e360
movq %r14, %rdi
callq 0x2e730