/* Copyright (C) 2011 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Chris Metcalf , 2011. The GNU C Library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. The GNU C Library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with the GNU C Library. If not, see . */ #include #include #include "ucontext_i.h" /* int getcontext (ucontext_t *ucp) */ .text ENTRY (__getcontext) FEEDBACK_ENTER(__getcontext) /* Save the callee-saved GPRs. There's no need to save the caller-saved GPRs since the eventual setcontext() or swapcontext() will assume those registers are all dead. Save value "1" to uc_flags to later recognize getcontext(). */ { movei r11, 1; ADDI_PTR r10, r0, UC_FLAGS_OFFSET } { ST_PTR r10, r11; addli r10, r0, UC_REG(30) } { ST r10, r30; ADDI_PTR r10, r10, REGSIZE } { ST r10, r31; ADDI_PTR r10, r10, REGSIZE } { ST r10, r32; ADDI_PTR r10, r10, REGSIZE } { ST r10, r33; ADDI_PTR r10, r10, REGSIZE } { ST r10, r34; ADDI_PTR r10, r10, REGSIZE } { ST r10, r35; ADDI_PTR r10, r10, REGSIZE } { ST r10, r36; ADDI_PTR r10, r10, REGSIZE } { ST r10, r37; ADDI_PTR r10, r10, REGSIZE } { ST r10, r38; ADDI_PTR r10, r10, REGSIZE } { ST r10, r39; ADDI_PTR r10, r10, REGSIZE } { ST r10, r40; ADDI_PTR r10, r10, REGSIZE } { ST r10, r41; ADDI_PTR r10, r10, REGSIZE } { ST r10, r42; ADDI_PTR r10, r10, REGSIZE } { ST r10, r43; ADDI_PTR r10, r10, REGSIZE } { ST r10, r44; ADDI_PTR r10, r10, REGSIZE } { ST r10, r45; ADDI_PTR r10, r10, REGSIZE } { ST r10, r46; ADDI_PTR r10, r10, REGSIZE } { ST r10, r47; ADDI_PTR r10, r10, REGSIZE } { ST r10, r48; ADDI_PTR r10, r10, REGSIZE } { ST r10, r49; ADDI_PTR r10, r10, REGSIZE } { ST r10, r50; ADDI_PTR r10, r10, REGSIZE } { ST r10, r51; ADDI_PTR r10, r10, REGSIZE } { ST r10, r52; ADDI_PTR r10, r10, REGSIZE } { ST r10, tp; ADDI_PTR r10, r10, REGSIZE } { ST r10, sp; ADDI_PTR r10, r10, REGSIZE } { ST r10, lr; ADDI_PTR r10, r10, REGSIZE } lnk r11 /* Point PC at the "jrp lr" instruction. */ addli r11, r11, .Lreturn - . { ST r10, r11; ADDI_PTR r10, r10, REGSIZE } mfspr r11, INTERRUPT_CRITICAL_SECTION { ST r10, r11 movei r1, 0 } /* rt_sigprocmask (SIG_BLOCK, NULL, &ucp->uc_sigmask, _NSIG / 8) */ { movei r3, _NSIG / 8 addli r2, r0, UC_SIGMASK_OFFSET } { movei r0, SIG_BLOCK moveli TREG_SYSCALL_NR_NAME, __NR_rt_sigprocmask } swint1 BNEZ r1, .Lsyscall_error .Lreturn: { movei r0, 0 jrp lr } .Lsyscall_error: j SYSCALL_ERROR_NAME END (__getcontext) .hidden __getcontext weak_alias (__getcontext, getcontext)