main
magical 2023-04-23 11:25:15 -07:00
parent 853b937691
commit e20f0c4b1e
3 changed files with 204 additions and 0 deletions

View File

@ -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:

152
lib/sort.s 100644
View File

@ -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

51
sorttest.s 100644
View File

@ -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