# This program runs a quicksort on an unsorted test data array. # Doug Johnson. October 2001, for CSE 410. # The code for the QuickSort routine is the result of cross compiling # an example from Sun. The original example was in Java. I converted # it to C, cross compiled it with gcc, and undid the branch delay slots. # The main method expects that the array is 100 words long. If # that is not the case, change the value in test0length. # It is expected that this program will be run under SPIM, so there # is no fancy output. Look at the data segment before and after # running the program to see that the sort has taken place. .data test0: .word 90,91,92,93,94,95,96,97,98,99 .word 80,81,82,83,84,85,86,87,88,89 .word 70,71,72,73,74,75,76,77,78,79 .word 60,61,62,63,64,65,66,67,68,69 .word 50,51,52,53,54,55,56,57,58,59 .word 40,41,42,43,44,45,46,47,48,49 .word 30,31,32,33,34,35,36,37,38,39 .word 20,21,22,23,24,25,26,27,28,29 .word 10,11,12,13,14,15,16,17,18,19 .word 0,1,2,3,4,5,6,7,8,9 test0length: .word 100 .text main: subu $sp,24 # create stack frame sw $ra,16($sp) # la $a0,test0 # $a0 = address of array to sort move $a1,$zero # $a1 = first element index lw $a2,test0length # number of words in array subu $a2,$a2,1 # $a2 = last element index jal QuickSort # call QuickSort lw $ra,16($sp) # restore from stack addu $sp,24 # j $ra # return # void swap(int a[], int i, int j) swap: sll $a1,$a1,2 # $a1 = 4*i addu $a1,$a1,$a0 # $a1 = addr(a[i]) lw $v1,0($a1) # $v1 = a[i] sll $a2,$a2,2 # $a2 = 4*j addu $a2,$a2,$a0 # $a2 = addr(a[j]) lw $v0,0($a2) # $v0 = a[j] sw $v0,0($a1) # a[i] = old a[j] sw $v1,0($a2) # a[j] = old a[i] j $ra # return # void QuickSort(int a[], int lo0, int hi0) QuickSort: subu $sp,$sp,48 # create stack frame sw $ra,40($sp) # sw $s5,36($sp) # sw $s4,32($sp) # sw $s3,28($sp) # sw $s2,24($sp) # sw $s1,20($sp) # sw $s0,16($sp) # move $s3,$a0 # $s3 = address(a) move $s5,$a1 # $s5 = lo0 move $s4,$a2 # $s4 = hi0 move $s0,$s5 # $s0 = lo move $s1,$s4 # $s1 = hi slt $v0,$s0,$s4 # if (lo0 < hi0) $v0=1 beqz $v0,$L4 # skip if nothing to do addu $v0,$s0,$s4 # $v0 = lo0 + hi0 srl $v1,$v0,31 # $v1 = sign($v0) addu $v0,$v0,$v1 # bias negative to truncate down sra $v0,$v0,1 # $v0 = (lo0 + hi0)/2 sll $v0,$v0,2 # byte pointer increment addu $v0,$v0,$s3 # $v0 = addr(a[(lo0 + hi0)/2]) lw $s2,0($v0) # $s2 = mid = a[(lo0 + hi0)/2] slt $v0,$s4,$s0 # if (hi0 < lo) $v0 = 1 bnez $v0,$L26 # skip if (hi0 < lo) $L22: slt $v0,$s0,$s4 # if (lo < hi0) $v0 = 1 beqz $v0,$L23 # skip if (!(lo < hi0) sll $v0,$s0,2 # $v0 = lo*4 addu $v0,$v0,$s3 # $v0 = address(a[lo]) lw $v0,0($v0) # $v0 = a[lo] addu $s0,$s0,1 # ++lo slt $v0,$v0,$s2 # if (a[lo] < mid) $v0 = 1 bnez $v0,$L22 # loop if (a[lo] < mid) addu $s0,$s0,-1 # --lo $L23: slt $v0,$s5,$s1 # if (lo0 < hi) $v0 = 1 beqz $v0,$L14 # skip if (!(lo0 < hi)) sll $v0,$s1,2 # $v0 = hi*4 addu $v0,$v0,$s3 # $v0 = address(a[h]) lw $v0,0($v0) # $v0 = a[hi] addu $s1,$s1,-1 # --hi slt $v0,$s2,$v0 # if (mid < a[hi]) $v0 = 1 bnez $v0,$L23 # loop if (mid < a[hi]) addu $s1,$s1,1 # ++hi $L14: slt $v0,$s1,$s0 # if (hi < lo) $v0 = 1 bnez $v0,$L26 # skip if (hi < lo) move $a0,$s3 # $a0 = address(a) move $a1,$s0 # $a1 = lo move $a2,$s1 # $a2 = ho jal swap # call swap addu $s0,$s0,1 # ++lo addu $s1,$s1,-1 # --hi slt $v0,$s1,$s0 # if (hi < lo) $v0 = 1 beqz $v0,$L22 # loop if (!(hi < lo)) ie, (lo <= hi) $L26: slt $v0,$s5,$s1 # if (lo0 < hi) $v0 = 1 beqz $v0,$L27 # skip if (!(lo0 < hi)) move $a0,$s3 # $a0 = address(a) move $a1,$s5 # $a1 = lo0 move $a2,$s1 # $a2 = hi jal QuickSort # call QuickSort $L27: slt $v0,$s0,$s4 # if (lo < hi0) $v0 = 1 beqz $v0,$L4 # skip if (!(lo < hi0)) move $a0,$s3 # $a0 = address(a) move $a1,$s0 # $a1 = lo move $a2,$s4 # $a2 = hi0 jal QuickSort # call QuickSort $L4: lw $ra,40($sp) # restore from stack lw $s5,36($sp) # lw $s4,32($sp) # lw $s3,28($sp) # lw $s2,24($sp) # lw $s1,20($sp) # lw $s0,16($sp) # addu $sp,$sp,48 # j $ra # return