# 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