about summary refs log tree commit diff
path: root/sysdeps/unix/sysv/linux/i386/swapcontext.S
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/linux/i386/swapcontext.S
parentb87507117c2424239f69ca7e3c5e6c2a52328839 (diff)
downloadglibc-77f844138c60d34df49205db10e85b5cdbf0bf0b.tar.gz
glibc-77f844138c60d34df49205db10e85b5cdbf0bf0b.tar.xz
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/linux/i386/swapcontext.S')
-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):