// File: /workspace/github_c_makefile_star2_O2/Encryptr[P]O-plus-plus/opp/compiler/compile_stmt.c
// Function: opp_compile_assign
static void opp_compile_assign(struct Opp_Context* opp, struct Opp_Node* node)
{
	struct Opp_Expr_Assign* assign = &node->assign_expr;

	switch (assign->ident->type)
	{
		case EDEREF:
		case EELEMENT:
			opp_compile_ptr_assign(opp, assign);
			return;
			break;

		case EDOT:
			opp_assign_dot(opp, assign);
			return;
			break;

		default: break;
	}

	bool global = assign->ident->unary_expr.bidx->type == TYPE_GLOBAL || 
			assign->ident->unary_expr.bidx->type == TYPE_EXTERN;

	if (global) {
		NEED_ADDR();
		opp_compile_expr(opp, assign->ident);
		REVERT();
	}

	Opp_Obj rhs = opp_compile_expr(opp, assign->val);
	Opp_Obj* lhs = &assign->ident->unary_expr.bidx->sym_type;

	opp_type_cast(opp, lhs, &rhs);
	
	OPCODE_START();
		OPCODE_TYPE(OPCODE_ASSIGN);
		opp->ir.opcodes[opp->ir.instr_idx].set.loc_type = opp_type_to_ir(lhs);
		if (global) {
			opp->ir.opcodes[opp->ir.instr_idx].set.global = true;
			opp->ir.opcodes[opp->ir.instr_idx].set.val.type = IMM_SYM;
			opp->ir.opcodes[opp->ir.instr_idx].set.val.imm_sym = 
				assign->ident->unary_expr.val.strval;
		}
		else {
			opp->ir.opcodes[opp->ir.instr_idx].set.val.type = IMM_I32;
			opp->ir.opcodes[opp->ir.instr_idx].set.val.imm_i32 = 
				assign->ident->unary_expr.bidx->offset;
		}
	OPCODE_END();
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %rbx
subq $0x28, %rsp
movq %rsi, %r14
movq %rdi, %rbx
movq 0x20(%rsi), %rsi
movl (%rsi), %eax
leal -0x7(%rax), %ecx
cmpl $0x2, %ecx
jae 0x4eb6
movb $0x1, 0x40(%rbx)
movq %rbx, %rdi
callq 0x3abc
leaq 0x8(%rsp), %r15
movq %rax, (%r15)
movq %rdx, 0x8(%r15)
movb $0x0, 0x40(%rbx)
movq 0x18(%r14), %rsi
movq %rbx, %rdi
callq 0x3abc
leaq 0x18(%rsp), %rcx
movq %rax, (%rcx)
movq %rdx, 0x8(%rcx)
movq %rbx, %rdi
movq %r15, %rsi
movq %rcx, %rdx
callq 0x37e2
movq %rbx, %rdi
callq 0x3725
movq 0x58(%rbx), %rax
imulq $0x28, 0x48(%rbx), %rcx
movl $0xf, (%rax,%rcx)
movq %r15, %rdi
callq 0x3766
movq 0x58(%rbx), %rcx
imulq $0x28, 0x48(%rbx), %rdx
movl %eax, 0x8(%rcx,%rdx)
jmp 0x503e
cmpl $0xd, %eax
jne 0x4f28
movb $0x1, 0x40(%rbx)
movq %rbx, %rdi
callq 0x3abc
leaq 0x8(%rsp), %r15
movq %rax, (%r15)
movq %rdx, 0x8(%r15)
movb $0x0, 0x40(%rbx)
movq 0x18(%r14), %rsi
movq %rbx, %rdi
callq 0x3abc
leaq 0x18(%rsp), %rcx
movq %rax, (%rcx)
movq %rdx, 0x8(%rcx)
movq %rbx, %rdi
movq %r15, %rsi
movq %rcx, %rdx
callq 0x37e2
movq %rbx, %rdi
callq 0x3725
imulq $0x28, 0x48(%rbx), %rax
addq 0x58(%rbx), %rax
cmpb $0x1, 0x3c(%rbx)
jne 0x4fe2
movl $0xf, (%rax)
leaq 0x8(%rsp), %rdi
jmp 0x4e9f
movq 0x20(%rsi), %rax
movl 0x8(%rax), %ebp
testl $0xfffffffb, %ebp       # imm = 0xFFFFFFFB
jne 0x4f47
movb $0x1, 0x40(%rbx)
movq %rbx, %rdi
callq 0x3abc
movb $0x0, 0x40(%rbx)
movq 0x18(%r14), %rsi
movq %rbx, %rdi
callq 0x3abc
leaq 0x8(%rsp), %rcx
movq %rax, (%rcx)
movq %rdx, 0x8(%rcx)
movq 0x20(%r14), %rax
movq 0x20(%rax), %r15
addq $0x10, %r15
movq %rbx, %rdi
movq %r15, %rsi
movq %rcx, %rdx
callq 0x37e2
movq %rbx, %rdi
callq 0x3725
movq 0x58(%rbx), %rax
imulq $0x28, 0x48(%rbx), %rcx
movl $0x10, (%rax,%rcx)
movq %r15, %rdi
callq 0x3766
movq 0x58(%rbx), %rcx
imulq $0x28, 0x48(%rbx), %rdx
movl %eax, 0x18(%rcx,%rdx)
testl $0xfffffffb, %ebp       # imm = 0xFFFFFFFB
jne 0x5015
imulq $0x28, 0x48(%rbx), %rax
movq 0x58(%rbx), %rcx
movb $0x1, 0x1c(%rcx,%rax)
imulq $0x28, 0x48(%rbx), %rax
movq 0x58(%rbx), %rcx
andl $0x0, 0x8(%rcx,%rax)
movq 0x20(%r14), %rax
movq 0x18(%rax), %rax
movq 0x58(%rbx), %rcx
imulq $0x28, 0x48(%rbx), %rdx
movq %rax, 0x10(%rcx,%rdx)
jmp 0x503e
movl $0x10, (%rax)
leaq 0x8(%rsp), %rdi
callq 0x3766
movq 0x58(%rbx), %rcx
imulq $0x28, 0x48(%rbx), %rdx
movl %eax, 0x18(%rcx,%rdx)
movq 0x58(%rbx), %rax
imulq $0x28, 0x48(%rbx), %rcx
movl $0x8, 0x8(%rax,%rcx)
movl 0x38(%rbx), %eax
jmp 0x5031
movq 0x58(%rbx), %rax
imulq $0x28, 0x48(%rbx), %rcx
movl $0x8, 0x8(%rax,%rcx)
movq 0x20(%r14), %rax
movq 0x20(%rax), %rax
movl 0x28(%rax), %eax
movq 0x58(%rbx), %rcx
imulq $0x28, 0x48(%rbx), %rdx
movl %eax, 0x10(%rcx,%rdx)
incq 0x48(%rbx)
addq $0x28, %rsp
popq %rbx
popq %r14
popq %r15
popq %rbp
retq