// File: /workspace/github_c_makefile_star2_O1/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), %r13
movq %r13, %rdi
movq %rbx, %rsi
movq %r14, %rdx
callq 0x53a00
cmpl $0x0, (%r14)
jne 0x536cb
leaq 0x90(%rsp), %r15
movq %r15, %rdi
callq 0x5e058
xorps %xmm0, %xmm0
movaps %xmm0, 0x20(%rsp)
movaps %xmm0, 0x10(%rsp)
movq 0x58(%rsp), %rsi
movq %r15, %rdi
movq %r14, %rdx
callq 0x5e080
cmpl $0x0, (%r14)
je 0x536e2
movq 0x10(%rsp), %rdi
callq 0x122c0
movq 0x18(%rsp), %rdi
callq 0x122c0
leaq 0x90(%rsp), %rdi
callq 0x5e917
cmpl $0x0, (%r14)
jne 0x536cb
leaq 0x90(%rsp), %r15
movq %r13, (%r15)
leaq 0x64e(%rip), %rax       # 0x53b94
movq %rax, 0x10(%r15)
leaq 0x667(%rip), %rax       # 0x53bb8
movq %rax, 0x8(%r15)
leaq 0x65d(%rip), %rax       # 0x53bb9
movq %rax, 0x18(%r15)
leaq 0x7ce(%rip), %rax       # 0x53d35
movq %rax, 0x20(%r15)
leaq 0x965(%rip), %rax       # 0x53ed7
movq %rax, 0x28(%r15)
leaq 0xa95(%rip), %rax       # 0x54012
movq %rax, 0x30(%r15)
leaq 0xb7d(%rip), %rax       # 0x54105
movq %rax, 0x38(%r15)
leaq 0xd3e(%rip), %rax       # 0x542d1
movq %rax, 0x40(%r15)
leaq 0xd38(%rip), %rax       # 0x542d6
movq %rax, 0x48(%r15)
leaq 0xe73(%rip), %rax       # 0x5441c
movq %rax, 0x50(%r15)
leaq 0xf3a(%rip), %rax       # 0x544ee
movq %rax, 0x58(%r15)
leaq 0xf5b(%rip), %rax       # 0x5451a
movq %rax, 0x60(%r15)
leaq 0xf7c(%rip), %rax       # 0x54546
movq %rax, 0x68(%r15)
leaq 0xf9d(%rip), %rax       # 0x54572
movq %rax, 0x78(%r15)
leaq 0x10e5(%rip), %rax      # 0x546c5
movq %rax, 0x70(%r15)
xorps %xmm0, %xmm0
movups %xmm0, 0x110(%r15)
leaq 0x1183(%rip), %rax      # 0x54779
movq %rax, 0x120(%r15)
movq 0xc0(%rbx), %rax
movq %r15, %rdi
movq %r13, %rsi
callq *0x80(%rax)
movq %rbx, %rdi
movq %r15, %rsi
movq %r14, %rdx
callq 0x528e8
cmpl $0x0, (%r14)
jne 0x536ad
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 0x54843
cmpl $0x0, (%r14)
jne 0x536ad
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 0x54843
cmpl $0x0, (%r14)
je 0x539cf
movq 0x50(%rsp), %rdi
callq 0x5572a
movq 0x48(%rsp), %rdi
callq 0x5572a
movq 0x78(%rsp), %rdi
callq 0x122c0
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)
movl $0x8, %esi
callq 0x12150
movq %rax, 0x78(%rsp)
testq %rax, %rax
je 0x539b1
leaq 0xc0(%rsp), %rdi
leaq 0x20(%rsp), %r15
movq %r15, %rsi
movq %r14, %rdx
callq 0x5df9f
movq %rax, -0x10(%r15)
cmpl $0x0, (%r14)
jne 0x53748
leaq 0xd8(%rsp), %rdi
leaq 0x28(%rsp), %r15
movq %r15, %rsi
movq %r14, %rdx
callq 0x5df9f
movq %rax, -0x10(%r15)
cmpl $0x0, (%r14)
jne 0x53509
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 0x5576a
cmpl $0x0, (%r14)
jne 0x53509
cmpq $0x2, 0x98(%rsp)
jb 0x53509
movl $0x1, %r12d
movq %rbx, 0x38(%rsp)
movq 0x90(%rsp), %rbx
imulq $0x130, %r12, %rdx      # imm = 0x130
movq 0x58(%rsp), %rcx
movq 0x38(%rcx), %rax
movq %rdx, 0x8(%rsp)
imulq $0x68, 0x8(%rbx,%rdx), %rdx
movq (%rax), %rbp
movq 0x58(%rbp,%rdx), %rax
cmpq 0x28(%rcx), %rax
je 0x5395b
addq 0x8(%rsp), %rbx
imulq $0x68, %rax, %rax
addq %rax, %rbp
cmpl $0x0, 0x20(%rbx)
js 0x538aa
leaq 0x18(%rbx), %r15
xorl %r13d, %r13d
movq %r15, %rdi
movq %r13, %rsi
callq 0x5dc3d
testb %al, %al
je 0x53896
leaq 0x10(%rsp), %rdi
movq %r13, %rsi
movq %r14, %rdx
callq 0x55c67
cmpl $0x0, (%r14)
jne 0x5395b
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 0x53869
subq $0x8, %rsp
movl $0xb, %r9d
movq %rbp, %rsi
movl $0x12, %edx
movl $0xe, %ecx
movq %r13, %r8
pushq %r14
pushq %r10
pushq %r13
callq 0x50928
addq $0x20, %rsp
jmp 0x5388c
movl $0xb, %r9d
movq %rbp, %rsi
movl $0x12, %edx
movl $0xe, %ecx
movq %r13, %r8
pushq %r14
pushq %r10
callq 0x509cb
addq $0x10, %rsp
cmpl $0x0, (%r14)
jne 0x5395b
leaq 0x1(%r13), %rax
movslq 0x20(%rbx), %rcx
cmpq %rcx, %r13
movq %rax, %r13
jl 0x537f7
cmpl $0x0, 0x38(%rbx)
js 0x5395b
leaq 0x30(%rbx), %r15
xorl %r13d, %r13d
movq %r15, %rdi
movq %r13, %rsi
callq 0x5dc3d
testb %al, %al
je 0x53947
leaq 0x10(%rsp), %rdi
movq %r13, %rsi
movq %r14, %rdx
callq 0x55ca5
cmpl $0x0, (%r14)
jne 0x5395b
movq 0x58(%rsp), %rdi
addl 0x30(%rdi), %eax
movq 0xc0(%rdi), %r10
movl 0x8(%r10), %ecx
movl 0x1c(%r10), %edx
cmpl %eax, %ecx
jl 0x5391f
notl %ecx
cmpl %ecx, %eax
jl 0x5391f
movl $0xb, %r9d
movq %rbp, %rsi
movl $0xe, %ecx
movq %r13, %r8
pushq %r14
pushq %rax
callq *0x60(%r10)
addq $0x10, %rsp
jmp 0x53941
subq $0x8, %rsp
movl $0xb, %r9d
movq %rbp, %rsi
movl $0xe, %ecx
movq %r13, %r8
pushq %r14
pushq %rax
pushq %r13
callq *0x58(%r10)
addq $0x20, %rsp
cmpl $0x0, (%r14)
jne 0x5395b
leaq 0x1(%r13), %rax
movslq 0x38(%rbx), %rcx
cmpq %rcx, %r13
movq %rax, %r13
jl 0x538bb
cmpl $0x0, (%r14)
movq 0x38(%rsp), %rbx
leaq 0x40(%rsp), %r13
jne 0x53509
movq 0x8(%rsp), %rsi
addq 0x90(%rsp), %rsi
leaq 0x40(%rsp), %rdi
leaq 0x10(%rsp), %rdx
movq %r12, %rcx
movq %r14, %r8
callq 0x5576a
cmpl $0x0, (%r14)
jne 0x53509
incq %r12
cmpq 0x98(%rsp), %r12
jb 0x537a5
jmp 0x53509
leaq 0x22223(%rip), %rdx     # 0x75bdb
movq %r14, %rdi
movl $0x1, %esi
movl $0x741, %ecx            # imm = 0x741
callq 0x145f4
jmp 0x53509
movq $0x10, (%rbx)
leaq 0x40(%rsp), %rdi
movq 0x8(%rdi), %rax
movq 0x10(%rdi), %rcx
movq 0x38(%rax), %rax
shlq $0x2, %rax
movq 0x38(%rcx), %rcx
leaq (%rax,%rcx,8), %rbx
addq (%rdi), %rbx
callq 0x54a5a
jmp 0x536cd