diff --git a/.gitignore b/.gitignore index 6b63016..9c95afb 100644 --- a/.gitignore +++ b/.gitignore @@ -4,3 +4,5 @@ /printstack /env /hexdump +/prtest +*.o diff --git a/Makefile b/Makefile index 7808680..b345799 100644 --- a/Makefile +++ b/Makefile @@ -9,11 +9,13 @@ all: true false cat env hexdump #all: echo %: %.o - $(LD) -o $@ $< + $(LD) -o $@ $(filter %.o, $^) %.o: %.s $(AS) -o $@ $< +prtest: prtest.o lib/printregs.o lib/hex.o + .PHONY: test test: @BIN=. test/true.sh diff --git a/lib/hex.s b/lib/hex.s new file mode 100644 index 0000000..28bd8a3 --- /dev/null +++ b/lib/hex.s @@ -0,0 +1,53 @@ +.global u64hex +.global u32hex +.global u8hex + +.macro hexnibble src, shift, dest + slli t1, \src, 64-\shift-4 # put high nibble of s7 in t1 + srli t1, t1, 64-4 + addi t2, t1, 0x30 # convert to decimal digit + bgt t5, t1, 0f # if digit >= 10, switch to alpha + addi t2, t1, 0x61-10 +0: + # copy digit to writebuf + sb t2, \dest +.endm + +.macro hexbyte src, shift, dest + hexnibble \src, (\shift+4), \dest + hexnibble \src, \shift, 1+\dest +.endm + +# arguments: +# a0 - buffer (8, 16 bytes) +# a1 - int (32, 64 bits) +# +# clobbers: t1, t2, t5 +# leaves a0 and a1 unchanged + +u64hex: + li t5, 10 + hexbyte a1, 56, 0(a0) + hexbyte a1, 48, 2(a0) + hexbyte a1, 40, 4(a0) + hexbyte a1, 32, 6(a0) + hexbyte a1, 24, 8(a0) + hexbyte a1, 16, 10(a0) + hexbyte a1, 8, 12(a0) + hexbyte a1, 0, 14(a0) + ret + +u32hex: + li t5, 10 + hexbyte a1, 24, 0(a0) + hexbyte a1, 16, 2(a0) + hexbyte a1, 8, 4(a0) + hexbyte a1, 0, 6(a0) + ret + +u8hex: + li t5, 10 + hexbyte s7, 0, 6(a0) + ret + + diff --git a/lib/printregs.s b/lib/printregs.s new file mode 100644 index 0000000..7cbc115 --- /dev/null +++ b/lib/printregs.s @@ -0,0 +1,207 @@ +.global printregs +.extern u64hex + +.option rvc +.option norelax # don't depend on gp being set correctly + +.data + +regmsg: +.ascii " x1/ra=0x................ x5/t0=0x................ x8/s0=0x................\n" +.ascii " x2/sp=0x................ x6/t1=0x................ x9/s1=0x................\n" +.ascii " x3/gp=0x................ x7/t2=0x................\n" +.ascii " x4/tp=0x................ x18/s2=0x................\n" +.ascii " x14/a4=0x................ x19/s3=0x................\n" +.ascii "x10/a0=0x................ x15/a5=0x................ x20/s4=0x................\n" +.ascii "x11/a1=0x................ x16/a6=0x................ x21/s5=0x................\n" +.ascii "x12/a2=0x................ x17/a7=0x................\n" +.ascii "x13/a3=0x................ x28/t3=0x................\n" +.ascii " x25/ s9=0x................ x29/t4=0x................\n" +.ascii "x22/s6=0x................ x26/s10=0x................ x30/t5=0x................\n" +.ascii "x23/s7=0x................ x27/s11=0x................ x31/t6=0x................\n" +.ascii "x24/s8=0x................\n" +.equ regmsg_size, (.) - regmsg + +# x1 ra x5 t0 x8 s0/fp +# x2 sp x6 t1 x9 s1 +# x3 gp x7 t2 +# x4 tp x18 s2 +# x14 a4 x19 s3 +# x10 a0 x15 a5 x20 s4 +# x11 a1 x16 a6 x21 s5 +# x12 a2 x17 a7 +# x13 a3 x28 t3 +# x25 s9 x29 t4 +# x22 s6 x26 s10 x30 t5 +# x23 s7 x27 s11 x31 t6 +# x24 s8 +# + + +# x1 ra +# x2 sp x5 t0 +# x3 gp x6 t1 x8 s0/fp +# x4 tp x7 t2 x9 s1 +# +# x10 a0 x14 a4 x18 s2 +# x11 a1 x15 a5 x19 s3 +# x12 a2 x16 a6 x20 s4 +# x13 a3 x17 a7 +# x28 t3 +# x21 s5 x25 s9 x29 t4 +# x22 s6 x26 s10 x30 t5 +# x23 s7 x27 s11 x31 t6 +# x24 s8 + +.text + +printregs: + # this routine is meant for debugging, + # so we treat all registers as callee-save + + # TODO: consider saving to globals instead of the stack + + # huh. it seems impossible to do anything useful + # with atomics without using registers + # + # li t0, 1 # Initialize swap value. + # 0:lw t1, (a0) # Check if lock is held. + # bnez t1, again # Retry if held. + # amoswap.w.aq t1, t0, (a0) # Attempt to acquire lock. + # bnez t1, 0b # Retry if held. + + # save regs to stack + sd sp, -8(sp) + addi sp, sp, -8*7 + sd a0, 0(sp) + sd a1, 8(sp) + sd t1, 16(sp) + sd t2, 24(sp) + sd t5, 32(sp) + sd ra, 40(sp) + + # copy string to stack? + + # write registers to string + la a0, regmsg+9 + ld a1, 40(sp) # x1 / ra + call u64hex + addi a0, a0, 16+11 + mv a1, x5 # t0 + call u64hex + addi a0, a0, 16+11 + mv a1, x8 # s0 + call u64hex + + addi a0, a0, 16+10 + ld a1, 48(sp) # x2/sp + call u64hex + addi a0, a0, 16+11 + ld a1, 16(sp) # x6/t1 + call u64hex + addi a0, a0, 16+11 + mv a1, x9 # s1 + call u64hex + + addi a0, a0, 16+10 + mv a1, x3 # gp + call u64hex + addi a0, a0, 16+11 + ld a1, 24(sp) # x7/t2 + call u64hex + + addi a0, a0, 16+10 + mv a1, x4 # tp + call u64hex + addi a0, a0, 16+11 + 16+11 + mv a1, x18 # s2 + call u64hex + + addi a0, a0, 16+10 + 16+11 + mv a1, x14 # a4 + call u64hex + addi a0, a0, 16+11 + mv a1, x19 # s3 + call u64hex + + addi a0, a0, 16+10 + ld a1, 0(sp) # x10/a0 + call u64hex + addi a0, a0, 16+11 + mv a1, x15 # a5 + call u64hex + addi a0, a0, 16+11 + mv a1, x20 # s4 + call u64hex + + addi a0, a0, 16+10 + ld a1, 8(sp) # a1 + call u64hex + addi a0, a0, 16+11 + mv a1, x16 # a6 + call u64hex + addi a0, a0, 16+11 + mv a1, x21 # s5 + call u64hex + + addi a0, a0, 16+10 + mv a1, x12 # a2 + call u64hex + addi a0, a0, 16+11 + mv a1, x17 # a7 + call u64hex + + addi a0, a0, 16+10 + mv a1, x13 # a3 + call u64hex + addi a0, a0, 16+11 + 16+11 + mv a1, x28 # t3 + call u64hex + + addi a0, a0, 16+10 + 16+11 + mv a1, x25 # s9 + call u64hex + addi a0, a0, 16+11 + mv a1, x29 # t4 + call u64hex + + addi a0, a0, 16+10 + mv a1, x22 # s6 + call u64hex + addi a0, a0, 16+11 + mv a1, x26 # s10 + call u64hex + addi a0, a0, 16+11 + ld a1, 32(sp) # x30 / t5 + call u64hex + + addi a0, a0, 16+10 + mv a1, x23 # s7 + call u64hex + addi a0, a0, 16+11 + mv a1, x27 # s11 + call u64hex + addi a0, a0, 16+11 + mv a1, x31 # t6 + call u64hex + + addi a0, a0, 16+10 + mv a1, x24 # s8 + call u64hex + + # print string + li a7, 64 # sys_write + li a0, 1 # stdout + la a1, regmsg + li a2, regmsg_size + ecall + + # restore saved registers + ld a0, 0(sp) + ld a1, 8(sp) + ld t1, 16(sp) + ld t2, 24(sp) + ld t5, 32(sp) + ld ra, 40(sp) + ld sp, 48(sp) + ret diff --git a/prtest.s b/prtest.s new file mode 100644 index 0000000..7b93cb9 --- /dev/null +++ b/prtest.s @@ -0,0 +1,39 @@ + +.globl _start +.extern printregs + +.text + +_start: + li x5, 5 + li x6, 6 + li x7, 7 + li x8, 8 + li x9, 9 + li x10, 10 + li x11, 11 + li x12, 12 + li x13, 13 + li x14, 14 + li x15, 15 + li x16, 16 + li x17, 17 + li x18, 18 + li x19, 19 + li x20, 20 + li x21, 21 + li x22, 22 + li x23, 23 + li x24, 24 + li x25, 25 + li x26, 26 + li x27, 27 + li x28, 28 + li x29, 29 + li x30, 30 + li x31, 31 + call printregs + li a7, 93 # sys_exit + li a0, 0 + ecall +