// File: /workspace/github_c_makefile_star2_O0/markdryan[P]subtilis/arch/arm32/arm_link.c
// Function: subtilis_arm_link_link
void subtilis_arm_link_link(subtilis_arm_link_t *link, uint8_t *buf,
			    size_t buf_size, const size_t *raw_constants,
			    size_t num_raw_constants, subtilis_error_t *err)
{
	size_t i;
	size_t si;
	size_t index;
	uint32_t *ptr;
	subtilis_arm_link_constant_t *cnst;

	for (i = 0; i < link->num_externals; i++) {
		index = link->externals[i];
		if (index >= buf_size) {
			subtilis_error_set_assertion_failed(err);
			return;
		}
		ptr = prv_get_word_ptr(buf, index, err);
		if (err->type != SUBTILIS_ERROR_OK)
			return;
		si = *ptr & 0xffffff;
		if (si >= link->num_sections) {
			subtilis_error_set_assertion_failed(err);
			return;
		}
		if (link->sections[si] == SIZE_MAX) {
			/* TODO: Need proper error here */
			subtilis_error_set_assertion_failed(err);
			return;
		}
		*ptr &= 0xff000000;
		*ptr |= ((link->sections[si] - (index + 8)) / 4) & 0xffffff;
	}

	for (i = 0; i < link->num_constants; i++) {
		cnst = &link->constants[i];
		if (cnst->constant_offset >= buf_size) {
			subtilis_error_set_assertion_failed(err);
			return;
		}
		if (cnst->index >= num_raw_constants) {
			subtilis_error_set_assertion_failed(err);
			return;
		}
		ptr = prv_get_word_ptr(buf, cnst->constant_offset, err);
		if (err->type != SUBTILIS_ERROR_OK)
			return;
		*ptr = (raw_constants[cnst->index] - cnst->code_index);
		/* Adjust for PC relative addressing. */
		*ptr -= 12;
	}

	for (i = 0; i < link->num_extrefs; i++) {
		cnst = &link->extrefs[i];
		if (cnst->constant_offset >= buf_size) {
			subtilis_error_set_assertion_failed(err);
			return;
		}
		if (cnst->index >= link->num_sections) {
			subtilis_error_set_assertion_failed(err);
			return;
		}
		ptr = prv_get_word_ptr(buf, cnst->constant_offset, err);
		if (err->type != SUBTILIS_ERROR_OK)
			return;
		*ptr = ((link->sections[cnst->index] - cnst->code_index) - 12);
	}
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x60, %rsp
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movq %rdx, -0x18(%rbp)
movq %rcx, -0x20(%rbp)
movq %r8, -0x28(%rbp)
movq %r9, -0x30(%rbp)
movq $0x0, -0x38(%rbp)
movq -0x38(%rbp), %rax
movq -0x8(%rbp), %rcx
cmpq 0x8(%rcx), %rax
jae 0x82c69
movq -0x8(%rbp), %rax
movq (%rax), %rax
movq -0x38(%rbp), %rcx
movq (%rax,%rcx,8), %rax
movq %rax, -0x48(%rbp)
movq -0x48(%rbp), %rax
cmpq -0x18(%rbp), %rax
jb 0x82b86
movq -0x30(%rbp), %rdi
movl $0xf, %esi
leaq 0x2a2d1(%rip), %rdx     # 0xace48
movl $0x8e, %ecx
callq 0x158e0
jmp 0x82e36
movq -0x10(%rbp), %rdi
movq -0x48(%rbp), %rsi
movq -0x30(%rbp), %rdx
callq 0x82e40
movq %rax, -0x50(%rbp)
movq -0x30(%rbp), %rax
cmpl $0x0, (%rax)
je 0x82ba9
jmp 0x82e36
movq -0x50(%rbp), %rax
movl (%rax), %eax
andl $0xffffff, %eax         # imm = 0xFFFFFF
movl %eax, %eax
movq %rax, -0x40(%rbp)
movq -0x40(%rbp), %rax
movq -0x8(%rbp), %rcx
cmpq 0x20(%rcx), %rax
jb 0x82be7
movq -0x30(%rbp), %rdi
movl $0xf, %esi
leaq 0x2a270(%rip), %rdx     # 0xace48
movl $0x96, %ecx
callq 0x158e0
jmp 0x82e36
movq -0x8(%rbp), %rax
movq 0x18(%rax), %rax
movq -0x40(%rbp), %rcx
cmpq $-0x1, (%rax,%rcx,8)
jne 0x82c19
movq -0x30(%rbp), %rdi
movl $0xf, %esi
leaq 0x2a23e(%rip), %rdx     # 0xace48
movl $0x9b, %ecx
callq 0x158e0
jmp 0x82e36
movq -0x50(%rbp), %rax
movl (%rax), %ecx
andl $0xff000000, %ecx       # imm = 0xFF000000
movl %ecx, (%rax)
movq -0x8(%rbp), %rax
movq 0x18(%rax), %rax
movq -0x40(%rbp), %rcx
movq (%rax,%rcx,8), %rdx
movq -0x48(%rbp), %rax
addq $0x8, %rax
subq %rax, %rdx
shrq $0x2, %rdx
andq $0xffffff, %rdx         # imm = 0xFFFFFF
movq -0x50(%rbp), %rax
movl (%rax), %ecx
orq %rdx, %rcx
movl %ecx, (%rax)
movq -0x38(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x38(%rbp)
jmp 0x82b38
movq $0x0, -0x38(%rbp)
movq -0x38(%rbp), %rax
movq -0x8(%rbp), %rcx
cmpq 0x30(%rcx), %rax
jae 0x82d52
movq -0x8(%rbp), %rax
movq 0x28(%rax), %rax
imulq $0x18, -0x38(%rbp), %rcx
addq %rcx, %rax
movq %rax, -0x58(%rbp)
movq -0x58(%rbp), %rax
movq 0x10(%rax), %rax
cmpq -0x18(%rbp), %rax
jb 0x82cc4
movq -0x30(%rbp), %rdi
movl $0xf, %esi
leaq 0x2a193(%rip), %rdx     # 0xace48
movl $0xa5, %ecx
callq 0x158e0
jmp 0x82e36
movq -0x58(%rbp), %rax
movq (%rax), %rax
cmpq -0x28(%rbp), %rax
jb 0x82cf0
movq -0x30(%rbp), %rdi
movl $0xf, %esi
leaq 0x2a167(%rip), %rdx     # 0xace48
movl $0xa9, %ecx
callq 0x158e0
jmp 0x82e36
movq -0x10(%rbp), %rdi
movq -0x58(%rbp), %rax
movq 0x10(%rax), %rsi
movq -0x30(%rbp), %rdx
callq 0x82e40
movq %rax, -0x50(%rbp)
movq -0x30(%rbp), %rax
cmpl $0x0, (%rax)
je 0x82d17
jmp 0x82e36
movq -0x20(%rbp), %rax
movq -0x58(%rbp), %rcx
movq (%rcx), %rcx
movq (%rax,%rcx,8), %rax
movq -0x58(%rbp), %rcx
subq 0x8(%rcx), %rax
movl %eax, %ecx
movq -0x50(%rbp), %rax
movl %ecx, (%rax)
movq -0x50(%rbp), %rax
movl (%rax), %ecx
subl $0xc, %ecx
movl %ecx, (%rax)
movq -0x38(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x38(%rbp)
jmp 0x82c71
movq $0x0, -0x38(%rbp)
movq -0x38(%rbp), %rax
movq -0x8(%rbp), %rcx
cmpq 0x48(%rcx), %rax
jae 0x82e36
movq -0x8(%rbp), %rax
movq 0x40(%rax), %rax
imulq $0x18, -0x38(%rbp), %rcx
addq %rcx, %rax
movq %rax, -0x58(%rbp)
movq -0x58(%rbp), %rax
movq 0x10(%rax), %rax
cmpq -0x18(%rbp), %rax
jb 0x82dad
movq -0x30(%rbp), %rdi
movl $0xf, %esi
leaq 0x2a0aa(%rip), %rdx     # 0xace48
movl $0xb7, %ecx
callq 0x158e0
jmp 0x82e36
movq -0x58(%rbp), %rax
movq (%rax), %rax
movq -0x8(%rbp), %rcx
cmpq 0x20(%rcx), %rax
jb 0x82dda
movq -0x30(%rbp), %rdi
movl $0xf, %esi
leaq 0x2a07a(%rip), %rdx     # 0xace48
movl $0xbb, %ecx
callq 0x158e0
jmp 0x82e36
movq -0x10(%rbp), %rdi
movq -0x58(%rbp), %rax
movq 0x10(%rax), %rsi
movq -0x30(%rbp), %rdx
callq 0x82e40
movq %rax, -0x50(%rbp)
movq -0x30(%rbp), %rax
cmpl $0x0, (%rax)
je 0x82dfe
jmp 0x82e36
movq -0x8(%rbp), %rax
movq 0x18(%rax), %rax
movq -0x58(%rbp), %rcx
movq (%rcx), %rcx
movq (%rax,%rcx,8), %rax
movq -0x58(%rbp), %rcx
subq 0x8(%rcx), %rax
subq $0xc, %rax
movl %eax, %ecx
movq -0x50(%rbp), %rax
movl %ecx, (%rax)
movq -0x38(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x38(%rbp)
jmp 0x82d5a
addq $0x60, %rsp
popq %rbp
retq
nopl (%rax)