// File: /workspace/github_cpp_makefile_star2_O1/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 0x637f2
movl %eax, 0x4fbef(%rip)     # 0x8e434
movq %r14, %rdi
xorl %esi, %esi
callq 0x637f2
movl %eax, 0x4fbe3(%rip)     # 0x8e438
movq %r14, %rdi
callq 0x63758
leaq 0x50174(%rip), %rdi     # 0x8e9d8
leaq 0x501a5(%rip), %rsi     # 0x8ea10
leaq 0x501d6(%rip), %rdx     # 0x8ea48
movq %r14, %rcx
callq 0x6f874
xorps %xmm0, %xmm0
leaq -0x50(%rbp), %rdi
movaps %xmm0, (%rdi)
movq $0x0, 0x10(%rdi)
movq %r14, %rsi
callq 0x6f9bd
leaq -0x98(%rbp), %rdi
leaq -0x50(%rbp), %rsi
callq 0x3fa4c
xorl %eax, %eax
leaq -0x160(%rbp), %rdi
movq %rax, (%rdi)
leaq 0x50121(%rip), %rsi     # 0x8e9d8
movq 0x50122(%rip), %rcx     # 0x8e9e0
movq %rcx, 0x8(%rdi)
movq %rax, 0x10(%rdi)
movq 0x50123(%rip), %rcx     # 0x8e9f0
movq %rcx, 0x18(%rdi)
movups 0x50120(%rip), %xmm0    # 0x8e9f8
movups %xmm0, 0x20(%rdi)
movq %rax, 0x30(%rdi)
leaq -0xd0(%rbp), %rdx
movq %rdi, (%rdx)
callq 0x3fe82
xorl %eax, %eax
leaq -0x128(%rbp), %rdi
movq %rax, (%rdi)
leaq 0x5010e(%rip), %rsi     # 0x8ea10
movq 0x5010f(%rip), %rcx     # 0x8ea18
movq %rcx, 0x8(%rdi)
movq %rax, 0x10(%rdi)
movq 0x50110(%rip), %rcx     # 0x8ea28
movq %rcx, 0x18(%rdi)
movups 0x5010d(%rip), %xmm0    # 0x8ea30
movups %xmm0, 0x20(%rdi)
movq %rax, 0x30(%rdi)
leaq -0xd0(%rbp), %rdx
movq %rdi, (%rdx)
callq 0x40050
leaq 0x5005f(%rip), %r8      # 0x8e9a0
leaq -0x98(%rbp), %rdi
leaq -0x160(%rbp), %rsi
leaq -0x128(%rbp), %rdx
movq %r14, %rcx
callq 0x643e1
leaq -0x128(%rbp), %rdi
callq 0x3fc9a
leaq -0x160(%rbp), %rdi
callq 0x3fbfa
movq -0x98(%rbp), %rdi
testq %rdi, %rdi
je 0x3e987
callq 0x2e360
leaq 0x5004a(%rip), %rsi     # 0x8e9d8
leaq 0x5007b(%rip), %rdx     # 0x8ea10
leaq -0x50(%rbp), %rdi
movq %r14, %rcx
callq 0x648f1
leaq -0x80(%rbp), %rdi
movq %r14, %rsi
callq 0x32d96
movl 0x4fa81(%rip), %edx     # 0x8e434
movl 0x4fa7f(%rip), %ecx     # 0x8e438
leaq 0x50088(%rip), %rdi     # 0x8ea48
leaq -0x80(%rbp), %rsi
callq 0x655d9
movq -0x80(%rbp), %rdi
testq %rdi, %rdi
je 0x3e9d7
callq 0x2e360
xorps %xmm0, %xmm0
movups %xmm0, (%rbx)
movq $0x0, 0x10(%rbx)
movl 0x4fa49(%rip), %ecx     # 0x8e434
movl 0x4fa46(%rip), %r8d     # 0x8e438
leaq 0x4ffdf(%rip), %rsi     # 0x8e9d8
leaq 0x50010(%rip), %rdx     # 0x8ea10
movq %rbx, %rdi
callq 0x6cc1d
movl 0x4fa25(%rip), %r8d     # 0x8e434
leaq 0x4ff8a(%rip), %rdi     # 0x8e9a0
leaq 0x4ffbb(%rip), %rdx     # 0x8e9d8
leaq 0x4ffec(%rip), %rcx     # 0x8ea10
movq %rbx, %rsi
movl $0x1, %r9d
callq 0x6d519
movl %eax, 0x4fa04(%rip)     # 0x8e43c
movl 0x4f9f9(%rip), %r8d     # 0x8e438
leaq 0x4ff5a(%rip), %rdi     # 0x8e9a0
leaq 0x4ff8b(%rip), %rdx     # 0x8e9d8
leaq 0x4ffbc(%rip), %rcx     # 0x8ea10
movq %rbx, %rsi
xorl %r9d, %r9d
callq 0x6d519
movl %eax, 0x4f9db(%rip)     # 0x8e440
movq %rbx, %rdi
callq 0x6e029
leaq -0xd0(%rbp), %rdi
movq %r14, %rsi
callq 0x700cf
leaq -0x30(%rbp), %rdi
movq %r14, %rsi
callq 0x70010
leaq 0x4f9a5(%rip), %rax     # 0x8e434
leaq 0x4ff42(%rip), %r8      # 0x8e9d8
leaq 0x4ff73(%rip), %r9      # 0x8ea10
leaq -0x68(%rbp), %rdi
leaq -0x30(%rbp), %rdx
leaq -0xd0(%rbp), %rcx
movq %rbx, %rsi
pushq %rax
pushq %r14
callq 0x69d41
addq $0x10, %rsp
xorps %xmm0, %xmm0
leaq -0xf0(%rbp), %rdi
movaps %xmm0, (%rdi)
movups 0x4fea1(%rip), %xmm0    # 0x8e970
movq 0x4feaa(%rip), %rax     # 0x8e980
leaq -0x68(%rbp), %r15
movups (%r15), %xmm1
movups %xmm1, 0x4fe8b(%rip)    # 0x8e970
movq 0x10(%r15), %rcx
movq %rcx, 0x4fe90(%rip)     # 0x8e980
movaps (%rdi), %xmm1
movaps %xmm0, (%rdi)
movq %rax, 0x10(%rdi)
movups %xmm1, (%r15)
movq $0x0, 0x10(%r15)
callq 0x3f9d0
movq %r15, %rdi
callq 0x3f9d0
leaq 0x4f91e(%rip), %rax     # 0x8e438
leaq 0x4feb7(%rip), %r8      # 0x8e9d8
leaq 0x4fee8(%rip), %r9      # 0x8ea10
leaq -0x68(%rbp), %rdi
leaq -0x30(%rbp), %rdx
leaq -0xd0(%rbp), %rcx
movq %rbx, %rsi
pushq %rax
pushq %r14
callq 0x6c9d0
addq $0x10, %rsp
leaq -0xf0(%rbp), %rdi
xorps %xmm0, %xmm0
movaps %xmm0, (%rdi)
movups 0x4fe2e(%rip), %xmm0    # 0x8e988
movq 0x4fe37(%rip), %rax     # 0x8e998
movups (%r15), %xmm1
movups %xmm1, 0x4fe1c(%rip)    # 0x8e988
movq 0x10(%r15), %rcx
movq %rcx, 0x4fe21(%rip)     # 0x8e998
movaps (%rdi), %xmm1
movaps %xmm0, (%rdi)
movq %rax, 0x10(%rdi)
movups %xmm1, (%r15)
movq $0x0, 0x10(%r15)
callq 0x3f9d0
movq %r15, %rdi
callq 0x3f9d0
movl 0x4f894(%rip), %ecx     # 0x8e434
leaq -0x30(%rbp), %rdx
movq %rbx, %rdi
movq %r14, %rsi
movl $0x1, %r8d
callq 0x68780
movl 0x4f87d(%rip), %ecx     # 0x8e438
leaq -0x30(%rbp), %rdx
movq %rbx, %rdi
movq %r14, %rsi
xorl %r8d, %r8d
callq 0x68780
movl 0x4f861(%rip), %ecx     # 0x8e434
movl 0x4f85e(%rip), %r8d     # 0x8e438
leaq -0x30(%rbp), %rdx
movq %rbx, %rdi
movq %r14, %rsi
callq 0x666e9
movl 0x4f845(%rip), %ecx     # 0x8e434
movl 0x4f842(%rip), %r8d     # 0x8e438
leaq -0x30(%rbp), %rdx
movq %rbx, %rdi
movq %r14, %rsi
callq 0x65e94
leaq 0x4fd64(%rip), %rsi     # 0x8e970
leaq 0x4fd75(%rip), %rdx     # 0x8e988
movq %rbx, %rdi
callq 0x65990
movq %r14, %rdi
callq 0x63e01
movq %r14, %rdi
callq 0x640f1
movq -0x30(%rbp), %rdi
testq %rdi, %rdi
je 0x3ec39
callq 0x2e360
leaq -0xd0(%rbp), %rdi
callq 0x40200
movq -0x50(%rbp), %rdi
testq %rdi, %rdi
je 0x3ec53
callq 0x2e360
movq %rbx, %rax
addq $0x148, %rsp            # imm = 0x148
popq %rbx
popq %r14
popq %r15
popq %rbp
retq
jmp 0x3ecba
jmp 0x3ecba
movq %rax, %r14
jmp 0x3eccb
jmp 0x3ecb0
movq %rax, %r14
movq -0x80(%rbp), %rdi
testq %rdi, %rdi
je 0x3ece4
jmp 0x3ecdf
movq %rax, %r14
leaq -0x128(%rbp), %rdi
callq 0x3fc9a
jmp 0x3ec91
movq %rax, %r14
leaq -0x160(%rbp), %rdi
callq 0x3fbfa
jmp 0x3eca2
movq %rax, %r14
movq -0x98(%rbp), %rdi
testq %rdi, %rdi
je 0x3ece4
jmp 0x3ecdf
movq %rax, %r14
jmp 0x3ecd7
movq %rax, %r14
jmp 0x3ece4
movq %rax, %r14
movq -0x30(%rbp), %rdi
testq %rdi, %rdi
je 0x3eccb
callq 0x2e360
leaq -0xd0(%rbp), %rdi
callq 0x40200
movq (%rbx), %rdi
testq %rdi, %rdi
je 0x3ece4
callq 0x2e360
movq -0x50(%rbp), %rdi
testq %rdi, %rdi
je 0x3ecf2
callq 0x2e360
movq %r14, %rdi
callq 0x2e730