// File: /workspace/github_c_makefile_star2_O0/vtereshkov[P]umka-lang/src/umka_gen.c
// Function: optimizeBinary
static bool optimizeBinary(CodeGen *gen, TokenKind tokKind, TypeKind typeKind)
{
    Instruction *prev = getPrevInstr(gen, 1), *prev2 = getPrevInstr(gen, 2);

    // Optimization: PUSH + PUSH + BINARY -> PUSH
    if (prev  && prev->opcode  == OP_PUSH && prev->inlineOpcode  == OP_NOP &&
        prev2 && prev2->opcode == OP_PUSH && prev2->inlineOpcode == OP_NOP &&
       (typeKindOrdinal(typeKind) || typeKindReal(typeKind) || typeKind == TYPE_BOOL))
    {
        Const lhs, rhs;
        if (typeKindReal(typeKind))
        {
            lhs.realVal = prev2->operand.realVal;
            rhs.realVal = prev->operand.realVal;
        }
        else
        {
            lhs.intVal = prev2->operand.intVal;
            rhs.intVal = prev->operand.intVal;
        }

        prev = prev2;
        genRemoveInstr(gen);

        Consts consts = {.error = gen->error};
        constBinary(&consts, &lhs, &rhs, tokKind, typeKind);

        prev->typeKind = typeKind;

        if (tokKind == TOK_EQEQ      || tokKind == TOK_NOTEQ   ||
            tokKind == TOK_GREATER   || tokKind == TOK_LESS    ||
            tokKind == TOK_GREATEREQ || tokKind == TOK_LESSEQ)
        {
            prev->typeKind = TYPE_BOOL;
        }

        if (typeKindReal(typeKind))
            prev->operand.realVal = lhs.realVal;
        else
            prev->operand.intVal = lhs.intVal;

        genUnnotify(gen);
        return true;
    }

    return false;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x40, %rsp
movq %rdi, -0x10(%rbp)
movl %esi, -0x14(%rbp)
movl %edx, -0x18(%rbp)
movq -0x10(%rbp), %rdi
movl $0x1, %esi
callq 0x18c30
movq %rax, -0x20(%rbp)
movq -0x10(%rbp), %rdi
movl $0x2, %esi
callq 0x18c30
movq %rax, -0x28(%rbp)
cmpq $0x0, -0x20(%rbp)
je 0x17992
movq -0x20(%rbp), %rax
cmpl $0x1, (%rax)
jne 0x17992
movq -0x20(%rbp), %rax
cmpl $0x0, 0x4(%rax)
jne 0x17992
cmpq $0x0, -0x28(%rbp)
je 0x17992
movq -0x28(%rbp), %rax
cmpl $0x1, (%rax)
jne 0x17992
movq -0x28(%rbp), %rax
cmpl $0x0, 0x4(%rax)
jne 0x17992
movl -0x18(%rbp), %edi
callq 0x193c0
testb $0x1, %al
jne 0x178a4
movl -0x18(%rbp), %edi
callq 0x19390
testb $0x1, %al
jne 0x178a4
cmpl $0xc, -0x18(%rbp)
jne 0x17992
movl -0x18(%rbp), %edi
callq 0x19390
testb $0x1, %al
jne 0x178b2
jmp 0x178d0
movq -0x28(%rbp), %rax
movsd 0x18(%rax), %xmm0
movsd %xmm0, -0x30(%rbp)
movq -0x20(%rbp), %rax
movsd 0x18(%rax), %xmm0
movsd %xmm0, -0x38(%rbp)
jmp 0x178e8
movq -0x28(%rbp), %rax
movq 0x18(%rax), %rax
movq %rax, -0x30(%rbp)
movq -0x20(%rbp), %rax
movq 0x18(%rax), %rax
movq %rax, -0x38(%rbp)
movq -0x28(%rbp), %rax
movq %rax, -0x20(%rbp)
movq -0x10(%rbp), %rdi
callq 0x18c80
movq -0x10(%rbp), %rax
movq 0x1e0(%rax), %rax
movq %rax, -0x40(%rbp)
movl -0x14(%rbp), %ecx
movl -0x18(%rbp), %r8d
leaq -0x40(%rbp), %rdi
leaq -0x30(%rbp), %rsi
leaq -0x38(%rbp), %rdx
callq 0x8c30
movl -0x18(%rbp), %ecx
movq -0x20(%rbp), %rax
movl %ecx, 0xc(%rax)
cmpl $0x2e, -0x14(%rbp)
je 0x1794e
cmpl $0x34, -0x14(%rbp)
je 0x1794e
cmpl $0x30, -0x14(%rbp)
je 0x1794e
cmpl $0x2f, -0x14(%rbp)
je 0x1794e
cmpl $0x36, -0x14(%rbp)
je 0x1794e
cmpl $0x35, -0x14(%rbp)
jne 0x17959
movq -0x20(%rbp), %rax
movl $0xc, 0xc(%rax)
movl -0x18(%rbp), %edi
callq 0x19390
testb $0x1, %al
jne 0x17967
jmp 0x17977
movsd -0x30(%rbp), %xmm0
movq -0x20(%rbp), %rax
movsd %xmm0, 0x18(%rax)
jmp 0x17983
movq -0x30(%rbp), %rcx
movq -0x20(%rbp), %rax
movq %rcx, 0x18(%rax)
movq -0x10(%rbp), %rdi
callq 0x16740
movb $0x1, -0x1(%rbp)
jmp 0x17996
movb $0x0, -0x1(%rbp)
movb -0x1(%rbp), %al
andb $0x1, %al
addq $0x40, %rsp
popq %rbp
retq
nopw %cs:(%rax,%rax)