-
Notifications
You must be signed in to change notification settings - Fork 0
/
isort.s
88 lines (76 loc) · 3.14 KB
/
isort.s
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
/*-----------------------------------------------------------------------------
isort.s - assembly insertion sort for education purposes
This file is distributed under the GNU General Public License, version 2 (GPLv2)
See https://www.gnu.org/licenses/old-licenses/gpl-2.0.en.html
Author: Stephen E. MacKenzie
------------------------------------------------------------------------------*/
.syntax unified
.text
.thumb_func
.global gen_sort
.global asm_int_less
.global asm_int_notless
/* -----------------------------------------------------------------------------
C declaration:
void gen_sort(int* a, const size_t count, int (*pred)(const int, const int));
Parameters: pointer to contiguous memory, size in words, a predicate functor
that implements the sorting criteria.
str_sort below does the same with an array of strings.
Here is my C version of insertion sort that I used to reason this out:
for(int* key = (first + 1); key != end; key++)
while(key > first && *key < *(key - 1)) {
swap(key, key - 1);
--key;
}
------------------------------------------------------------------------------*/
asm_int_less:
cmp r0, r1
ite ge
movge r0, #0
movlt r0, #1 /*better explicity put in case r0 hold > 1 */
bx lr
asm_int_notless:
cmp r0, r1
ite ge
movge r0, #1
movlt r0, #0 /*better explicity put in case r0 hold > 1 */
bx lr
/*----------------------------------------------------------------------------*/
gen_sort:
stmfd sp!, {r4-r11} /* we will need more registers for the loops */
mov r7, #0 /* outer loop */
mov r8, r1 /* inner loop copy of outer loop or key */
mov r9, #0 /* inner loop acting as key - 1 */
cmp r1, #0 /* quick exit if len variable is zero */
it eq /* IF above statement is true, next line executes */
moveq pc, lr /* return, exit function */
for_loop:
add r7, r7, #1 /* init at 0, first time set to 1 is good */
cmp r7, r1 /* check for outer loop termination condition */
beq sort_end /* we are done, sorting */
mov r8, r7 /* ELSE r8 saves r7 */
b while_loop
while_loop:
cmp r8, #0 /* test for loop termination */
beq for_loop
mov r9, r8 /* ELSE r8 key, r9 key - 1 */
sub r9, r9, #1
ldr r4, [r0, r8, lsl #2] /* r4: array[key] */
ldr r5, [r0, r9, lsl #2] /* swap temp1 */
// compare needs to save context
mov r11, r2 /* save the predicate before push*/
stmfd sp!, {r0-r3, lr}
mov r0, r4
mov r1, r5
blx r11
mov r10, r0
ldmfd sp!, {r0-r3, lr}
cmp r10, #1
bne for_loop
str r4, [r0, r9, lsl #2] /* ELSE swap*/
str r5, [r0, r8, lsl #2]
sub r8, r8, #1 /* and continue */
b while_loop
sort_end:
ldmfd sp!, {r4-r11} /* restore registers used for the loops */
bx lr