// File: baziotis[P]minijava-cpp/llvm.cpp
// Function: llvm_op(int, llvalue_t, llvalue_t)
llvalue_t llvm_op(int op, llvalue_t res1, llvalue_t res2) {
    if (res1.kind == LLVALUE::CONST && res2.kind == LLVALUE::CONST) {
        return llvm_op_const(op, res1.val, res2.val);
    }

    long lhs = gen_reg();
    print_codegen_indentation();
    emit("%%%ld = ", lhs);
    switch (op) {
    case '+': emit("add i32 "); break;
    case '-': emit("sub i32 "); break;
    case '*': emit("mul i32 "); break;
    case '<': emit("icmp slt i32 "); break;
    case '&': emit("and i1 "); break;
    default: assert(0);
    }
    cgen_print_llvalue(res1);
    emit(", ");
    cgen_print_llvalue(res2);
    emit("\n");
    return register_llv(lhs, {});
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0xb0, %rsp
movq %rdi, -0x80(%rbp)
movq %rdi, -0x78(%rbp)
leaq 0x30(%rbp), %rax
movq %rax, -0x70(%rbp)
leaq 0x10(%rbp), %rax
movq %rax, -0x68(%rbp)
movl %esi, -0x4(%rbp)
cmpl $0x1, (%rax)
jne 0x5fc3
movq -0x70(%rbp), %rax
cmpl $0x1, (%rax)
jne 0x5fc3
movq -0x80(%rbp), %rdi
movq -0x70(%rbp), %rax
movq -0x68(%rbp), %rcx
movl -0x4(%rbp), %esi
movl 0x18(%rcx), %edx
movl 0x18(%rax), %ecx
callq 0x5c50
jmp 0x615c
callq 0x5a40
movq %rax, -0x10(%rbp)
callq 0x5f30
movq -0x10(%rbp), %rsi
leaq 0x1421f(%rip), %rdi     # 0x1a1fb
xorl %eax, %eax
callq 0x5b70
movl -0x4(%rbp), %eax
addl $-0x26, %eax
movl %eax, %ecx
movq %rcx, -0x88(%rbp)
subl $0x16, %eax
ja 0x605e
movq -0x88(%rbp), %rax
leaq 0x13f2b(%rip), %rcx     # 0x19f30
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
leaq 0x141ef(%rip), %rdi     # 0x1a204
movb $0x0, %al
callq 0x5b70
jmp 0x607d
leaq 0x141e8(%rip), %rdi     # 0x1a20d
movb $0x0, %al
callq 0x5b70
jmp 0x607d
leaq 0x141e1(%rip), %rdi     # 0x1a216
movb $0x0, %al
callq 0x5b70
jmp 0x607d
leaq 0x141da(%rip), %rdi     # 0x1a21f
movb $0x0, %al
callq 0x5b70
jmp 0x607d
leaq 0x141d8(%rip), %rdi     # 0x1a22d
movb $0x0, %al
callq 0x5b70
jmp 0x607d
leaq 0x1591d(%rip), %rdi     # 0x1b982
leaq 0x14145(%rip), %rsi     # 0x1a1b1
movl $0x9f, %edx
leaq 0x141bd(%rip), %rcx     # 0x1a235
callq 0x20d0
movq -0x68(%rbp), %rax
movq (%rax), %rcx
movq %rcx, -0x30(%rbp)
movq 0x8(%rax), %rcx
movq %rcx, -0x28(%rbp)
movq 0x10(%rax), %rcx
movq %rcx, -0x20(%rbp)
movq 0x18(%rax), %rax
movq %rax, -0x18(%rbp)
leaq -0x30(%rbp), %rax
xorl %edi, %edi
movq (%rax), %rcx
movq %rcx, (%rsp)
movq 0x8(%rax), %rcx
movq %rcx, 0x8(%rsp)
movq 0x10(%rax), %rcx
movq %rcx, 0x10(%rsp)
movq 0x18(%rax), %rax
movq %rax, 0x18(%rsp)
callq 0x5d40
leaq 0x15fce(%rip), %rdi     # 0x1c0a2
movb $0x0, %al
callq 0x5b70
movq -0x70(%rbp), %rax
movq (%rax), %rcx
movq %rcx, -0x50(%rbp)
movq 0x8(%rax), %rcx
movq %rcx, -0x48(%rbp)
movq 0x10(%rax), %rcx
movq %rcx, -0x40(%rbp)
movq 0x18(%rax), %rax
movq %rax, -0x38(%rbp)
leaq -0x50(%rbp), %rax
xorl %edi, %edi
movq (%rax), %rcx
movq %rcx, (%rsp)
movq 0x8(%rax), %rcx
movq %rcx, 0x8(%rsp)
movq 0x10(%rax), %rcx
movq %rcx, 0x10(%rsp)
movq 0x18(%rax), %rax
movq %rax, 0x18(%rsp)
callq 0x5d40
leaq 0x14612(%rip), %rdi     # 0x1a744
movb $0x0, %al
callq 0x5b70
movq -0x80(%rbp), %rdi
movq -0x10(%rbp), %rsi
movq $0x0, -0x60(%rbp)
movl $0x0, -0x58(%rbp)
movq -0x60(%rbp), %rdx
movl -0x58(%rbp), %ecx
callq 0x5ad0
movq -0x78(%rbp), %rax
addq $0xb0, %rsp
popq %rbp
retq
nopl (%rax)