diff options
Diffstat (limited to 'sysdeps/unix/sysv/linux/s390/s390-32/swapcontext.S')
-rw-r--r-- | sysdeps/unix/sysv/linux/s390/s390-32/swapcontext.S | 29 |
1 files changed, 22 insertions, 7 deletions
diff --git a/sysdeps/unix/sysv/linux/s390/s390-32/swapcontext.S b/sysdeps/unix/sysv/linux/s390/s390-32/swapcontext.S index b022f2ca74..41ede4b7b2 100644 --- a/sysdeps/unix/sysv/linux/s390/s390-32/swapcontext.S +++ b/sysdeps/unix/sysv/linux/s390/s390-32/swapcontext.S @@ -1,4 +1,4 @@ -/* Copyright (C) 2002-2013 Free Software Foundation, Inc. +/* Copyright (C) 2002-2014 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Martin Schwidefsky (schwidefsky@de.ibm.com). @@ -33,6 +33,9 @@ other than the PRESERVED state. */ ENTRY(__swapcontext) + /* While not part of the ABI a system call never clobbers r0 + or r1. So keeping the values here while calling + rt_sigprocmask is ok. */ lr %r1,%r2 lr %r0,%r3 @@ -62,19 +65,31 @@ ENTRY(__swapcontext) std %f14,SC_FPRS+112(%r1) std %f15,SC_FPRS+120(%r1) - /* Set __swapcontext return value to 0. */ - slr %r2,%r2 - /* Store access registers. */ stam %a0,%a15,SC_ACRS(%r1) + /* Set __swapcontext return value to 0. */ + slr %r2,%r2 + /* Store general purpose registers. */ stm %r0,%r15,SC_GPRS(%r1) - /* sigprocmask (SIG_SETMASK, &sc->sc_mask, NULL). */ - la %r2,SIG_BLOCK + /* Copy uc_flags into the new ucontext_t. */ lr %r5,%r0 - la %r3,SC_MASK(%r5) + l %r2,SC_FLGS(%r5) + st %r2,SC_FLGS(%r1) + + /* Save/restore the upper halfs if necessary. */ + tml %r2,1 /* UCONTEXT_UC_FLAGS_HIGH_GPRS */ + jz 0f + .machine "z900" + .machinemode "zarch_nohighgprs" + stmh %r0,%r15,SC_HIGHGPRS(%r1) + lmh %r0,%r15,SC_HIGHGPRS(%r5) + + /* rt_sigprocmask (SIG_SETMASK, &sc->sc_mask, NULL, sigsetsize). */ +0: la %r2,SIG_BLOCK + la %r3,SC_MASK(%r5) slr %r4,%r4 lhi %r5,_NSIG8 svc SYS_ify(rt_sigprocmask) |