From 3cf01adb3940f23808bcbf04d964bb15bed1ed5a Mon Sep 17 00:00:00 2001 From: Andreas Jaeger Date: Thu, 28 Mar 2002 19:07:58 +0000 Subject: Update. 2002-03-28 Andreas Jaeger * sysdeps/unix/sysv/linux/x86_64/swapcontext.S: New. * sysdeps/unix/sysv/linux/x86_64/getcontext.S: New. * sysdeps/unix/sysv/linux/x86_64/setcontext.S: New. * sysdeps/unix/sysv/linux/x86_64/ucontext_i.h: New. --- sysdeps/unix/sysv/linux/x86_64/swapcontext.S | 105 +++++++++++++++++++++++++++ 1 file changed, 105 insertions(+) create mode 100644 sysdeps/unix/sysv/linux/x86_64/swapcontext.S (limited to 'sysdeps/unix/sysv/linux/x86_64/swapcontext.S') diff --git a/sysdeps/unix/sysv/linux/x86_64/swapcontext.S b/sysdeps/unix/sysv/linux/x86_64/swapcontext.S new file mode 100644 index 0000000000..3dddb3cec2 --- /dev/null +++ b/sysdeps/unix/sysv/linux/x86_64/swapcontext.S @@ -0,0 +1,105 @@ +/* Save current context and install the given one. + Copyright (C) 2002 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Andreas Jaeger , 2002. + + 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, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#include + +#include "ucontext_i.h" + + +/* int __swapcontext (ucontext_t *oucp, const ucontext_t *ucp); + + Saves the machine context in oucp such that when it is activated, + it appears as if __swapcontextt() returned again, restores the + machine context in ucp and thereby resumes execution in that + context. + + This implementation is intended to be used for *synchronous* context + switches only. Therefore, it does not have to save anything + other than the PRESERVED state. */ + +ENTRY(__swapcontext) + /* Save the preserved registers and the return address. */ + movq %rbx, oRBX(%rdi) + movq %rbp, oRBP(%rdi) + movq %r12, oR12(%rdi) + movq %r13, oR13(%rdi) + movq %r14, oR14(%rdi) + movq %r15, oR15(%rdi) + + movq (%rsp), %rcx + movq %rcx, oRIP(%rdi) + leaq 8(%rsp), %rcx /* Exclude the return address. */ + movq %rcx, oRSP(%rdi) + + /* We have separate floating-point register content memory on the + stack. We use the __fpregs_mem block in the context. Set the + links up correctly. */ + leaq oFPREGSMEM(%rdi), %rcx + movq %rcx, oFPREGS(%rdi) + /* Save the floating-point environment. */ + fnstenv (%rcx) + stmxcsr oMXCSR(%rdi) + + + /* The syscall destroys some registers, save them. */ + movq %rsi, %r12 + + /* Save the current signal mask and install the new one with + rt_sigprocmask (SIG_BLOCK, newset, oldset,_NSIG/8). */ + leaq oSIGMASK(%rdi), %rdx + leaq oSIGMASK(%rsi), %rsi + movq $SIG_SETMASK, %rdi + movq $_NSIG8,%r10 + movq $__NR_rt_sigprocmask, %rax + syscall + cmpq $-4095, %rax /* Check %rax for error. */ + jae SYSCALL_ERROR_LABEL /* Jump to error handler if error. */ + + /* Restore destroyed registers. */ + movq %r12, %rsi + + /* Restore the floating-point context. Not the registers, only the + rest. */ + movq oFPREGS(%rsi), %rcx + fldenv (%rcx) + ldmxcsr oMXCSR(%rsi) + + /* Load the new stack pointer and the preserved registers. */ + movq oRSP(%rsi), %rsp + movq oRBX(%rsi), %rbx + movq oRBP(%rsi), %rbp + movq oR12(%rsi), %r12 + movq oR13(%rsi), %r13 + movq oR14(%rsi), %r14 + movq oR15(%rsi), %r15 + + /* The following ret should return to the address set with + getcontext. Therefore push the address on the stack. */ + movq oRIP(%rsi), %rcx + pushq %rcx + + /* Clear rax to indicate success. */ + xorq %rax, %rax + +L(pseudo_end): + ret +PSEUDO_END(__swapcontext) + +weak_alias(__swapcontext, swapcontext) -- cgit 1.4.1