// File: /workspace/github_c_makefile_star2_O0/markdryan[P]subtilis/frontend/reference_type.c
// Function: subtilis_reference_type_pop_and_deref
void subtilis_reference_type_pop_and_deref(subtilis_parser_t *p,
					   subtilis_error_t *err)
{
	size_t reg;
	subtilis_ir_operand_t op2;
	subtilis_ir_operand_t dest;
	size_t fn_addr;
	subtilis_ir_arg_t *ir_args = malloc(sizeof(*ir_args));

	if (!ir_args) {
		subtilis_error_set_oom(err);
		return;
	}

	fn_addr = subtilis_ir_section_add_instr1(
	    p->current, SUBTILIS_OP_INSTR_POP_I32, err);
	if (err->type != SUBTILIS_ERROR_OK)
		return;

	reg = subtilis_ir_section_add_instr1(p->current,
					     SUBTILIS_OP_INSTR_POP_I32, err);
	if (err->type != SUBTILIS_ERROR_OK)
		return;

	ir_args[0].type = SUBTILIS_IR_REG_TYPE_INTEGER;
	ir_args[0].reg = reg;
	ir_args[0].nop = SIZE_MAX;

	subtilis_ir_section_add_call_ptr(p->current, 1, ir_args, fn_addr, err);
	if (err->type != SUBTILIS_ERROR_OK)
		return;

	if (p->current->cleanup_stack == SIZE_MAX) {
		subtilis_error_set_assertion_failed(err);
		return;
	}

	/*
	 * TODO: The part of the register allocator that preserves
	 * live registers between basic blocks can't handle the case
	 * when an instruction uses the same register for both source
	 * and destination.  Ultimately, all that code is going to dissapear
	 * when we have a global register allocator, so for now we're just
	 * going to live with it.
	 */

	/*
	 * H'mm, I think I may have fixed this so
	 * this comment may no longer be valid.
	 */

	op2.integer = 1;
	dest.reg = p->current->cleanup_stack;
	op2.reg = subtilis_ir_section_add_instr(
	    p->current, SUBTILIS_OP_INSTR_SUBI_I32, dest, op2, err);
	if (err->type != SUBTILIS_ERROR_OK)
		return;

	subtilis_ir_section_add_instr_no_reg2(p->current, SUBTILIS_OP_INSTR_MOV,
					      dest, op2, err);
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x40, %rsp
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movl $0x18, %edi
callq 0x121b0
movq %rax, -0x38(%rbp)
cmpq $0x0, -0x38(%rbp)
jne 0x6f3a4
movq -0x10(%rbp), %rdi
movl $0x1, %esi
leaq 0x3d6ed(%rip), %rdx     # 0xaca82
movl $0x540, %ecx            # imm = 0x540
callq 0x158e0
jmp 0x6f4d5
movq -0x8(%rbp), %rax
movq 0x48(%rax), %rdi
movq -0x10(%rbp), %rdx
movl $0x7c, %esi
callq 0x384e0
movq %rax, -0x30(%rbp)
movq -0x10(%rbp), %rax
cmpl $0x0, (%rax)
je 0x6f3cc
jmp 0x6f4d5
movq -0x8(%rbp), %rax
movq 0x48(%rax), %rdi
movq -0x10(%rbp), %rdx
movl $0x7c, %esi
callq 0x384e0
movq %rax, -0x18(%rbp)
movq -0x10(%rbp), %rax
cmpl $0x0, (%rax)
je 0x6f3f4
jmp 0x6f4d5
movq -0x38(%rbp), %rax
movl $0x0, (%rax)
movq -0x18(%rbp), %rcx
movq -0x38(%rbp), %rax
movq %rcx, 0x8(%rax)
movq -0x38(%rbp), %rax
movq $-0x1, 0x10(%rax)
movq -0x8(%rbp), %rax
movq 0x48(%rax), %rdi
movq -0x38(%rbp), %rdx
movq -0x30(%rbp), %rcx
movq -0x10(%rbp), %r8
movl $0x1, %esi
callq 0x39f60
movq -0x10(%rbp), %rax
cmpl $0x0, (%rax)
je 0x6f442
jmp 0x6f4d5
movq -0x8(%rbp), %rax
movq 0x48(%rax), %rax
cmpq $-0x1, 0xb8(%rax)
jne 0x6f470
movq -0x10(%rbp), %rdi
movl $0xf, %esi
leaq 0x3d61e(%rip), %rdx     # 0xaca82
movl $0x557, %ecx            # imm = 0x557
callq 0x158e0
jmp 0x6f4d5
movl $0x1, -0x20(%rbp)
movq -0x8(%rbp), %rax
movq 0x48(%rax), %rax
movq 0xb8(%rax), %rax
movq %rax, -0x28(%rbp)
movq -0x8(%rbp), %rax
movq 0x48(%rax), %rdi
movq -0x10(%rbp), %r8
movq -0x28(%rbp), %rdx
movq -0x20(%rbp), %rcx
movl $0xb, %esi
callq 0x38230
movq %rax, -0x20(%rbp)
movq -0x10(%rbp), %rax
cmpl $0x0, (%rax)
je 0x6f4b7
jmp 0x6f4d5
movq -0x8(%rbp), %rax
movq 0x48(%rax), %rdi
movq -0x10(%rbp), %r8
movq -0x28(%rbp), %rdx
movq -0x20(%rbp), %rcx
movl $0x1d, %esi
callq 0x385a0
addq $0x40, %rsp
popq %rbp
retq
nopl (%rax,%rax)