446cf2
commit 15eab1e3e89129ab3ed03f5bdc3415b26e9caeb9
446cf2
Author: H.J. Lu <hjl.tools@gmail.com>
446cf2
Date:   Sat Feb 1 05:44:55 2020 -0800
446cf2
446cf2
    i386: Don't unnecessarily save and restore EAX, ECX and EDX [BZ# 25262]
446cf2
    
446cf2
    On i386, since EAX, ECX and EDX are caller-saved, there are no need
446cf2
    to save and restore EAX, ECX and EDX in getcontext, setcontext and
446cf2
    swapcontext.  They just need to clear EAX on success.  The extra
446cf2
    scratch registers are needed to enable CET.
446cf2
    
446cf2
    Tested on i386.
446cf2
    
446cf2
    Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
446cf2
---
446cf2
446cf2
diff --git a/sysdeps/unix/sysv/linux/i386/getcontext.S b/sysdeps/unix/sysv/linux/i386/getcontext.S
446cf2
index 26ca08a..6637596 100644
446cf2
--- a/sysdeps/unix/sysv/linux/i386/getcontext.S
446cf2
+++ b/sysdeps/unix/sysv/linux/i386/getcontext.S
446cf2
@@ -26,13 +26,7 @@ ENTRY(__getcontext)
446cf2
 	/* Load address of the context data structure.  */
446cf2
 	movl	4(%esp), %eax
446cf2
 
446cf2
-	/* Return value of getcontext.  EAX is the only register whose
446cf2
-	   value is not preserved.  */
446cf2
-	movl	$0, oEAX(%eax)
446cf2
-
446cf2
-	/* Save the 32-bit register values and the return address.  */
446cf2
-	movl	%ecx, oECX(%eax)
446cf2
-	movl	%edx, oEDX(%eax)
446cf2
+	/* Save the preserved register values and the return address.  */
446cf2
 	movl	%edi, oEDI(%eax)
446cf2
 	movl	%esi, oESI(%eax)
446cf2
 	movl	%ebp, oEBP(%eax)
446cf2
diff --git a/sysdeps/unix/sysv/linux/i386/setcontext.S b/sysdeps/unix/sysv/linux/i386/setcontext.S
446cf2
index a604fca..7565d7d 100644
446cf2
--- a/sysdeps/unix/sysv/linux/i386/setcontext.S
446cf2
+++ b/sysdeps/unix/sysv/linux/i386/setcontext.S
446cf2
@@ -65,22 +65,19 @@ ENTRY(__setcontext)
446cf2
 	cfi_offset (esi, oESI)
446cf2
 	cfi_offset (ebp, oEBP)
446cf2
 	cfi_offset (ebx, oEBX)
446cf2
-	cfi_offset (edx, oEDX)
446cf2
-	cfi_offset (ecx, oECX)
446cf2
 	movl	oESP(%eax), %esp
446cf2
 
446cf2
 	/* Push the return address on the new stack so we can return there.  */
446cf2
 	pushl	%ecx
446cf2
 
446cf2
-	/* Load the values of all the 32-bit registers (except ESP).
446cf2
-	   Since we are loading from EAX, it must be last.  */
446cf2
+	/* Load the values of all the preserved registers (except ESP).  */
446cf2
 	movl	oEDI(%eax), %edi
446cf2
 	movl	oESI(%eax), %esi
446cf2
 	movl	oEBP(%eax), %ebp
446cf2
 	movl	oEBX(%eax), %ebx
446cf2
-	movl	oEDX(%eax), %edx
446cf2
-	movl	oECX(%eax), %ecx
446cf2
-	movl	oEAX(%eax), %eax
446cf2
+
446cf2
+	/* All done, return 0 for success.  */
446cf2
+	xorl	%eax, %eax
446cf2
 
446cf2
 	/* End FDE here, we fall into another context.  */
446cf2
 	cfi_endproc
446cf2
diff --git a/sysdeps/unix/sysv/linux/i386/swapcontext.S b/sysdeps/unix/sysv/linux/i386/swapcontext.S
446cf2
index 431f22c..ce27d51 100644
446cf2
--- a/sysdeps/unix/sysv/linux/i386/swapcontext.S
446cf2
+++ b/sysdeps/unix/sysv/linux/i386/swapcontext.S
446cf2
@@ -26,13 +26,7 @@ ENTRY(__swapcontext)
446cf2
 	/* Load address of the context data structure we save in.  */
446cf2
 	movl	4(%esp), %eax
446cf2
 
446cf2
-	/* Return value of swapcontext.  EAX is the only register whose
446cf2
-	   value is not preserved.  */
446cf2
-	movl	$0, oEAX(%eax)
446cf2
-
446cf2
-	/* Save the 32-bit register values and the return address.  */
446cf2
-	movl	%ecx, oECX(%eax)
446cf2
-	movl	%edx, oEDX(%eax)
446cf2
+	/* Save the preserved register values and the return address.  */
446cf2
 	movl	%edi, oEDI(%eax)
446cf2
 	movl	%esi, oESI(%eax)
446cf2
 	movl	%ebp, oEBP(%eax)
446cf2
@@ -91,15 +85,14 @@ ENTRY(__swapcontext)
446cf2
 	/* Push the return address on the new stack so we can return there.  */
446cf2
 	pushl	%ecx
446cf2
 
446cf2
-	/* Load the values of all the 32-bit registers (except ESP).
446cf2
-	   Since we are loading from EAX, it must be last.  */
446cf2
+	/* Load the values of all the preserved registers (except ESP).  */
446cf2
 	movl	oEDI(%eax), %edi
446cf2
 	movl	oESI(%eax), %esi
446cf2
 	movl	oEBP(%eax), %ebp
446cf2
 	movl	oEBX(%eax), %ebx
446cf2
-	movl	oEDX(%eax), %edx
446cf2
-	movl	oECX(%eax), %ecx
446cf2
-	movl	oEAX(%eax), %eax
446cf2
+
446cf2
+	/* All done, return 0 for success.  */
446cf2
+	xorl	%eax, %eax
446cf2
 
446cf2
 	/* The following 'ret' will pop the address of the code and jump
446cf2
 	   to it.  */
446cf2
diff --git a/sysdeps/unix/sysv/linux/i386/ucontext_i.sym b/sysdeps/unix/sysv/linux/i386/ucontext_i.sym
446cf2
index b11a550..1dfe03d 100644
446cf2
--- a/sysdeps/unix/sysv/linux/i386/ucontext_i.sym
446cf2
+++ b/sysdeps/unix/sysv/linux/i386/ucontext_i.sym
446cf2
@@ -21,9 +21,6 @@ oESI		mreg (ESI)
446cf2
 oEBP		mreg (EBP)
446cf2
 oESP		mreg (ESP)
446cf2
 oEBX		mreg (EBX)
446cf2
-oEDX		mreg (EDX)
446cf2
-oECX		mreg (ECX)
446cf2
-oEAX		mreg (EAX)
446cf2
 oEIP		mreg (EIP)
446cf2
 oFPREGS		mcontext (fpregs)
446cf2
 oSIGMASK	ucontext (uc_sigmask)
446cf2