// File: /workspace/github_c_makefile_star2_O2/vtereshkov[P]umka-lang/src/umka_const.c
// Function: constCallBuiltin
void constCallBuiltin(const Consts *consts, Const *arg, const Const *arg2, TypeKind argTypeKind, BuiltinFunc builtinVal)
{
    switch (builtinVal)
    {
        case BUILTIN_REAL:
        case BUILTIN_REAL_LHS:
        {
            if (argTypeKind == TYPE_UINT)
                arg->realVal = arg->uintVal;
            else
                arg->realVal = arg->intVal;
            break;
        }
        case BUILTIN_ROUND:     arg->intVal  = (int64_t)round(arg->realVal); break;
        case BUILTIN_TRUNC:     arg->intVal  = (int64_t)trunc(arg->realVal); break;
        case BUILTIN_CEIL:      arg->intVal  = (int64_t)ceil (arg->realVal); break;
        case BUILTIN_FLOOR:     arg->intVal  = (int64_t)floor(arg->realVal); break;
        case BUILTIN_ABS:
        {
            if (arg->intVal == LLONG_MIN)
                consts->error->handler(consts->error->context, "abs() domain error");
            arg->intVal = llabs(arg->intVal);
            break;
        }
        case BUILTIN_FABS:      arg->realVal = fabs(arg->realVal); break;
        case BUILTIN_SQRT:
        {
            if (arg->realVal < 0)
                consts->error->handler(consts->error->context, "sqrt() domain error");
            arg->realVal = sqrt(arg->realVal);
            break;
        }
        case BUILTIN_SIN:       arg->realVal = sin (arg->realVal); break;
        case BUILTIN_COS:       arg->realVal = cos (arg->realVal); break;
        case BUILTIN_ATAN:      arg->realVal = atan(arg->realVal); break;
        case BUILTIN_ATAN2:
        {
            if (arg->realVal == 0 || arg2->realVal == 0)
                consts->error->handler(consts->error->context, "atan2() domain error");
            arg->realVal = atan2(arg->realVal, arg2->realVal);
            break;
        }
        case BUILTIN_EXP:       arg->realVal = exp (arg->realVal); break;
        case BUILTIN_LOG:
        {
            if (arg->realVal <= 0)
                consts->error->handler(consts->error->context, "log() domain error");
            arg->realVal = log(arg->realVal);
            break;
        }
        case BUILTIN_LEN:       arg->intVal  = strlen((char *)arg->ptrVal); break;

        default: consts->error->handler(consts->error->context, "Illegal function");
    }

}

// Assembly:
pushq %r14
pushq %rbx
pushq %rax
addl $-0x6, %r8d
cmpl $0x1c, %r8d
ja 0x6cb3
movq %rdx, %r14
movq %rsi, %rbx
leaq 0x63428(%rip), %rax     # 0x69f34
movslq (%rax,%r8,4), %rdx
addq %rax, %rdx
jmpq *%rdx
movq (%rbx), %rax
cmpl $0xb, %ecx
jne 0x6cac
movq %rax, %xmm0
punpckldq 0x634a2(%rip), %xmm0 # xmm0 = xmm0[0],mem[0],xmm0[1],mem[1]
subpd 0x634aa(%rip), %xmm0    # 0x69fe0
movapd %xmm0, %xmm1
unpckhpd %xmm0, %xmm1            # xmm1 = xmm1[1],xmm0[1]
addsd %xmm0, %xmm1
movsd %xmm1, (%rbx)
jmp 0x6cd8
movsd (%rbx), %xmm0
callq 0x33c0
jmp 0x6cd4
movsd (%rbx), %xmm0
callq 0x31f0
jmp 0x6cd4
movsd (%rbx), %xmm0
callq 0x3070
jmp 0x6be1
movsd (%rbx), %xmm0
callq 0x33b0
jmp 0x6be1
movsd (%rbx), %xmm0
xorpd %xmm2, %xmm2
ucomisd %xmm2, %xmm0
jne 0x6b8d
jnp 0x6b9a
movsd (%r14), %xmm1
ucomisd %xmm2, %xmm1
jne 0x6bb5
jp 0x6bb5
movq (%rdi), %rcx
movq 0x20(%rcx), %rdi
leaq 0x634eb(%rip), %rsi     # 0x6a093
xorl %eax, %eax
callq *(%rcx)
movsd (%rbx), %xmm0
movsd (%r14), %xmm1
callq 0x32e0
jmp 0x6cd4
movsd (%rbx), %xmm0
callq 0x3360
jmp 0x6be1
movsd (%rbx), %xmm0
callq 0x3100
jmp 0x6cd4
movsd (%rbx), %xmm0
callq 0x30b0
cvttsd2si %xmm0, %rax
movq %rax, (%rbx)
jmp 0x6cd8
movq (%rbx), %rax
movq %rax, %rcx
negq %rcx
jno 0x6c0e
movq (%rdi), %rcx
movq 0x20(%rcx), %rdi
leaq 0x63465(%rip), %rsi     # 0x6a06c
xorl %eax, %eax
callq *(%rcx)
movq (%rbx), %rax
movq %rax, %rcx
negq %rcx
cmovsq %rax, %rcx
movq %rcx, (%rbx)
jmp 0x6cd8
movsd (%rbx), %xmm0
andpd 0x63384(%rip), %xmm0    # 0x69fb0
movlpd %xmm0, (%rbx)
jmp 0x6cd8
movsd (%rbx), %xmm0
xorpd %xmm1, %xmm1
ucomisd %xmm0, %xmm1
jb 0x6c59
movq (%rdi), %rcx
movq 0x20(%rcx), %rdi
leaq 0x63457(%rip), %rsi     # 0x6a0a8
xorl %eax, %eax
callq *(%rcx)
movsd (%rbx), %xmm0
callq 0x31d0
jmp 0x6cd4
movq (%rbx), %rdi
callq 0x3130
jmp 0x6be6
movsd (%rbx), %xmm0
callq 0x3350
jmp 0x6cd4
movsd (%rbx), %xmm0
xorpd %xmm1, %xmm1
ucomisd %xmm0, %xmm1
jbe 0x6ca0
movq (%rdi), %rcx
movq 0x20(%rcx), %rdi
leaq 0x633eb(%rip), %rsi     # 0x6a07f
xorl %eax, %eax
callq *(%rcx)
xorpd %xmm1, %xmm1
movsd (%rbx), %xmm0
ucomisd %xmm1, %xmm0
jb 0x6ccf
sqrtsd %xmm0, %xmm0
jmp 0x6cd4
cvtsi2sd %rax, %xmm0
jmp 0x6cd4
movq (%rdi), %rax
movq (%rax), %rcx
movq 0x20(%rax), %rdi
leaq 0x633f7(%rip), %rsi     # 0x6a0bb
xorl %eax, %eax
addq $0x8, %rsp
popq %rbx
popq %r14
jmpq *%rcx
callq 0x33a0
movsd %xmm0, (%rbx)
addq $0x8, %rsp
popq %rbx
popq %r14
retq