From 43a66b39ccf0f0206913cd4efce71f66bd103781 Mon Sep 17 00:00:00 2001 From: Yannis Huber Date: Wed, 1 Jul 2020 23:26:33 +0200 Subject: [PATCH] riscv: refactor assembly files to support RV64 and F extension --- src/device/riscv/handleinterrupt.S | 130 ++++++++++++++++++++++++++ src/device/riscv/handleinterrupt32.S | 44 --------- src/device/riscv/handleinterrupt64.S | 44 --------- src/runtime/scheduler_tinygoriscv.S | 42 +++++---- src/runtime/scheduler_tinygoriscv64.S | 32 ------- targets/k210.json | 3 +- targets/riscv.json | 4 +- targets/riscv32.json | 4 - targets/riscv64.json | 7 +- 9 files changed, 163 insertions(+), 147 deletions(-) create mode 100644 src/device/riscv/handleinterrupt.S delete mode 100644 src/device/riscv/handleinterrupt32.S delete mode 100644 src/device/riscv/handleinterrupt64.S delete mode 100644 src/runtime/scheduler_tinygoriscv64.S diff --git a/src/device/riscv/handleinterrupt.S b/src/device/riscv/handleinterrupt.S new file mode 100644 index 00000000..dbf54f01 --- /dev/null +++ b/src/device/riscv/handleinterrupt.S @@ -0,0 +1,130 @@ +#ifdef F_EXTENSION +#define NREG 48 +#define LFREG flw +#define SFREG fsw +#else +#define NREG 16 +#endif + +#ifdef RV64 +#define REGSIZE 8 +#define SREG sd +#define LREG ld +#else +#define REGSIZE 4 +#define SREG sw +#define LREG lw +#endif + +.section .text.handleInterruptASM +.global handleInterruptASM +.type handleInterruptASM,@function +handleInterruptASM: + // Save and restore all registers, because the hardware only saves/restores + // the pc. + // Note: we have to do this in assembly because the "interrupt"="machine" + // attribute is broken in LLVM: https://bugs.llvm.org/show_bug.cgi?id=42984 + addi sp, sp, -NREG*REGSIZE + SREG ra, 0*REGSIZE(sp) + SREG t0, 1*REGSIZE(sp) + SREG t1, 2*REGSIZE(sp) + SREG t2, 3*REGSIZE(sp) + SREG a0, 4*REGSIZE(sp) + SREG a1, 5*REGSIZE(sp) + SREG a2, 6*REGSIZE(sp) + SREG a3, 7*REGSIZE(sp) + SREG a4, 8*REGSIZE(sp) + SREG a5, 9*REGSIZE(sp) + SREG a6, 10*REGSIZE(sp) + SREG a7, 11*REGSIZE(sp) + SREG t3, 12*REGSIZE(sp) + SREG t4, 13*REGSIZE(sp) + SREG t5, 14*REGSIZE(sp) + SREG t6, 15*REGSIZE(sp) +#ifdef F_EXTENSION + SFREG f0, (0 + 16)*REGSIZE(sp) + SFREG f1, (1 + 16)*REGSIZE(sp) + SFREG f2, (2 + 16)*REGSIZE(sp) + SFREG f3, (3 + 16)*REGSIZE(sp) + SFREG f4, (4 + 16)*REGSIZE(sp) + SFREG f5, (5 + 16)*REGSIZE(sp) + SFREG f6, (6 + 16)*REGSIZE(sp) + SFREG f7, (7 + 16)*REGSIZE(sp) + SFREG f8, (8 + 16)*REGSIZE(sp) + SFREG f9, (9 + 16)*REGSIZE(sp) + SFREG f10,(10 + 16)*REGSIZE(sp) + SFREG f11,(11 + 16)*REGSIZE(sp) + SFREG f12,(12 + 16)*REGSIZE(sp) + SFREG f13,(13 + 16)*REGSIZE(sp) + SFREG f14,(14 + 16)*REGSIZE(sp) + SFREG f15,(15 + 16)*REGSIZE(sp) + SFREG f16,(16 + 16)*REGSIZE(sp) + SFREG f17,(17 + 16)*REGSIZE(sp) + SFREG f18,(18 + 16)*REGSIZE(sp) + SFREG f19,(19 + 16)*REGSIZE(sp) + SFREG f20,(20 + 16)*REGSIZE(sp) + SFREG f21,(21 + 16)*REGSIZE(sp) + SFREG f22,(22 + 16)*REGSIZE(sp) + SFREG f23,(23 + 16)*REGSIZE(sp) + SFREG f24,(24 + 16)*REGSIZE(sp) + SFREG f25,(25 + 16)*REGSIZE(sp) + SFREG f26,(26 + 16)*REGSIZE(sp) + SFREG f27,(27 + 16)*REGSIZE(sp) + SFREG f28,(28 + 16)*REGSIZE(sp) + SFREG f29,(29 + 16)*REGSIZE(sp) + SFREG f30,(30 + 16)*REGSIZE(sp) + SFREG f31,(31 + 16)*REGSIZE(sp) +#endif + call handleInterrupt +#ifdef F_EXTENSION + LFREG f0, (31 + 16)*REGSIZE(sp) + LFREG f1, (30 + 16)*REGSIZE(sp) + LFREG f2, (29 + 16)*REGSIZE(sp) + LFREG f3, (28 + 16)*REGSIZE(sp) + LFREG f4, (27 + 16)*REGSIZE(sp) + LFREG f5, (26 + 16)*REGSIZE(sp) + LFREG f6, (25 + 16)*REGSIZE(sp) + LFREG f7, (24 + 16)*REGSIZE(sp) + LFREG f8, (23 + 16)*REGSIZE(sp) + LFREG f9, (22 + 16)*REGSIZE(sp) + LFREG f10,(21 + 16)*REGSIZE(sp) + LFREG f11,(20 + 16)*REGSIZE(sp) + LFREG f12,(19 + 16)*REGSIZE(sp) + LFREG f13,(18 + 16)*REGSIZE(sp) + LFREG f14,(17 + 16)*REGSIZE(sp) + LFREG f15,(16 + 16)*REGSIZE(sp) + LFREG f16,(15 + 16)*REGSIZE(sp) + LFREG f17,(14 + 16)*REGSIZE(sp) + LFREG f18,(13 + 16)*REGSIZE(sp) + LFREG f19,(12 + 16)*REGSIZE(sp) + LFREG f20,(11 + 16)*REGSIZE(sp) + LFREG f21,(10 + 16)*REGSIZE(sp) + LFREG f22,(9 + 16)*REGSIZE(sp) + LFREG f23,(8 + 16)*REGSIZE(sp) + LFREG f24,(7 + 16)*REGSIZE(sp) + LFREG f25,(6 + 16)*REGSIZE(sp) + LFREG f26,(5 + 16)*REGSIZE(sp) + LFREG f27,(4 + 16)*REGSIZE(sp) + LFREG f28,(3 + 16)*REGSIZE(sp) + LFREG f29,(2 + 16)*REGSIZE(sp) + LFREG f30,(1 + 16)*REGSIZE(sp) + LFREG f31,(0 + 16)*REGSIZE(sp) +#endif + LREG t6, 15*REGSIZE(sp) + LREG t5, 14*REGSIZE(sp) + LREG t4, 13*REGSIZE(sp) + LREG t3, 12*REGSIZE(sp) + LREG a7, 11*REGSIZE(sp) + LREG a6, 10*REGSIZE(sp) + LREG a5, 9*REGSIZE(sp) + LREG a4, 8*REGSIZE(sp) + LREG a3, 7*REGSIZE(sp) + LREG a2, 6*REGSIZE(sp) + LREG a1, 5*REGSIZE(sp) + LREG a0, 4*REGSIZE(sp) + LREG t2, 3*REGSIZE(sp) + LREG t1, 2*REGSIZE(sp) + LREG t0, 1*REGSIZE(sp) + LREG ra, 0*REGSIZE(sp) + addi sp, sp, NREG*REGSIZE + mret diff --git a/src/device/riscv/handleinterrupt32.S b/src/device/riscv/handleinterrupt32.S deleted file mode 100644 index 4358977a..00000000 --- a/src/device/riscv/handleinterrupt32.S +++ /dev/null @@ -1,44 +0,0 @@ -.section .text.handleInterruptASM -.global handleInterruptASM -.type handleInterruptASM,@function -handleInterruptASM: - // Save and restore all registers, because the hardware only saves/restores - // the pc. - // Note: we have to do this in assembly because the "interrupt"="machine" - // attribute is broken in LLVM: https://bugs.llvm.org/show_bug.cgi?id=42984 - addi sp, sp, -64 - sw ra, 60(sp) - sw t0, 56(sp) - sw t1, 52(sp) - sw t2, 48(sp) - sw a0, 44(sp) - sw a1, 40(sp) - sw a2, 36(sp) - sw a3, 32(sp) - sw a4, 28(sp) - sw a5, 24(sp) - sw a6, 20(sp) - sw a7, 16(sp) - sw t3, 12(sp) - sw t4, 8(sp) - sw t5, 4(sp) - sw t6, 0(sp) - call handleInterrupt - lw t6, 0(sp) - lw t5, 4(sp) - lw t4, 8(sp) - lw t3, 12(sp) - lw a7, 16(sp) - lw a6, 20(sp) - lw a5, 24(sp) - lw a4, 28(sp) - lw a3, 32(sp) - lw a2, 36(sp) - lw a1, 40(sp) - lw a0, 44(sp) - lw t2, 48(sp) - lw t1, 52(sp) - lw t0, 56(sp) - lw ra, 60(sp) - addi sp, sp, 64 - mret diff --git a/src/device/riscv/handleinterrupt64.S b/src/device/riscv/handleinterrupt64.S deleted file mode 100644 index e0c6a3bf..00000000 --- a/src/device/riscv/handleinterrupt64.S +++ /dev/null @@ -1,44 +0,0 @@ -.section .text.handleInterruptASM -.global handleInterruptASM -.type handleInterruptASM,@function -handleInterruptASM: - // Save and restore all registers, because the hardware only saves/restores - // the pc. - // Note: we have to do this in assembly because the "interrupt"="machine" - // attribute is broken in LLVM: https://bugs.llvm.org/show_bug.cgi?id=42984 - addi sp, sp, -128 - sd ra, 120(sp) - sd t0, 112(sp) - sd t1, 104(sp) - sd t2, 96(sp) - sd a0, 88(sp) - sd a1, 80(sp) - sd a2, 72(sp) - sd a3, 64(sp) - sd a4, 56(sp) - sd a5, 48(sp) - sd a6, 40(sp) - sd a7, 32(sp) - sd t3, 24(sp) - sd t4, 16(sp) - sd t5, 8(sp) - sd t6, 0(sp) - call handleInterrupt - ld t6, 0(sp) - ld t5, 8(sp) - ld t4, 16(sp) - ld t3, 24(sp) - ld a7, 32(sp) - ld a6, 40(sp) - ld a5, 48(sp) - ld a4, 56(sp) - ld a3, 64(sp) - ld a2, 72(sp) - ld a1, 80(sp) - ld a0, 88(sp) - ld t2, 96(sp) - ld t1, 104(sp) - ld t0, 112(sp) - ld ra, 120(sp) - addi sp, sp, 128 - mret diff --git a/src/runtime/scheduler_tinygoriscv.S b/src/runtime/scheduler_tinygoriscv.S index 3766bae7..9749ca22 100644 --- a/src/runtime/scheduler_tinygoriscv.S +++ b/src/runtime/scheduler_tinygoriscv.S @@ -1,32 +1,42 @@ +#ifdef RV64 +#define REGSIZE 8 +#define SREG sd +#define LREG ld +#else +#define REGSIZE 4 +#define SREG sw +#define LREG lw +#endif + .section .text.tinygo_scanCurrentStack .global tinygo_scanCurrentStack .type tinygo_scanCurrentStack, %function tinygo_scanCurrentStack: // Push callee-saved registers onto the stack. - addi sp, sp, -64 - sw ra, 60(sp) - sw s11, 56(sp) - sw s10, 52(sp) - sw s9, 48(sp) - sw s8, 44(sp) - sw s7, 40(sp) - sw s6, 36(sp) - sw s5, 32(sp) - sw s4, 28(sp) - sw s3, 24(sp) - sw s2, 20(sp) - sw s1, 16(sp) - sw s0, 12(sp) + addi sp, sp, -13*REGSIZE + SREG ra, 0*REGSIZE(sp) + SREG s11, 1*REGSIZE(sp) + SREG s10, 2*REGSIZE(sp) + SREG s9, 3*REGSIZE(sp) + SREG s8, 4*REGSIZE(sp) + SREG s7, 5*REGSIZE(sp) + SREG s6, 6*REGSIZE(sp) + SREG s5, 7*REGSIZE(sp) + SREG s4, 8*REGSIZE(sp) + SREG s3, 9*REGSIZE(sp) + SREG s2, 10*REGSIZE(sp) + SREG s1, 11*REGSIZE(sp) + SREG s0, 12*REGSIZE(sp) // Scan the stack. mv a0, sp call tinygo_scanstack // Restore return address. - lw ra, 60(sp) + LREG ra, 0(sp) // Restore stack state. - addi sp, sp, 64 + addi sp, sp, 13*REGSIZE // Return to the caller. ret diff --git a/src/runtime/scheduler_tinygoriscv64.S b/src/runtime/scheduler_tinygoriscv64.S deleted file mode 100644 index 84be3e2d..00000000 --- a/src/runtime/scheduler_tinygoriscv64.S +++ /dev/null @@ -1,32 +0,0 @@ -.section .text.tinygo_scanCurrentStack -.global tinygo_scanCurrentStack -.type tinygo_scanCurrentStack, %function -tinygo_scanCurrentStack: - // Push callee-saved registers onto the stack. - addi sp, sp, -104 - sd ra, 96(sp) - sd s11, 88(sp) - sd s10, 80(sp) - sd s9, 72(sp) - sd s8, 64(sp) - sd s7, 56(sp) - sd s6, 48(sp) - sd s5, 40(sp) - sd s4, 32(sp) - sd s3, 24(sp) - sd s2, 16(sp) - sd s1, 8(sp) - sd s0, 0(sp) - - // Scan the stack. - mv a0, sp - call tinygo_scanstack - - // Restore return address. - ld ra, 96(sp) - - // Restore stack state. - addi sp, sp, 104 - - // Return to the caller. - ret diff --git a/targets/k210.json b/targets/k210.json index 5ddd9dba..77fcc53d 100644 --- a/targets/k210.json +++ b/targets/k210.json @@ -1,5 +1,6 @@ { "inherits": ["riscv64"], "features": ["+a", "+c", "+m", "+f", "+d"], - "build-tags": ["k210", "kendryte"] + "build-tags": ["k210", "kendryte"], + "cflags": ["-D=F_EXTENSION"] } diff --git a/targets/riscv.json b/targets/riscv.json index a2d4aaeb..da40416b 100644 --- a/targets/riscv.json +++ b/targets/riscv.json @@ -17,7 +17,9 @@ "--gc-sections" ], "extra-files": [ - "src/device/riscv/start.S" + "src/device/riscv/start.S", + "src/runtime/scheduler_tinygoriscv.S", + "src/device/riscv/handleinterrupt.S" ], "gdb": "riscv64-unknown-elf-gdb" } diff --git a/targets/riscv32.json b/targets/riscv32.json index fb1bdb94..24f5cee9 100644 --- a/targets/riscv32.json +++ b/targets/riscv32.json @@ -9,9 +9,5 @@ ], "ldflags": [ "-melf32lriscv" - ], - "extra-files": [ - "src/runtime/scheduler_tinygoriscv.S", - "src/device/riscv/handleinterrupt32.S" ] } diff --git a/targets/riscv64.json b/targets/riscv64.json index 20c7f1ba..f73700c9 100644 --- a/targets/riscv64.json +++ b/targets/riscv64.json @@ -5,13 +5,10 @@ "cflags": [ "--target=riscv64--none", "-march=rv64gc", - "-mabi=lp64" + "-mabi=lp64", + "-D=RV64" ], "ldflags": [ "-melf64lriscv" - ], - "extra-files": [ - "src/runtime/scheduler_tinygoriscv64.S", - "src/device/riscv/handleinterrupt64.S" ] }