This is the mail archive of the
libc-alpha@sourceware.org
mailing list for the glibc project.
[Committed] S/390: Fix setjmp/longjmp FPR register save/restore
- From: Andreas Krebbel <krebbel at linux dot vnet dot ibm dot com>
- To: libc-alpha at sourceware dot org
- Date: Wed, 23 Jan 2013 10:04:08 +0100
- Subject: [Committed] S/390: Fix setjmp/longjmp FPR register save/restore
Hi,
I've committed the attached patch to fix setjmp/longjmp for floating
point on S/390. For some reason the wrong FPRs have been saved and
restored. According to the zABI f8-f15 are call-saved.
http://refspecs.linuxfoundation.org/ELF/zSeries/lzsabi0_zSeries.html#AEN413
Surprisingly there have been already enough slots in jmpbuf to save 8
FPRs.
Bye,
-Andreas-
2013-01-23 Andreas Krebbel <Andreas.Krebbel@de.ibm.com>
* sysdeps/s390/bits/setjmp.h: Fix comment.
* sysdeps/s390/s390-64/__longjmp.c: Restore f8-f15.
* sysdeps/s390/s390-64/setjmp.S: Save f8-f15.
---
sysdeps/s390/bits/setjmp.h | 2 +-
sysdeps/s390/s390-64/__longjmp.c | 12 ++++++++----
sysdeps/s390/s390-64/setjmp.S | 12 ++++++++----
3 files changed, 17 insertions(+), 9 deletions(-)
Index: glibc/sysdeps/s390/bits/setjmp.h
===================================================================
--- glibc.orig/sysdeps/s390/bits/setjmp.h
+++ glibc/sysdeps/s390/bits/setjmp.h
@@ -34,7 +34,7 @@ typedef struct __s390_jmp_buf
long int __gregs[10];
# if __WORDSIZE == 64
- /* We save fpu registers 1, 3, 5 and 7. */
+ /* We save fpu registers f8 - f15. */
long __fpregs[8];
# else
/* We save fpu registers 4 and 6. */
Index: glibc/sysdeps/s390/s390-64/setjmp.S
===================================================================
--- glibc.orig/sysdeps/s390/s390-64/setjmp.S
+++ glibc/sysdeps/s390/s390-64/setjmp.S
@@ -55,10 +55,14 @@ ENTRY(__sigsetjmp)
#else
stmg %r6,%r15,0(%r2) /* Store registers in jmp_buf. */
#endif
- std %f1,80(%r2)
- std %f3,88(%r2)
- std %f5,96(%r2)
- std %f7,104(%r2)
+ std %f8,80(%r2)
+ std %f9,88(%r2)
+ std %f10,96(%r2)
+ std %f11,104(%r2)
+ std %f12,112(%r2)
+ std %f13,120(%r2)
+ std %f14,128(%r2)
+ std %f15,136(%r2)
#if defined NOT_IN_libc && defined IS_IN_rtld
/* In ld.so we never save the signal mask. */
lghi %r2,0
Index: glibc/sysdeps/s390/s390-64/__longjmp.c
===================================================================
--- glibc.orig/sysdeps/s390/s390-64/__longjmp.c
+++ glibc/sysdeps/s390/s390-64/__longjmp.c
@@ -42,10 +42,14 @@ __longjmp (__jmp_buf env, int val)
register void *r1 __asm ("%r1") = (void *) env;
#endif
/* Restore registers and jump back. */
- asm volatile ("ld %%f7,104(%1)\n\t"
- "ld %%f5,96(%1)\n\t"
- "ld %%f3,88(%1)\n\t"
- "ld %%f1,80(%1)\n\t"
+ asm volatile ("ld %%f8,80(%1)\n\t"
+ "ld %%f9,88(%1)\n\t"
+ "ld %%f10,96(%1)\n\t"
+ "ld %%f11,104(%1)\n\t"
+ "ld %%f12,112(%1)\n\t"
+ "ld %%f13,120(%1)\n\t"
+ "ld %%f14,128(%1)\n\t"
+ "ld %%f15,136(%1)\n\t"
#ifdef PTR_DEMANGLE
"lmg %%r6,%%r13,0(%1)\n\t"
"lmg %%r4,%%r5,64(%1)\n\t"