COMPACT_MARK_WITH_STACK = 1
NO_BIT_INSTRUCTIONS = 1

@ mark used nodes and pointers in argument parts and link backward pointers

	ldr	r12,=heap_size_33
	ldr	r4,[r12]
	lsl	r4,r4,#5
	ldr	r12,=heap_size_32_33
	str	r4,[r12]
@ heap_size_32_33 in r2
	mov	r2,r4

	ldr	r12,=heap_p3
	ldr	r11,[r12]
@ heap_p3 in r11

.if COMPACT_MARK_WITH_STACK
	add	r9,sp,#-8000
.endif
	ldr	r12,=caf_list
	ldr	r4,[r12]
.if COMPACT_MARK_WITH_STACK
	ldr	r12,=end_stack
	str	r9,[r12]
@ end_stack in r0
	mov	r0,r9
.endif
	cmp	r4,#0
	beq	end_mark_cafs

mark_cafs_lp:
	ldr	r12,[r4,#-4]
	str	r12,[sp,#-4]!
.if COMPACT_MARK_WITH_STACK
	add	r9,r4,#4
	ldr	r4,[r4]
	add	r6,r9,r4,lsl #2
.else
	add	r8,r4,#4
	ldr	r4,[r4]
	add	r6,r8,r4,lsl #2
.endif
	ldr	r12,=end_vector
	str	r6,[r12]

	str	pc,[sp,#-4]!
.if COMPACT_MARK_WITH_STACK
	bl	rmark_stack_nodes
.else
	bl	mark_stack_nodes
.endif

	ldr	r4,[sp],#4
	tst	r4,r4
	bne	mark_cafs_lp

end_mark_cafs:
.if COMPACT_MARK_WITH_STACK
	ldr	r12,=stack_p
	ldr	r9,[r12]
.else
	ldr	r12,=stack_p
	ldr	r8,[r12]
.endif

	ldr	r12,=stack_top
	ldr	r6,[r12]
	ldr	r12,=end_vector
	str	r6,[r12]
	str	pc,[sp,#-4]!
.if COMPACT_MARK_WITH_STACK
	bl	rmark_stack_nodes
.else
	bl	mark_stack_nodes
.endif

.ifdef MEASURE_GC
	str	pc,[sp,#-4]!
	bl	add_mark_compact_garbage_collect_time
.endif

	b	compact_heap

	.ltorg

.if COMPACT_MARK_WITH_STACK
	.include "armcompact_rmark.s"
	.include "armcompact_rmarkr.s"
.else
	.include "armcompact_mark.s"
.endif

@ compact the heap

compact_heap:

.ifdef FINALIZERS
	ldr	r6,=finalizer_list
	ldr	r7,=free_finalizer_list

	ldr	r8,[r6]
determine_free_finalizers_after_compact1:
	ldr	r12,=__Nil-4
	cmp	r8,r12
	beq	end_finalizers_after_compact1

	ldr	r12,=heap_p3
	ldr	r4,[r12]
	sub	r4,r8,r4
	lsr	r3,r4,#7
	and	r4,r4,#31*4
	lsr	r9,r4,#2
	mov	r12,#1
	lsl	r9,r12,r9

	ldr	r12,[r10,r3,lsl #2]
	tst	r9,r12
	beq	finalizer_not_used_after_compact1

	ldr	r4,[r8]
	mov	r9,r8
	b	finalizer_find_descriptor

finalizer_find_descriptor_lp:
	and	r4,r4,#-4
	mov	r9,r4
	ldr	r4,[r4]
finalizer_find_descriptor:
	tst	r4,#1
	bne	finalizer_find_descriptor_lp

	ldr	r12,=e____system__kFinalizerGCTemp+2
	str	r12,[r9]

	cmp	r8,r6
	bhi	finalizer_no_reverse

	ldr	r4,[r8]
	add	r9,r6,#1
	str	r9,[r8]
	str	r4,[r6]

finalizer_no_reverse:
	add	r6,r8,#4
	ldr	r8,[r8,#4]
	b	determine_free_finalizers_after_compact1

finalizer_not_used_after_compact1:
	ldr	r12,=e____system__kFinalizerGCTemp+2
	str	r12,[r8]

	str	r8,[r7]
	add	r7,r8,#4

	ldr	r8,[r8,#4]
	str	r8,[r6]

	b	determine_free_finalizers_after_compact1

end_finalizers_after_compact1:
	str	r8,[r7]	

	ldr	r12,=finalizer_list
	ldr	r6,[r12]
	ldr	r12,=__Nil-4
	cmp	r6,r12
	beq	finalizer_list_empty
	tst	r6,#3
	bne	finalizer_list_already_reversed
	ldr	r4,[r6]
	ldr	r12,=finalizer_list+1
	str	r12,[r6]
	ldr	r12,=finalizer_list
	str	r4,[r12]
finalizer_list_already_reversed:
finalizer_list_empty:

 .if COMPACT_MARK_WITH_STACK
	ldr	r9,=free_finalizer_list
	ldr	r6,[r9]
	ldr	r12,=__Nil-4
	cmp	r6,r12
 .else
	ldr	r8,=free_finalizer_list
	ldr	r6,[r8]
	ldr	r12,=__Nil-4
	cmp	r6,r12
 .endif
	beq	free_finalizer_list_empty
	ldr	r6,=free_finalizer_list+4
	ldr	r12,=end_vector
	str	r6,[r12]
 .if COMPACT_MARK_WITH_STACK
	str	pc,[sp,#-4]!
	bl	rmark_stack_nodes
 .else
	str	pc,[sp,#-4]!
	bl	mark_stack_nodes
 .endif
free_finalizer_list_empty:
.endif

	ldr	r12,=heap_size_33
	ldr	r4,[r12]
	mov	r3,r4
	lsl	r3,r3,#5

	ldr	r12,=heap_p3
	ldr	r12,[r12]
	add	r3,r3,r12

	ldr	r12,=end_heap_p3
	str	r3,[r12]
@ end_heap_p3 in r0
 	mov	r0,r3

	add	r4,r4,#3
	lsr	r4,r4,#2
@ vector_counter in r2
	mov	r2,r4

	ldr	r12,=heap_vector
	ldr	r6,[r12]
@ vector_p in r1
	mov	r1,r6

	mov	r12,#-4
	rsb	r3,r6,r12
	ldr	r12,=neg_heap_vector_plus_4
	str	r3,[r12]

	ldr	r12,=heap_p3
	ldr	r10,[r12]
	mov	r9,#0
@ heap_p3 in r11
	mov	r11,r10
	b	skip_zeros

@ d0,a0,a2: free
find_non_zero_long:
skip_zeros:
	subs	r2,r2,#1
	bcc	end_copy
	ldr	r9,[r1],#4
	cmp	r9,#0
	beq	skip_zeros
@ a2: free
end_skip_zeros:
	ldr	r12,=neg_heap_vector_plus_4
	ldr	r8,[r12]
	add	r8,r8,r1

	add	r8,r11,r8,lsl #5

bsf_and_copy_nodes:
	neg	r12,r9
	and	r12,r12,r9
	clz	r3,r12
	rsb	r3,r3,#31

copy_nodes:
	ldr	r4,[r8,r3,lsl #2]

	bic	r9,r9,r12

	add	r12,r8,#4
	add	r6,r12,r3,lsl #2
	sub	r4,r4,#1

	tst	r4,#2
	beq	begin_update_list_2

	ldr	r3,[r4,#-10]
	subs	r4,r4,#2

	tst	r3,#1
	beq	end_list_2
find_descriptor_2:
	and	r3,r3,#-4
	ldr	r3,[r3]
	tst	r3,#1
	bne	find_descriptor_2

end_list_2:
	mov	r7,r3
	ldrh	r3,[r3,#-2]
	cmp	r3,#256
	blo	no_record_arguments

	ldrh	r7,[r7,#-2+2]
	subs	r7,r7,#2
	bhs	copy_record_arguments_aa

	sub	r3,r3,#256
	sub	r3,r3,#3

copy_record_arguments_all_b:
	str	r3,[sp,#-4]!
	ldr	r12,=heap_vector
	ldr	r3,[r12]

update_up_list_1r:
	mov	r7,r4
	sub	r4,r4,r11

	str	r6,[sp,#-4]!

	and	r6,r4,#31*4
	lsr	r4,r4,#7
	lsr	r6,r6,#2
	mov	r12,#1
	lsl	r6,r12,r6

	ldr	r4,[r3,r4,lsl #2]

	ands	r4,r4,r6

	ldr	r6,[sp],#4
	beq	copy_argument_part_1r

	ldr	r4,[r7]
	str	r10,[r7]
	subs	r4,r4,#3
	b	update_up_list_1r

copy_argument_part_1r:
	ldr	r4,[r7]
	str	r10,[r7]
	str	r4,[r10],#4

	sub	r4,r6,r11
	lsr	r4,r4,#2

	mov	r3,r4
	and	r3,r3,#31
	cmp	r3,#1
	bhs	bit_in_this_word

	sub	r2,r2,#1
	ldr	r9,[r1],#4

	ldr	r12,=neg_heap_vector_plus_4
	ldr	r8,[r12]
	add	r8,r8,r1
	add	r8,r11,r8,lsl #5

bit_in_this_word:
	mov	r12,#1
	lsl	r12,r12,r3
	bic	r9,r9,r12

	ldr	r3,[sp],#4

copy_b_record_argument_part_arguments:
	ldr	r4,[r6],#4
	str	r4,[r10],#4
	subs	r3,r3,#1
	bcs	copy_b_record_argument_part_arguments

	cmp	r9,#0
	bne	bsf_and_copy_nodes
	b	find_non_zero_long

copy_record_arguments_aa:
	ldr	r12,=256+2
	sub	r3,r3,r7
	sub	r3,r3,r12

	str	r3,[sp,#-4]!
	str	r7,[sp,#-4]!

update_up_list_2r:
	mov	r7,r4
	ldr	r4,[r7]
	and	r3,r4,#3
	subs	r3,r3,#3
	bne	copy_argument_part_2r

	str	r10,[r7]
	subs	r4,r4,#3
	b	update_up_list_2r

copy_argument_part_2r:
	str	r10,[r7]
	cmp	r4,r6
	blo	copy_record_argument_2
.ifdef SHARE_CHAR_INT
	cmp	r4,r0
	bhs	copy_record_argument_2
.endif
	mov	r7,r4
	ldr	r4,[r7]
	add	r3,r10,#1
	str	r3,[r7]
copy_record_argument_2:
	str	r4,[r10],#4

	ldr	r3,[sp],#4
	subs	r3,r3,#1
	bcc	no_pointers_in_record

copy_record_pointers:
	ldr	r7,[r6],#4
	cmp	r7,r6
	blo	copy_record_pointers_2
.ifdef SHARE_CHAR_INT
	cmp	r7,r0
	bhs	copy_record_pointers_2
.endif
	ldr	r4,[r7]
	add	r10,r10,#1
	str	r10,[r7]
	subs	r10,r10,#1
	mov	r7,r4
copy_record_pointers_2:
	str	r7,[r10],#4
	subs	r3,r3,#1
	bcs	copy_record_pointers

no_pointers_in_record:
	ldr	r3,[sp],#4

	subs	r3,r3,#1
	bcc	no_non_pointers_in_record

copy_non_pointers_in_record:
	ldr	r4,[r6],#4
	str	r4,[r10],#4
	subs	r3,r3,#1
	bcs	copy_non_pointers_in_record

no_non_pointers_in_record:
	cmp	r9,#0
	bne	bsf_and_copy_nodes
	b	find_non_zero_long

no_record_arguments:
	subs	r3,r3,#3
update_up_list_2:
	mov	r7,r4
	ldr	r4,[r4]
	add	r4,r4,#1
	str	r10,[r7]
	tst	r4,#3
	bne	copy_argument_part_2

	subs	r4,r4,#4
	b	update_up_list_2

copy_argument_part_2:
	sub	r4,r4,#1
	cmp	r4,r6
	bcc	copy_arguments_1
.ifdef SHARE_CHAR_INT
	cmp	r4,r0
	bcs	copy_arguments_1
.endif
	mov	r7,r4
	ldr	r4,[r4]
	add	r10,r10,#1
	str	r10,[r7]
	subs	r10,r10,#1
copy_arguments_1:
	str	r4,[r10],#4

copy_argument_part_arguments:
	ldr	r7,[r6],#4
	cmp	r7,r6
	bcc	copy_arguments_2
.ifdef SHARE_CHAR_INT
	cmp	r7,r0
	bcs	copy_arguments_2
.endif
	ldr	r4,[r7]
	add	r10,r10,#1
	str	r10,[r7]
	subs	r10,r10,#1
	mov	r7,r4
copy_arguments_2:
	str	r7,[r10],#4
	subs	r3,r3,#1
	bcs	copy_argument_part_arguments

	cmp	r9,#0
	bne	bsf_and_copy_nodes
	b	find_non_zero_long

update_list_2_:
	subs	r4,r4,#1
update_list_2:
	str	r10,[r7]
begin_update_list_2:
	mov	r7,r4
	ldr	r4,[r4]
update_list__2:
	tst	r4,#1
	beq	end_update_list_2
	tst	r4,#2
	beq	update_list_2_
	add	r7,r4,#-3
	ldr	r4,[r4,#-3]
	b	update_list__2

end_update_list_2:
	str	r10,[r7]

	str	r4,[r10],#4

	tst	r4,#2
	beq	move_lazy_node

	ldrh	r3,[r4,#-2]
	tst	r3,r3
	beq	move_hnf_0

	cmp	r3,#256
	bhs	move_record

	subs	r3,r3,#2
	bcc	move_hnf_1
	beq	move_hnf_2

move_hnf_3:
	ldr	r7,[r6],#4
	cmp	r7,r6
	bcc	move_hnf_3_1
.ifdef SHARE_CHAR_INT
	cmp	r7,r0
	bcs	move_hnf_3_1
.endif
	add	r4,r10,#1
	ldr	r3,[r7]
	str	r4,[r7]
	mov	r7,r3
move_hnf_3_1:
	str	r7,[r10]

	ldr	r7,[r6],#4
	cmp	r7,r6
	bcc	move_hnf_3_2
.ifdef SHARE_CHAR_INT
	cmp	r7,r0
	bcs	move_hnf_3_2
.endif
	add	r4,r10,#4+2+1
	ldr	r3,[r7]
	str	r4,[r7]
	mov	r7,r3
move_hnf_3_2:
	str	r7,[r10,#4]
	add	r10,r10,#8

	cmp	r9,#0
	bne	bsf_and_copy_nodes
	b	find_non_zero_long

move_hnf_2:
	ldr	r7,[r6],#4
	cmp	r7,r6
	bcc	move_hnf_2_1
.ifdef SHARE_CHAR_INT
	cmp	r7,r0
	bcs	move_hnf_2_1
.endif
	add	r4,r10,#1
	ldr	r3,[r7]
	str	r4,[r7]
	mov	r7,r3
move_hnf_2_1:
	str	r7,[r10]

	ldr	r7,[r6],#4
	cmp	r7,r6
	bcc	move_hnf_2_2
.ifdef SHARE_CHAR_INT
	cmp	r7,r0
	bcs	move_hnf_2_2
.endif
	add	r4,r10,#4+1
	ldr	r3,[r7]
	str	r4,[r7]
	mov	r7,r3
move_hnf_2_2:
	str	r7,[r10,#4]
	add	r10,r10,#8

	cmp	r9,#0
	bne	bsf_and_copy_nodes
	b	find_non_zero_long

move_hnf_1:
	ldr	r7,[r6],#4
	cmp	r7,r6
	bcc	move_hnf_1_
.ifdef SHARE_CHAR_INT
	cmp	r7,r0
	bcs	move_hnf_1_
.endif
	add	r4,r10,#1
	ldr	r3,[r7]
	str	r4,[r7]
	mov	r7,r3
move_hnf_1_:
	str	r7,[r10],#4

	cmp	r9,#0
	bne	bsf_and_copy_nodes
	b	find_non_zero_long

move_record:
	ldr	r12,=258
	subs	r3,r3,r12
	blo	move_record_1
	beq	move_record_2

move_record_3:
	ldrh	r3,[r4,#-2+2]
	subs	r3,r3,#1
	bhi	move_hnf_3

	ldr	r7,[r6],#4
	blo	move_record_3_1b

move_record_3_1a:
	cmp	r7,r6
	blo	move_record_3_1b
.ifdef SHARE_CHAR_INT
	cmp	r7,r0
	bhs	move_record_3_1b
.endif
	add	r4,r10,#1
	ldr	r3,[r7]
	str	r4,[r7]
	mov	r7,r3
move_record_3_1b:
	str	r7,[r10],#4

	ldr	r7,[r6],#4
	cmp	r7,r6
	blo	move_record_3_2
.ifdef SHARE_CHAR_INT
	cmp	r7,r0
	bhs	move_record_3_2
.endif
	str	r8,[sp,#-4]!
	sub	r4,r7,r11

	ldr	r12,=heap_vector
	ldr	r3,[r12]
	add	r4,r4,#4
	and	r8,r4,#31*4
	lsr	r4,r4,#7
	lsr	r8,r8,#2
	mov	r12,#1
	lsl	r8,r12,r8

	ldr	r12,[r3,r4,lsl #2]
	tst	r8,r12
	beq	not_linked_record_argument_part_3_b

	sub	r4,r10,r11

	and	r8,r4,#31*4
	lsr	r4,r4,#7
	lsr	r8,r8,#2
	mov	r12,#1
	lsl	r8,r12,r8
	ldr	r12,[r3,r4,lsl #2]
	orr	r12,r12,r8
	str	r12,[r3,r4,lsl #2]
	ldr	r8,[sp],#4
	b	linked_record_argument_part_3_b

not_linked_record_argument_part_3_b:
	ldr	r12,[r3,r4,lsl #2]
	orr	r12,r12,r8
	str	r12,[r3,r4,lsl #2]

	sub	r4,r10,r11

	and	r8,r4,#31*4
	lsr	r4,r4,#7

	lsr	r8,r8,#2
	mov	r12,#1
	mvn	r8,r12,lsl r8

	ldr	r12,[r3,r4,lsl #2]
	and	r12,r12,r8
	str	r12,[r3,r4,lsl #2]
	ldr	r8,[sp],#4

linked_record_argument_part_3_b:
	ldr	r3,[r7]
	add	r4,r10,#2+1
	str	r4,[r7]
	mov	r7,r3
move_record_3_2:
	str	r7,[r10],#4

	sub	r3,r6,r11
	lsr	r3,r3,#2
	subs	r3,r3,#1
	and	r3,r3,#31
	cmp	r3,#2
	blo	bit_in_next_word

	mov	r12,#1
	lsl	r12,r12,r3
	bic	r9,r9,r12

	cmp	r9,#0
	bne	bsf_and_copy_nodes
	b	find_non_zero_long

bit_in_next_word:
	sub	r2,r2,#1
	ldr	r9,[r1],#4

	mov	r12,#1
	lsl	r12,r12,r3
	bic	r9,r9,r12

	cmp	r9,#0
	beq	skip_zeros
	b	end_skip_zeros

move_record_2:
	ldrh	r12,[r4,#-2+2]
	cmp	r12,#1
	bhi	move_hnf_2
	blo	move_real_or_file

move_record_2_ab:
	ldr	r7,[r6],#4
	cmp	r7,r6
	blo	move_record_2_1
.ifdef SHARE_CHAR_INT
	cmp	r7,r0
	bhs	move_record_2_1
.endif
	add	r4,r10,#1
	ldr	r3,[r7]
	str	r4,[r7]
	mov	r7,r3
move_record_2_1:
	str	r7,[r10]
	ldr	r3,[r6],#4
	str	r3,[r10,#4]
	add	r10,r10,#8

	cmp	r9,#0
	bne	bsf_and_copy_nodes
	b	find_non_zero_long

move_record_1:
	ldrh	r3,[r4,#-2+2]
	tst	r3,r3
	bne	move_hnf_1
	b	move_int_bool_or_char

move_real_or_file:
	ldr	r4,[r6],#4
	str	r4,[r10],#4
move_int_bool_or_char:
	ldr	r4,[r6],#4
	str	r4,[r10],#4
copy_normal_hnf_0:
	cmp	r9,#0
	bne	bsf_and_copy_nodes
	b	find_non_zero_long

move_hnf_0:
	ldr	r12,=INT+2
	cmp	r4,r12
	blo	move_real_file_string_or_array
	ldr	r12,=CHAR+2
	cmp	r4,r12
	bls	move_int_bool_or_char
.ifdef DLL
move_normal_hnf_0:
.endif

	cmp	r9,#0
	bne	bsf_and_copy_nodes
	b	find_non_zero_long

move_real_file_string_or_array:
	ldr	r12,=__STRING__+2
	cmp	r4,r12
	bhi	move_real_or_file
	bne	move_array

	ldr	r4,[r6]
	add	r4,r4,#3
	lsr	r4,r4,#2

cp_s_arg_lp3:
	ldr	r3,[r6],#4
	str	r3,[r10],#4
	subs	r4,r4,#1
	bcs	cp_s_arg_lp3

	cmp	r9,#0
	bne	bsf_and_copy_nodes
	b	find_non_zero_long

move_array:
.ifdef DLL
	ldr	r12,=__ARRAY__+2
	cmp	r4,r12
	blo	move_normal_hnf_0
.endif
	cmp	r9,#0
	bne	bsf_and_end_array_bit

skip_zeros_a:
	ldr	r9,[r1],#4
	sub	r2,r2,#1
	cmp	r9,#0
	beq	skip_zeros_a

	ldr	r12,=neg_heap_vector_plus_4
	ldr	r8,[r12]
	add	r8,r8,r1

	add	r8,r11,r8,lsl #5

bsf_and_end_array_bit:
	neg	r12,r9
	and	r12,r12,r9
	clz	r3,r12
	rsb	r3,r3,#31

end_array_bit:
	bic	r9,r9,r12

	add	r3,r8,r3,lsl #2

	cmp	r6,r3
	bne	move_a_array

move_b_array:
	ldr	r7,[r6]
	str	r7,[r10]
	ldr	r3,[r6,#4]!
	ldrh	r4,[r3,#-2]
	add	r10,r10,#4
	tst	r4,r4
	beq	move_strict_basic_array

	subs	r4,r4,#256
	mul	r7,r4,r7
	mov	r4,r7
	b	cp_s_arg_lp3

move_strict_basic_array:
	mov	r4,r7
	ldr	r12,=INT+2
	cmp	r3,r12
	beq	cp_s_arg_lp3

	ldr	r12,=BOOL+2
	cmp	r3,r12
	beq	move_bool_array

	add	r4,r4,r4
	b	cp_s_arg_lp3

move_bool_array:
	add	r4,r4,#3
	lsr	r4,r4,#2
	b	cp_s_arg_lp3

move_a_array:
	mov	r7,r3
	subs	r3,r3,r6
	lsr	r3,r3,#2

	str	r9,[sp,#-4]!

	subs	r3,r3,#1
	blo	end_array

	ldr	r9,[r6]
	ldr	r4,[r7,#-4]
	str	r9,[r7,#-4]
	str	r4,[r10]
	ldr	r4,[r7]
	ldr	r9,[r6,#4]
	add	r6,r6,#8
	str	r9,[r7]
	str	r4,[r10,#4]
	add	r10,r10,#8
	tst	r4,r4
	beq	st_move_array_lp

	ldrh	r9,[r4,#-2+2]
	ldrh	r4,[r4,#-2]
	subs	r4,r4,#256
	cmp	r4,r9
	beq	st_move_array_lp

move_array_ab:
	str	r6,[sp,#-4]!

	ldr	r7,[r10,#-8]
	mov	r3,r9
	mul	r7,r4,r7
	lsl	r7,r7,#2

	subs	r4,r4,r3
	add	r7,r7,r6
	str	pc,[sp,#-4]!
	bl	reorder

	ldr	r6,[sp],#4
	subs	r3,r3,#1
	subs	r4,r4,#1

	str	r3,[sp,#-4]!
	str	r4,[sp,#-4]!
	ldr	r12,[r10,#-8]
	str	r12,[sp,#-4]!
	b	st_move_array_lp_ab

move_array_ab_lp1:
	ldr	r4,[sp,#8]
move_array_ab_a_elements:
	ldr	r3,[r6],#4
	cmp	r3,r6
	blo	move_array_element_ab
.ifdef SHARE_CHAR_INT
	cmp	r3,r0
	bcs	move_array_element_ab
.endif
	mov	r7,r3
	ldr	r3,[r7]
	add	r10,r10,#1
	str	r10,[r7]
	subs	r10,r10,#1
move_array_element_ab:
	str	r3,[r10],#4
	subs	r4,r4,#1
	bcs	move_array_ab_a_elements

	ldr	r4,[sp,#4]
move_array_ab_b_elements:
	ldr	r3,[r6],#4
	str	r3,[r10],#4
	subs	r4,r4,#1
	bcs	move_array_ab_b_elements

st_move_array_lp_ab:
	ldr	r12,[sp]
	subs	r12,r12,#1
	str	r12,[sp]
	bcs	move_array_ab_lp1

	add	sp,sp,#12
	b	end_array	

move_array_lp1:
	ldr	r4,[r6],#4
	add	r10,r10,#4
	cmp	r4,r6
	blo	move_array_element
.ifdef SHARE_CHAR_INT
	cmp	r4,r0
	bcs	move_array_element
.endif
	ldr	r9,[r4]
	mov	r7,r4
	str	r9,[r10,#-4]
	add	r4,r10,#-4+1
	str	r4,[r7]

	subs	r3,r3,#1
	bcs	move_array_lp1

	b	end_array

move_array_element:
	str	r4,[r10,#-4]
st_move_array_lp:
	subs	r3,r3,#1
	bcs	move_array_lp1

end_array:
	ldr	r9,[sp],#4

	cmp	r9,#0
	bne	bsf_and_copy_nodes
	b	find_non_zero_long

move_lazy_node:
	mov	r7,r4
	ldr	r3,[r7,#-4]
	tst	r3,r3
	beq	move_lazy_node_0

	subs	r3,r3,#1
	ble	move_lazy_node_1

	cmp	r3,#256
	bge	move_closure_with_unboxed_arguments

move_lazy_node_arguments:
	ldr	r7,[r6],#4
	cmp	r7,r6
	bcc	move_lazy_node_arguments_
.ifdef SHARE_CHAR_INT
	cmp	r7,r0
	bcs	move_lazy_node_arguments_
.endif
	ldr	r4,[r7]
	str	r4,[r10]
	add	r4,r10,#1
	add	r10,r10,#4
	str	r4,[r7]
	subs	r3,r3,#1
	bcs	move_lazy_node_arguments

	cmp	r9,#0
	bne	bsf_and_copy_nodes
	b	find_non_zero_long

move_lazy_node_arguments_:
	str	r7,[r10],#4
	subs	r3,r3,#1
	bcs	move_lazy_node_arguments

	cmp	r9,#0
	bne	bsf_and_copy_nodes
	b	find_non_zero_long

move_lazy_node_1:
	ldr	r7,[r6],#4
	cmp	r7,r6
	bcc	move_lazy_node_1_
.ifdef SHARE_CHAR_INT
	cmp	r7,r0
	bcs	move_lazy_node_1_
.endif
	add	r4,r10,#1
	ldr	r3,[r7]
	str	r4,[r7]
	mov	r7,r3
move_lazy_node_1_:
	str	r7,[r10]
	add	r10,r10,#8

	cmp	r9,#0
	bne	bsf_and_copy_nodes
	b	find_non_zero_long

move_lazy_node_0:
	add	r10,r10,#8

	cmp	r9,#0
	bne	bsf_and_copy_nodes
	b	find_non_zero_long

move_closure_with_unboxed_arguments:
	beq	move_closure_with_unboxed_arguments_1
	add	r3,r3,#1
	mov	r4,r3
	and	r3,r3,#255
	lsr	r4,r4,#8
	subs	r3,r3,r4
	beq	move_non_pointers_of_closure

	str	r4,[sp,#-4]!

move_closure_with_unboxed_arguments_lp:
	ldr	r7,[r6],#4
	cmp	r7,r6
	bcc	move_closure_with_unboxed_arguments_
.ifdef SHARE_CHAR_INT
	cmp	r7,r0
	bcs	move_closure_with_unboxed_arguments_
.endif
	ldr	r4,[r7]
	str	r4,[r10]
	add	r4,r10,#1
	add	r10,r10,#4
	str	r4,[r7]
	subs	r3,r3,#1
	bne	move_closure_with_unboxed_arguments_lp

	ldr	r4,[sp],#4
	b	move_non_pointers_of_closure

move_closure_with_unboxed_arguments_:
	str	r7,[r10],#4
	subs	r3,r3,#1
	bne	move_closure_with_unboxed_arguments_lp

	ldr	r4,[sp],#4

move_non_pointers_of_closure:
	ldr	r3,[r6],#4
	str	r3,[r10],#4
	subs	r4,r4,#1
	bne	move_non_pointers_of_closure

	cmp	r9,#0
	bne	bsf_and_copy_nodes
	b	find_non_zero_long

move_closure_with_unboxed_arguments_1:
	ldr	r4,[r6]
	str	r4,[r10]
	add	r10,r10,#8
	cmp	r9,#0
	bne	bsf_and_copy_nodes
	b	find_non_zero_long	

	.ltorg

end_copy:

.ifdef FINALIZERS
	ldr	r12,=finalizer_list
	ldr	r6,[r12]

restore_finalizer_descriptors:
	ldr	r12,=__Nil-4
	cmp	r6,r12
	beq	end_restore_finalizer_descriptors

	ldr	r12,=e____system__kFinalizer+2
	str	r12,[r6]
	ldr	r6,[r6,#4]
	b	restore_finalizer_descriptors

end_restore_finalizer_descriptors:
.endif