// File: /workspace/github_c_makefile_star2_O3/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 0x50d4
movb $0x1, 0x40(%rbx)
movq %rbx, %rdi
callq 0x3bac
leaq 0x8(%rsp), %r15
movq %rax, (%r15)
movq %rdx, 0x8(%r15)
movb $0x0, 0x40(%rbx)
movq 0x18(%r14), %rsi
movq %rbx, %rdi
callq 0x3bac
leaq 0x18(%rsp), %rcx
movq %rax, (%rcx)
movq %rdx, 0x8(%rcx)
movq %rbx, %rdi
movq %r15, %rsi
movq %rcx, %rdx
callq 0x38a2
movq %rbx, %rdi
callq 0x37d7
movq 0x48(%rbx), %rax
movq 0x58(%rbx), %rcx
leaq (%rax,%rax,4), %rax
movl $0xf, (%rcx,%rax,8)
movq %r15, %rdi
callq 0x3820
movq 0x48(%rbx), %rcx
movq 0x58(%rbx), %rdx
leaq (%rcx,%rcx,4), %rcx
movl %eax, 0x8(%rdx,%rcx,8)
jmp 0x5295
cmpl $0xd, %eax
jne 0x514d
movb $0x1, 0x40(%rbx)
movq %rbx, %rdi
callq 0x3bac
leaq 0x8(%rsp), %r15
movq %rax, (%r15)
movq %rdx, 0x8(%r15)
movb $0x0, 0x40(%rbx)
movq 0x18(%r14), %rsi
movq %rbx, %rdi
callq 0x3bac
leaq 0x18(%rsp), %rcx
movq %rax, (%rcx)
movq %rdx, 0x8(%rcx)
movq %rbx, %rdi
movq %r15, %rsi
movq %rcx, %rdx
callq 0x38a2
movq %rbx, %rdi
callq 0x37d7
movq 0x48(%rbx), %rax
leaq (%rax,%rax,4), %rax
shlq $0x3, %rax
addq 0x58(%rbx), %rax
cmpb $0x1, 0x3c(%rbx)
jne 0x521d
movl $0xf, (%rax)
leaq 0x8(%rsp), %rdi
jmp 0x50ba
movq 0x20(%rsi), %rax
movl 0x8(%rax), %ebp
testl $0xfffffffb, %ebp       # imm = 0xFFFFFFFB
jne 0x516c
movb $0x1, 0x40(%rbx)
movq %rbx, %rdi
callq 0x3bac
movb $0x0, 0x40(%rbx)
movq 0x18(%r14), %rsi
movq %rbx, %rdi
callq 0x3bac
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 0x38a2
movq %rbx, %rdi
callq 0x37d7
movq 0x48(%rbx), %rax
movq 0x58(%rbx), %rcx
leaq (%rax,%rax,4), %rax
movl $0x10, (%rcx,%rax,8)
movq %r15, %rdi
callq 0x3820
movq 0x48(%rbx), %rcx
movq 0x58(%rbx), %rdx
leaq (%rcx,%rcx,4), %rcx
movl %eax, 0x18(%rdx,%rcx,8)
testl $0xfffffffb, %ebp       # imm = 0xFFFFFFFB
jne 0x5266
movq 0x48(%rbx), %rax
movq 0x58(%rbx), %rcx
leaq (%rax,%rax,4), %rax
movb $0x1, 0x1c(%rcx,%rax,8)
movq 0x48(%rbx), %rax
movq 0x58(%rbx), %rcx
leaq (%rax,%rax,4), %rax
movl $0x0, 0x8(%rcx,%rax,8)
movq 0x20(%r14), %rax
movq 0x18(%rax), %rax
movq 0x48(%rbx), %rcx
movq 0x58(%rbx), %rdx
leaq (%rcx,%rcx,4), %rcx
movq %rax, 0x10(%rdx,%rcx,8)
jmp 0x5295
movl $0x10, (%rax)
leaq 0x8(%rsp), %rdi
callq 0x3820
movq 0x48(%rbx), %rcx
movq 0x58(%rbx), %rdx
leaq (%rcx,%rcx,4), %rcx
movl %eax, 0x18(%rdx,%rcx,8)
movq 0x48(%rbx), %rax
movq 0x58(%rbx), %rcx
leaq (%rax,%rax,4), %rax
movl $0x8, 0x8(%rcx,%rax,8)
movl 0x38(%rbx), %eax
movq 0x58(%rbx), %rcx
movq 0x48(%rbx), %rdx
leaq (%rdx,%rdx,4), %rdx
movl %eax, 0x10(%rcx,%rdx,8)
jmp 0x5295
movq 0x48(%rbx), %rax
movq 0x58(%rbx), %rcx
leaq (%rax,%rax,4), %rax
movl $0x8, 0x8(%rcx,%rax,8)
movq 0x20(%r14), %rax
movq 0x20(%rax), %rax
movl 0x28(%rax), %eax
movq 0x48(%rbx), %rcx
movq 0x58(%rbx), %rdx
leaq (%rcx,%rcx,4), %rcx
movl %eax, 0x10(%rdx,%rcx,8)
incq 0x48(%rbx)
addq $0x28, %rsp
popq %rbx
popq %r14
popq %r15
popq %rbp
retq