// File: /workspace/github_c_makefile_star2_O1/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 0xf9ad
movq %rdx, %r14
movq %rsi, %rbx
leaq 0x6771f(%rip), %rax     # 0x76f34
movslq (%rax,%r8,4), %rdx
addq %rax, %rdx
jmpq *%rdx
movq (%rbx), %rax
cmpl $0xb, %ecx
jne 0xf9a6
movq %rax, %xmm0
punpckldq 0x677a9(%rip), %xmm0 # xmm0 = xmm0[0],mem[0],xmm0[1],mem[1]
subpd 0x677b1(%rip), %xmm0    # 0x76ff0
movapd %xmm0, %xmm1
unpckhpd %xmm0, %xmm1            # xmm1 = xmm1[1],xmm0[1]
addsd %xmm0, %xmm1
movsd %xmm1, (%rbx)
jmp 0xf9d2
movsd (%rbx), %xmm0
callq 0x33c0
jmp 0xf9ce
movsd (%rbx), %xmm0
callq 0x31f0
jmp 0xf9ce
movsd (%rbx), %xmm0
callq 0x3070
jmp 0xf8ea
movsd (%rbx), %xmm0
callq 0x33b0
jmp 0xf8ea
movsd (%rbx), %xmm1
xorpd %xmm0, %xmm0
ucomisd %xmm0, %xmm1
jne 0xf896
jnp 0xf8a3
movsd (%r14), %xmm1
ucomisd %xmm0, %xmm1
jne 0xf8b5
jp 0xf8b5
movq (%rdi), %rcx
movq 0x20(%rcx), %rdi
leaq 0x677e2(%rip), %rsi     # 0x77093
xorl %eax, %eax
callq *(%rcx)
movsd (%rbx), %xmm0
movsd (%r14), %xmm1
callq 0x32e0
jmp 0xf9ce
movsd (%rbx), %xmm0
callq 0x3360
jmp 0xf8ea
movsd (%rbx), %xmm0
callq 0x3100
jmp 0xf9ce
movsd (%rbx), %xmm0
callq 0x30b0
cvttsd2si %xmm0, %rax
movq %rax, (%rbx)
jmp 0xf9d2
xorl %eax, %eax
cmpq (%rbx), %rax
jno 0xf910
movq (%rdi), %rcx
movq 0x20(%rcx), %rdi
leaq 0x67760(%rip), %rsi     # 0x7706c
xorl %eax, %eax
callq *(%rcx)
movq (%rbx), %rax
movq %rax, %rcx
negq %rcx
cmovsq %rax, %rcx
movq %rcx, (%rbx)
jmp 0xf9d2
movsd (%rbx), %xmm0
andpd 0x6769f(%rip), %xmm0    # 0x76fd0
movlpd %xmm0, (%rbx)
jmp 0xf9d2
xorpd %xmm0, %xmm0
ucomisd (%rbx), %xmm0
jb 0xf956
movq (%rdi), %rcx
movq 0x20(%rcx), %rdi
leaq 0x67756(%rip), %rsi     # 0x770a8
xorl %eax, %eax
callq *(%rcx)
movsd (%rbx), %xmm0
callq 0x31d0
jmp 0xf9ce
movq (%rbx), %rdi
callq 0x3130
jmp 0xf8ef
movsd (%rbx), %xmm0
callq 0x3350
jmp 0xf9ce
xorpd %xmm1, %xmm1
ucomisd (%rbx), %xmm1
jbe 0xf996
movq (%rdi), %rcx
movq 0x20(%rcx), %rdi
leaq 0x676f1(%rip), %rsi     # 0x7707f
xorl %eax, %eax
callq *(%rcx)
xorpd %xmm1, %xmm1
movsd (%rbx), %xmm0
ucomisd %xmm1, %xmm0
jb 0xf9c9
sqrtsd %xmm0, %xmm0
jmp 0xf9ce
cvtsi2sd %rax, %xmm0
jmp 0xf9ce
movq (%rdi), %rax
movq (%rax), %rcx
movq 0x20(%rax), %rdi
leaq 0x676fd(%rip), %rsi     # 0x770bb
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