// File: /workspace/github_c_makefile_star2_O3/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 0x538a3
cmpl $0x0, (%r14)
jne 0x53549
leaq 0x90(%rsp), %r12
movq %r12, %rdi
callq 0x5e060
xorps %xmm0, %xmm0
movaps %xmm0, 0x30(%rsp)
movaps %xmm0, 0x20(%rsp)
movq 0x58(%rsp), %rsi
movq %r12, %rdi
movq %r14, %rdx
callq 0x5e088
cmpl $0x0, (%r14)
je 0x53560
movq 0x20(%rsp), %rdi
callq 0x122c0
movq 0x28(%rsp), %rdi
callq 0x122c0
leaq 0x90(%rsp), %rdi
callq 0x5e927
cmpl $0x0, (%r14)
jne 0x53549
leaq 0x90(%rsp), %r12
movq %r15, (%r12)
leaq 0x684(%rip), %rax       # 0x53a37
movq %rax, 0x10(%r12)
leaq 0x69c(%rip), %rax       # 0x53a5b
movq %rax, 0x8(%r12)
leaq 0x691(%rip), %rax       # 0x53a5c
movq %rax, 0x18(%r12)
leaq 0x823(%rip), %rax       # 0x53bfa
movq %rax, 0x20(%r12)
leaq 0x9b9(%rip), %rax       # 0x53d9c
movq %rax, 0x28(%r12)
leaq 0xaf6(%rip), %rax       # 0x53ee5
movq %rax, 0x30(%r12)
leaq 0xbf8(%rip), %rax       # 0x53ff3
movq %rax, 0x38(%r12)
leaq 0xdbe(%rip), %rax       # 0x541c5
movq %rax, 0x40(%r12)
leaq 0xdb7(%rip), %rax       # 0x541ca
movq %rax, 0x48(%r12)
leaq 0xedf(%rip), %rax       # 0x542fe
movq %rax, 0x50(%r12)
leaq 0xfa1(%rip), %rax       # 0x543cc
movq %rax, 0x58(%r12)
leaq 0xfc1(%rip), %rax       # 0x543f8
movq %rax, 0x60(%r12)
leaq 0xfe1(%rip), %rax       # 0x54424
movq %rax, 0x68(%r12)
leaq 0x1001(%rip), %rax      # 0x54450
movq %rax, 0x78(%r12)
leaq 0x1144(%rip), %rax      # 0x5459f
movq %rax, 0x70(%r12)
xorps %xmm0, %xmm0
movups %xmm0, 0x110(%r12)
leaq 0x11dc(%rip), %rax      # 0x5464f
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 0x5275c
cmpl $0x0, (%r14)
jne 0x5352b
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 0x5472a
cmpl $0x0, (%r14)
jne 0x5352b
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 0x5472a
cmpl $0x0, (%r14)
je 0x53872
movq 0x50(%rsp), %rdi
callq 0x558ba
movq 0x48(%rsp), %rdi
callq 0x558ba
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 0x53854
leaq 0xc0(%rsp), %rdi
leaq 0x30(%rsp), %r12
movq %r12, %rsi
movq %r14, %rdx
callq 0x5dfa6
movq %rax, -0x10(%r12)
cmpl $0x0, (%r14)
jne 0x53375
leaq 0xd8(%rsp), %rdi
leaq 0x38(%rsp), %r12
movq %r12, %rsi
movq %r14, %rdx
callq 0x5dfa6
movq %rax, -0x10(%r12)
cmpl $0x0, (%r14)
jne 0x53375
leaq 0x20(%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 0x558fa
cmpl $0x0, (%r14)
jne 0x53375
cmpq $0x2, 0x98(%rsp)
jb 0x53375
movl $0x1, %eax
movq %rax, 0x10(%rsp)
movq 0x90(%rsp), %rbp
imulq $0x130, 0x10(%rsp), %rdx # imm = 0x130
movq 0x58(%rsp), %rcx
movq 0x38(%rcx), %rax
movq %rdx, 0x18(%rsp)
imulq $0x68, 0x8(%rbp,%rdx), %rdx
movq (%rax), %rax
movq %rax, 0x8(%rsp)
movq 0x58(%rax,%rdx), %rax
cmpq 0x28(%rcx), %rax
je 0x537fc
addq 0x18(%rsp), %rbp
imulq $0x68, %rax, %rax
addq %rax, 0x8(%rsp)
cmpl $0x0, 0x20(%rbp)
js 0x5373a
leaq 0x18(%rbp), %r12
xorl %r13d, %r13d
movq %r12, %rdi
movq %r13, %rsi
callq 0x5dc45
testb %al, %al
je 0x53726
leaq 0x20(%rsp), %rdi
movq %r13, %rsi
movq %r14, %rdx
callq 0x55df7
cmpl $0x0, (%r14)
jne 0x53375
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 0x536f7
subq $0x8, %rsp
movl $0xb, %r9d
movq 0x10(%rsp), %rsi
movl $0x12, %edx
movl $0xe, %ecx
movq %r13, %r8
pushq %r14
pushq %r10
pushq %r13
callq 0x5077e
addq $0x20, %rsp
jmp 0x5371c
movl $0xb, %r9d
movq 0x8(%rsp), %rsi
movl $0x12, %edx
movl $0xe, %ecx
movq %r13, %r8
pushq %r14
pushq %r10
callq 0x50821
addq $0x10, %rsp
cmpl $0x0, (%r14)
jne 0x53375
leaq 0x1(%r13), %rax
movslq 0x20(%rbp), %rcx
cmpq %rcx, %r13
movq %rax, %r13
jl 0x53683
cmpl $0x0, 0x38(%rbp)
js 0x537fc
leaq 0x30(%rbp), %r13
xorl %r12d, %r12d
movq %r13, %rdi
movq %r12, %rsi
callq 0x5dc45
testb %al, %al
je 0x537e7
leaq 0x20(%rsp), %rdi
movq %r12, %rsi
movq %r14, %rdx
callq 0x55e35
cmpl $0x0, (%r14)
jne 0x53375
movq 0x58(%rsp), %rdi
addl 0x30(%rdi), %eax
movq 0xc0(%rdi), %r10
movl 0x8(%r10), %ecx
movl 0x1c(%r10), %edx
cmpl %eax, %ecx
jl 0x537b9
notl %ecx
cmpl %ecx, %eax
jl 0x537b9
movl $0xb, %r9d
movq 0x8(%rsp), %rsi
movl $0xe, %ecx
movq %r12, %r8
pushq %r14
pushq %rax
callq *0x60(%r10)
addq $0x10, %rsp
jmp 0x537dd
subq $0x8, %rsp
movl $0xb, %r9d
movq 0x10(%rsp), %rsi
movl $0xe, %ecx
movq %r12, %r8
pushq %r14
pushq %rax
pushq %r12
callq *0x58(%r10)
addq $0x20, %rsp
cmpl $0x0, (%r14)
jne 0x53375
leaq 0x1(%r12), %rax
movslq 0x38(%rbp), %rcx
cmpq %rcx, %r12
movq %rax, %r12
jl 0x5374b
cmpl $0x0, (%r14)
jne 0x53375
movq 0x18(%rsp), %rsi
addq 0x90(%rsp), %rsi
leaq 0x40(%rsp), %rdi
leaq 0x20(%rsp), %rdx
movq 0x10(%rsp), %rcx
movq %r14, %r8
callq 0x558fa
cmpl $0x0, (%r14)
jne 0x53375
movq 0x10(%rsp), %rax
incq %rax
movq %rax, 0x10(%rsp)
cmpq 0x98(%rsp), %rax
jb 0x53628
jmp 0x53375
leaq 0x223d5(%rip), %rdx     # 0x75c30
movq %r14, %rdi
movl $0x1, %esi
movl $0x741, %ecx            # imm = 0x741
callq 0x145a4
jmp 0x53375
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 0x54949
jmp 0x5354b