lib/sort
parent
853b937691
commit
e20f0c4b1e
1
Makefile
1
Makefile
|
@ -15,6 +15,7 @@ all: true false cat env hexdump
|
||||||
$(AS) -o $@ $<
|
$(AS) -o $@ $<
|
||||||
|
|
||||||
prtest: prtest.o lib/printregs.o lib/hex.o
|
prtest: prtest.o lib/printregs.o lib/hex.o
|
||||||
|
sorttest: lib/sort.o
|
||||||
|
|
||||||
.PHONY: test
|
.PHONY: test
|
||||||
test:
|
test:
|
||||||
|
|
|
@ -0,0 +1,152 @@
|
||||||
|
.global sort
|
||||||
|
|
||||||
|
# a0 = pointer to array to be sorted
|
||||||
|
# a1 = length of array (signed)
|
||||||
|
# a2 = element size (unsigned)
|
||||||
|
# a3 - comparison function
|
||||||
|
# a4 - context
|
||||||
|
sort:
|
||||||
|
# insertion sort
|
||||||
|
# for i = 0 to n-1
|
||||||
|
# for j = i downto 0
|
||||||
|
# if a[j-1] > a[j]
|
||||||
|
# swap a[j-1], a[j]
|
||||||
|
|
||||||
|
# i = 0
|
||||||
|
# for n-1 downto 0
|
||||||
|
# i += esize
|
||||||
|
# j = i
|
||||||
|
# while j > 0:
|
||||||
|
# if cmp(j-esize, j) > 0
|
||||||
|
# swap(j-esize, j)
|
||||||
|
# else
|
||||||
|
# break
|
||||||
|
# j -= esize
|
||||||
|
#
|
||||||
|
|
||||||
|
# bail early if n <= 1
|
||||||
|
li t0, 1
|
||||||
|
bgt a1, t0, 0f
|
||||||
|
li a0, 0
|
||||||
|
ret
|
||||||
|
0:
|
||||||
|
|
||||||
|
# check if n*esize overflows or is negative
|
||||||
|
mulhu t1, a1, a2
|
||||||
|
beqz t1, 0f
|
||||||
|
li a0, -1
|
||||||
|
ret
|
||||||
|
0:
|
||||||
|
|
||||||
|
sd ra, -1*8(sp)
|
||||||
|
sd s0, -2*8(sp)
|
||||||
|
sd s1, -3*8(sp)
|
||||||
|
sd s2, -4*8(sp)
|
||||||
|
sd s3, -5*8(sp)
|
||||||
|
sd s4, -6*8(sp)
|
||||||
|
sd s5, -7*8(sp)
|
||||||
|
sd s6, -8*8(sp)
|
||||||
|
addi sp, sp, -8*8
|
||||||
|
|
||||||
|
mv s0, a2 # pointer to element i - base
|
||||||
|
# s1 is pointer to element j - base
|
||||||
|
mv s2, a0 # base pointer
|
||||||
|
mv s3, a1 # array len
|
||||||
|
mv s4, a2 # element size
|
||||||
|
mv s5, a3 # cmp
|
||||||
|
mv s6, a4 # context
|
||||||
|
|
||||||
|
# we know we have at least 2 elements,
|
||||||
|
# so no check necessary at the top of the loop
|
||||||
|
addi s3, s3, -1
|
||||||
|
.Louter.top:
|
||||||
|
# i += esize
|
||||||
|
# j = i
|
||||||
|
add s0, s0, s4
|
||||||
|
mv s1, s0
|
||||||
|
|
||||||
|
.Linner.top:
|
||||||
|
add a1, s1, s2 # create pointers
|
||||||
|
sub a0, a1, s4
|
||||||
|
mv a2, s6
|
||||||
|
jalr s5 # cmp
|
||||||
|
#li a0, 1
|
||||||
|
blez a0, .Lcmp.less
|
||||||
|
|
||||||
|
.Lcmp.greater:
|
||||||
|
.Lswap:
|
||||||
|
add a1, s1, s2
|
||||||
|
sub a0, a1, s4
|
||||||
|
mv a2, s4
|
||||||
|
call swap
|
||||||
|
|
||||||
|
.Linner.step:
|
||||||
|
sub s1, s1, s4
|
||||||
|
bnez s1, .Linner.top
|
||||||
|
|
||||||
|
.Lcmp.less:
|
||||||
|
.Louter.step:
|
||||||
|
addi s3, s3, -1 # n -= 1
|
||||||
|
bnez s3, .Louter.top
|
||||||
|
|
||||||
|
.Lreturn:
|
||||||
|
addi sp, sp, 8*8
|
||||||
|
ld ra, -1*8(sp)
|
||||||
|
ld s0, -2*8(sp)
|
||||||
|
ld s1, -3*8(sp)
|
||||||
|
ld s2, -4*8(sp)
|
||||||
|
ld s3, -5*8(sp)
|
||||||
|
ld s4, -6*8(sp)
|
||||||
|
ld s5, -7*8(sp)
|
||||||
|
ld s6, -8*8(sp)
|
||||||
|
ret
|
||||||
|
|
||||||
|
.Lerror:
|
||||||
|
li a0, -1
|
||||||
|
j .Lreturn
|
||||||
|
|
||||||
|
swap:
|
||||||
|
# TODO: larger things
|
||||||
|
li t0, 8
|
||||||
|
bgtu a2, t0, bigswap
|
||||||
|
beq a2, t0, swap8
|
||||||
|
li t0, 4
|
||||||
|
beq a2, t0, swap4
|
||||||
|
li t0, 2
|
||||||
|
beq a2, t0, swap2
|
||||||
|
li t0, 1
|
||||||
|
beq a2, t0, swap1
|
||||||
|
beqz a2, .Lret
|
||||||
|
|
||||||
|
# TODO: weird size: 0, 3, 5, 6, 7
|
||||||
|
.Lret:
|
||||||
|
ret
|
||||||
|
|
||||||
|
swap8:
|
||||||
|
ld t0, (a0)
|
||||||
|
ld t1, (a1)
|
||||||
|
sd t1, (a0)
|
||||||
|
sd t0, (a1)
|
||||||
|
ret
|
||||||
|
swap4:
|
||||||
|
lwu t0, (a0)
|
||||||
|
lwu t1, (a1)
|
||||||
|
sw t1, (a0)
|
||||||
|
sw t0, (a1)
|
||||||
|
ret
|
||||||
|
swap2:
|
||||||
|
lhu t0, (a0)
|
||||||
|
lhu t1, (a1)
|
||||||
|
sh t1, (a0)
|
||||||
|
sh t0, (a1)
|
||||||
|
ret
|
||||||
|
swap1:
|
||||||
|
lbu t0, (a0)
|
||||||
|
lbu t1, (a1)
|
||||||
|
sb t1, (a0)
|
||||||
|
sb t0, (a1)
|
||||||
|
ret
|
||||||
|
|
||||||
|
bigswap:
|
||||||
|
# TODO
|
||||||
|
ret
|
|
@ -0,0 +1,51 @@
|
||||||
|
.globl _start
|
||||||
|
.extern sort
|
||||||
|
|
||||||
|
.data
|
||||||
|
|
||||||
|
array:
|
||||||
|
.ascii "ABC "
|
||||||
|
.ascii "ZZZ "
|
||||||
|
.ascii "CCC "
|
||||||
|
.ascii "BBB "
|
||||||
|
.ascii "DED "
|
||||||
|
.ascii "\n"
|
||||||
|
.equ len, (.) - array
|
||||||
|
|
||||||
|
.text
|
||||||
|
|
||||||
|
_start:
|
||||||
|
.option push
|
||||||
|
.option norelax
|
||||||
|
la gp, __global_pointer$
|
||||||
|
.option pop
|
||||||
|
|
||||||
|
li a7, 64
|
||||||
|
li a0, 1
|
||||||
|
la a1, array
|
||||||
|
li a2, len
|
||||||
|
ecall
|
||||||
|
|
||||||
|
la a0, array
|
||||||
|
li a1, len/4
|
||||||
|
li a2, 4
|
||||||
|
la a3, cmp
|
||||||
|
li a4, 0
|
||||||
|
|
||||||
|
call sort
|
||||||
|
|
||||||
|
li a7, 64
|
||||||
|
li a0, 1
|
||||||
|
la a1, array
|
||||||
|
li a2, len
|
||||||
|
ecall
|
||||||
|
|
||||||
|
li a7, 93 # sys_exit
|
||||||
|
li a0, 0
|
||||||
|
ecall
|
||||||
|
|
||||||
|
cmp:
|
||||||
|
lw t0, (a0)
|
||||||
|
lw t1, (a1)
|
||||||
|
sgtu a0, t0, t1
|
||||||
|
ret
|
Loading…
Reference in New Issue