summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--pcompact.a789
-rw-r--r--pcompact_rmark.a835
-rw-r--r--pcompact_rmarkr.a783
3 files changed, 1635 insertions, 772 deletions
diff --git a/pcompact.a b/pcompact.a
index ee55b11..948325a 100644
--- a/pcompact.a
+++ b/pcompact.a
@@ -1,7 +1,6 @@
; mark used nodes and pointers in argument parts and link backward pointers
-
lea o0,heap_size_33
lwz d7,0(o0)
@@ -9,20 +8,24 @@
slwi d7,d7,5
lwz d0,0(o0)
- stwu a4,-4(sp)
li g3,128
+ subi d4,sp,8000
+
+ stwu a4,-4(sp)
+
cmpwi 0,d0,0
beq end_mark_cafs
mark_cafs_lp:
lwz d1,0(d0)
lwz o5,-4(d0)
- addi a2,d0,4
+
+ addi a3,d0,4
slwi d0,d1,2
- add a4,a2,d0
+ add a4,a3,d0
- bl mark_stack_nodes
+ bl rmark_stack_nodes
addic. d0,o5,0
bne mark_cafs_lp
@@ -31,10 +34,11 @@ end_mark_cafs:
lea o0,stack_p
lwz a4,0(sp)
- lwz a2,0(o0)
+
+ lwz a3,0(o0)
addi sp,sp,4
- bl mark_stack_nodes
+ bl rmark_stack_nodes
if MEASURE_GC
stwu o4,-4(sp)
@@ -47,770 +51,8 @@ end_mark_cafs:
b compact_heap
-mark_stack_nodes3:
- stw a0,-4(a2)
- b mark_stack_nodes
-
-mark_stack_nodes2:
- lwz g1,0(a0)
- addi d0,a2,1-4
- stw g1,-4(a2)
- stw d0,0(a0)
-
-mark_stack_nodes:
- cmpw 0,a4,a2
- beq end_mark_nodes
-
- lwz a0,0(a2)
- addi a2,a2,4
-
- sub d0,a0,d6
- if SHARE_CHAR_INT
- cmplw 0,d0,d7
- bge- mark_stack_nodes
- endif
-
- srwi o0,d0,5
- lbzx o1,o4,o0
- rlwinm o2,d0,32-2,29,31
- rlwnm. r0,o1,o2,24,24
- bne- mark_stack_nodes2
-
- li d3,0
- li d5,1
-
-mark_arguments:
- lwz d0,0-NODE_POINTER_OFFSET(a0)
- srw o3,g3,o2
-
- or o1,o1,o3
-
- andi. r0,d0,2
- lha d2,-2(d0)
-
- stbx o1,o4,o0
-
- cmpwi 6,d2,0
- beq mark_lazy_node
-
- beq 6,mark_hnf_0
-
- cmplwi 0,d2,256
- addi a0,a0,4
- bge mark_record
-
- subic. d2,d2,2
- beq mark_hnf_2
- blt mark_hnf_1
-
-mark_hnf_3:
- lwz a1,4-NODE_POINTER_OFFSET(a0)
-mark_hnf_3_:
- sub d0,a1,d6
- srwi o0,d0,5
- lbzx o1,o4,o0
- rlwinm o2,d0,32-2,29,31
- srw o3,g3,o2
- and. r0,o1,o3
- bne shared_argument_part
-
- or o1,o1,o3
- stbx o1,o4,o0
-
-no_shared_argument_part:
- lwz o0,0-NODE_POINTER_OFFSET(a0)
- or d3,d3,d5
- ori o0,o0,2
- stw o0,0-NODE_POINTER_OFFSET(a0)
- stwu d3,4-NODE_POINTER_OFFSET(a0)
-
- lwz o0,0-NODE_POINTER_OFFSET(a1)
- slwi d2,d2,2
- ori o0,o0,1
- stw o0,0-NODE_POINTER_OFFSET(a1)
-
- lwzux d2,a1,d2
- li d5,0
- stw a0,0-NODE_POINTER_OFFSET(a1)
- mr d3,a1
- mr a0,d2
- b mark_node
-
-shared_argument_part:
- cmplw 0,a1,a0
- bgt mark_hnf_1
-
- lwz o0,0-NODE_POINTER_OFFSET(a1)
- addi d0,a0,4+2+1
- stw d0,0-NODE_POINTER_OFFSET(a1)
- stw o0,4-NODE_POINTER_OFFSET(a0)
- b mark_hnf_1
-
-mark_lazy_node_1:
-; remove if no selectors:
- bne mark_selector_node_1
-mark_hnf_1:
- lwz d2,0-NODE_POINTER_OFFSET(a0)
- or d3,d3,d5
- stw d3,0-NODE_POINTER_OFFSET(a0)
- mr d3,a0
- li d5,2
- mr a0,d2
- b mark_node
-
-mark_selector_node_1:
- baddicc d2,3
- lwz a1,0-NODE_POINTER_OFFSET(a0)
- beq mark_indirection_node
-
- addic. d2,d2,1
- sub o2,a1,d6
- ble mark_record_selector_node_1
-
- srwi d2,o2,5
- lbzx g1,o4,d2
- rlwinm g2,o2,32-2,29,31
- rlwnm. r0,g1,g2,24,24
- bne mark_hnf_1
-
- lwz d2,0-NODE_POINTER_OFFSET(a1)
- andi. r0,d2,2
- beq mark_hnf_1
-
- lha g1,-2(d2)
- cmplwi 0,g1,2
- ble small_tuple_or_record
-
-large_tuple_or_record:
- lwz d1,8-NODE_POINTER_OFFSET(a1)
-
- sub o2,d1,d6
- srwi d2,o2,5
- lbzx g1,o4,d2
- rlwinm g2,o2,32-2,29,31
- rlwnm. r0,g1,g2,24,24
- bne mark_hnf_1
-
-small_tuple_or_record:
- if LINUX
- lwz g1,-8(d0)
- mflr r0
- else
- lha g1,-6(d0)
- mflr r0
- lwzx g1,rtoc,g1
- endif
- andc o1,o1,o3
-
- lwz g1,4(g1)
- subi d2,a0,4
-
- mtlr g1
- stbx o1,o4,o0
- mr a0,a1
- stwu r0,-4(sp)
- blrl
- mtlr r0
-
- lea g1,__indirection
- stw a0,4-NODE_POINTER_OFFSET(d2)
- stw g1,0-NODE_POINTER_OFFSET(d2)
- b mark_node
-
-mark_record_selector_node_1:
- srwi d2,o2,5
- lbzx g1,o4,d2
- rlwinm g2,o2,32-2,29,31
- beq mark_strict_record_selector_node_1
-
- rlwnm. r0,g1,g2,24,24
- bne mark_hnf_1
-
- lwz d2,0-NODE_POINTER_OFFSET(a1)
- andi. r0,d2,2
- beq mark_hnf_1
-
- lha g1,-2(d2)
- cmplwi 0,g1,258
- ble small_tuple_or_record
- b large_tuple_or_record
-
-mark_strict_record_selector_node_1:
- rlwnm. r0,g1,g2,24,24
- bne mark_hnf_1
-
- lwz d2,0-NODE_POINTER_OFFSET(a1)
- andi. r0,d2,2
- beq mark_hnf_1
-
- lha g1,-2(d2)
- cmplwi 0,g1,258
- ble select_from_small_record
-
- lwz d1,8-NODE_POINTER_OFFSET(a1)
- sub o2,d1,d6
-
- srwi d2,o2,5
- lbzx g1,o4,d2
- rlwinm g2,o2,32-2,29,31
- rlwnm. r0,g1,g2,24,24
- bne mark_hnf_1
-
-select_from_small_record:
- if LINUX
- lwz g1,-8(d0)
- mflr r0
- else
- lha g1,-6(d0)
- mflr r0
- lwzx g1,rtoc,g1
- endif
- subi a0,a0,4
- lwz g1,4(g1)
-
- mtlr g1
- stwu r0,-4(sp)
- blrl
- mtlr r0
-
- b mark_next_node
-
-mark_indirection_node:
- andc o1,o1,o3
- stbx o1,o4,o0
-
- mr a0,a1
- b mark_node
-
-mark_hnf_2:
- lwz o0,0-NODE_POINTER_OFFSET(a0)
- or d3,d3,d5
- ori o0,o0,2
- stw o0,0-NODE_POINTER_OFFSET(a0)
- lwzu d2,4-NODE_POINTER_OFFSET(a0)
- stw d3,0-NODE_POINTER_OFFSET(a0)
- mr d3,a0
- li d5,0
- mr a0,d2
-
-mark_node:
- sub d0,a0,d6
- if SHARE_CHAR_INT
- cmplw 0,d0,d7
- bge- mark_next_node_after_static
- endif
- srwi o0,d0,5
- lbzx o1,o4,o0
- rlwinm o2,d0,32-2,29,31
- rlwnm. r0,o1,o2,24,24
- beq+ mark_arguments
-
-mark_next_node:
- cmpwi 0,d5,0
- bne mark_parent
-
- lwzu d2,-4-NODE_POINTER_OFFSET(d3)
- lwz o0,4-NODE_POINTER_OFFSET(d3)
- andi. d5,d2,3
-
- cmpwi 0,d5,3
- beq argument_part_cycle1
-
- stw o0,0-NODE_POINTER_OFFSET(d3)
-
-c_argument_part_cycle1:
- cmplw 0,a0,d3
- bgt no_reverse_1
-
- lwz o0,0-NODE_POINTER_OFFSET(a0)
- addi d0,d3,4+1
- stw o0,4-NODE_POINTER_OFFSET(d3)
- stw d0,0-NODE_POINTER_OFFSET(a0)
- clrrwi a0,d2,2
- b mark_node
-
-no_reverse_1:
- stw a0,4-NODE_POINTER_OFFSET(d3)
- clrrwi a0,d2,2
- b mark_node
-
-mark_lazy_node:
- beq 6,mark_next_node
-
- bsubicc d2,1
- baddi a0,4
- ble mark_lazy_node_1
-
- cmplwi 0,d2,255
- bge mark_closure_with_unboxed_arguments
-
-mark_closure_with_unboxed_arguments_:
- lwz o0,0-NODE_POINTER_OFFSET(a0)
- slwi d2,d2,2
- ori o0,o0,2
- stw o0,0(a0)
-
- lwzux d2,a0,d2
- or d3,d3,d5
- stw d3,0-NODE_POINTER_OFFSET(a0)
- mr d3,a0
- li d5,0
- mr a0,d2
- b mark_node
-
-mark_closure_with_unboxed_arguments:
-; baddi d2,1
- srwi d0,d2,8
- bandic d2,255
-; bsub d2,d0
- bsubc d2,d0
-; bsubicc d2,1
- bgt mark_closure_with_unboxed_arguments_
- beq mark_hnf_1
- bsubi a0,4
- b mark_next_node
-
-mark_hnf_0:
- if SHARE_CHAR_INT
- cmpw d0,int_reg
- bne no_int_3
-
- lwz d2,4-NODE_POINTER_OFFSET(a0)
- cmplwi 0,d2,33
- bge mark_next_node
-
- andc o1,o1,o3
- stbx o1,o4,o0
-
- lea a0,small_integers
- slwi d2,d2,3
- add a0,a0,d2
- b mark_next_node_after_static
-
-no_int_3:
- cmplw d0,char_reg
- bne no_char_3
-
- andc o1,o1,o3
- stbx o1,o4,o0
-
- lbz d2,7-NODE_POINTER_OFFSET(a0)
- lea a0,static_characters
- slwi d2,d2,3
- add a0,a0,d2
- b mark_next_node_after_static
-
-no_char_3:
- blt no_normal_hnf_0
-
- subi a0,d0,2-ZERO_ARITY_DESCRIPTOR_OFFSET
-
- andc o1,o1,o3
- stbx o1,o4,o0
- b mark_next_node_after_static
-
-no_normal_hnf_0:
- endif
-
- lea o0,__ARRAY__2
- cmplw 0,d0,o0
- bne+ mark_next_node
- b mark_array
-
-mark_record:
- subic. d2,d2,258
- beq mark_record_2
- blt mark_record_1
-
-mark_record_3:
- lhz d2,-2+2(d0)
- lwz a1,4-NODE_POINTER_OFFSET(a0)
- subic. d2,d2,1
- blt mark_record_3_bb
-
- beq mark_record_3_ab
-
- subic. d2,d2,1
- beq mark_record_3_aab
-
- b mark_hnf_3_
-
-mark_record_3_bb:
- subi a0,a0,4
-
- sub d0,a1,d6
- setmbit o4,d0,d1,o0,o1,o2,2
-
- cmplw a1,a0
- bgt mark_next_node
-
- srwi. o0,o0,1
-
- lwz o2,0-NODE_POINTER_OFFSET(a1)
- addi d0,a0,8+2+1
- stw o2,8-NODE_POINTER_OFFSET(a0)
- stw d0,0-NODE_POINTER_OFFSET(a1)
-
- bne+ not_next_byte_1
-
- addi d1,d1,1
- lbzx o1,o4,d1
- li o0,128
-not_next_byte_1:
- and. r0,o1,o0
- beq+ not_yet_linked_bb
-
- sub d0,a0,d6
- addi d0,d0,8
- setmbit o4,d0,d1,o0,o1,o2,2
- b mark_next_node
-
-not_yet_linked_bb:
- or o1,o1,o0
- stbx o1,o4,d1
- b mark_next_node
-
-mark_record_3_ab:
- sub d0,a1,d6
- setmbit o4,d0,d1,o0,o1,o2,2
-
- cmplw 0,a1,a0
- bgt mark_hnf_1
-
- srwi. o0,o0,1
-
- lwz o2,0-NODE_POINTER_OFFSET(a1)
- addi d0,a0,4+2+1
- stw o2,4-NODE_POINTER_OFFSET(a0)
- stw d0,0-NODE_POINTER_OFFSET(a1)
-
- bne+ not_next_byte_2
-
- addi d1,d1,1
- lbzx o1,o4,d1
- li o0,128
-not_next_byte_2:
- and. r0,o1,o0
- beq+ not_yet_linked_ab
-
- sub d0,a0,d6
- addi d0,d0,4
- setmbit o4,d0,d1,o0,o1,o2,2
- b mark_hnf_1
-
-not_yet_linked_ab:
- or o1,o1,o0
- stbx o1,o4,d1
- b mark_hnf_1
-
-mark_record_3_aab:
- sub d0,a1,d6
-
- tstmbit o4,d0,d1,o0,o1,o2,2
- bne shared_argument_part
-
- srw o0,g3,o2
- or o1,o1,o0
- stbx o1,o4,d1
-
- lwz o0,0-NODE_POINTER_OFFSET(a0)
- or d3,d3,d5
- ori o0,o0,2
- stw o0,0-NODE_POINTER_OFFSET(a0)
- stwu d3,4-NODE_POINTER_OFFSET(a0)
-
- lwz d2,0-NODE_POINTER_OFFSET(a1)
- li d5,1
- stw a0,0-NODE_POINTER_OFFSET(a1)
- mr d3,a1
- mr a0,d2
- b mark_node
-
-mark_record_2:
- lhz g1,-2+2(d0)
- cmplwi g1,1
- bgt mark_hnf_2
- beq mark_hnf_1
-
- subi a0,a0,4
- b mark_next_node
-
-mark_record_1:
- lhz g1,-2+2(d0)
- tst g1
- bne mark_hnf_1
-
- subi a0,a0,4
- b mark_next_node
-
-mark_array:
- lwz d1,8-NODE_POINTER_OFFSET(a0)
- tst d1
- beq mark_lazy_array
-
- lhz d0,-2(d1)
- tst d0
- beq mark_b_record_array
-
- lhz d1,-2+2(d1)
- tst d1
- beq mark_b_record_array
-
- subi d0,d0,256
- cmpw 0,d0,d1
- beq mark_a_record_array
-
-mark_ab_record_array:
- mr o2,d2
- mr o3,d3
- stw d5,-4(sp)
-
- lwz d2,4-NODE_POINTER_OFFSET(a0)
- addi a0,a0,8
- stw a0,-8(sp)
-
- slwi d2,d2,2
- mullw a1,d2,d0
-
- sub d0,d0,d1
- addi a0,a0,4
- add a1,a1,a0
-
- mflr r0
- stw r0,-12(sp)
- bl reorder
- lwz r0,-12(sp)
-
- lwz a0,-8(sp)
- mtlr r0
-
- lwz d0,-4(a0)
- mullw d0,d0,d1
-
- lwz d5,-4(sp)
- mr d3,o3
- mr d2,o2
- b mark_lr_array
-
-mark_b_record_array:
- sub d0,a0,d6
- addi d0,d0,4
- setmbit o4,d0,d1,o0,o1,o2,2
- b mark_next_node
-
-mark_a_record_array:
- lwz d0,4-NODE_POINTER_OFFSET(a0)
- addi a0,a0,8
- mullw d0,d0,d1
- b mark_lr_array
-
-mark_lazy_array:
- lwz d0,4-NODE_POINTER_OFFSET(a0)
- addi a0,a0,8
-mark_lr_array:
- sub d1,a0,d6
- srwi d1,d1,2
- add d1,d1,d0
- setmbit o4,d1,d2,o0,o1,o2,0
-
- cmplwi 0,d0,1
- ble mark_array_length_0_1
-
- mr a1,a0
- slwi d0,d0,2
- add a0,a0,d0
-
- lwz d2,0-NODE_POINTER_OFFSET(a0)
- lwz o0,0-NODE_POINTER_OFFSET(a1)
- stw d2,0-NODE_POINTER_OFFSET(a1)
- stw o0,0-NODE_POINTER_OFFSET(a0)
-
- lwzu d2,-4-NODE_POINTER_OFFSET(a0)
- lwzu o0,-4-NODE_POINTER_OFFSET(a1)
- addi d2,d2,2
- stw o0,0-NODE_POINTER_OFFSET(a0)
- stw d2,0-NODE_POINTER_OFFSET(a1)
-
- lwzu d2,-4-NODE_POINTER_OFFSET(a0)
- or d3,d3,d5
- stw d3,0-NODE_POINTER_OFFSET(a0)
- mr d3,a0
- li d5,0
- mr a0,d2
- b mark_node
-
-mark_array_length_0_1:
- subi a0,a0,8
- blt mark_next_node
-
- lwz d1,12-NODE_POINTER_OFFSET(a0)
- lwz o0,8-NODE_POINTER_OFFSET(a0)
- lwz o1,4-NODE_POINTER_OFFSET(a0)
- stw o0,12-NODE_POINTER_OFFSET(a0)
- stw o1,8-NODE_POINTER_OFFSET(a0)
- stwu d1,4-NODE_POINTER_OFFSET(a0)
- b mark_hnf_1
-
-
-mark_parent:
- tst d3
- beq mark_stack_nodes2
-
- subic. d5,d5,1
- beq argument_part_parent
-
- cmplw a0,d3
- lwz d2,0-NODE_POINTER_OFFSET(d3)
- bgt no_reverse_2
-
- mr a1,a0
- addi d0,d3,1
- lwz a0,0-NODE_POINTER_OFFSET(a1)
- stw d0,0-NODE_POINTER_OFFSET(a1)
-
-no_reverse_2:
- stw a0,0-NODE_POINTER_OFFSET(d3)
- subi a0,d3,4
- andi. d5,d2,3
- clrrwi d3,d2,2
- b mark_next_node
-
-argument_part_parent:
- mr a1,d3
- mr d3,a0
-
- lwz d2,0-NODE_POINTER_OFFSET(a1)
-
- mr a0,a1
-
-skip_upward_pointers:
- andi. d0,d2,3
- cmpwi 0,d0,3
- bne no_upward_pointer
-
- clrrwi a1,d2,2
- lwz d2,0-NODE_POINTER_OFFSET(a1)
- b skip_upward_pointers
-
-no_upward_pointer:
- cmplw 0,d3,a0
- bgt no_reverse_3
-
- mr a6,d3
- lwz d3,0-NODE_POINTER_OFFSET(d3)
- addi d0,a0,1
- stw d0,0-NODE_POINTER_OFFSET(a6)
-
-no_reverse_3:
- stw d3,0-NODE_POINTER_OFFSET(a1)
-
- clrrwi d3,d2,2
-
- lwzu d2,-4-NODE_POINTER_OFFSET(d3)
-
- cmplw 6,a0,d3
-
- lwz o0,4-NODE_POINTER_OFFSET(d3)
- andi. d5,d2,3
- stw o0,0-NODE_POINTER_OFFSET(d3)
-
- bgt 6,no_reverse_4
-
- lwz o0,0-NODE_POINTER_OFFSET(a0)
- stw o0,4-NODE_POINTER_OFFSET(d3)
- addi d0,d3,4+2+1
- stw d0,0-NODE_POINTER_OFFSET(a0)
- clrrwi a0,d2,2
- b mark_node
-
-no_reverse_4:
- stw a0,4-NODE_POINTER_OFFSET(d3)
- clrrwi a0,d2,2
- b mark_node
-
-argument_part_cycle1:
- mr d1,a1
-
-skip_pointer_list1:
- clrrwi a1,d2,2
- lwz d2,0-NODE_POINTER_OFFSET(a1)
- andi. d5,d2,3
- cmpwi 0,d5,3
- beq skip_pointer_list1
-
- stw o0,0-NODE_POINTER_OFFSET(a1)
- mr a1,d1
- b c_argument_part_cycle1
-
- if SHARE_CHAR_INT
-mark_next_node_after_static:
- cmpwi 0,d5,0
- bne mark_parent_after_static
-
- lwzu d2,-4-NODE_POINTER_OFFSET(d3)
- lwz o0,4-NODE_POINTER_OFFSET(d3)
- andi. d5,d2,3
-
- cmpwi 0,d5,3
- beq argument_part_cycle2
-
- stw o0,0-NODE_POINTER_OFFSET(d3)
-
-c_argument_part_cycle2:
- stw a0,4-NODE_POINTER_OFFSET(d3)
- clrrwi a0,d2,2
- b mark_node
-
-mark_parent_after_static:
- cmpwi 0,d3,0
- beq mark_stack_nodes3
-
- subic. d5,d5,1
- beq argument_part_parent_after_static
-
- lwz d2,0-NODE_POINTER_OFFSET(d3)
- stw a0,0-NODE_POINTER_OFFSET(d3)
- subi a0,d3,4
- andi. d5,d2,3
- clrrwi d3,d2,2
- b mark_next_node
-
-argument_part_parent_after_static:
- mr a1,d3
- mr d3,a0
-
- lwz d2,0-NODE_POINTER_OFFSET(a1)
-
- mr a0,a1
-
-skip_upward_pointers_2:
- andi. d0,d2,3
- cmpwi 0,d0,3
- bne no_reverse_3
-
- clrrwi a1,d2,2
- lwz d2,0-NODE_POINTER_OFFSET(a1)
- b skip_upward_pointers_2
-
-argument_part_cycle2:
- mr d1,a1
-
-skip_pointer_list2:
- clrrwi a1,d2,2
- lwz d2,0-NODE_POINTER_OFFSET(a1)
- andi. d5,d2,3
- cmpwi 0,d5,3
- beq skip_pointer_list2
-
- stw o0,0-NODE_POINTER_OFFSET(a1)
- mr a1,d1
- b c_argument_part_cycle2
- endif
-
-end_mark_nodes:
- addi a2,a2,4
- blr
-
+ include 'pcompact_rmark.a'
+ include 'pcompact_rmarkr.a'
; compact the heap
@@ -897,7 +139,10 @@ finalizer_list_empty:
stwu a4,-4(sp)
addi a4,a2,4
- bl mark_stack_nodes
+
+ mr a3,a2
+ bl rmark_stack_nodes
+
lwz a4,0(sp)
addi sp,sp,4
diff --git a/pcompact_rmark.a b/pcompact_rmark.a
new file mode 100644
index 0000000..3ce30ee
--- /dev/null
+++ b/pcompact_rmark.a
@@ -0,0 +1,835 @@
+
+rmark_stack_nodes:
+ mflr r0
+ stwu r0,-4(sp)
+ b rmark_stack_nodes_
+
+rmark_stack_nodes1:
+ lwz d1,0(a0)
+ addi d0,a3,1
+ stw d1,0(a3)
+ stw d0,0(a0)
+
+rmark_next_stack_node:
+ addi a3,a3,4
+ cmpw 0,a4,a3
+ beq end_rmark_nodes
+
+rmark_stack_nodes_:
+ lwz a0,0(a3)
+
+ sub d0,a0,d6
+ cmplw 0,d0,d7
+ bge- rmark_next_stack_node
+
+ srwi o0,d0,5
+ lbzx o1,o4,o0
+ rlwinm o2,d0,32-2,29,31
+ rlwnm. r0,o1,o2,24,24
+ bne- rmark_stack_nodes1
+
+ srw o3,g3,o2
+
+ lwz d0,0(a0)
+ li g1,0
+ stw a3,-4(sp)
+
+ or o1,o1,o3
+
+ addi a2,a3,1
+ stw d0,0(a3)
+
+ stbx o1,o4,o0
+
+ li d1,-1
+ stwu g1,-8(sp)
+ stw a2,0(a0)
+ bl rmark_no_reverse
+
+ addi a3,a3,4
+ cmpw 0,a4,a3
+ bne rmark_stack_nodes_
+
+end_rmark_nodes:
+ lwz r0,0(sp)
+ addi sp,sp,4
+ mtlr r0
+ blr
+
+rmark_node_d1:
+ sub d0,a0,d6
+ cmplw 0,d0,d7
+ bge- rmark_next_node
+
+ b rmark_node_
+
+rmark_hnf_2:
+ addi d1,a0,4
+ lwz d0,4(a0)
+
+ cmplw 0,sp,d4
+
+ mr a3,a0
+ lwz a0,0(a0)
+
+ stw d1,-4(sp)
+ stwu d0,-8(sp)
+
+ blt rmark_using_reversal
+
+rmark_node:
+ sub d0,a0,d6
+ cmplw 0,d0,d7
+ bge- rmark_next_node
+
+ mr d1,a3
+
+rmark_node_:
+ srwi o0,d0,5
+ lbzx o1,o4,o0
+ rlwinm o2,d0,32-2,29,31
+ rlwnm. r0,o1,o2,24,24
+ bne rmark_reverse_and_mark_next_node
+
+ srw o3,g3,o2
+ or o1,o1,o3
+
+ lwz d0,0(a0)
+
+ stbx o1,o4,o0
+
+rmark_arguments:
+ cmplw 0,a0,d1
+ bgt rmark_no_reverse
+
+ addi a2,a3,1
+ stw d0,0(a3)
+ stw a2,0(a0)
+
+rmark_no_reverse:
+ andi. r0,d0,2
+ lha d2,-2(d0)
+
+ cmpwi 6,d2,0
+ beq rmark_lazy_node
+
+ beq 6,rmark_hnf_0
+
+ cmplwi 0,d2,256
+ addi a0,a0,4
+ bge rmark_record
+
+ subic. d2,d2,2
+ beq rmark_hnf_2
+ blt rmark_hnf_1
+
+rmark_hnf_3:
+ lwz a1,4-NODE_POINTER_OFFSET(a0)
+rmark_hnf_3_:
+ cmplw 0,sp,d4
+ blt rmark_using_reversal_
+
+ sub d0,a1,d6
+ srwi o0,d0,5
+ lbzx o1,o4,o0
+ rlwinm o2,d0,32-2,29,31
+ srw o3,g3,o2
+ and. r0,o1,o3
+ bne rmark_shared_argument_part
+
+ or o1,o1,o3
+ stbx o1,o4,o0
+
+rmark_no_shared_argument_part:
+ slwi d1,d2,2
+ stw a0,-4(sp)
+ addi a3,a0,4
+ lwz a0,0(a0)
+ add a1,a1,d1
+ stwu a0,-8(sp)
+
+rmark_push_hnf_args:
+ bsubicc d2,1
+
+ lwz d1,0(a1)
+ stw a1,-4(sp)
+ bsubi a1,4
+ stwu d1,-8(sp)
+
+ bgt rmark_push_hnf_args
+
+ lwz a0,0(a1)
+ cmplw a1,a3
+ bgt rmark_no_reverse_argument_pointer
+
+ addi a2,a3,3
+ stw a0,0(a3)
+ stw a2,0(a1)
+
+ sub d0,a0,d6
+ cmplw 0,d0,d7
+ bge- rmark_next_node
+
+ mr d1,a1
+ b rmark_node_
+
+rmark_no_reverse_argument_pointer:
+ mr a3,a1
+ b rmark_node
+
+rmark_shared_argument_part:
+ cmplw 0,a1,a0
+ bgt rmark_hnf_1
+
+ lwz d1,0-NODE_POINTER_OFFSET(a1)
+ addi d0,a0,4+2+1
+ stw d0,0-NODE_POINTER_OFFSET(a1)
+ stw d1,4-NODE_POINTER_OFFSET(a0)
+ b rmark_hnf_1
+
+rmark_record:
+ subic. d2,d2,258
+ beq rmark_record_2
+ blt rmark_record_1
+
+rmark_record_3:
+ lhz d2,-2+2(d0)
+ lwz a1,4-NODE_POINTER_OFFSET(a0)
+ subic. d2,d2,1
+ blt rmark_record_3_bb
+
+ beq rmark_record_3_ab
+
+ subic. d2,d2,1
+ beq rmark_record_3_aab
+
+ b rmark_hnf_3_
+
+rmark_record_3_bb:
+ subi a0,a0,4
+
+ sub d0,a1,d6
+ setmbit o4,d0,o0,o3,o1,o2,2
+
+ cmplw a1,a0
+ bgt rmark_next_node
+
+ srwi. o3,o3,1
+
+ lwz o2,0-NODE_POINTER_OFFSET(a1)
+ addi d0,a0,8+2+1
+ stw o2,8-NODE_POINTER_OFFSET(a0)
+ stw d0,0-NODE_POINTER_OFFSET(a1)
+
+ bne+ rmark_not_next_byte_1
+
+ addi o0,o0,1
+ lbzx o1,o4,o0
+ li o3,128
+rmark_not_next_byte_1:
+ and. r0,o1,o3
+ beq+ rmark_not_yet_linked_bb
+
+ sub d0,a0,d6
+ addi d0,d0,8
+ setmbit o4,d0,o0,o3,o1,o2,2
+ b rmark_next_node
+
+rmark_not_yet_linked_bb:
+ or o1,o1,o3
+ stbx o1,o4,o0
+ b rmark_next_node
+
+rmark_record_3_ab:
+ sub d0,a1,d6
+ setmbit o4,d0,o0,o3,o1,o2,2
+
+ cmplw 0,a1,a0
+ bgt rmark_hnf_1
+
+ srwi. o3,o3,1
+
+ lwz o2,0-NODE_POINTER_OFFSET(a1)
+ addi d0,a0,4+2+1
+ stw o2,4-NODE_POINTER_OFFSET(a0)
+ stw d0,0-NODE_POINTER_OFFSET(a1)
+
+ bne+ rmark_not_next_byte_2
+
+ addi o0,o0,1
+ lbzx o1,o4,o0
+ li o3,128
+rmark_not_next_byte_2:
+ and. r0,o1,o3
+ beq+ rmark_not_yet_linked_ab
+
+ sub d0,a0,d6
+ addi d0,d0,4
+ setmbit o4,d0,o0,o3,o1,o2,2
+ b rmark_hnf_1
+
+rmark_not_yet_linked_ab:
+ or o1,o1,o3
+ stbx o1,o4,o0
+ b rmark_hnf_1
+
+rmark_record_3_aab:
+ cmplw 0,sp,d4
+ blt rmark_using_reversal_
+
+ sub d0,a1,d6
+
+ tstmbit o4,d0,o0,o3,o1,o2,2
+ bne rmark_shared_argument_part
+
+ stw a0,-4(sp)
+
+ srw o3,g3,o2
+
+ addi a3,a0,4
+ lwz a0,0(a0)
+
+ or o1,o1,o3
+ stbx o1,o4,o0
+
+ stwu a0,-8(sp)
+
+ lwz a0,0(a1)
+ cmplw a1,a3
+ bgt rmark_no_reverse_argument_pointer
+
+ addi a2,a3,3
+ stw a0,0(a3)
+ stw a2,0(a1)
+
+ sub d0,a0,d6
+ cmplw 0,d0,d7
+ bge- rmark_next_node
+
+ mr d1,a1
+ b rmark_node_
+
+rmark_record_2:
+ lhz g1,-2+2(d0)
+ cmplwi g1,1
+ bgt rmark_hnf_2
+ beq rmark_hnf_1
+ b rmark_next_node
+
+rmark_record_1:
+ lhz g1,-2+2(d0)
+ tst g1
+ bne rmark_hnf_1
+ b rmark_next_node
+
+rmark_lazy_node_1:
+ bne rmark_selector_node_1
+
+rmark_hnf_1:
+ mr a3,a0
+ lwz a0,0-NODE_POINTER_OFFSET(a0)
+ b rmark_node
+
+rmark_indirection_node:
+ subi g1,a0,4
+ andc o1,o1,o3
+ mr a0,a1
+
+ cmplw g1,d1
+
+ stbx o1,o4,o0
+ stw a1,0(a3)
+
+ bgt rmark_node_d1
+ stw d0,0(g1)
+ b rmark_node_d1
+
+rmark_selector_node_1:
+ baddicc d2,3
+ lwz a1,0-NODE_POINTER_OFFSET(a0)
+ beq rmark_indirection_node
+
+ addic. d2,d2,1
+ sub o2,a1,d6
+ ble rmark_record_selector_node_1
+
+ srwi d2,o2,5
+ lbzx g1,o4,d2
+ rlwinm g2,o2,32-2,29,31
+ rlwnm. r0,g1,g2,24,24
+ bne rmark_hnf_1
+
+ lwz d2,0-NODE_POINTER_OFFSET(a1)
+ andi. r0,d2,2
+ beq rmark_hnf_1
+
+ lha g1,-2(d2)
+ cmplwi 0,g1,2
+ ble rmark_small_tuple_or_record
+
+rmark_large_tuple_or_record:
+ lwz o2,8-NODE_POINTER_OFFSET(a1)
+ sub o2,o2,d6
+
+ srwi d2,o2,5
+ lbzx g1,o4,d2
+ rlwinm g2,o2,32-2,29,31
+ rlwnm. r0,g1,g2,24,24
+ bne rmark_hnf_1
+
+rmark_small_tuple_or_record:
+ if LINUX
+ lwz g1,-8(d0)
+ mflr r0
+ else
+ lha g1,-6(d0)
+ mflr r0
+ lwzx g1,rtoc,g1
+ endif
+ andc o1,o1,o3
+
+ lwz g1,4(g1)
+ subi d2,a0,4
+
+ stbx o1,o4,o0
+ mtctr g1
+ mr a0,a1
+ mr d3,d1
+ stw a3,-4(sp)
+ stwu r0,-8(sp)
+ bctrl
+ lwz a3,0(sp)
+ addi sp,sp,4
+ mtlr r0
+ mr d1,d3
+
+ lea g1,__indirection
+ stw a0,0(a3)
+
+ stw a0,4-NODE_POINTER_OFFSET(d2)
+ stw g1,0-NODE_POINTER_OFFSET(d2)
+ b rmark_node_d1
+
+rmark_record_selector_node_1:
+ srwi d2,o2,5
+ lbzx g1,o4,d2
+ rlwinm g2,o2,32-2,29,31
+ beq rmark_strict_record_selector_node_1
+
+ rlwnm. r0,g1,g2,24,24
+ bne rmark_hnf_1
+
+ lwz d2,0-NODE_POINTER_OFFSET(a1)
+ andi. r0,d2,2
+ beq rmark_hnf_1
+
+ lha g1,-2(d2)
+ cmplwi 0,g1,258
+ ble rmark_small_tuple_or_record
+ b rmark_large_tuple_or_record
+
+rmark_strict_record_selector_node_1:
+ rlwnm. r0,g1,g2,24,24
+ bne rmark_hnf_1
+
+ lwz d2,0-NODE_POINTER_OFFSET(a1)
+ andi. r0,d2,2
+ beq rmark_hnf_1
+
+ lha g1,-2(d2)
+ cmplwi 0,g1,258
+ ble rmark_select_from_small_record
+
+ lwz o2,8-NODE_POINTER_OFFSET(a1)
+ sub o2,o2,d6
+
+ srwi d2,o2,5
+ lbzx g1,o4,d2
+ rlwinm g2,o2,32-2,29,31
+ rlwnm. r0,g1,g2,24,24
+ bne rmark_hnf_1
+
+rmark_select_from_small_record:
+ if LINUX
+ lwz g1,-8(d0)
+ mflr r0
+ else
+ lha g1,-6(d0)
+ mflr r0
+ lwzx g1,rtoc,g1
+ endif
+ subi a0,a0,4
+
+ cmplw a0,d1
+ bgt rmark_selector_pointer_not_reversed
+
+ stw d0,0(a0)
+
+ lwz g1,4(g1)
+
+ stw a0,0(a3)
+
+ mtctr g1
+ stw a3,-4(sp)
+ stwu r0,-8(sp)
+ bctrl
+ lwz a3,0(sp)
+ addi sp,sp,4
+ mtlr r0
+
+ lwz d0,0(a0)
+ addi a3,a3,1
+ stw a3,0(a0)
+ stw d0,-1(a3)
+ b rmark_next_node
+
+rmark_selector_pointer_not_reversed:
+ lwz g1,4(g1)
+
+ mtctr g1
+ stwu r0,-4(sp)
+ bctrl
+ mtlr r0
+
+ b rmark_next_node
+
+rmark_reverse_and_mark_next_node:
+ cmplw a0,d1
+ bgt rmark_next_node
+
+ lwz d0,0(a0)
+ stw d0,0(a3)
+ addi a3,a3,1
+ stw a3,0(a0)
+
+rmark_next_node:
+ lwz a0,0(sp)
+ lwz a3,4(sp)
+ addi sp,sp,8
+
+ cmplwi a0,1
+ bgt rmark_node
+
+ blr
+
+rmark_lazy_node:
+ beq 6,rmark_next_node
+
+ bsubicc d2,1
+ baddi a0,4
+ ble rmark_lazy_node_1
+
+ cmplwi 0,d2,255
+ bge rmark_closure_with_unboxed_arguments
+
+rmark_closure_with_unboxed_arguments_:
+ slwi d1,d2,2
+ add a0,a0,d1
+
+rmark_push_lazy_args
+ bsubicc d2,1
+
+ lwz d1,0(a0)
+ stw a0,-4(sp)
+ bsubi a0,4
+ stwu d1,-8(sp)
+
+ bgt rmark_push_lazy_args
+
+ cmplw 0,sp,d4
+
+ mr a3,a0
+ lwz a0,0(a0)
+
+ bge rmark_node
+ b rmark_using_reversal
+
+rmark_closure_with_unboxed_arguments:
+; baddi d2,1
+ srwi d0,d2,8
+ bandic d2,255
+; bsub d2,d0
+ bsubc d2,d0
+; bsubicc d2,1
+ bgt rmark_closure_with_unboxed_arguments_
+ beq rmark_hnf_1
+ b rmark_next_node
+
+rmark_hnf_0:
+ cmpw d0,int_reg
+ beq rmark_int
+
+ cmplw d0,char_reg
+ beq rmark_char
+ blt rmark_no_normal_hnf_0
+
+ cmplw a0,d1
+
+ andc o1,o1,o3
+ subi a1,d0,2-ZERO_ARITY_DESCRIPTOR_OFFSET
+ stbx o1,o4,o0
+ stw a1,0(a3)
+
+ bgt rmark_next_node
+ stw d0,0(a0)
+ b rmark_next_node
+
+rmark_int:
+ lwz d2,4-NODE_POINTER_OFFSET(a0)
+ cmplwi 0,d2,33
+ bge rmark_next_node
+
+ lea a1,small_integers
+ andc o1,o1,o3
+ slwi d2,d2,3
+
+ stbx o1,o4,o0
+ add a1,a1,d2
+
+ cmplw a0,d1
+
+ stw a1,0(a3)
+
+ bgt rmark_next_node
+ stw d0,0(a0)
+ b rmark_next_node
+
+rmark_char:
+ andc o1,o1,o3
+ lbz d2,7-NODE_POINTER_OFFSET(a0)
+
+ lea a1,static_characters
+ stbx o1,o4,o0
+ slwi d2,d2,3
+
+ add a1,a1,d2
+
+ cmplw a0,d1
+
+ stw a1,0(a3)
+
+ bgt rmark_next_node
+ stw d0,0(a0)
+ b rmark_next_node
+
+rmark_no_normal_hnf_0:
+ lea g0,__ARRAY__2
+ cmplw 0,d0,g0
+ bne+ rmark_next_node
+
+rmark_array:
+ lwz g1,8-NODE_POINTER_OFFSET(a0)
+ tst g1
+ beq rmark_lazy_array
+
+ lhz d0,-2(g1)
+ tst d0
+ beq rmark_b_array
+
+ lhz g1,-2+2(g1)
+ subi d0,d0,256
+ tst g1
+ beq rmark_b_array
+
+ cmplw 0,sp,d4
+ blt rmark_array_using_reversal
+
+ cmpw 0,d0,g1
+ mr d1,g1
+ beq rmark_a_record_array
+
+rmark_ab_record_array:
+ mr o2,d2
+ mr o3,d3
+
+ lwz d2,4-NODE_POINTER_OFFSET(a0)
+ addi a0,a0,8
+ stw a0,-4(sp)
+
+ slwi d2,d2,2
+ mullw a1,d2,d0
+
+ sub d0,d0,d1
+ addi a0,a0,4
+ add a1,a1,a0
+
+ mflr r0
+ stw r0,-8(sp)
+ bl reorder2
+ lwz r0,-8(sp)
+ lwz a0,-4(sp)
+ mtlr r0
+
+ lwz d0,-4(a0)
+ mullw d0,d0,d1
+
+ mr d3,o3
+ mr d2,o2
+ b rmark_lr_array
+
+rmark_b_array:
+ sub d0,a0,d6
+ addi d0,d0,4
+ setmbit o4,d0,o0,o3,o1,o2,2
+ b rmark_next_node
+
+rmark_a_record_array:
+ lwz d0,4-NODE_POINTER_OFFSET(a0)
+ addi a0,a0,8
+ mullw d0,d0,d1
+ b rmark_lr_array
+
+rmark_lazy_array:
+ cmplw 0,sp,d4
+ blt rmark_array_using_reversal
+
+ lwz d0,4-NODE_POINTER_OFFSET(a0)
+ addi a0,a0,8
+rmark_lr_array:
+ sub d1,a0,d6
+ srwi d1,d1,2
+ add d1,d1,d0
+ setmbit o4,d1,o0,o3,o1,o2,0
+
+ cmplwi 0,d0,1
+ ble rmark_array_length_0_1
+
+ mr a1,a0
+ slwi d0,d0,2
+ add a0,a0,d0
+
+ lwz d2,0-NODE_POINTER_OFFSET(a0)
+ lwz o0,0-NODE_POINTER_OFFSET(a1)
+ stw d2,0-NODE_POINTER_OFFSET(a1)
+ stw o0,0-NODE_POINTER_OFFSET(a0)
+
+ lwzu d2,-4-NODE_POINTER_OFFSET(a0)
+ lwzu o0,-4-NODE_POINTER_OFFSET(a1)
+ stw o0,0-NODE_POINTER_OFFSET(a0)
+ stw d2,0-NODE_POINTER_OFFSET(a1)
+
+ mflr r0
+ if 0
+ stw a4,-4(sp)
+ mr a4,a0
+ else
+ stw a0,-4(sp)
+ endif
+ mr a3,a1
+ stwu r0,-8(sp)
+ b rmark_array_nodes_
+
+rmark_array_nodes1:
+ cmplw 0,a0,a3
+ bgt rmark_next_array_node
+
+ lwz d1,0(a0)
+ addi d0,a3,1
+ stw d1,0(a3)
+ stw d0,0(a0)
+
+rmark_next_array_node:
+ if 0
+ addi a3,a3,4
+ cmpw 0,a4,a3
+ else
+ lwz d0,4(sp)
+ addi a3,a3,4
+ cmpw 0,d0,a3
+ endif
+ beq end_rmark_array_nodes
+
+rmark_array_nodes_:
+ lwz a0,0(a3)
+
+ sub d0,a0,d6
+ cmplw 0,d0,d7
+ bge- rmark_next_array_node
+
+ srwi o0,d0,5
+ lbzx o1,o4,o0
+ rlwinm o2,d0,32-2,29,31
+ rlwnm. r0,o1,o2,24,24
+ bne- rmark_array_nodes1
+
+ srw o3,g3,o2
+
+ lwz d0,0(a0)
+ li g1,1
+ stw a3,-4(sp)
+
+ or o1,o1,o3
+
+ stwu g1,-8(sp)
+
+ stbx o1,o4,o0
+
+ mr d1,a3
+ bl rmark_arguments
+
+ if 0
+ addi a3,a3,4
+ cmpw 0,a4,a3
+ else
+ lwz d0,4(sp)
+ addi a3,a3,4
+ cmpw 0,d0,a3
+ endif
+ bne rmark_array_nodes_
+
+end_rmark_array_nodes:
+ lwz r0,0(sp)
+ if 0
+ lwz a4,4(sp)
+ endif
+ addi sp,sp,8
+ mtlr r0
+ b rmark_next_node
+
+rmark_array_length_0_1:
+ subi a0,a0,8
+ blt rmark_next_node
+
+ lwz d1,12-NODE_POINTER_OFFSET(a0)
+ lwz o0,8-NODE_POINTER_OFFSET(a0)
+ lwz o1,4-NODE_POINTER_OFFSET(a0)
+ stw o0,12-NODE_POINTER_OFFSET(a0)
+ stw o1,8-NODE_POINTER_OFFSET(a0)
+ stwu d1,4-NODE_POINTER_OFFSET(a0)
+ b rmark_hnf_1
+
+reorder2:
+ mr d2,d0
+ mr d3,d1
+ slwi g0,d0,2
+ slwi g1,d1,2
+ add a0,a0,g1
+ sub a1,a1,g0
+ b st_reorder_lp2
+
+reorder_lp2:
+ lwzu o0,-4(a1)
+ subic. d2,d2,1
+
+ lwz o1,0(a0)
+ stw o0,0(a0)
+ addi a0,a0,4
+
+ bne+ next_b_in_element2
+ mr d2,d0
+ add a0,a0,g1
+next_b_in_element2:
+
+ subic. d3,d3,1
+ stw o1,0(a1)
+
+ bne+ next_a_in_element2
+ mr d3,d1
+ sub a1,a1,g0
+next_a_in_element2:
+
+st_reorder_lp2:
+ cmplw 1,a1,a0
+ bgt 1,reorder_lp2
+
+ blr
diff --git a/pcompact_rmarkr.a b/pcompact_rmarkr.a
new file mode 100644
index 0000000..3efb806
--- /dev/null
+++ b/pcompact_rmarkr.a
@@ -0,0 +1,783 @@
+
+rmark_using_reversal:
+ stw a3,-4(sp)
+ li d3,0
+ li d5,1
+ stwu a3,-8(sp)
+ b rmarkr_node
+
+rmark_using_reversal_:
+ subi a0,a0,4
+ stw d1,-4(sp)
+ cmplw 0,a0,d1
+ stwu a3,-8(sp)
+ bgt rmark_no_undo_reverse_1
+ stw a0,0(a3)
+ stw d0,0(a0)
+rmark_no_undo_reverse_1:
+ li d3,0
+ li d5,1
+ b rmarkr_arguments
+
+rmark_array_using_reversal:
+ stw d1,-4(sp)
+ cmplw 0,a0,d1
+ stwu a3,-8(sp)
+ bgt rmark_no_undo_reverse_2
+ lea d0,__ARRAY__2
+ stw a0,0(a3)
+ stw d0,0(a0)
+rmark_no_undo_reverse_2:
+ li d3,0
+ li d5,1
+ b rmarkr_arguments
+
+rmarkr_hnf_2:
+ lwz o0,0-NODE_POINTER_OFFSET(a0)
+ or d3,d3,d5
+ ori o0,o0,2
+ stw o0,0-NODE_POINTER_OFFSET(a0)
+ lwzu d2,4-NODE_POINTER_OFFSET(a0)
+ stw d3,0-NODE_POINTER_OFFSET(a0)
+ mr d3,a0
+ li d5,0
+ mr a0,d2
+
+rmarkr_node:
+ sub d0,a0,d6
+ cmplw 0,d0,d7
+ bge- rmarkr_next_node_after_static
+
+ srwi o0,d0,5
+ lbzx o1,o4,o0
+ rlwinm o2,d0,32-2,29,31
+ rlwnm. r0,o1,o2,24,24
+ bne rmarkr_next_node
+
+rmarkr_arguments:
+ lwz d0,0-NODE_POINTER_OFFSET(a0)
+ srw o3,g3,o2
+
+ or o1,o1,o3
+
+ andi. r0,d0,2
+ lha d2,-2(d0)
+
+ stbx o1,o4,o0
+
+ cmpwi 6,d2,0
+ beq rmarkr_lazy_node
+
+ beq 6,rmarkr_hnf_0
+
+ cmplwi 0,d2,256
+ addi a0,a0,4
+ bge rmarkr_record
+
+ subic. d2,d2,2
+ beq rmarkr_hnf_2
+ blt rmarkr_hnf_1
+
+rmarkr_hnf_3:
+ lwz a1,4-NODE_POINTER_OFFSET(a0)
+rmarkr_hnf_3_:
+ sub d0,a1,d6
+ srwi o0,d0,5
+ lbzx o1,o4,o0
+ rlwinm o2,d0,32-2,29,31
+ srw o3,g3,o2
+ and. r0,o1,o3
+ bne rmarkr_shared_argument_part
+
+ or o1,o1,o3
+ stbx o1,o4,o0
+
+rmarkr_no_shared_argument_part:
+ lwz o0,0-NODE_POINTER_OFFSET(a0)
+ or d3,d3,d5
+ ori o0,o0,2
+ stw o0,0-NODE_POINTER_OFFSET(a0)
+ stwu d3,4-NODE_POINTER_OFFSET(a0)
+
+ lwz o0,0-NODE_POINTER_OFFSET(a1)
+ slwi d2,d2,2
+ ori o0,o0,1
+ stw o0,0-NODE_POINTER_OFFSET(a1)
+
+ lwzux d2,a1,d2
+ li d5,0
+ stw a0,0-NODE_POINTER_OFFSET(a1)
+ mr d3,a1
+ mr a0,d2
+ b rmarkr_node
+
+rmarkr_shared_argument_part:
+ cmplw 0,a1,a0
+ bgt rmarkr_hnf_1
+
+ lwz o0,0-NODE_POINTER_OFFSET(a1)
+ addi d0,a0,4+2+1
+ stw d0,0-NODE_POINTER_OFFSET(a1)
+ stw o0,4-NODE_POINTER_OFFSET(a0)
+ b rmarkr_hnf_1
+
+rmarkr_lazy_node_1:
+ bne rmarkr_selector_node_1
+
+rmarkr_hnf_1:
+ lwz d2,0-NODE_POINTER_OFFSET(a0)
+ or d3,d3,d5
+ stw d3,0-NODE_POINTER_OFFSET(a0)
+ mr d3,a0
+ li d5,2
+ mr a0,d2
+ b rmarkr_node
+
+rmarkr_selector_node_1:
+ baddicc d2,3
+ lwz a1,0-NODE_POINTER_OFFSET(a0)
+ beq rmarkr_indirection_node
+
+ addic. d2,d2,1
+ sub o2,a1,d6
+ ble rmarkr_record_selector_node_1
+
+ srwi d2,o2,5
+ lbzx g1,o4,d2
+ rlwinm g2,o2,32-2,29,31
+ rlwnm. r0,g1,g2,24,24
+ bne rmarkr_hnf_1
+
+ lwz d2,0-NODE_POINTER_OFFSET(a1)
+ andi. r0,d2,2
+ beq rmarkr_hnf_1
+
+ lha g1,-2(d2)
+ cmplwi 0,g1,2
+ ble rmarkr_small_tuple_or_record
+
+rmarkr_large_tuple_or_record:
+ lwz d1,8-NODE_POINTER_OFFSET(a1)
+
+ sub o2,d1,d6
+ srwi d2,o2,5
+ lbzx g1,o4,d2
+ rlwinm g2,o2,32-2,29,31
+ rlwnm. r0,g1,g2,24,24
+ bne rmarkr_hnf_1
+
+rmarkr_small_tuple_or_record:
+ if LINUX
+ lwz g1,-8(d0)
+ mflr r0
+ else
+ lha g1,-6(d0)
+ mflr r0
+ lwzx g1,rtoc,g1
+ endif
+ andc o1,o1,o3
+
+ lwz g1,4(g1)
+ subi d2,a0,4
+
+ mtlr g1
+ stbx o1,o4,o0
+ mr a0,a1
+ stwu r0,-4(sp)
+ blrl
+ mtlr r0
+
+ lea g1,__indirection
+ stw a0,4-NODE_POINTER_OFFSET(d2)
+ stw g1,0-NODE_POINTER_OFFSET(d2)
+ b rmarkr_node
+
+rmarkr_record_selector_node_1:
+ srwi d2,o2,5
+ lbzx g1,o4,d2
+ rlwinm g2,o2,32-2,29,31
+ beq rmarkr_strict_record_selector_node_1
+
+ rlwnm. r0,g1,g2,24,24
+ bne rmarkr_hnf_1
+
+ lwz d2,0-NODE_POINTER_OFFSET(a1)
+ andi. r0,d2,2
+ beq rmarkr_hnf_1
+
+ lha g1,-2(d2)
+ cmplwi 0,g1,258
+ ble rmarkr_small_tuple_or_record
+ b rmarkr_large_tuple_or_record
+
+rmarkr_strict_record_selector_node_1:
+ rlwnm. r0,g1,g2,24,24
+ bne rmarkr_hnf_1
+
+ lwz d2,0-NODE_POINTER_OFFSET(a1)
+ andi. r0,d2,2
+ beq rmarkr_hnf_1
+
+ lha g1,-2(d2)
+ cmplwi 0,g1,258
+ ble rmarkr_select_from_small_record
+
+ lwz d1,8-NODE_POINTER_OFFSET(a1)
+ sub o2,d1,d6
+
+ srwi d2,o2,5
+ lbzx g1,o4,d2
+ rlwinm g2,o2,32-2,29,31
+ rlwnm. r0,g1,g2,24,24
+ bne rmarkr_hnf_1
+
+rmarkr_select_from_small_record:
+ if LINUX
+ lwz g1,-8(d0)
+ mflr r0
+ else
+ lha g1,-6(d0)
+ mflr r0
+ lwzx g1,rtoc,g1
+ endif
+ subi a0,a0,4
+ lwz g1,4(g1)
+
+ mtlr g1
+ stwu r0,-4(sp)
+ blrl
+ mtlr r0
+
+ b rmarkr_next_node
+
+rmarkr_indirection_node:
+ andc o1,o1,o3
+ stbx o1,o4,o0
+
+ mr a0,a1
+ b rmarkr_node
+
+rmarkr_next_node:
+ cmpwi 0,d5,0
+ bne rmarkr_parent
+
+ lwzu d2,-4-NODE_POINTER_OFFSET(d3)
+ lwz o0,4-NODE_POINTER_OFFSET(d3)
+ andi. d5,d2,3
+
+ cmpwi 0,d5,3
+ beq rmarkr_argument_part_cycle1
+
+ stw o0,0-NODE_POINTER_OFFSET(d3)
+
+rmarkr_c_argument_part_cycle1:
+ cmplw 0,a0,d3
+ bgt rmarkr_no_reverse_1
+
+ lwz o0,0-NODE_POINTER_OFFSET(a0)
+ addi d0,d3,4+1
+ stw o0,4-NODE_POINTER_OFFSET(d3)
+ stw d0,0-NODE_POINTER_OFFSET(a0)
+ clrrwi a0,d2,2
+ b rmarkr_node
+
+rmarkr_no_reverse_1:
+ stw a0,4-NODE_POINTER_OFFSET(d3)
+ clrrwi a0,d2,2
+ b rmarkr_node
+
+rmarkr_lazy_node:
+ beq 6,rmarkr_next_node
+
+ bsubicc d2,1
+ baddi a0,4
+ ble rmarkr_lazy_node_1
+
+ cmplwi 0,d2,255
+ bge rmarkr_closure_with_unboxed_arguments
+
+rmarkr_closure_with_unboxed_arguments_:
+ lwz o0,0-NODE_POINTER_OFFSET(a0)
+ slwi d2,d2,2
+ ori o0,o0,2
+ stw o0,0(a0)
+
+ lwzux d2,a0,d2
+ or d3,d3,d5
+ stw d3,0-NODE_POINTER_OFFSET(a0)
+ mr d3,a0
+ li d5,0
+ mr a0,d2
+ b rmarkr_node
+
+rmarkr_closure_with_unboxed_arguments:
+; baddi d2,1
+ srwi d0,d2,8
+ bandic d2,255
+; bsub d2,d0
+ bsubc d2,d0
+; bsubicc d2,1
+ bgt rmarkr_closure_with_unboxed_arguments_
+ beq rmarkr_hnf_1
+ bsubi a0,4
+ b rmarkr_next_node
+
+rmarkr_hnf_0:
+ cmpw d0,int_reg
+ bne rmarkr_no_int_3
+
+ lwz d2,4-NODE_POINTER_OFFSET(a0)
+ cmplwi 0,d2,33
+ bge rmarkr_next_node
+
+ andc o1,o1,o3
+ stbx o1,o4,o0
+
+ lea a0,small_integers
+ slwi d2,d2,3
+ add a0,a0,d2
+ b rmarkr_next_node_after_static
+
+rmarkr_no_int_3:
+ cmplw d0,char_reg
+ bne rmarkr_no_char_3
+
+ andc o1,o1,o3
+ stbx o1,o4,o0
+
+ lbz d2,7-NODE_POINTER_OFFSET(a0)
+ lea a0,static_characters
+ slwi d2,d2,3
+ add a0,a0,d2
+ b rmarkr_next_node_after_static
+
+rmarkr_no_char_3:
+ blt rmarkr_no_normal_hnf_0
+
+ subi a0,d0,2-ZERO_ARITY_DESCRIPTOR_OFFSET
+
+ andc o1,o1,o3
+ stbx o1,o4,o0
+ b rmarkr_next_node_after_static
+
+rmarkr_no_normal_hnf_0:
+ lea o0,__ARRAY__2
+ cmplw 0,d0,o0
+ bne+ rmarkr_next_node
+ b rmarkr_array
+
+rmarkr_record:
+ subic. d2,d2,258
+ beq rmarkr_record_2
+ blt rmarkr_record_1
+
+rmarkr_record_3:
+ lhz d2,-2+2(d0)
+ lwz a1,4-NODE_POINTER_OFFSET(a0)
+ subic. d2,d2,1
+ blt rmarkr_record_3_bb
+
+ beq rmarkr_record_3_ab
+
+ subic. d2,d2,1
+ beq rmarkr_record_3_aab
+
+ b rmarkr_hnf_3_
+
+rmarkr_record_3_bb:
+ subi a0,a0,4
+
+ sub d0,a1,d6
+ setmbit o4,d0,d1,o0,o1,o2,2
+
+ cmplw a1,a0
+ bgt rmarkr_next_node
+
+ srwi. o0,o0,1
+
+ lwz o2,0-NODE_POINTER_OFFSET(a1)
+ addi d0,a0,8+2+1
+ stw o2,8-NODE_POINTER_OFFSET(a0)
+ stw d0,0-NODE_POINTER_OFFSET(a1)
+
+ bne+ rmarkr_not_next_byte_1
+
+ addi d1,d1,1
+ lbzx o1,o4,d1
+ li o0,128
+rmarkr_not_next_byte_1:
+ and. r0,o1,o0
+ beq+ rmarkr_not_yet_linked_bb
+
+ sub d0,a0,d6
+ addi d0,d0,8
+ setmbit o4,d0,d1,o0,o1,o2,2
+ b rmarkr_next_node
+
+rmarkr_not_yet_linked_bb:
+ or o1,o1,o0
+ stbx o1,o4,d1
+ b rmarkr_next_node
+
+rmarkr_record_3_ab:
+ sub d0,a1,d6
+ setmbit o4,d0,d1,o0,o1,o2,2
+
+ cmplw 0,a1,a0
+ bgt rmarkr_hnf_1
+
+ srwi. o0,o0,1
+
+ lwz o2,0-NODE_POINTER_OFFSET(a1)
+ addi d0,a0,4+2+1
+ stw o2,4-NODE_POINTER_OFFSET(a0)
+ stw d0,0-NODE_POINTER_OFFSET(a1)
+
+ bne+ rmarkr_not_next_byte_2
+
+ addi d1,d1,1
+ lbzx o1,o4,d1
+ li o0,128
+rmarkr_not_next_byte_2:
+ and. r0,o1,o0
+ beq+ rmarkr_not_yet_linked_ab
+
+ sub d0,a0,d6
+ addi d0,d0,4
+ setmbit o4,d0,d1,o0,o1,o2,2
+ b rmarkr_hnf_1
+
+rmarkr_not_yet_linked_ab:
+ or o1,o1,o0
+ stbx o1,o4,d1
+ b rmarkr_hnf_1
+
+rmarkr_record_3_aab:
+ sub d0,a1,d6
+
+ tstmbit o4,d0,d1,o0,o1,o2,2
+ bne rmarkr_shared_argument_part
+
+ srw o0,g3,o2
+ or o1,o1,o0
+ stbx o1,o4,d1
+
+ lwz o0,0-NODE_POINTER_OFFSET(a0)
+ or d3,d3,d5
+ ori o0,o0,2
+ stw o0,0-NODE_POINTER_OFFSET(a0)
+ stwu d3,4-NODE_POINTER_OFFSET(a0)
+
+ lwz d2,0-NODE_POINTER_OFFSET(a1)
+ li d5,1
+ stw a0,0-NODE_POINTER_OFFSET(a1)
+ mr d3,a1
+ mr a0,d2
+ b rmarkr_node
+
+rmarkr_record_2:
+ lhz g1,-2+2(d0)
+ cmplwi g1,1
+ bgt rmarkr_hnf_2
+ beq rmarkr_hnf_1
+
+ subi a0,a0,4
+ b rmarkr_next_node
+
+rmarkr_record_1:
+ lhz g1,-2+2(d0)
+ tst g1
+ bne rmarkr_hnf_1
+
+ subi a0,a0,4
+ b rmarkr_next_node
+
+rmarkr_array:
+ lwz d1,8-NODE_POINTER_OFFSET(a0)
+ tst d1
+ beq rmarkr_lazy_array
+
+ lhz d0,-2(d1)
+ tst d0
+ beq rmarkr_b_record_array
+
+ lhz d1,-2+2(d1)
+ tst d1
+ beq rmarkr_b_record_array
+
+ subi d0,d0,256
+ cmpw 0,d0,d1
+ beq rmarkr_a_record_array
+
+rmarkr_ab_record_array:
+ mr o2,d2
+ mr o3,d3
+
+ lwz d2,4-NODE_POINTER_OFFSET(a0)
+ addi a0,a0,8
+ stw a0,-4(sp)
+
+ slwi d2,d2,2
+ mullw a1,d2,d0
+
+ sub d0,d0,d1
+ addi a0,a0,4
+ add a1,a1,a0
+
+ mflr r0
+ stw r0,-8(sp)
+ bl reorder2
+ lwz r0,-8(sp)
+
+ lwz a0,-4(sp)
+ mtlr r0
+
+ lwz d0,-4(a0)
+ mullw d0,d0,d1
+
+ mr d3,o3
+ mr d2,o2
+ b rmarkr_lr_array
+
+rmarkr_b_record_array:
+ sub d0,a0,d6
+ addi d0,d0,4
+ setmbit o4,d0,d1,o0,o1,o2,2
+ b rmarkr_next_node
+
+rmarkr_a_record_array:
+ lwz d0,4-NODE_POINTER_OFFSET(a0)
+ addi a0,a0,8
+ mullw d0,d0,d1
+ b rmarkr_lr_array
+
+rmarkr_lazy_array:
+ lwz d0,4-NODE_POINTER_OFFSET(a0)
+ addi a0,a0,8
+rmarkr_lr_array:
+ sub d1,a0,d6
+ srwi d1,d1,2
+ add d1,d1,d0
+ setmbit o4,d1,d2,o0,o1,o2,0
+
+ cmplwi 0,d0,1
+ ble rmarkr_array_length_0_1
+
+ mr a1,a0
+ slwi d0,d0,2
+ add a0,a0,d0
+
+ lwz d2,0-NODE_POINTER_OFFSET(a0)
+ lwz o0,0-NODE_POINTER_OFFSET(a1)
+ stw d2,0-NODE_POINTER_OFFSET(a1)
+ stw o0,0-NODE_POINTER_OFFSET(a0)
+
+ lwzu d2,-4-NODE_POINTER_OFFSET(a0)
+ lwzu o0,-4-NODE_POINTER_OFFSET(a1)
+ addi d2,d2,2
+ stw o0,0-NODE_POINTER_OFFSET(a0)
+ stw d2,0-NODE_POINTER_OFFSET(a1)
+
+ lwzu d2,-4-NODE_POINTER_OFFSET(a0)
+ or d3,d3,d5
+ stw d3,0-NODE_POINTER_OFFSET(a0)
+ mr d3,a0
+ li d5,0
+ mr a0,d2
+ b rmarkr_node
+
+rmarkr_array_length_0_1:
+ subi a0,a0,8
+ blt rmarkr_next_node
+
+ lwz d1,12-NODE_POINTER_OFFSET(a0)
+ lwz o0,8-NODE_POINTER_OFFSET(a0)
+ lwz o1,4-NODE_POINTER_OFFSET(a0)
+ stw o0,12-NODE_POINTER_OFFSET(a0)
+ stw o1,8-NODE_POINTER_OFFSET(a0)
+ stwu d1,4-NODE_POINTER_OFFSET(a0)
+ b rmarkr_hnf_1
+
+rmarkr_parent:
+ tst d3
+ beq end_rmarkr
+
+ subic. d5,d5,1
+ beq rmarkr_argument_part_parent
+
+ cmplw a0,d3
+ lwz d2,0-NODE_POINTER_OFFSET(d3)
+ bgt rmarkr_no_reverse_2
+
+ mr a1,a0
+ addi d0,d3,1
+ lwz a0,0-NODE_POINTER_OFFSET(a1)
+ stw d0,0-NODE_POINTER_OFFSET(a1)
+
+rmarkr_no_reverse_2:
+ stw a0,0-NODE_POINTER_OFFSET(d3)
+ subi a0,d3,4
+ andi. d5,d2,3
+ clrrwi d3,d2,2
+ b rmarkr_next_node
+
+rmarkr_argument_part_parent:
+ mr a1,d3
+ mr d3,a0
+
+ lwz d2,0-NODE_POINTER_OFFSET(a1)
+
+ mr a0,a1
+
+rmarkr_skip_upward_pointers:
+ andi. d0,d2,3
+ cmpwi 0,d0,3
+ bne rmarkr_no_upward_pointer
+
+ clrrwi a1,d2,2
+ lwz d2,0-NODE_POINTER_OFFSET(a1)
+ b rmarkr_skip_upward_pointers
+
+rmarkr_no_upward_pointer:
+ cmplw 0,d3,a0
+ bgt rmarkr_no_reverse_3
+
+ mr o0,d3
+ lwz d3,0-NODE_POINTER_OFFSET(d3)
+ addi d0,a0,1
+ stw d0,0-NODE_POINTER_OFFSET(o0)
+
+rmarkr_no_reverse_3:
+ stw d3,0-NODE_POINTER_OFFSET(a1)
+
+ clrrwi d3,d2,2
+
+ lwzu d2,-4-NODE_POINTER_OFFSET(d3)
+
+ cmplw 6,a0,d3
+
+ lwz o0,4-NODE_POINTER_OFFSET(d3)
+ andi. d5,d2,3
+ stw o0,0-NODE_POINTER_OFFSET(d3)
+
+ bgt 6,rmarkr_no_reverse_4
+
+ lwz o0,0-NODE_POINTER_OFFSET(a0)
+ stw o0,4-NODE_POINTER_OFFSET(d3)
+ addi d0,d3,4+2+1
+ stw d0,0-NODE_POINTER_OFFSET(a0)
+ clrrwi a0,d2,2
+ b rmarkr_node
+
+rmarkr_no_reverse_4:
+ stw a0,4-NODE_POINTER_OFFSET(d3)
+ clrrwi a0,d2,2
+ b rmarkr_node
+
+rmarkr_argument_part_cycle1:
+ mr d1,a1
+
+rmarkr_skip_pointer_list1:
+ clrrwi a1,d2,2
+ lwz d2,0-NODE_POINTER_OFFSET(a1)
+ andi. d5,d2,3
+ cmpwi 0,d5,3
+ beq rmarkr_skip_pointer_list1
+
+ stw o0,0-NODE_POINTER_OFFSET(a1)
+ mr a1,d1
+ b rmarkr_c_argument_part_cycle1
+
+rmarkr_next_node_after_static:
+ cmpwi 0,d5,0
+ bne rmarkr_parent_after_static
+
+ lwzu d2,-4-NODE_POINTER_OFFSET(d3)
+ lwz o0,4-NODE_POINTER_OFFSET(d3)
+ andi. d5,d2,3
+
+ cmpwi 0,d5,3
+ beq rmarkr_argument_part_cycle2
+
+ stw o0,0-NODE_POINTER_OFFSET(d3)
+
+rmarkr_c_argument_part_cycle2:
+ stw a0,4-NODE_POINTER_OFFSET(d3)
+ clrrwi a0,d2,2
+ b rmarkr_node
+
+rmarkr_parent_after_static:
+ cmpwi 0,d3,0
+ beq end_rmarkr_after_static
+
+ subic. d5,d5,1
+ beq rmarkr_argument_part_parent_after_static
+
+ lwz d2,0-NODE_POINTER_OFFSET(d3)
+ stw a0,0-NODE_POINTER_OFFSET(d3)
+ subi a0,d3,4
+ andi. d5,d2,3
+ clrrwi d3,d2,2
+ b rmarkr_next_node
+
+rmarkr_argument_part_parent_after_static:
+ mr a1,d3
+ mr d3,a0
+
+ lwz d2,0-NODE_POINTER_OFFSET(a1)
+
+ mr a0,a1
+
+rmarkr_skip_upward_pointers_2:
+ andi. d0,d2,3
+ cmpwi 0,d0,3
+ bne rmarkr_no_reverse_3
+
+ clrrwi a1,d2,2
+ lwz d2,0-NODE_POINTER_OFFSET(a1)
+ b rmarkr_skip_upward_pointers_2
+
+rmarkr_argument_part_cycle2:
+ mr d1,a1
+
+rmarkr_skip_pointer_list2:
+ clrrwi a1,d2,2
+ lwz d2,0-NODE_POINTER_OFFSET(a1)
+ andi. d5,d2,3
+ cmpwi 0,d5,3
+ beq rmarkr_skip_pointer_list2
+
+ stw o0,0-NODE_POINTER_OFFSET(a1)
+ mr a1,d1
+ b rmarkr_c_argument_part_cycle2
+
+end_rmarkr_after_static:
+ lwz a3,0(sp)
+ addi sp,sp,8
+ stw a0,0(a3)
+ b rmarkr_next_stack_node
+
+end_rmarkr:
+ lwz d1,4(sp)
+ lwz a3,0(sp)
+ cmplw 0,a0,d1
+ addi sp,sp,8
+ bgt rmarkr_no_reverse_5
+ mr a1,a0
+ addi d0,a3,1
+ lwz a0,0(a0)
+ stw d0,0(a1)
+rmarkr_no_reverse_5:
+ stw a0,0(a3)
+
+rmarkr_next_stack_node:
+ cmplw 0,sp,d4
+ bge rmark_next_node
+
+ lwz a0,0(sp)
+ lwz a3,4(sp)
+ addi sp,sp,8
+
+ cmplwi a0,1
+ bgt rmark_using_reversal
+ b rmark_next_node_