From a203837b1fa0d4d86da911bf034766f3ab6bab50 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=B6nke=20Holz?= Date: Wed, 21 Feb 2024 18:18:14 +0100 Subject: [PATCH] LibC: Save callee-saved floating-point registers in setjmp for riscv64 --- Userland/Libraries/LibC/arch/riscv64/setjmp.S | 36 ++++++++++++++++--- Userland/Libraries/LibC/setjmp.h | 3 +- 2 files changed, 34 insertions(+), 5 deletions(-) diff --git a/Userland/Libraries/LibC/arch/riscv64/setjmp.S b/Userland/Libraries/LibC/arch/riscv64/setjmp.S index 7700d8babb..f31760b123 100644 --- a/Userland/Libraries/LibC/arch/riscv64/setjmp.S +++ b/Userland/Libraries/LibC/arch/riscv64/setjmp.S @@ -56,8 +56,22 @@ sigsetjmp: sd s9, 9*8(a0) sd s10, 10*8(a0) sd s11, 11*8(a0) - sd sp, 12*8(a0) - sd ra, 13*8(a0) + + fsd fs0, 12*8(a0) // Save floating-point registers + fsd fs1, 13*8(a0) // NOTE: We only support ABI_FLEN=64 in LibELF/Validation.cpp, + fsd fs2, 14*8(a0) // so we only save the lower 64 bits of the fs* registers. + fsd fs3, 15*8(a0) + fsd fs4, 16*8(a0) + fsd fs5, 17*8(a0) + fsd fs6, 18*8(a0) + fsd fs7, 19*8(a0) + fsd fs8, 20*8(a0) + fsd fs9, 21*8(a0) + fsd fs10, 22*8(a0) + fsd fs11, 23*8(a0) + + sd sp, 24*8(a0) + sd ra, 25*8(a0) li a0, 0 ret @@ -81,8 +95,22 @@ longjmp: ld s9, 9*8(a0) ld s10, 10*8(a0) ld s11, 11*8(a0) - ld sp, 12*8(a0) - ld ra, 13*8(a0) + + fld fs0, 12*8(a0) // Restore floating-point registers + fld fs1, 13*8(a0) // NOTE: We only support ABI_FLEN=64 in LibELF/Validation.cpp, + fld fs2, 14*8(a0) // so we only restore the lower 64 bits of the fs* registers. + fld fs3, 15*8(a0) + fld fs4, 16*8(a0) + fld fs5, 17*8(a0) + fld fs6, 18*8(a0) + fld fs7, 19*8(a0) + fld fs8, 20*8(a0) + fld fs9, 21*8(a0) + fld fs10, 22*8(a0) + fld fs11, 23*8(a0) + + ld sp, 24*8(a0) + ld ra, 25*8(a0) mv a0, a1 bnez a0, .Lnonzero diff --git a/Userland/Libraries/LibC/setjmp.h b/Userland/Libraries/LibC/setjmp.h index 918595e967..a69a0adfe6 100644 --- a/Userland/Libraries/LibC/setjmp.h +++ b/Userland/Libraries/LibC/setjmp.h @@ -33,6 +33,7 @@ struct __jmp_buf { uint64_t regs[22]; #elif defined(__riscv) && __riscv_xlen == 64 uint64_t s[12]; + uint64_t fs[12]; uint64_t sp; uint64_t ra; #else @@ -54,7 +55,7 @@ static_assert(sizeof(struct __jmp_buf) == 72, "struct __jmp_buf unsynchronized w # elif defined(__aarch64__) static_assert(sizeof(struct __jmp_buf) == 184, "struct __jmp_buf unsynchronized with aarch64/setjmp.S"); # elif defined(__riscv) && __riscv_xlen == 64 -static_assert(sizeof(struct __jmp_buf) == 120, "struct __jmp_buf unsynchronized with riscv64/setjmp.S"); +static_assert(sizeof(struct __jmp_buf) == 216, "struct __jmp_buf unsynchronized with riscv64/setjmp.S"); # else # error "Unknown architecture" # endif