// File: /workspace/github_c_makefile_star2_O3/vtereshkov[P]umka-lang/src/umka_expr.c
// Function: doApplyOperator
void doApplyOperator(Compiler *comp, const Type **type, const Type **rightType, Const *constant, Const *rightConstant, TokenKind op, bool apply, bool convertLhs)
{
    // First, the right-hand side type is converted to the left-hand side type
    doImplicitTypeConvEx(comp, *type, rightType, rightConstant, false, true);

    // Second, the left-hand side type is converted to the right-hand side type for symmetric operators
    if (convertLhs)
        doImplicitTypeConvEx(comp, *rightType, type, constant, true, false);

    typeAssertCompatible(&comp->types, *type, *rightType);
    typeAssertValidOperator(&comp->types, *type, op);

    if (apply)
    {
        if ((*type)->kind == TYPE_STR && (op == TOK_PLUS || op == TOK_PLUSEQ))
            doApplyStrCat(comp, constant, rightConstant, op);
        else
        {
            if (constant)
                constBinary(&comp->consts, constant, rightConstant, op, *type);
            else
                genBinary(&comp->gen, op, *type);
        }
    }
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x18, %rsp
movl %r9d, %ebp
movq %rcx, 0x8(%rsp)
movq %rdx, %r14
movq %rsi, %r13
movq %rdi, %rbx
movb 0x50(%rsp), %r15b
movb 0x58(%rsp), %r12b
movq (%rsi), %rsi
movq %r8, 0x10(%rsp)
movq %r8, %rcx
xorl %r8d, %r8d
movl $0x1, %r9d
callq 0xcabc
testb %r12b, %r12b
je 0xda2a
movq (%r14), %rsi
movq %rbx, %rdi
movq %r13, %rdx
movq 0x8(%rsp), %rcx
movl $0x1, %r8d
xorl %r9d, %r9d
callq 0xcabc
leaq 0x4e18(%rbx), %r12
movq (%r13), %rsi
movq (%r14), %rdx
movq %r12, %rdi
callq 0x1a277
movq (%r13), %rsi
movq %r12, %rdi
movl %ebp, %edx
callq 0x1a4dd
testb %r15b, %r15b
je 0xdaee
movq (%r13), %r8
cmpl $0x14, (%r8)
jne 0xdafd
cmpl $0x20, %ebp
je 0xda73
cmpl $0x16, %ebp
jne 0xdafd
movq 0x8(%rsp), %r13
testq %r13, %r13
je 0xdb4d
cmpl $0x20, %ebp
jne 0xda9c
movq 0x5118(%rbx), %rdi
leaq 0x690be(%rip), %rsi     # 0x76b52
xorl %eax, %eax
callq *0x50f8(%rbx)
movq (%r13), %rax
movq 0x10(%rsp), %r15
movq (%r15), %rcx
movl -0x10(%rcx), %ecx
addl -0x10(%rax), %ecx
leaq 0xf0(%rbx), %rdi
movslq %ecx, %rsi
callq 0x7b1c
movq %rax, %r14
movq (%r13), %rsi
movq %rax, %rdi
callq 0x30a0
movq %r14, (%r13)
movq 0x5288(%rbx), %r8
addq $0x4e68, %rbx           # imm = 0x4E68
movq %rbx, %rdi
movq %r13, %rsi
movq %r15, %rdx
movl $0x16, %ecx
jmp 0xdb18
addq $0x18, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movq 0x8(%rsp), %rsi
testq %rsi, %rsi
je 0xdb2b
addq $0x4e68, %rbx           # imm = 0x4E68
movq %rbx, %rdi
movq 0x10(%rsp), %rdx
movl %ebp, %ecx
addq $0x18, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
jmp 0x9f1e
addq $0x4e70, %rbx           # imm = 0x4E70
movq %rbx, %rdi
movl %ebp, %esi
movq %r8, %rdx
addq $0x18, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
jmp 0x137c1
leaq 0x4e70(%rbx), %r14
movq 0x5288(%rbx), %rdx
movq %r14, %rdi
movl %ebp, %esi
callq 0x137c1
movq 0x5288(%rbx), %r15
leaq 0x4e38(%rbx), %rdi
leaq 0x100(%rbx), %rdx
addq $0x4220, %rbx           # imm = 0x4220
movq %r12, %rsi
movq %rbx, %rcx
movq %r15, %r8
movl $0x1, %r9d
callq 0x153ba
movl 0x120(%rax), %edx
movq %r14, %rdi
movq %r15, %rsi
addq $0x18, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
jmp 0x14698