lib/sort
parent
853b937691
commit
e20f0c4b1e
1
Makefile
1
Makefile
|
@ -15,6 +15,7 @@ all: true false cat env hexdump
|
|||
$(AS) -o $@ $<
|
||||
|
||||
prtest: prtest.o lib/printregs.o lib/hex.o
|
||||
sorttest: lib/sort.o
|
||||
|
||||
.PHONY: 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