// File: /workspace/github_c_makefile_star2_O0/markdryan[P]subtilis/backends/riscos_common/riscos_arm.c
// Function: prv_add_preamble
static void prv_add_preamble(subtilis_arm_section_t *arm_s, size_t globals,
			     subtilis_error_t *err)
{
	subtilis_arm_reg_t dest;
	subtilis_arm_reg_t op1;
	subtilis_arm_reg_t op2;
	size_t needed;
	subtilis_arm_instr_t *instr;
	subtilis_arm_br_instr_t *br;
	const uint32_t stack_size = 8192;
	const uint32_t min_heap_size = subtilis_arm_heap_min_size();

	/* globals needs to be divisible by 4. */

	if (globals & 3)
		globals += 4 - (globals & 3);
	needed = globals + stack_size + min_heap_size;

	if (arm_s->settings->handle_escapes)
		needed += 12;

	if (needed > 0xffffffff) {
		subtilis_error_set_assertion_failed(err);
		return;
	}

	/*
	 * The second word is going to contain the start of the heap.  We can't
	 * execute this code so we need to skip it with a mov pc, pc.
	 */

	subtilis_arm_add_mov_reg(arm_s, SUBTILIS_ARM_CCODE_AL, false, 15, 15,
				 err);
	if (err->type != SUBTILIS_ERROR_OK)
		return;

	/*
	 * Just a dummy instruction to save space for the start of the heap.
	 * We'll write the heap start in here later on when linking.
	 */

	subtilis_arm_add_mov_reg(arm_s, SUBTILIS_ARM_CCODE_AL, false, 15, 15,
				 err);
	if (err->type != SUBTILIS_ERROR_OK)
		return;

	/* OS_GetEnv */
	/* read_mask = 0 */
	/* write_mask = 0x7 = R0, R1, R2 */
	subtilis_arm_add_swi(arm_s, SUBTILIS_ARM_CCODE_AL, 0x10, 0, 0x7, err);
	if (err->type != SUBTILIS_ERROR_OK)
		return;

	dest = 12;

	/* Load heap start into R11 */

	prv_load_heap_pointer(arm_s, 10, 11, err);
	if (err->type != SUBTILIS_ERROR_OK)
		return;

	/*
	 * Check we have enough memory for code + globals + escape_handler +
	 * 8KB of stack + 8KB of heap.  At some point we'll make this
	 * configurable.
	 */

	subtilis_arm_add_add_imm(arm_s, SUBTILIS_ARM_CCODE_AL, false, 12, 11,
				 (uint32_t)needed, err);
	if (err->type != SUBTILIS_ERROR_OK)
		return;

	subtilis_arm_add_cmp(arm_s, SUBTILIS_ARM_INSTR_CMP,
			     SUBTILIS_ARM_CCODE_AL, 12, 1, err);
	if (err->type != SUBTILIS_ERROR_OK)
		return;

	instr =
	    subtilis_arm_section_add_instr(arm_s, SUBTILIS_ARM_INSTR_B, err);
	if (err->type != SUBTILIS_ERROR_OK)
		return;

	br = &instr->operands.br;
	br->ccode = SUBTILIS_ARM_CCODE_GT;
	br->link = false;
	br->link_type = SUBTILIS_ARM_BR_LINK_VOID;
	br->target.label = arm_s->no_cleanup_label;

	op1 = 1;

	/*
	 * TODO:  This can be a simple sub.  Avoid label if possible.  We'd
	 * only need the label if we allow globals in multiple files.
	 */

	(void)subtilis_add_data_imm_ldr_datai(arm_s, SUBTILIS_ARM_INSTR_SUB,
					      SUBTILIS_ARM_CCODE_AL, false,
					      dest, op1, globals, err);
	if (err->type != SUBTILIS_ERROR_OK)
		return;

	dest = 13;
	op2 = 12;

	if (arm_s->settings->handle_escapes) {
		// Reserve 12 bytes for escape condition and old handler details

		subtilis_arm_add_sub_imm(arm_s, SUBTILIS_ARM_CCODE_AL, false,
					 dest, op2, 12, err);
		if (err->type != SUBTILIS_ERROR_OK)
			return;

		subtilis_arm_add_mov_imm(arm_s, SUBTILIS_ARM_CCODE_AL, false, 1,
					 0, err);
		if (err->type != SUBTILIS_ERROR_OK)
			return;

		subtilis_arm_add_stran_imm(
		    arm_s, SUBTILIS_ARM_INSTR_STR, SUBTILIS_ARM_CCODE_AL, 1, 12,
		    RISCOS_ARM_GLOBAL_ESC_FLAG, false, err);
		if (err->type != SUBTILIS_ERROR_OK)
			return;
		prv_add_escape_handler(arm_s, err);
	} else {
		subtilis_arm_add_mov_reg(arm_s, SUBTILIS_ARM_CCODE_AL, false,
					 dest, op2, err);
	}
	if (err->type != SUBTILIS_ERROR_OK)
		return;

	prv_init_heap(arm_s, stack_size, err);
	if (err->type != SUBTILIS_ERROR_OK)
		return;

	if (!arm_s->fp_if) {
		subtilis_error_set_assertion_failed(err);
		return;
	}

	arm_s->fp_if->preamble_fn(arm_s, err);
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x70, %rsp
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movq %rdx, -0x18(%rbp)
movl $0x2000, -0x4c(%rbp)    # imm = 0x2000
callq 0x8d9d0
movl %eax, -0x50(%rbp)
movq -0x10(%rbp), %rax
andq $0x3, %rax
cmpq $0x0, %rax
je 0xa3b79
movq -0x10(%rbp), %rcx
andq $0x3, %rcx
movl $0x4, %eax
subq %rcx, %rax
addq -0x10(%rbp), %rax
movq %rax, -0x10(%rbp)
movq -0x10(%rbp), %rax
addq $0x2000, %rax           # imm = 0x2000
movl -0x50(%rbp), %ecx
addq %rcx, %rax
movq %rax, -0x38(%rbp)
movq -0x8(%rbp), %rax
movq 0xa8(%rax), %rax
testb $0x1, (%rax)
je 0xa3ba9
movq -0x38(%rbp), %rax
addq $0xc, %rax
movq %rax, -0x38(%rbp)
movl $0xffffffff, %eax       # imm = 0xFFFFFFFF
cmpq %rax, -0x38(%rbp)
jbe 0xa3bd3
movq -0x18(%rbp), %rdi
movl $0xf, %esi
leaq 0xcac0(%rip), %rdx      # 0xb0684
movl $0xf5, %ecx
callq 0x158e0
jmp 0xa3f45
movq -0x8(%rbp), %rdi
movq -0x18(%rbp), %rax
movl $0xd, %esi
movl $0xe, %edx
xorl %ecx, %ecx
movl $0xf, %r9d
movq %r9, %r8
movq %rax, (%rsp)
callq 0x71fa0
movq -0x18(%rbp), %rax
cmpl $0x0, (%rax)
je 0xa3c07
jmp 0xa3f45
movq -0x8(%rbp), %rdi
movq -0x18(%rbp), %rax
movl $0xd, %esi
movl $0xe, %edx
xorl %ecx, %ecx
movl $0xf, %r9d
movq %r9, %r8
movq %rax, (%rsp)
callq 0x71fa0
movq -0x18(%rbp), %rax
cmpl $0x0, (%rax)
je 0xa3c3b
jmp 0xa3f45
movq -0x8(%rbp), %rdi
movq -0x18(%rbp), %r9
movl $0xe, %esi
movl $0x10, %edx
xorl %ecx, %ecx
movl $0x7, %r8d
callq 0x71f20
movq -0x18(%rbp), %rax
cmpl $0x0, (%rax)
je 0xa3c68
jmp 0xa3f45
movq $0xc, -0x20(%rbp)
movq -0x8(%rbp), %rdi
movq -0x18(%rbp), %rcx
movl $0xa, %esi
movl $0xb, %edx
callq 0xa6830
movq -0x18(%rbp), %rax
cmpl $0x0, (%rax)
je 0xa3c95
jmp 0xa3f45
movq -0x8(%rbp), %rdi
movq -0x38(%rbp), %rax
movl %eax, %r10d
movq -0x18(%rbp), %rax
movl $0x4, %esi
movl $0x2, %edx
movl $0xe, %ecx
xorl %r8d, %r8d
movl $0xc, %r9d
movq $0xb, (%rsp)
movl %r10d, 0x8(%rsp)
movq %rax, 0x10(%rsp)
callq 0x71640
movq -0x18(%rbp), %rax
cmpl $0x0, (%rax)
je 0xa3ce1
jmp 0xa3f45
movq -0x8(%rbp), %rdi
movq -0x18(%rbp), %r9
movl $0xa, %esi
movl $0xe, %edx
movl $0xc, %ecx
movl $0x1, %r8d
callq 0x72710
movq -0x18(%rbp), %rax
cmpl $0x0, (%rax)
je 0xa3d11
jmp 0xa3f45
movq -0x8(%rbp), %rdi
movq -0x18(%rbp), %rdx
movl $0x16, %esi
callq 0x70b50
movq %rax, -0x40(%rbp)
movq -0x18(%rbp), %rax
cmpl $0x0, (%rax)
je 0xa3d35
jmp 0xa3f45
movq -0x40(%rbp), %rax
addq $0x8, %rax
movq %rax, -0x48(%rbp)
movq -0x48(%rbp), %rax
movl $0xc, (%rax)
movq -0x48(%rbp), %rax
movb $0x0, 0x4(%rax)
movq -0x48(%rbp), %rax
movl $0x0, 0x8(%rax)
movq -0x8(%rbp), %rax
movq 0xb0(%rax), %rcx
movq -0x48(%rbp), %rax
movq %rcx, 0x10(%rax)
movq $0x1, -0x28(%rbp)
movq -0x8(%rbp), %rdi
movq -0x20(%rbp), %r8
movq -0x28(%rbp), %r9
movq -0x10(%rbp), %rax
movl %eax, %r10d
movq -0x18(%rbp), %rax
movl $0x2, %esi
movl $0xe, %edx
xorl %ecx, %ecx
movl %r10d, (%rsp)
movq %rax, 0x8(%rsp)
callq 0x71410
movq -0x18(%rbp), %rax
cmpl $0x0, (%rax)
je 0xa3db8
jmp 0xa3f45
movq $0xd, -0x20(%rbp)
movq $0xc, -0x30(%rbp)
movq -0x8(%rbp), %rax
movq 0xa8(%rax), %rax
testb $0x1, (%rax)
je 0xa3eb5
movq -0x8(%rbp), %rdi
movq -0x20(%rbp), %r9
movq -0x30(%rbp), %r10
movq -0x18(%rbp), %rax
movl $0x2, %esi
movl $0x4, %edx
movl $0xe, %ecx
xorl %r8d, %r8d
movq %r10, (%rsp)
movl $0xc, 0x8(%rsp)
movq %rax, 0x10(%rsp)
callq 0x71640
movq -0x18(%rbp), %rax
cmpl $0x0, (%rax)
je 0xa3e22
jmp 0xa3f45
movq -0x8(%rbp), %rdi
movq -0x18(%rbp), %rax
movl $0xd, %esi
movl $0xf, %edx
movl $0xe, %ecx
xorl %r8d, %r8d
movl $0x1, %r9d
movl $0x0, (%rsp)
movq %rax, 0x8(%rsp)
callq 0x71b10
movq -0x18(%rbp), %rax
cmpl $0x0, (%rax)
je 0xa3e61
jmp 0xa3f45
movq -0x8(%rbp), %rdi
movq -0x18(%rbp), %rax
movl $0x13, %esi
movl $0xe, %edx
movl $0x1, %ecx
movl $0xc, %r8d
movl $0xfffffffc, %r9d       # imm = 0xFFFFFFFC
xorl %r10d, %r10d
movl $0x0, (%rsp)
movq %rax, 0x8(%rsp)
callq 0x72030
movq -0x18(%rbp), %rax
cmpl $0x0, (%rax)
je 0xa3ea6
jmp 0xa3f45
movq -0x8(%rbp), %rdi
movq -0x18(%rbp), %rsi
callq 0xa8300
jmp 0xa3eda
movq -0x8(%rbp), %rdi
movq -0x20(%rbp), %r8
movq -0x30(%rbp), %r9
movq -0x18(%rbp), %rax
movl $0xd, %esi
movl $0xe, %edx
xorl %ecx, %ecx
movq %rax, (%rsp)
callq 0x71fa0
movq -0x18(%rbp), %rax
cmpl $0x0, (%rax)
je 0xa3ee5
jmp 0xa3f45
movq -0x8(%rbp), %rdi
movq -0x18(%rbp), %rdx
movl $0x2000, %esi           # imm = 0x2000
callq 0xa85f0
movq -0x18(%rbp), %rax
cmpl $0x0, (%rax)
je 0xa3f02
jmp 0xa3f45
movq -0x8(%rbp), %rax
cmpq $0x0, 0xc0(%rax)
jne 0xa3f2c
movq -0x18(%rbp), %rdi
movl $0xf, %esi
leaq 0xc764(%rip), %rdx      # 0xb0684
movl $0x166, %ecx            # imm = 0x166
callq 0x158e0
jmp 0xa3f45
movq -0x8(%rbp), %rax
movq 0xc0(%rax), %rax
movq 0x20(%rax), %rax
movq -0x8(%rbp), %rdi
movq -0x18(%rbp), %rsi
callq *%rax
addq $0x70, %rsp
popq %rbp
retq
nopl (%rax,%rax)