فهرست منبع

LibC: Save callee-saved floating-point registers in setjmp for riscv64

Sönke Holz 1 سال پیش
والد
کامیت
a203837b1f
2فایلهای تغییر یافته به همراه34 افزوده شده و 5 حذف شده
  1. 32 4
      Userland/Libraries/LibC/arch/riscv64/setjmp.S
  2. 2 1
      Userland/Libraries/LibC/setjmp.h

+ 32 - 4
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

+ 2 - 1
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