// File: /workspace/github_c_makefile_star2_O0/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:
subq $0x58, %rsp
movq %rdi, 0x50(%rsp)
movq %rsi, 0x48(%rsp)
movq 0x48(%rsp), %rax
addq $0x10, %rax
movq %rax, 0x40(%rsp)
movq 0x40(%rsp), %rax
movq 0x10(%rax), %rax
movl (%rax), %eax
movl %eax, 0xc(%rsp)
addl $-0x7, %eax
subl $0x2, %eax
jb 0x81a0
jmp 0x8195
movl 0xc(%rsp), %eax
subl $0xd, %eax
je 0x81b4
jmp 0x81c8
movq 0x50(%rsp), %rdi
movq 0x40(%rsp), %rsi
callq 0x8db0
jmp 0x838b
movq 0x50(%rsp), %rdi
movq 0x40(%rsp), %rsi
callq 0x8e80
jmp 0x838b
jmp 0x81ca
movq 0x40(%rsp), %rax
movq 0x10(%rax), %rax
movq 0x20(%rax), %rcx
movb $0x1, %al
cmpl $0x0, 0x8(%rcx)
movb %al, 0xb(%rsp)
je 0x81fb
movq 0x40(%rsp), %rax
movq 0x10(%rax), %rax
movq 0x20(%rax), %rax
cmpl $0x4, 0x8(%rax)
sete %al
movb %al, 0xb(%rsp)
movb 0xb(%rsp), %al
andb $0x1, %al
movb %al, 0x3f(%rsp)
testb $0x1, 0x3f(%rsp)
je 0x823b
movq 0x50(%rsp), %rax
movb $0x1, 0x40(%rax)
movq 0x50(%rsp), %rdi
movq 0x40(%rsp), %rax
movq 0x10(%rax), %rsi
callq 0x5d60
movq %rax, 0x28(%rsp)
movq %rdx, 0x30(%rsp)
movq 0x50(%rsp), %rax
movb $0x0, 0x40(%rax)
movq 0x50(%rsp), %rdi
movq 0x40(%rsp), %rax
movq 0x8(%rax), %rsi
callq 0x5d60
movq %rax, 0x18(%rsp)
movq %rdx, 0x20(%rsp)
movq 0x40(%rsp), %rax
movq 0x10(%rax), %rax
movq 0x20(%rax), %rax
addq $0x10, %rax
movq %rax, 0x10(%rsp)
movq 0x50(%rsp), %rdi
movq 0x10(%rsp), %rsi
leaq 0x18(%rsp), %rdx
callq 0x5820
movq 0x50(%rsp), %rdi
callq 0x5600
movq 0x50(%rsp), %rax
movq 0x58(%rax), %rax
movq 0x50(%rsp), %rcx
imulq $0x28, 0x48(%rcx), %rcx
addq %rcx, %rax
movl $0x10, (%rax)
movq 0x10(%rsp), %rdi
callq 0x5670
movl %eax, %ecx
movq 0x50(%rsp), %rax
movq 0x58(%rax), %rax
movq 0x50(%rsp), %rdx
imulq $0x28, 0x48(%rdx), %rdx
addq %rdx, %rax
movl %ecx, 0x18(%rax)
testb $0x1, 0x3f(%rsp)
je 0x8334
movq 0x50(%rsp), %rax
movq 0x58(%rax), %rax
movq 0x50(%rsp), %rcx
imulq $0x28, 0x48(%rcx), %rcx
addq %rcx, %rax
movb $0x1, 0x1c(%rax)
movq 0x50(%rsp), %rax
movq 0x58(%rax), %rax
movq 0x50(%rsp), %rcx
imulq $0x28, 0x48(%rcx), %rcx
addq %rcx, %rax
movl $0x0, 0x8(%rax)
movq 0x40(%rsp), %rax
movq 0x10(%rax), %rax
movq 0x18(%rax), %rcx
movq 0x50(%rsp), %rax
movq 0x58(%rax), %rax
movq 0x50(%rsp), %rdx
imulq $0x28, 0x48(%rdx), %rdx
addq %rdx, %rax
movq %rcx, 0x10(%rax)
jmp 0x837a
movq 0x50(%rsp), %rax
movq 0x58(%rax), %rax
movq 0x50(%rsp), %rcx
imulq $0x28, 0x48(%rcx), %rcx
addq %rcx, %rax
movl $0x8, 0x8(%rax)
movq 0x40(%rsp), %rax
movq 0x10(%rax), %rax
movq 0x20(%rax), %rax
movl 0x28(%rax), %ecx
movq 0x50(%rsp), %rax
movq 0x58(%rax), %rax
movq 0x50(%rsp), %rdx
imulq $0x28, 0x48(%rdx), %rdx
addq %rdx, %rax
movl %ecx, 0x10(%rax)
movq 0x50(%rsp), %rax
movq 0x48(%rax), %rcx
addq $0x1, %rcx
movq %rcx, 0x48(%rax)
addq $0x58, %rsp
retq