-
Notifications
You must be signed in to change notification settings - Fork 0
/
CombSort.asm
99 lines (75 loc) · 2.75 KB
/
CombSort.asm
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
89
90
91
92
93
94
95
96
97
98
99
## void comb_sort(T* input, int size, bool ascending)
## t* input = $a0
## int size = $a1
## bool ascending = $a3
########################################################
## temp = $s0
## i = $s1
## gap = $s2
## bool swapped = $s3
########################################################
.data
comb_gap:
.double 1.3
.text
comb_sort:
add $s2, $a1, $zero # gap = size
li $s3, 0 # swapped = false
j comb_while_bottom
comb_while_top:
ble $s2, 1, if_continue # if gap > 1 do following, else continue
mtc1 $s2, $f1 # convert (int)gap to single prec. floating point
cvt.s.w $f1, $f1 # convert (int)gap to single prec. floating point now $f1 = (double)gap
l.s $f2, comb_gap # loads gap ( = 1.3 ) on to $f2
div.s $f3, $f1, $f2 # $f3 = (double)(gap / 1.3)
cvt.w.s $f3, $f3 #
mfc1 $s2, $f3 # gap = (int)((double)gap/ 1.3)
if_continue: # not if, continues
li $s3, 0 # swapped = false
# starting of for loop
add $s1, $zero, $zero # i = 0
j comb_for_bottom
comb_for_top:
########## if else part (inside of the for loop)
bne $a3, 1, comb_for_not_asc # branch if not ascending ( != 1 )
#ascending part
# if (input[i] - input[i + gap] > 0)
sll $t2, $s1, 2 # $t2 = i*4
add $t2, $a0, $t2 # $t2 = input[i]'s address
add $t3, $s1, $s2 # $t3 = i + gap
sll $t3, $t3, 2 # $t3 = (i+gap) * 4
add $t3, $a0, $t3 # $t3 = input[i+gap]'s address
lw $t5, 0($t2) # get the value of input[i]
lw $t6, 0($t3) # get the value of input[i + gap]
sub $t4, $t5, $t6 # $t4 = input[i] - input[i + gap]
ble $t4, 0, comb_for_update # if $t4 is NOT >0 then go to increment
add $s0, $t5, $zero # temp = input[i]
sw $t3, 0($t2) # input[i] = input[i + gap];
sw $s0, 0($t3) # input[i + gap] = temp;
li $s3, 1 # swapped = true;
comb_for_not_asc:
# if (input[i] - input[i + gap] < 0)
sll $t2, $s1, 2 # $t2 = i*4
add $t2, $a0, $t2 # $t2 = input[i]'s address
add $t3, $s1, $s2 # $t3 = i + gap
sll $t3, $t3, 2 # $t3 = (i+gap) * 4
add $t3, $a0, $t3 # $t3 = input[i+gap]'s address
lw $t5, 0($t2) # get the value of input[i]
lw $t6, 0($t3) # get the value of input[i + gap]
sub $t4, $t5, $t6 # $t4 = input[i] - input[i + gap]
bge $t4, 0, comb_for_update # if $t4 is NOT <0 then go to increment
add $s0, $t6, $zero # temp = input[i + gap];
sw $t2, 0($t3) # input[i + gap] = input[i];
sw $s0, 0($t2) # input[i] = temp;
li $s3, 1 # swapped = true;
comb_for_update:
addi $s1, $s1, 1 # i++
##########
comb_for_bottom: # for loop testing
add $t0, $s2, $s1 # $t0 = gap + i
blt $t0, $a1, comb_for_top # gap + i < size
comb_while_bottom: # while loop testing
sgt $t1, $s2, 1 # gap > 1 => $t1=1
or $t1, $t1, $s3 # $t1=1 if (gap>1 || swapped)
beq $t1, 1, comb_while_top
#jr $ra