// File: /workspace/github_c_makefile_star2_O2/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
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x1b8, %rsp            # imm = 0x1B8
movq %rsi, %r14
movq %rdi, %rbx
leaq 0x40(%rsp), %r15
movq %r15, %rdi
movq %rbx, %rsi
movq %r14, %rdx
callq 0x5048a
cmpl $0x0, (%r14)
jne 0x4ffe1
leaq 0x90(%rsp), %r12
movq %r12, %rdi
callq 0x59ea8
xorps %xmm0, %xmm0
movaps %xmm0, 0x20(%rsp)
movaps %xmm0, 0x10(%rsp)
movq 0x58(%rsp), %rsi
movq %r12, %rdi
movq %r14, %rdx
callq 0x59ed0
cmpl $0x0, (%r14)
je 0x4fff8
movq 0x10(%rsp), %rdi
callq 0x122c0
movq 0x18(%rsp), %rdi
callq 0x122c0
leaq 0x90(%rsp), %rdi
callq 0x5a6ce
cmpl $0x0, (%r14)
je 0x502ae
xorl %ebx, %ebx
movq %rbx, %rax
addq $0x1b8, %rsp            # imm = 0x1B8
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movq 0x98(%rsp), %rdi
movq %rdi, 0x88(%rsp)
pushq $0x8
popq %rsi
callq 0x12150
movq %rax, 0x78(%rsp)
testq %rax, %rax
je 0x50446
leaq 0xc0(%rsp), %rdi
leaq 0x20(%rsp), %r12
movq %r12, %rsi
movq %r14, %rdx
callq 0x59e04
movq %rax, -0x10(%r12)
cmpl $0x0, (%r14)
jne 0x4ffb6
leaq 0xd8(%rsp), %rdi
leaq 0x28(%rsp), %r12
movq %r12, %rsi
movq %r14, %rdx
callq 0x59e04
movq %rax, -0x10(%r12)
cmpl $0x0, (%r14)
jne 0x4ffb6
leaq 0x10(%rsp), %rdx
movq 0x10(%rdx), %rax
movq 0x18(%rdx), %rcx
shlq $0x2, %rax
leaq (%rax,%rcx,8), %rax
leaq 0x40(%rsp), %rdi
movq %rax, (%rdi)
movq 0x90(%rsp), %rsi
xorl %ecx, %ecx
movq %r14, %r8
callq 0x51ffc
cmpl $0x0, (%r14)
jne 0x4ffb6
pushq $0x1
popq %rax
movq %rax, (%rsp)
movq (%rsp), %rax
cmpq 0x98(%rsp), %rax
jae 0x4ffb6
movq 0x90(%rsp), %r13
imulq $0x130, (%rsp), %rsi    # imm = 0x130
movq 0x58(%rsp), %rcx
movq 0x38(%rcx), %rax
imulq $0x68, 0x8(%r13,%rsi), %rdx
movq (%rax), %rdi
movq 0x58(%rdi,%rdx), %rax
cmpq 0x28(%rcx), %rax
je 0x50279
movq %rsi, 0x38(%rsp)
addq %rsi, %r13
imulq $0x68, %rax, %rax
addq %rax, %rdi
movq %rdi, 0x8(%rsp)
leaq 0x18(%r13), %r12
xorl %ebp, %ebp
movslq 0x20(%r13), %rax
cmpq %rax, %rbp
jg 0x501b2
movq %r12, %rdi
movq %rbp, %rsi
callq 0x59b05
testb %al, %al
je 0x501aa
leaq 0x10(%rsp), %rdi
movq %rbp, %rsi
movq %r14, %rdx
callq 0x524c1
cmpl $0x0, (%r14)
jne 0x4ffb6
movq 0x58(%rsp), %rdi
movl 0x30(%rdi), %ecx
leal (%rcx,%rax), %r10d
addl %ecx, %eax
addl $0xfffff000, %eax       # imm = 0xFFFFF000
cmpl $0xffffe000, %eax       # imm = 0xFFFFE000
ja 0x50183
subq $0x8, %rsp
movq 0x10(%rsp), %rsi
pushq $0x12
popq %rdx
pushq $0xe
popq %rcx
movq %rbp, %r8
pushq $0xb
popq %r9
pushq %r14
pushq %r10
pushq %rbp
callq 0x4d75d
addq $0x20, %rsp
jmp 0x501a0
movq 0x8(%rsp), %rsi
pushq $0x12
popq %rdx
pushq $0xe
popq %rcx
movq %rbp, %r8
pushq $0xb
popq %r9
pushq %r14
pushq %r10
callq 0x4d7e4
popq %rax
popq %rcx
cmpl $0x0, (%r14)
jne 0x4ffb6
incq %rbp
jmp 0x50109
leaq 0x30(%r13), %rbp
xorl %r12d, %r12d
movslq 0x38(%r13), %rax
cmpq %rax, %r12
jg 0x50262
movq %rbp, %rdi
movq %r12, %rsi
callq 0x59b05
testb %al, %al
je 0x5025a
leaq 0x10(%rsp), %rdi
movq %r12, %rsi
movq %r14, %rdx
callq 0x524fb
cmpl $0x0, (%r14)
jne 0x4ffb6
movq 0x58(%rsp), %rdi
addl 0x30(%rdi), %eax
movq 0xc0(%rdi), %r10
movl 0x8(%r10), %ecx
movl 0x1c(%r10), %edx
cmpl %eax, %ecx
jl 0x50230
notl %ecx
cmpl %ecx, %eax
jl 0x50230
movq 0x8(%rsp), %rsi
pushq $0xe
popq %rcx
movq %r12, %r8
pushq $0xb
popq %r9
pushq %r14
pushq %rax
callq *0x60(%r10)
addq $0x10, %rsp
jmp 0x50250
subq $0x8, %rsp
movq 0x10(%rsp), %rsi
pushq $0xe
popq %rcx
movq %r12, %r8
pushq $0xb
popq %r9
pushq %r14
pushq %rax
pushq %r12
callq *0x58(%r10)
addq $0x20, %rsp
cmpl $0x0, (%r14)
jne 0x4ffb6
incq %r12
jmp 0x501b9
cmpl $0x0, (%r14)
jne 0x4ffb6
movq 0x90(%rsp), %r13
movq 0x38(%rsp), %rsi
addq %rsi, %r13
leaq 0x40(%rsp), %rdi
movq %r13, %rsi
leaq 0x10(%rsp), %rdx
movq (%rsp), %r12
movq %r12, %rcx
movq %r14, %r8
callq 0x51ffc
incq %r12
movq %r12, (%rsp)
cmpl $0x0, (%r14)
je 0x500ac
jmp 0x4ffb6
leaq 0x90(%rsp), %r12
movq %r15, (%r12)
leaq 0x353(%rip), %rax       # 0x50614
movq %rax, 0x10(%r12)
leaq 0x36b(%rip), %rax       # 0x50638
movq %rax, 0x8(%r12)
leaq 0x360(%rip), %rax       # 0x50639
movq %rax, 0x18(%r12)
leaq 0x4a5(%rip), %rax       # 0x5078a
movq %rax, 0x20(%r12)
leaq 0x630(%rip), %rax       # 0x50921
movq %rax, 0x28(%r12)
leaq 0x73b(%rip), %rax       # 0x50a38
movq %rax, 0x30(%r12)
leaq 0x808(%rip), %rax       # 0x50b11
movq %rax, 0x38(%r12)
leaq 0x9bd(%rip), %rax       # 0x50cd2
movq %rax, 0x40(%r12)
leaq 0x9b6(%rip), %rax       # 0x50cd7
movq %rax, 0x48(%r12)
leaq 0xad2(%rip), %rax       # 0x50dff
movq %rax, 0x50(%r12)
leaq 0xb90(%rip), %rax       # 0x50ec9
movq %rax, 0x58(%r12)
leaq 0xbac(%rip), %rax       # 0x50ef1
movq %rax, 0x60(%r12)
leaq 0xbc8(%rip), %rax       # 0x50f19
movq %rax, 0x68(%r12)
leaq 0xbe4(%rip), %rax       # 0x50f41
movq %rax, 0x78(%r12)
leaq 0xd25(%rip), %rax       # 0x5108e
movq %rax, 0x70(%r12)
xorps %xmm0, %xmm0
movups %xmm0, 0x110(%r12)
leaq 0xdb6(%rip), %rax       # 0x51137
movq %rax, 0x120(%r12)
movq 0xc0(%rbx), %rax
movq %r12, %rdi
movq %r15, %rsi
callq *0x80(%rax)
movq %rbx, %rdi
movq %r12, %rsi
movq %r14, %rdx
callq 0x4f404
cmpl $0x0, (%r14)
jne 0x50435
leaq 0x40(%rsp), %rdi
movq 0x8(%rdi), %rax
movl 0x38(%rax), %ebp
subl 0x50(%rax), %ebp
movq 0x10(%rdi), %rsi
imull 0x40(%rax), %ebp
movl 0x50(%rsi), %eax
movl 0x38(%rsi), %ecx
movl 0x40(%rsi), %r8d
subl %eax, %ecx
imull %r8d, %ecx
movl 0x30(%rbx), %r15d
addl (%rdi), %r15d
imull %eax, %r8d
movl %r15d, %edx
subl %r8d, %edx
addl %ecx, %r15d
addl %r15d, %ebp
movl %ebp, %ecx
movq %r14, %r8
callq 0x511f4
cmpl $0x0, (%r14)
jne 0x50435
leaq 0x40(%rsp), %rdi
movq 0x8(%rdi), %rsi
movq 0x10(%rdi), %rax
movl 0x40(%rsi), %ecx
imull 0x50(%rsi), %ecx
subl %ecx, %r15d
movl 0x40(%rax), %ecx
imull 0x50(%rax), %ecx
addl %ecx, %ebp
movl %r15d, %edx
movl %ebp, %ecx
movq %r14, %r8
callq 0x511f4
cmpl $0x0, (%r14)
je 0x50462
xorl %ebx, %ebx
leaq 0x40(%rsp), %rdi
callq 0x513cc
jmp 0x4ffe3
leaq 0x1f75e(%rip), %rdx     # 0x6fbab
pushq $0x1
popq %rsi
movq %r14, %rdi
movl $0x741, %ecx            # imm = 0x741
callq 0x1429e
jmp 0x4ffb6
movq $0x10, (%rbx)
movq 0x48(%rsp), %rax
movq 0x50(%rsp), %rcx
movq 0x38(%rax), %rax
shlq $0x2, %rax
movq 0x38(%rcx), %rcx
leaq (%rax,%rcx,8), %rbx
addq 0x40(%rsp), %rbx
jmp 0x50437