aboutsummaryrefslogtreecommitdiff
path: root/sysdeps/unix/sysv
diff options
context:
space:
mode:
authorRoland McGrath <roland@gnu.org>2003-04-06 20:59:45 +0000
committerRoland McGrath <roland@gnu.org>2003-04-06 20:59:45 +0000
commit77f844138c60d34df49205db10e85b5cdbf0bf0b (patch)
treec1f07f211e43127c11a7b440cc815f14de4e4301 /sysdeps/unix/sysv
parentb87507117c2424239f69ca7e3c5e6c2a52328839 (diff)
downloadglibc-77f844138c60d34df49205db10e85b5cdbf0bf0b.tar
glibc-77f844138c60d34df49205db10e85b5cdbf0bf0b.tar.gz
glibc-77f844138c60d34df49205db10e85b5cdbf0bf0b.tar.bz2
glibc-77f844138c60d34df49205db10e85b5cdbf0bf0b.zip
2003-04-06 Roland McGrath <roland@redhat.com>
* sysdeps/unix/sysv/linux/i386/swapcontext.S: Rewrite register restoration as done for setcontext yesterday.
Diffstat (limited to 'sysdeps/unix/sysv')
-rw-r--r--sysdeps/unix/sysv/linux/i386/swapcontext.S56
1 files changed, 22 insertions, 34 deletions
diff --git a/sysdeps/unix/sysv/linux/i386/swapcontext.S b/sysdeps/unix/sysv/linux/i386/swapcontext.S
index e44e9301b0..d909e659e4 100644
--- a/sysdeps/unix/sysv/linux/i386/swapcontext.S
+++ b/sysdeps/unix/sysv/linux/i386/swapcontext.S
@@ -1,5 +1,5 @@
/* Save current context and install the given one.
- Copyright (C) 2001, 2002 Free Software Foundation, Inc.
+ Copyright (C) 2001, 2002, 2003 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@redhat.com>, 2001.
@@ -78,43 +78,31 @@ ENTRY(__swapcontext)
movl oFPREGS(%eax), %ecx
fldenv (%ecx)
- /* Restore the FS segment registers. */
+ /* Restore the FS segment register. We don't touch the GS register
+ since it is used for threads. */
movl oFS(%eax), %edx
movw %dx, %fs
+ /* Fetch the address to return to. */
+ movl oEIP(%eax), %ecx
+
/* Load the new stack pointer. */
- movl oESP(%eax), %ecx
- /* Make room for 8 registers and the return address. We will load
- the values from the stack. */
- subl $36, %ecx
-
- /* Move the values of all the 32-bit registers (except ESP) on
- the stack. This happens in the form the 'popa' instruction
- expects it. Before this block put the address of the code
- to execute. */
- movl oEDI(%eax), %ebx
- movl oESI(%eax), %edx
- movl oEBP(%eax), %esi
- movl oEBX(%eax), %edi
- movl %ebx, (%ecx)
- movl %edx, 4(%ecx)
- movl %esi, 8(%ecx)
- movl %edi, 16(%ecx)
- movl oEDX(%eax), %ebx
- movl oECX(%eax), %edx
- movl oEAX(%eax), %esi
- movl oEIP(%eax), %edi
- movl %ebx, 20(%ecx)
- movl %edx, 24(%ecx)
- movl %esi, 28(%ecx)
- movl %edi, 32(%ecx)
-
- /* Set the new stack address. The stack points now to the block
- we put the register content in. */
- movl %ecx, %esp
- /* Restore the register content. */
- popa
- /* The following 'ret' will pop the addres of the code and jump
+ movl oESP(%eax), %esp
+
+ /* Push the return address on the new stack so we can return there. */
+ pushl %ecx
+
+ /* Load the values of all the 32-bit registers (except ESP).
+ Since we are loading from EAX, it must be last. */
+ movl oEDI(%eax), %edi
+ movl oESI(%eax), %esi
+ movl oEBP(%eax), %ebp
+ movl oEBX(%eax), %ebx
+ movl oEDX(%eax), %edx
+ movl oECX(%eax), %ecx
+ movl oEAX(%eax), %eax
+
+ /* The following 'ret' will pop the address of the code and jump
to it. */
L(pseudo_end):