// File: eniac[P]Mantis/src/compile/compile_p4.cpp
// Function: augmentIngress(std::vector<AstNode*, std::allocator<AstNode*>>*)
bool augmentIngress(vector<AstNode*>* astNodes) {
    // Fetch ingress
    P4ExprNode* ingressNode = findIngress(*astNodes);
    if (!ingressNode) {
        PANIC("Error: could not find the egress control block. Perhaps you didn't call it 'ingress'?\n");
        exit(1);
    }

    // Rename ingress
    ingressNode->name1_->word_ = new string(kOrigIngControlName);

    // Generate new ingress function that wraps original
    ostringstream oss;
    oss << "control ingress {\n"
            // Separate ing and egr for cases when queueing > PCIe latency (large packet buffer+congested link)
            << "  " << kSetmblIngControlName << "();\n"
            << "  " << kOrigIngControlName << "();\n" 
            << "  " << kSetargsIngControlName << "();\n"
            << "  " << kRegArgGateIngControlName << "();\n"            
        << "}\n\n";
    StrNode* newIngressNode = new StrNode(new string(oss.str()));

    // Inject wrapper right before original
    InputNode* firstInput = dynamic_cast<InputNode*>(ingressNode->parent_);
    InputNode* secondInput = new InputNode(firstInput->next_,
                                           firstInput->expression_);
    firstInput->next_ = secondInput;
    secondInput->parent_ = firstInput;

    firstInput->expression_ = newIngressNode;
    astNodes->push_back(secondInput);

    return true;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x270, %rsp            # imm = 0x270
movq %rdi, -0x8(%rbp)
movq -0x8(%rbp), %rdi
callq 0x12c8a0
movq %rax, -0x10(%rbp)
cmpq $0x0, -0x10(%rbp)
jne 0x118188
movq 0x5be56(%rip), %rax     # 0x173fb0
movq (%rax), %rdi
leaq 0x25b8b(%rip), %rsi     # 0x13dcef
leaq 0x25bec(%rip), %rdx     # 0x13dd57
movl $0x8d, %ecx
leaq 0x25bfb(%rip), %r8      # 0x13dd72
movb $0x0, %al
callq 0xaa850
movl $0x1, %edi
callq 0xaa6c0
movl $0x20, %edi
callq 0xaa560
movq %rax, -0x1d0(%rbp)
movq %rax, -0x1d8(%rbp)
movb $0x1, -0x25(%rbp)
leaq -0x11(%rbp), %rdi
movq %rdi, -0x1c8(%rbp)
callq 0xaaa70
movq -0x1d0(%rbp), %rdi
movq -0x1c8(%rbp), %rdx
leaq 0x25bb8(%rip), %rsi     # 0x13dd81
callq 0xaa7d0
jmp 0x1181d0
movq -0x1d8(%rbp), %rcx
movb $0x0, -0x25(%rbp)
movq -0x10(%rbp), %rax
movq 0x48(%rax), %rax
movq %rcx, 0x40(%rax)
leaq -0x11(%rbp), %rdi
callq 0xaa5f0
leaq -0x1a0(%rbp), %rdi
movq %rdi, -0x1e8(%rbp)
callq 0xaa7b0
movq -0x1e8(%rbp), %rdi
leaq 0x25b80(%rip), %rsi     # 0x13dd91
callq 0xaa540
movq %rax, -0x1e0(%rbp)
jmp 0x11821f
movq -0x1e0(%rbp), %rdi
leaq 0x2410b(%rip), %rsi     # 0x13c338
callq 0xaa540
movq %rax, -0x1f0(%rbp)
jmp 0x11823b
movq -0x1f0(%rbp), %rdi
leaq 0x25b5b(%rip), %rsi     # 0x13dda4
callq 0xaa540
movq %rax, -0x1f8(%rbp)
jmp 0x118257
movq -0x1f8(%rbp), %rdi
leaq 0x25b4b(%rip), %rsi     # 0x13ddb0
callq 0xaa540
movq %rax, -0x200(%rbp)
jmp 0x118273
movq -0x200(%rbp), %rdi
leaq 0x240b7(%rip), %rsi     # 0x13c338
callq 0xaa540
movq %rax, -0x208(%rbp)
jmp 0x11828f
movq -0x208(%rbp), %rdi
leaq 0x25ae4(%rip), %rsi     # 0x13dd81
callq 0xaa540
movq %rax, -0x210(%rbp)
jmp 0x1182ab
movq -0x210(%rbp), %rdi
leaq 0x25af7(%rip), %rsi     # 0x13ddb0
callq 0xaa540
movq %rax, -0x218(%rbp)
jmp 0x1182c7
movq -0x218(%rbp), %rdi
leaq 0x24063(%rip), %rsi     # 0x13c338
callq 0xaa540
movq %rax, -0x220(%rbp)
jmp 0x1182e3
movq -0x220(%rbp), %rdi
leaq 0x25ac4(%rip), %rsi     # 0x13ddb5
callq 0xaa540
movq %rax, -0x228(%rbp)
jmp 0x1182ff
movq -0x228(%rbp), %rdi
leaq 0x25aa3(%rip), %rsi     # 0x13ddb0
callq 0xaa540
movq %rax, -0x230(%rbp)
jmp 0x11831b
movq -0x230(%rbp), %rdi
leaq 0x2400f(%rip), %rsi     # 0x13c338
callq 0xaa540
movq %rax, -0x238(%rbp)
jmp 0x118337
movq -0x238(%rbp), %rdi
leaq 0x25a7c(%rip), %rsi     # 0x13ddc1
callq 0xaa540
movq %rax, -0x240(%rbp)
jmp 0x118353
movq -0x240(%rbp), %rdi
leaq 0x25a4f(%rip), %rsi     # 0x13ddb0
callq 0xaa540
movq %rax, -0x248(%rbp)
jmp 0x11836f
movq -0x248(%rbp), %rdi
leaq 0x260d8(%rip), %rsi     # 0x13e455
callq 0xaa540
jmp 0x118384
movl $0x48, %edi
callq 0xaa560
movq %rax, -0x250(%rbp)
jmp 0x118397
movl $0x20, %edi
callq 0xaa560
movq %rax, -0x258(%rbp)
jmp 0x1183aa
movq -0x258(%rbp), %rdi
leaq -0x1a0(%rbp), %rsi
callq 0xaa580
jmp 0x1183bf
movq -0x258(%rbp), %rsi
movq -0x250(%rbp), %rdi
callq 0xb2890
jmp 0x1183d4
movq -0x250(%rbp), %rax
movq %rax, -0x1a8(%rbp)
movq -0x10(%rbp), %rax
movq 0x30(%rax), %rax
movq %rax, -0x260(%rbp)
cmpq $0x0, %rax
je 0x11849b
movq -0x260(%rbp), %rdi
leaq 0x5a1d7(%rip), %rsi     # 0x1725e0
leaq 0x5a508(%rip), %rdx     # 0x172918
xorl %eax, %eax
movl %eax, %ecx
callq 0xaa660
movq %rax, -0x268(%rbp)
jmp 0x1184a6
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x20(%rbp)
movl %eax, -0x24(%rbp)
leaq -0x11(%rbp), %rdi
callq 0xaa5f0
testb $0x1, -0x25(%rbp)
jne 0x118442
jmp 0x11844e
movq -0x1d8(%rbp), %rdi
callq 0xaa4e0
jmp 0x118585
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x20(%rbp)
movl %eax, -0x24(%rbp)
jmp 0x118579
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x20(%rbp)
movl %eax, -0x24(%rbp)
jmp 0x11848a
movq -0x258(%rbp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x20(%rbp)
movl %eax, -0x24(%rbp)
callq 0xaa4e0
movq -0x250(%rbp), %rdi
callq 0xaa4e0
jmp 0x118579
xorl %eax, %eax
movq %rax, -0x268(%rbp)
jmp 0x1184a6
movq -0x268(%rbp), %rax
movq %rax, -0x1b0(%rbp)
movl $0x50, %edi
callq 0xaa560
movq %rax, -0x270(%rbp)
jmp 0x1184c7
movq -0x270(%rbp), %rdi
movq -0x1b0(%rbp), %rax
movq 0x40(%rax), %rsi
movq 0x48(%rax), %rdx
callq 0xb2350
jmp 0x1184e4
movq -0x270(%rbp), %rax
movq %rax, -0x1b8(%rbp)
movq -0x1b8(%rbp), %rcx
movq -0x1b0(%rbp), %rax
movq %rcx, 0x40(%rax)
movq -0x1b0(%rbp), %rcx
movq -0x1b8(%rbp), %rax
movq %rcx, 0x30(%rax)
movq -0x1a8(%rbp), %rcx
movq -0x1b0(%rbp), %rax
movq %rcx, 0x48(%rax)
movq -0x8(%rbp), %rdi
movq -0x1b8(%rbp), %rax
movq %rax, -0x1c0(%rbp)
leaq -0x1c0(%rbp), %rsi
callq 0xb2540
jmp 0x118548
leaq -0x1a0(%rbp), %rdi
callq 0xaa130
movb $0x1, %al
andb $0x1, %al
addq $0x270, %rsp            # imm = 0x270
popq %rbp
retq
movq -0x270(%rbp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x20(%rbp)
movl %eax, -0x24(%rbp)
callq 0xaa4e0
leaq -0x1a0(%rbp), %rdi
callq 0xaa130
movq -0x20(%rbp), %rdi
callq 0xaaa60
nop