// File: /workspace/github_cpp_makefile_star2_O3/pfnet-research[P]pml/src/translate_to_mdp.cpp
// Function: calc_binop_bound(value_info_t const&, value_info_t const&, ast::expr_kind_t)
value_info_t calc_binop_bound(
        value_info_t const& lhs,
        value_info_t const& rhs,
        ast::expr_kind_t op) {
    switch (op) {
    case ast::expr_kind_t::Add:
        return value_info_t {
            format("({}+{})", lhs.name, rhs.name),
            *lhs.bound + *rhs.bound
        };
    case ast::expr_kind_t::Sub:
        return value_info_t {
            format("({}-{})", lhs.name, rhs.name),
            *lhs.bound - *rhs.bound
        };
    case ast::expr_kind_t::Mul:
        return value_info_t {
            format("({}*{})", lhs.name, rhs.name),
            *lhs.bound * *rhs.bound
        };
    case ast::expr_kind_t::Div:
        return value_info_t {
            format("({}/{})", lhs.name, rhs.name),
            *lhs.bound / *rhs.bound
        };
    case ast::expr_kind_t::Eq:
        return value_info_t {
            format("{}={}", lhs.name, rhs.name),
            util::nullopt
        };
    case ast::expr_kind_t::Neq:
        return value_info_t {
            format("({}!={})", lhs.name, rhs.name),
            util::nullopt
        };
    case ast::expr_kind_t::Leq:
        return value_info_t {
            format("({}<={})", lhs.name, rhs.name),
            util::nullopt
        };
    case ast::expr_kind_t::Geq:
        return value_info_t {
            format("({}>={})", lhs.name, rhs.name),
            util::nullopt
        };
    case ast::expr_kind_t::And:
        return value_info_t {
            format("({}&{})", lhs.name, rhs.name),
            util::nullopt
        };
    case ast::expr_kind_t::Or:
        return value_info_t {
            format("({}|{})", lhs.name, rhs.name),
            util::nullopt
        };
    default:
        throw std::logic_error{"invalid binop"};
    }
}

// Assembly:
pushq %r15
pushq %r14
pushq %r12
pushq %rbx
subq $0x28, %rsp
addl $-0x6, %ecx
cmpl $0xa, %ecx
ja 0x3e99e
movq %rdx, %r14
movq %rsi, %r15
movq %rdi, %rbx
leaq 0xcd17(%rip), %rax      # 0x4b3e4
movslq (%rax,%rcx,4), %rcx
addq %rax, %rcx
jmpq *%rcx
leaq 0x18(%rsp), %r12
movq %r12, -0x10(%r12)
leaq 0xcddf(%rip), %rsi      # 0x4b4c6
leaq 0xcddf(%rip), %rdx      # 0x4b4cd
leaq 0x8(%rsp), %rdi
callq 0x116f8
leaq 0x8(%rsp), %rsi
movq %rbx, %rdi
movq %r15, %rdx
movq %r14, %rcx
callq 0x3ea28
movl 0x20(%r14), %eax
movl 0x24(%r14), %ecx
addl 0x20(%r15), %eax
addl 0x24(%r15), %ecx
jmp 0x3e899
leaq 0x18(%rsp), %r12
movq %r12, -0x10(%r12)
leaq 0xcdde(%rip), %rsi      # 0x4b50f
leaq 0xcdde(%rip), %rdx      # 0x4b516
leaq 0x8(%rsp), %rdi
callq 0x116f8
leaq 0x8(%rsp), %rsi
movq %rbx, %rdi
movq %r15, %rdx
movq %r14, %rcx
callq 0x3ea28
jmp 0x3e974
leaq 0x18(%rsp), %r12
movq %r12, -0x10(%r12)
leaq 0xcd9c(%rip), %rsi      # 0x4b507
leaq 0xcd9c(%rip), %rdx      # 0x4b50e
leaq 0x8(%rsp), %rdi
callq 0x116f8
leaq 0x8(%rsp), %rsi
movq %rbx, %rdi
movq %r15, %rdx
movq %r14, %rcx
callq 0x3ea28
jmp 0x3e974
leaq 0x18(%rsp), %r12
movq %r12, -0x10(%r12)
leaq 0xcd41(%rip), %rsi      # 0x4b4e6
leaq 0xcd3f(%rip), %rdx      # 0x4b4eb
leaq 0x8(%rsp), %rdi
callq 0x116f8
leaq 0x8(%rsp), %rsi
movq %rbx, %rdi
movq %r15, %rdx
movq %r14, %rcx
callq 0x3ea28
jmp 0x3e974
leaq 0x18(%rsp), %r12
movq %r12, -0x10(%r12)
leaq 0xccef(%rip), %rsi      # 0x4b4ce
leaq 0xccef(%rip), %rdx      # 0x4b4d5
leaq 0x8(%rsp), %rdi
callq 0x116f8
leaq 0x8(%rsp), %rsi
movq %rbx, %rdi
movq %r15, %rdx
movq %r14, %rcx
callq 0x3ea28
movl 0x20(%r15), %eax
movl 0x24(%r15), %ecx
subl 0x24(%r14), %eax
subl 0x20(%r14), %ecx
jmp 0x3e899
leaq 0x18(%rsp), %r12
movq %r12, -0x10(%r12)
leaq 0xccc3(%rip), %rsi      # 0x4b4ec
leaq 0xccc4(%rip), %rdx      # 0x4b4f4
leaq 0x8(%rsp), %rdi
callq 0x116f8
leaq 0x8(%rsp), %rsi
movq %rbx, %rdi
movq %r15, %rdx
movq %r14, %rcx
callq 0x3ea28
jmp 0x3e974
leaq 0x18(%rsp), %r12
movq %r12, -0x10(%r12)
leaq 0xcc73(%rip), %rsi      # 0x4b4d6
leaq 0xcc73(%rip), %rdx      # 0x4b4dd
leaq 0x8(%rsp), %rdi
callq 0x116f8
leaq 0x8(%rsp), %rsi
movq %rbx, %rdi
movq %r15, %rdx
movq %r14, %rcx
callq 0x3ea28
movl 0x20(%r14), %eax
movl 0x24(%r14), %ecx
imull 0x20(%r15), %eax
imull 0x24(%r15), %ecx
shlq $0x20, %rcx
orq %rcx, %rax
movq %rax, 0x20(%rbx)
jmp 0x3e939
leaq 0x18(%rsp), %r12
movq %r12, -0x10(%r12)
leaq 0xcc44(%rip), %rsi      # 0x4b4fe
leaq 0xcc45(%rip), %rdx      # 0x4b506
leaq 0x8(%rsp), %rdi
callq 0x116f8
leaq 0x8(%rsp), %rsi
movq %rbx, %rdi
movq %r15, %rdx
movq %r14, %rcx
callq 0x3ea28
jmp 0x3e974
leaq 0x18(%rsp), %r12
movq %r12, -0x10(%r12)
leaq 0xcbea(%rip), %rsi      # 0x4b4de
leaq 0xcbea(%rip), %rdx      # 0x4b4e5
leaq 0x8(%rsp), %rdi
callq 0x116f8
leaq 0x8(%rsp), %rsi
movq %rbx, %rdi
movq %r15, %rdx
movq %r14, %rcx
callq 0x3ea28
movl 0x20(%r15), %eax
movl 0x24(%r15), %ecx
movl 0x24(%r14), %edi
cltd
idivl %edi
movl %eax, %esi
movl %ecx, %eax
cltd
idivl %edi
shlq $0x20, %rax
orq %rax, %rsi
movq %rsi, 0x20(%rbx)
movb $0x1, 0x28(%rbx)
jmp 0x3e978
leaq 0x18(%rsp), %r12
movq %r12, -0x10(%r12)
leaq 0xcba5(%rip), %rsi      # 0x4b4f5
leaq 0xcba6(%rip), %rdx      # 0x4b4fd
leaq 0x8(%rsp), %rdi
callq 0x116f8
leaq 0x8(%rsp), %rsi
movq %rbx, %rdi
movq %r15, %rdx
movq %r14, %rcx
callq 0x3ea28
movb $0x0, 0x28(%rbx)
movq 0x8(%rsp), %rdi
cmpq %r12, %rdi
je 0x3e98f
movq 0x18(%rsp), %rsi
incq %rsi
callq 0x92e0
movq %rbx, %rax
addq $0x28, %rsp
popq %rbx
popq %r12
popq %r14
popq %r15
retq
movl $0x10, %edi
callq 0x9150
movq %rax, %r14
leaq 0xcb65(%rip), %rsi      # 0x4b517
movq %rax, %rdi
callq 0x93c0
movq 0x2360f(%rip), %rsi     # 0x61fd0
movq 0x235e0(%rip), %rdx     # 0x61fa8
movq %r14, %rdi
callq 0x94b0
movq %rax, %rbx
movq %r14, %rdi
callq 0x9200
jmp 0x3ea20
jmp 0x3e9ef
jmp 0x3e9ef
jmp 0x3e9ef
jmp 0x3e9ef
jmp 0x3e9ef
jmp 0x3e9ef
jmp 0x3e9ef
jmp 0x3e9ef
jmp 0x3e9ef
movq %rax, %rbx
movq 0x8(%rsp), %rdi
cmpq %r12, %rdi
je 0x3ea20
movq 0x18(%rsp), %rsi
incq %rsi
callq 0x92e0
jmp 0x3ea20
jmp 0x3ea1d
jmp 0x3ea1d
jmp 0x3ea1d
jmp 0x3ea1d
jmp 0x3ea1d
jmp 0x3ea1d
jmp 0x3ea1d
jmp 0x3ea1d
jmp 0x3ea1d
movq %rax, %rbx
movq %rbx, %rdi
callq 0x94e0