// File: /workspace/github_c_makefile_star2_O0/markdryan[P]subtilis/arch/arm32/arm_reg_alloc.c
// Function: subtilis_arm_reg_alloc
size_t subtilis_arm_reg_alloc(subtilis_arm_section_t *arm_s,
			      subtilis_error_t *err)
{
	subtlis_arm_walker_t walker;
	subtilis_arm_reg_ud_t ud;
	size_t retval;
	int32_t offset;
	int32_t adjusted_offset;
	int32_t arg_offset;
	int32_t int_spill_space;
	int32_t real_spill_space;

	prv_init_arm_reg_ud(&ud, arm_s, err);
	if (err->type != SUBTILIS_ERROR_OK)
		return 0;

	prv_link_basic_blocks(&ud, err);
	if (err->type != SUBTILIS_ERROR_OK)
		return 0;

	walker.user_data = &ud;
	walker.label_fn = prv_alloc_label;
	walker.directive_fn = prv_alloc_directive;
	walker.data_fn = prv_alloc_data_instr;
	walker.mul_fn = prv_alloc_mul_instr;
	walker.cmp_fn = prv_alloc_cmp_instr;
	walker.mov_fn = prv_alloc_mov_instr;
	walker.stran_fn = prv_alloc_stran_instr;
	walker.mtran_fn = prv_alloc_mtran_instr;
	walker.br_fn = prv_alloc_br_instr;
	walker.swi_fn = prv_alloc_swi_instr;
	walker.ldrc_fn = prv_alloc_ldrc_instr;
	walker.ldrp_fn = prv_alloc_ldrp_instr;
	walker.adr_fn = prv_alloc_adr_instr;
	walker.cmov_fn = prv_alloc_cmov_instr;
	walker.flags_fn = prv_alloc_flags_instr;
	walker.stran_misc_fn = NULL;
	walker.simd_fn = NULL;
	walker.signx_fn = prv_alloc_signx_instr;
	arm_s->fp_if->init_real_alloc_fn(&walker, &ud);

	subtilis_arm_walk(arm_s, &walker, err);
	if (err->type != SUBTILIS_ERROR_OK)
		goto cleanup;

	/*
	 * See the description of the stack layout above to understand
	 * this code.  The register allocators assume they are sole
	 * onwers of the stack and that any arguments of their type
	 * are the first offsets spilled.  This assumption is invalid
	 * if more than one type of argument is passed on the stack or
	 * virtual registers of any type are actually spilled.  So we
	 * need to adjust the offsets of the spill code before we
	 * insert it.  There are two offsets one for spilled registers
	 * and one for spilled arguments.  The register allocators
	 * treat spilled arguments as being contiguous with their spilled
	 * registers but this is not necessarily the case, hence the
	 * two offsets.
	 */

	/*
	 * Note the space allocated to spill arguments by the register
	 * allocators won't actually be used as their values are stored
	 * further up the stack.
	 */

	int_spill_space = (ud.int_regs->spill_max - ud.int_regs->spilt_args) *
			  ud.int_regs->reg_size;

	real_spill_space =
	    (ud.real_regs->spill_max - ud.real_regs->spilt_args) *
	    ud.real_regs->reg_size;

	offset = ud.basic_block_spill + arm_s->locals;

	/*
	 * The register allocators assign offsets to spilled registers after
	 * they have assigned offsets to any arguments passed on the stack.
	 * However, such arguments are not in reality stored as part of the
	 * virtual registers spill space, so we need to subtract these
	 * arguments to correctly compute the adjusted offset.
	 */

	adjusted_offset =
	    offset - (ud.real_regs->spilt_args * ud.real_regs->reg_size);
	arg_offset = offset + real_spill_space + int_spill_space;
	prv_insert_spill_code(&ud, ud.real_regs, adjusted_offset, arg_offset,
			      err);
	if (err->type != SUBTILIS_ERROR_OK)
		goto cleanup;

	offset += real_spill_space;
	adjusted_offset =
	    offset - (ud.int_regs->spilt_args * ud.int_regs->reg_size);
	arg_offset += ud.real_regs->spilt_args * ud.real_regs->reg_size;
	prv_insert_spill_code(&ud, ud.int_regs, adjusted_offset, arg_offset,
			      err);
	if (err->type != SUBTILIS_ERROR_OK)
		goto cleanup;

	arm_s->reg_counter = 16;

	retval = (ud.int_regs->spill_max * sizeof(int32_t)) +
		 (ud.real_regs->spill_max * sizeof(double)) +
		 ud.basic_block_spill;

	prv_free_arm_reg_ud(&ud);

	return retval;

cleanup:

	prv_free_arm_reg_ud(&ud);

	return 0;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x1b0, %rsp            # imm = 0x1B0
movq %rdi, -0x10(%rbp)
movq %rsi, -0x18(%rbp)
movq -0x10(%rbp), %rsi
movq -0x18(%rbp), %rdx
leaq -0x190(%rbp), %rdi
callq 0x77d80
movq -0x18(%rbp), %rax
cmpl $0x0, (%rax)
je 0x77a3d
movq $0x0, -0x8(%rbp)
jmp 0x77d69
movq -0x18(%rbp), %rsi
leaq -0x190(%rbp), %rdi
callq 0x78010
movq -0x18(%rbp), %rax
cmpl $0x0, (%rax)
je 0x77a63
movq $0x0, -0x8(%rbp)
jmp 0x77d69
leaq -0x190(%rbp), %rax
movq %rax, -0x140(%rbp)
leaq 0x768(%rip), %rax       # 0x781e0
movq %rax, -0x130(%rbp)
leaq 0x7ba(%rip), %rax       # 0x78240
movq %rax, -0x138(%rbp)
leaq 0x7cc(%rip), %rax       # 0x78260
movq %rax, -0x128(%rbp)
leaq 0x98e(%rip), %rax       # 0x78430
movq %rax, -0x120(%rbp)
leaq 0xba0(%rip), %rax       # 0x78650
movq %rax, -0x118(%rbp)
leaq 0xd32(%rip), %rax       # 0x787f0
movq %rax, -0x110(%rbp)
leaq 0xe54(%rip), %rax       # 0x78920
movq %rax, -0x108(%rbp)
leaq 0x1096(%rip), %rax      # 0x78b70
movq %rax, -0x100(%rbp)
leaq 0x10c8(%rip), %rax      # 0x78bb0
movq %rax, -0xf8(%rbp)
leaq 0x126a(%rip), %rax      # 0x78d60
movq %rax, -0xf0(%rbp)
leaq 0x13bc(%rip), %rax      # 0x78ec0
movq %rax, -0xe8(%rbp)
leaq 0x140e(%rip), %rax      # 0x78f20
movq %rax, -0xe0(%rbp)
leaq 0x1460(%rip), %rax      # 0x78f80
movq %rax, -0xd8(%rbp)
leaq 0x14b2(%rip), %rax      # 0x78fe0
movq %rax, -0xc8(%rbp)
leaq 0x1714(%rip), %rax      # 0x79250
movq %rax, -0xd0(%rbp)
movq $0x0, -0x30(%rbp)
movq $0x0, -0x28(%rbp)
leaq 0x1826(%rip), %rax      # 0x79380
movq %rax, -0x20(%rbp)
movq -0x10(%rbp), %rax
movq 0xc0(%rax), %rax
leaq -0x140(%rbp), %rdi
leaq -0x190(%rbp), %rsi
callq *0x80(%rax)
movq -0x10(%rbp), %rdi
movq -0x18(%rbp), %rdx
leaq -0x140(%rbp), %rsi
callq 0x75fe0
movq -0x18(%rbp), %rax
cmpl $0x0, (%rax)
je 0x77b9f
jmp 0x77d55
movq -0x188(%rbp), %rax
movq 0x38(%rax), %rax
movq -0x188(%rbp), %rcx
subq 0x50(%rcx), %rax
movq -0x188(%rbp), %rcx
imulq 0x40(%rcx), %rax
movl %eax, -0x1a8(%rbp)
movq -0x180(%rbp), %rax
movq 0x38(%rax), %rax
movq -0x180(%rbp), %rcx
subq 0x50(%rcx), %rax
movq -0x180(%rbp), %rcx
imulq 0x40(%rcx), %rax
movl %eax, -0x1ac(%rbp)
movq -0x190(%rbp), %rax
movq -0x10(%rbp), %rcx
addq 0x30(%rcx), %rax
movl %eax, -0x19c(%rbp)
movslq -0x19c(%rbp), %rax
movq -0x180(%rbp), %rcx
movq 0x50(%rcx), %rcx
movq -0x180(%rbp), %rdx
imulq 0x40(%rdx), %rcx
subq %rcx, %rax
movl %eax, -0x1a0(%rbp)
movl -0x19c(%rbp), %eax
addl -0x1ac(%rbp), %eax
addl -0x1a8(%rbp), %eax
movl %eax, -0x1a4(%rbp)
movq -0x180(%rbp), %rsi
movl -0x1a0(%rbp), %edx
movl -0x1a4(%rbp), %ecx
movq -0x18(%rbp), %r8
leaq -0x190(%rbp), %rdi
callq 0x794b0
movq -0x18(%rbp), %rax
cmpl $0x0, (%rax)
je 0x77c74
jmp 0x77d55
movl -0x1ac(%rbp), %eax
addl -0x19c(%rbp), %eax
movl %eax, -0x19c(%rbp)
movslq -0x19c(%rbp), %rax
movq -0x188(%rbp), %rcx
movq 0x50(%rcx), %rcx
movq -0x188(%rbp), %rdx
imulq 0x40(%rdx), %rcx
subq %rcx, %rax
movl %eax, -0x1a0(%rbp)
movq -0x180(%rbp), %rax
movq 0x50(%rax), %rcx
movq -0x180(%rbp), %rax
imulq 0x40(%rax), %rcx
movslq -0x1a4(%rbp), %rax
addq %rcx, %rax
movl %eax, -0x1a4(%rbp)
movq -0x188(%rbp), %rsi
movl -0x1a0(%rbp), %edx
movl -0x1a4(%rbp), %ecx
movq -0x18(%rbp), %r8
leaq -0x190(%rbp), %rdi
callq 0x794b0
movq -0x18(%rbp), %rax
cmpl $0x0, (%rax)
je 0x77d02
jmp 0x77d55
movq -0x10(%rbp), %rax
movq $0x10, (%rax)
movq -0x188(%rbp), %rax
movq 0x38(%rax), %rax
shlq $0x2, %rax
movq -0x180(%rbp), %rcx
movq 0x38(%rcx), %rcx
shlq $0x3, %rcx
addq %rcx, %rax
addq -0x190(%rbp), %rax
movq %rax, -0x198(%rbp)
leaq -0x190(%rbp), %rdi
callq 0x795d0
movq -0x198(%rbp), %rax
movq %rax, -0x8(%rbp)
jmp 0x77d69
leaq -0x190(%rbp), %rdi
callq 0x795d0
movq $0x0, -0x8(%rbp)
movq -0x8(%rbp), %rax
addq $0x1b0, %rsp            # imm = 0x1B0
popq %rbp
retq
nopw %cs:(%rax,%rax)