// File: /workspace/github_c_makefile_star2_O0/lucvoo[P]sparse-dev/linearize.c
// Function: linearize_call_expression
static pseudo_t linearize_call_expression(struct entrypoint *ep, struct expression *expr)
{
	struct expression *arg, *fn;
	struct instruction *insn;
	pseudo_t retval, call;
	struct ctype *ctype = NULL;
	struct symbol *fntype;
	struct context *context;

	if (!expr->ctype)
		return VOID;

	fn = expr->fn;
	fntype = fn->ctype;

	// handle builtins
	if (fntype->op && fntype->op->linearize) {
		retval = fntype->op->linearize(ep, expr);
		if (retval)
			return retval;
	}

	ctype = &fntype->ctype;

	insn = alloc_typed_instruction(OP_CALL, expr->ctype);
	add_symbol(&insn->fntypes, fntype);
	FOR_EACH_PTR(expr->args, arg) {
		pseudo_t new = linearize_expression(ep, arg);
		use_pseudo(insn, new, add_pseudo(&insn->arguments, new));
		add_symbol(&insn->fntypes, arg->ctype);
	} END_FOR_EACH_PTR(arg);

	if (fn->type == EXPR_PREOP && fn->op == '*' && is_func_type(fn->ctype))
		fn = fn->unop;

	if (fn->type == EXPR_SYMBOL) {
		call = symbol_pseudo(ep, fn->symbol);
	} else {
		call = linearize_expression(ep, fn);
	}
	use_pseudo(insn, call, &insn->func);
	retval = VOID;
	if (expr->ctype != &void_ctype)
		retval = alloc_pseudo(insn);
	insn->target = retval;
	add_one_insn(ep, insn);

	if (ctype) {
		FOR_EACH_PTR(ctype->contexts, context) {
			int in = context->in;
			int out = context->out;
			int check = 0;
			int context_diff;
			if (in < 0) {
				check = 1;
				in = 0;
			}
			if (out < 0) {
				check = 0;
				out = 0;
			}
			context_diff = out - in;
			if (check || context_diff) {
				insn = alloc_instruction(OP_CONTEXT, 0);
				insn->increment = context_diff;
				insn->check = check;
				insn->context_expr = context->context;
				add_one_insn(ep, insn);
			}
		} END_FOR_EACH_PTR(context);

		if (ctype->modifiers & MOD_NORETURN)
			add_unreachable(ep);
	}

	return retval;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0xc0, %rsp
movq %rdi, -0x10(%rbp)
movq %rsi, -0x18(%rbp)
movq $0x0, -0x48(%rbp)
movq -0x18(%rbp), %rax
cmpq $0x0, 0x10(%rax)
jne 0x1c786
leaq 0x6f633(%rip), %rax     # 0x8bdb0
movq %rax, -0x8(%rbp)
jmp 0x1cbc7
movq -0x18(%rbp), %rax
movq 0x20(%rax), %rax
movq %rax, -0x28(%rbp)
movq -0x28(%rbp), %rax
movq 0x10(%rax), %rax
movq %rax, -0x50(%rbp)
movq -0x50(%rbp), %rax
cmpq $0x0, 0x40(%rax)
je 0x1c7e8
movq -0x50(%rbp), %rax
movq 0x40(%rax), %rax
cmpq $0x0, 0x20(%rax)
je 0x1c7e8
movq -0x50(%rbp), %rax
movq 0x40(%rax), %rax
movq 0x20(%rax), %rax
movq -0x10(%rbp), %rdi
movq -0x18(%rbp), %rsi
callq *%rax
movq %rax, -0x38(%rbp)
cmpq $0x0, -0x38(%rbp)
je 0x1c7e6
movq -0x38(%rbp), %rax
movq %rax, -0x8(%rbp)
jmp 0x1cbc7
jmp 0x1c7e8
movq -0x50(%rbp), %rax
addq $0x48, %rax
addq $0x18, %rax
movq %rax, -0x48(%rbp)
movq -0x18(%rbp), %rax
movq 0x10(%rax), %rsi
movl $0x4a, %edi
callq 0x1a240
movq %rax, -0x30(%rbp)
movq -0x30(%rbp), %rdi
addq $0x30, %rdi
addq $0x10, %rdi
movq -0x50(%rbp), %rsi
callq 0x17cb0
movq -0x18(%rbp), %rax
movq 0x28(%rax), %rax
movq %rax, -0x60(%rbp)
movq -0x60(%rbp), %rax
movq %rax, -0x68(%rbp)
movq -0x60(%rbp), %rax
movq %rax, -0x70(%rbp)
cmpq $0x0, -0x60(%rbp)
jne 0x1c84b
jmp 0x1c92d
jmp 0x1c84d
movl $0x0, -0x74(%rbp)
movl -0x74(%rbp), %eax
movq -0x68(%rbp), %rcx
movw (%rcx), %cx
shlw $0x8, %cx
sarw $0x8, %cx
movswl %cx, %ecx
cmpl %ecx, %eax
jge 0x1c915
movq -0x68(%rbp), %rax
movslq -0x74(%rbp), %rcx
movq 0x18(%rax,%rcx,8), %rax
movq %rax, -0x20(%rbp)
movq -0x68(%rbp), %rax
movw (%rax), %ax
sarw $0x8, %ax
cwtl
cmpl $0x0, %eax
je 0x1c89c
cmpq $0x0, -0x20(%rbp)
jne 0x1c89c
jmp 0x1c907
movq -0x10(%rbp), %rdi
movq -0x20(%rbp), %rsi
callq 0x1bb90
movq %rax, -0x80(%rbp)
movq -0x30(%rbp), %rax
movq %rax, -0xc0(%rbp)
movq -0x80(%rbp), %rax
movq %rax, -0xb8(%rbp)
movq -0x30(%rbp), %rdi
addq $0x30, %rdi
addq $0x8, %rdi
movq -0x80(%rbp), %rsi
callq 0x1a4b0
movq -0xc0(%rbp), %rdi
movq -0xb8(%rbp), %rsi
movq %rax, %rdx
callq 0x1a290
movq -0x30(%rbp), %rdi
addq $0x30, %rdi
addq $0x10, %rdi
movq -0x20(%rbp), %rax
movq 0x10(%rax), %rsi
callq 0x17cb0
movl -0x74(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x74(%rbp)
jmp 0x1c854
jmp 0x1c917
movq -0x68(%rbp), %rax
movq 0x10(%rax), %rax
movq %rax, -0x68(%rbp)
cmpq -0x60(%rbp), %rax
jne 0x1c84d
movq -0x28(%rbp), %rax
movl (%rax), %eax
andl $0xff, %eax
cmpl $0x9, %eax
jne 0x1c965
movq -0x28(%rbp), %rax
cmpl $0x2a, 0x4(%rax)
jne 0x1c965
movq -0x28(%rbp), %rax
movq 0x10(%rax), %rdi
callq 0x1f570
cmpl $0x0, %eax
je 0x1c965
movq -0x28(%rbp), %rax
movq 0x20(%rax), %rax
movq %rax, -0x28(%rbp)
movq -0x28(%rbp), %rax
movl (%rax), %eax
andl $0xff, %eax
cmpl $0x3, %eax
jne 0x1c98c
movq -0x10(%rbp), %rdi
movq -0x28(%rbp), %rax
movq 0x20(%rax), %rsi
callq 0x1d630
movq %rax, -0x40(%rbp)
jmp 0x1c99d
movq -0x10(%rbp), %rdi
movq -0x28(%rbp), %rsi
callq 0x1bb90
movq %rax, -0x40(%rbp)
movq -0x30(%rbp), %rdi
movq -0x40(%rbp), %rsi
movq -0x30(%rbp), %rdx
addq $0x30, %rdx
callq 0x1a290
leaq 0x6f3f7(%rip), %rax     # 0x8bdb0
movq %rax, -0x38(%rbp)
movq -0x18(%rbp), %rax
leaq 0x74b30(%rip), %rcx     # 0x914f8
cmpq %rcx, 0x10(%rax)
je 0x1c9db
movq -0x30(%rbp), %rdi
callq 0x1a340
movq %rax, -0x38(%rbp)
movq -0x38(%rbp), %rcx
movq -0x30(%rbp), %rax
movq %rcx, 0x20(%rax)
movq -0x10(%rbp), %rdi
movq -0x30(%rbp), %rsi
callq 0x1b5b0
cmpq $0x0, -0x48(%rbp)
je 0x1cbbf
jmp 0x1ca01
movq -0x48(%rbp), %rax
movq 0x18(%rax), %rax
movq %rax, -0x88(%rbp)
movq -0x88(%rbp), %rax
movq %rax, -0x90(%rbp)
movq -0x88(%rbp), %rax
movq %rax, -0x98(%rbp)
cmpq $0x0, -0x88(%rbp)
jne 0x1ca3b
jmp 0x1cba0
jmp 0x1ca3d
movl $0x0, -0x9c(%rbp)
movl -0x9c(%rbp), %eax
movq -0x90(%rbp), %rcx
movw (%rcx), %cx
shlw $0x8, %cx
sarw $0x8, %cx
movswl %cx, %ecx
cmpl %ecx, %eax
jge 0x1cb7f
movq -0x90(%rbp), %rax
movslq -0x9c(%rbp), %rcx
movq 0x18(%rax,%rcx,8), %rax
movq %rax, -0x58(%rbp)
movq -0x90(%rbp), %rax
movw (%rax), %ax
sarw $0x8, %ax
cwtl
cmpl $0x0, %eax
je 0x1caa1
cmpq $0x0, -0x58(%rbp)
jne 0x1caa1
jmp 0x1cb6b
movq -0x58(%rbp), %rax
movl 0x8(%rax), %eax
movl %eax, -0xa0(%rbp)
movq -0x58(%rbp), %rax
movl 0xc(%rax), %eax
movl %eax, -0xa4(%rbp)
movl $0x0, -0xa8(%rbp)
cmpl $0x0, -0xa0(%rbp)
jge 0x1cae2
movl $0x1, -0xa8(%rbp)
movl $0x0, -0xa0(%rbp)
cmpl $0x0, -0xa4(%rbp)
jge 0x1caff
movl $0x0, -0xa8(%rbp)
movl $0x0, -0xa4(%rbp)
movl -0xa4(%rbp), %eax
subl -0xa0(%rbp), %eax
movl %eax, -0xac(%rbp)
cmpl $0x0, -0xa8(%rbp)
jne 0x1cb23
cmpl $0x0, -0xac(%rbp)
je 0x1cb69
movl $0x4f, %edi
xorl %esi, %esi
callq 0x1afb0
movq %rax, -0x30(%rbp)
movl -0xac(%rbp), %ecx
movq -0x30(%rbp), %rax
movl %ecx, 0x30(%rax)
movl -0xa8(%rbp), %ecx
movq -0x30(%rbp), %rax
movl %ecx, 0x34(%rax)
movq -0x58(%rbp), %rax
movq (%rax), %rcx
movq -0x30(%rbp), %rax
movq %rcx, 0x38(%rax)
movq -0x10(%rbp), %rdi
movq -0x30(%rbp), %rsi
callq 0x1b5b0
jmp 0x1cb6b
movl -0x9c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x9c(%rbp)
jmp 0x1ca47
jmp 0x1cb81
movq -0x90(%rbp), %rax
movq 0x10(%rax), %rax
movq %rax, -0x90(%rbp)
cmpq -0x88(%rbp), %rax
jne 0x1ca3d
movq -0x48(%rbp), %rax
movq 0x8(%rax), %rax
andq $0x10000000, %rax       # imm = 0x10000000
cmpq $0x0, %rax
je 0x1cbbd
movq -0x10(%rbp), %rdi
callq 0x1f5b0
jmp 0x1cbbf
movq -0x38(%rbp), %rax
movq %rax, -0x8(%rbp)
movq -0x8(%rbp), %rax
addq $0xc0, %rsp
popq %rbp
retq
nopw %cs:(%rax,%rax)