Extract more bits from calc.s; use qemu for testing
This commit is contained in:
parent
8f252c15c6
commit
82a0fde80d
6 changed files with 133 additions and 156 deletions
6
Makefile
6
Makefile
|
@ -4,7 +4,7 @@ ASFLAGS=-g -mabi=ilp32e -march=rv32ec
|
|||
CFLAGS=$(ASFLAGS)
|
||||
LD=riscv64-unknown-elf-ld
|
||||
export JQ?=jaq
|
||||
export RV32EMU?=$(HOME)/Source/github.com/sysprog21/rv32emu/build/rv32emu
|
||||
export QEMU?=qemu-riscv32
|
||||
|
||||
all: calc.elf
|
||||
|
||||
|
@ -14,12 +14,12 @@ check: tests
|
|||
hello.elf: hello.o
|
||||
$(LD) -m elf32lriscv $^ -o $@
|
||||
|
||||
calc.elf: hex.o calc.o
|
||||
calc.elf: mem.o hex.o debug.o calc.o
|
||||
$(LD) -m elf32lriscv -T link.ld $^ -o $@
|
||||
|
||||
tests: tests/btohex.elf tests/tohex.elf
|
||||
|
||||
tests/btohex.elf: hex.o tests/btohex.o
|
||||
tests/btohex.elf: mem.o hex.o debug.o tests/btohex.o
|
||||
$(LD) -m elf32lriscv -T link.ld $^ -o $@
|
||||
|
||||
tests/tohex.elf: hex.o tests/tohex.o
|
||||
|
|
150
calc.s
150
calc.s
|
@ -4,59 +4,24 @@
|
|||
# Provide program starting address to linker
|
||||
.global _start
|
||||
|
||||
.extern tohex
|
||||
.extern regdump
|
||||
|
||||
/* newlib system calls */
|
||||
.set SYSEXIT, 93
|
||||
.set SYSWRITE, 64
|
||||
|
||||
.section .rodata
|
||||
str: .ascii "Hello World!\n"
|
||||
.set str_size, .-str
|
||||
|
||||
str2: .ascii "regdump\n"
|
||||
.set str2_size, .-str2
|
||||
|
||||
regnames:
|
||||
.ascii "x0", "ra", "sp", "gp", "tp", "t0", "t1", "t2", "s0", "s1", "a0", "a1", "a2", "a3", "a4", "a5"
|
||||
|
||||
.section .bss
|
||||
buf: .skip 20 # room for 20 byte string
|
||||
# x10: ABCDEFGH\n is 14 chars
|
||||
|
||||
.section .data
|
||||
buflen: .byte 0 # length of buf string
|
||||
# .section .rodata
|
||||
|
||||
# .section .bss
|
||||
|
||||
.text
|
||||
_start:
|
||||
li t1, 0
|
||||
li t2, 5
|
||||
|
||||
# dummy test for jal instruction
|
||||
.L1:
|
||||
jal x0, .L2
|
||||
.L2:
|
||||
nop
|
||||
|
||||
loop:
|
||||
beq t1, t2, end
|
||||
|
||||
li t0, SYSWRITE # "write" syscall
|
||||
li a0, 1 # 1 = standard output (stdout)
|
||||
la a1, str # load address of hello string
|
||||
li a2, str_size # length of hello string
|
||||
ecall # invoke syscall to print the string
|
||||
addi t1, t1, 1
|
||||
j loop
|
||||
|
||||
end:
|
||||
# do some adding
|
||||
li a0, 0x80000000 # 0.5
|
||||
li a1, 1 # 1
|
||||
li a2, 0x80000000 # 0.5
|
||||
li a3, 1 # 1
|
||||
# jal add64
|
||||
jal add64
|
||||
#add t1, a0, 0 # copy a0 to t0 as end with overwrite it
|
||||
jal regdump
|
||||
|
||||
|
@ -82,110 +47,3 @@ add64:
|
|||
ret
|
||||
|
||||
|
||||
# Print values of all registers (in hex)
|
||||
# write syscall uses t0, a0, a1, a2
|
||||
regdump:
|
||||
# save all registers to preserve their state when entering the function
|
||||
# except sp, which will be offset by -64
|
||||
addi sp, sp, -64 # allocate stack space to stash all registers
|
||||
sw x0, 0(sp)
|
||||
sw x1, 4(sp)
|
||||
sw x2, 8(sp)
|
||||
sw x3, 12(sp)
|
||||
sw x4, 16(sp)
|
||||
sw x5, 20(sp)
|
||||
sw x6, 24(sp)
|
||||
sw x7, 28(sp)
|
||||
sw x8, 32(sp)
|
||||
sw x9, 36(sp)
|
||||
sw x10, 40(sp)
|
||||
sw x11, 44(sp)
|
||||
sw x12, 48(sp)
|
||||
sw x13, 52(sp)
|
||||
sw x14, 56(sp)
|
||||
sw x15, 60(sp)
|
||||
|
||||
li t0, SYSWRITE # "write" syscall
|
||||
li a0, 1 # 1 = standard output (stdout)
|
||||
la a1, str2 # load address of hello string
|
||||
li a2, str2_size # length of other string
|
||||
ecall # invoke syscall to print the string
|
||||
|
||||
li s0, 0
|
||||
li s1, 16
|
||||
|
||||
regdump_loop:
|
||||
beq s0, s1, regdump_done
|
||||
la a1, regnames # load address of regnames
|
||||
slli a2, s0, 1 # a2 = s0 * 2
|
||||
add a1, a1, a2 # a1 = a1 + a2
|
||||
|
||||
# copy regname to buf
|
||||
la a0, buf # load address of buf into a0 as dest
|
||||
li a2, 2 # copy 2 bytes
|
||||
addi sp, sp, -4 # allocate stack space
|
||||
sw ra, 0(sp) # save contents of ra
|
||||
jal memcpy
|
||||
lw ra, 0(sp) # restore contents of ra
|
||||
addi sp, sp, 4 # deallocate stack space
|
||||
# append ': '
|
||||
li t0, ':
|
||||
sb t0, 0(a0)
|
||||
li t0, 0x20
|
||||
sb t0, 1(a0)
|
||||
addi a0, a0, 2 # bump a0 address over ': ' text
|
||||
mv a1, a0 # load address of output buffer to a1
|
||||
slli a2, s0, 2 # calculate the offset of the register value relative to sp
|
||||
add a2, a2, sp # a2 = sp + (s0 * 4)
|
||||
lw a0, 0(a2) # load register value to format into a0
|
||||
addi sp, sp, -8 # allocate stack space
|
||||
sw a1, 4(sp) # save contents of a1
|
||||
sw ra, 0(sp) # save contents of ra
|
||||
jal tohex
|
||||
lw ra, 0(sp) # restore contents of ra
|
||||
lw a1, 4(sp) # restore contents of a1 (buffer)
|
||||
addi sp, sp, 8 # deallocate stack space
|
||||
li t0, '\n # append newline
|
||||
sb t0, 8(a1)
|
||||
|
||||
# print the register name and value
|
||||
li t0, SYSWRITE # "write" syscall
|
||||
li a0, 1 # 1 = standard output (stdout)
|
||||
la a1, buf
|
||||
li a2, 4+8+1 # length of register name string:
|
||||
# rr: 12345678\n
|
||||
ecall # invoke syscall to print the string
|
||||
|
||||
addi s0, s0, 1
|
||||
j regdump_loop
|
||||
|
||||
regdump_done:
|
||||
# TODO: Restore s0 & s1
|
||||
addi sp, sp, 64 # deallocate stack space
|
||||
ret
|
||||
|
||||
|
||||
# memcpy, copy n bytes of memory from src to dest
|
||||
# arguments:
|
||||
# a0: dest address
|
||||
# a1: source address
|
||||
# a2: number of bytes to copy
|
||||
# temporaries used:
|
||||
# t0, t1
|
||||
# return:
|
||||
# a0: address of dest + n
|
||||
# a1: address of src + n
|
||||
#
|
||||
memcpy:
|
||||
li t0, 0
|
||||
memcpy_loop:
|
||||
# TODO: copy in chunks of 4 bytes if n > 4
|
||||
beq t0, a2, memcpy_done
|
||||
lbu t1, 0(a1)
|
||||
sb t1, 0(a0)
|
||||
addi a0, a0, 1
|
||||
addi a1, a1, 1
|
||||
addi t0, t0, 1
|
||||
j memcpy_loop
|
||||
memcpy_done:
|
||||
ret
|
||||
|
|
93
debug.s
Normal file
93
debug.s
Normal file
|
@ -0,0 +1,93 @@
|
|||
# Debugging routines
|
||||
|
||||
.extern tohex
|
||||
.extern memcpy
|
||||
|
||||
.global regdump
|
||||
|
||||
/* newlib system calls */
|
||||
.set SYSWRITE, 64
|
||||
|
||||
.section .rodata
|
||||
regnames:
|
||||
.ascii "x0", "ra", "sp", "gp", "tp", "t0", "t1", "t2", "s0", "s1", "a0", "a1", "a2", "a3", "a4", "a5"
|
||||
|
||||
.section .bss
|
||||
buf: .skip 15 # room for 20 byte string
|
||||
# x10: ABCDEFGH\n is 14 chars
|
||||
.text
|
||||
# Print values of all registers (in hex)
|
||||
# write syscall uses t0, a0, a1, a2
|
||||
regdump:
|
||||
# save all registers to preserve their state when entering the function
|
||||
# except sp, which will be offset by -64
|
||||
addi sp, sp, -64 # allocate stack space to stash all registers
|
||||
sw x0, 0(sp)
|
||||
sw x1, 4(sp)
|
||||
sw x2, 8(sp)
|
||||
sw x3, 12(sp)
|
||||
sw x4, 16(sp)
|
||||
sw x5, 20(sp)
|
||||
sw x6, 24(sp)
|
||||
sw x7, 28(sp)
|
||||
sw x8, 32(sp)
|
||||
sw x9, 36(sp)
|
||||
sw x10, 40(sp)
|
||||
sw x11, 44(sp)
|
||||
sw x12, 48(sp)
|
||||
sw x13, 52(sp)
|
||||
sw x14, 56(sp)
|
||||
sw x15, 60(sp)
|
||||
|
||||
li s0, 0
|
||||
li s1, 16
|
||||
|
||||
regdump_loop:
|
||||
beq s0, s1, regdump_done
|
||||
la a1, regnames # load address of regnames
|
||||
slli a2, s0, 1 # a2 = s0 * 2
|
||||
add a1, a1, a2 # a1 = a1 + a2
|
||||
|
||||
# copy regname to buf
|
||||
la a0, buf # load address of buf into a0 as dest
|
||||
li a2, 2 # copy 2 bytes
|
||||
addi sp, sp, -4 # allocate stack space
|
||||
sw ra, 0(sp) # save contents of ra
|
||||
jal memcpy
|
||||
lw ra, 0(sp) # restore contents of ra
|
||||
addi sp, sp, 4 # deallocate stack space
|
||||
# append ': '
|
||||
li t0, ':
|
||||
sb t0, 0(a0)
|
||||
li t0, 0x20
|
||||
sb t0, 1(a0)
|
||||
addi a0, a0, 2 # bump a0 address over ': ' text
|
||||
mv a1, a0 # load address of output buffer to a1
|
||||
slli a2, s0, 2 # calculate the offset of the register value relative to sp
|
||||
add a2, a2, sp # a2 = sp + (s0 * 4)
|
||||
lw a0, 0(a2) # load register value to format into a0
|
||||
addi sp, sp, -8 # allocate stack space
|
||||
sw a1, 4(sp) # save contents of a1
|
||||
sw ra, 0(sp) # save contents of ra
|
||||
jal tohex
|
||||
lw ra, 0(sp) # restore contents of ra
|
||||
lw a1, 4(sp) # restore contents of a1 (buffer)
|
||||
addi sp, sp, 8 # deallocate stack space
|
||||
li t0, '\n # append newline
|
||||
sb t0, 8(a1)
|
||||
|
||||
# print the register name and value
|
||||
li t0, SYSWRITE # "write" syscall
|
||||
li a0, 1 # 1 = standard output (stdout)
|
||||
la a1, buf
|
||||
li a2, 4+8+1 # length of register name string:
|
||||
# rr: 12345678\n
|
||||
ecall # invoke syscall to print the string
|
||||
|
||||
addi s0, s0, 1
|
||||
j regdump_loop
|
||||
|
||||
regdump_done:
|
||||
# TODO: Restore s0 & s1
|
||||
addi sp, sp, 64 # deallocate stack space
|
||||
ret
|
27
mem.s
Normal file
27
mem.s
Normal file
|
@ -0,0 +1,27 @@
|
|||
.global memcpy
|
||||
|
||||
.text
|
||||
# memcpy, copy n bytes of memory from src to dest
|
||||
# arguments:
|
||||
# a0: dest address
|
||||
# a1: source address
|
||||
# a2: number of bytes to copy
|
||||
# temporaries used:
|
||||
# t0, t1
|
||||
# return:
|
||||
# a0: address of dest + n
|
||||
# a1: address of src + n
|
||||
#
|
||||
memcpy:
|
||||
li t0, 0
|
||||
memcpy_loop:
|
||||
# TODO: copy in chunks of 4 bytes if n > 4
|
||||
beq t0, a2, memcpy_done
|
||||
lbu t1, 0(a1)
|
||||
sb t1, 0(a0)
|
||||
addi a0, a0, 1
|
||||
addi a1, a1, 1
|
||||
addi t0, t0, 1
|
||||
j memcpy_loop
|
||||
memcpy_done:
|
||||
ret
|
|
@ -5,6 +5,7 @@
|
|||
.global _start
|
||||
|
||||
.extern btohex
|
||||
.extern regdump
|
||||
|
||||
/* newlib system calls */
|
||||
.set SYSEXIT, 93
|
||||
|
@ -13,7 +14,7 @@
|
|||
_start:
|
||||
li a0, 0xA5
|
||||
jal btohex
|
||||
mv a1, a0
|
||||
jal regdump
|
||||
|
||||
li t0, SYSEXIT # "exit" syscall
|
||||
la a0, 0 # Use 0 return code
|
||||
|
|
|
@ -3,16 +3,14 @@
|
|||
test_btohex() {
|
||||
# FIXME: Remove grep when this bug is fixed:
|
||||
# https://github.com/sysprog21/rv32emu/issues/561
|
||||
result=$("${RV32EMU}" -d - -q tests/btohex.elf | grep -v '^[0-9]' | "${JQ}" .x11)
|
||||
result=$("${QEMU}" -B 0x80000000 -s 2k tests/btohex.elf | grep '^a0:')
|
||||
|
||||
# 16693 is 5A in ASCII (reversed from input due to little endian)
|
||||
test $? -eq 0 && test "${result}" -eq 13633
|
||||
# 3541 is 5A in ASCII (reversed from input due to little endian)
|
||||
test $? -eq 0 && test "${result}" = "a0: 00003541"
|
||||
}
|
||||
|
||||
test_tohex() {
|
||||
# FIXME: Remove grep when this bug is fixed:
|
||||
# https://github.com/sysprog21/rv32emu/issues/561
|
||||
result=$("${RV32EMU}" -q tests/tohex.elf | grep -v '^[0-9]')
|
||||
result=$("${QEMU}" -B 0x80000000 -s 2k tests/tohex.elf)
|
||||
|
||||
test $? -eq 0 && test "${result}" = "CAFEFEED"
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue