about summary refs log tree commit diff
diff options
context:
space:
mode:
authorRichard Henderson <rth@redhat.com>2014-05-25 14:57:53 -0400
committerRichard Henderson <rth@redhat.com>2014-05-29 12:37:24 -0400
commitb5be4597716eff94149f5529c8eb2cd3b4296188 (patch)
tree70bacc7639c71fea51ace01baee640ce3fd6e8df
parent645d44abe3ca6253a9d4762f092e4a1b9d294b11 (diff)
downloadglibc-b5be4597716eff94149f5529c8eb2cd3b4296188.tar.gz
glibc-b5be4597716eff94149f5529c8eb2cd3b4296188.tar.xz
glibc-b5be4597716eff94149f5529c8eb2cd3b4296188.zip
aarch64: Improve syscall-cancel stack frame
One push instead of N; use stp/ldp to halve the insns.
-rw-r--r--ChangeLog10
-rw-r--r--sysdeps/unix/sysv/linux/aarch64/nptl/sysdep-cancel.h112
2 files changed, 36 insertions, 86 deletions
diff --git a/ChangeLog b/ChangeLog
index 3a20a6520d..26812de5f1 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,15 @@
 2014-05-29  Richard Henderson  <rth@twiddle.net>
 
+	* sysdeps/unix/sysv/linux/aarch64/nptl/sysdep-cancel.h (PSEUDO):
+	Always allocate 64 bytes of stack frame.  Use ldp/stp to create
+	it and break it down.
+	(DOCARGS_0, DOCARGS_1): Do nothing.
+	(DOCARGS_2): Update to store into the new stack frame.
+	(DOCARGS_3, DOCARGS_4, DOCARGS_5, DOCARGS_6): Likewise.
+	(UNDOCARGS_1): Update to restore from the new stack frame.
+	(UNDOCARGS_2, UNDOCARGS_3, UNDOCARGS_4): Likewise.
+	(UNDOCARGS_5, UNDOCARGS_6): Likewise.
+
 	* sysdeps/unix/sysv/linux/aarch64/nptl/sysdep-cancel.h
 	(SINGLE_THREAD_P): New parameter for result regno.
 	(PSEUDO): Update to match; use cbz instead of beq.
diff --git a/sysdeps/unix/sysv/linux/aarch64/nptl/sysdep-cancel.h b/sysdeps/unix/sysv/linux/aarch64/nptl/sysdep-cancel.h
index bdb5c73780..0f5bb514e3 100644
--- a/sysdeps/unix/sysv/linux/aarch64/nptl/sysdep-cancel.h
+++ b/sysdeps/unix/sysv/linux/aarch64/nptl/sysdep-cancel.h
@@ -38,20 +38,22 @@ ENTRY (__##syscall_name##_nocancel);					\
 ENTRY (name);								\
 	SINGLE_THREAD_P(16);						\
 	cbz	w16, .Lpseudo_nocancel;					\
-	DOCARGS_##args;	/* save syscall args etc. around CENABLE.  */	\
+	/* Setup common stack frame no matter the number of args.	\
+	   Also save the first arg, since it's basically free.  */	\
+	stp	x30, x0, [sp, -64]!;					\
+	cfi_adjust_cfa_offset (64);					\
+	cfi_rel_offset (x30, 0);					\
+	DOCARGS_##args;		/* save syscall args around CENABLE.  */ \
 	CENABLE;							\
-	mov	x16, x0;	/* put mask in safe place.  */		\
+	mov	x16, x0;	/* save mask around syscall.  */	\
 	UNDOCARGS_##args;	/* restore syscall args.  */		\
-	mov	x8, SYS_ify (syscall_name);	/* do the call.  */	\
-	svc	0;							\
-	str	x0, [sp, -16]!;	/* save syscall return value.  */	\
-	cfi_adjust_cfa_offset (16);					\
-	mov	x0, x16;	 /* get mask back.  */			\
+	DO_CALL (syscall_name, args);					\
+	str	x0, [sp, 8];	/* save result around CDISABLE.  */	\
+	mov	x0, x16;	/* restore mask for CDISABLE.  */	\
 	CDISABLE;							\
-	ldr	x0, [sp], 16;						\
-	cfi_adjust_cfa_offset (-16);					\
-	ldr	x30, [sp], 16;						\
-	cfi_adjust_cfa_offset (-16);					\
+	/* Break down the stack frame, restoring result at once.  */	\
+	ldp	x30, x0, [sp], 64;					\
+	cfi_adjust_cfa_offset (-64);					\
 	cfi_restore (x30);						\
 	b	.Lpseudo_finish;					\
 	cfi_endproc;							\
@@ -63,83 +65,21 @@ ENTRY (name);								\
 	SYSCALL_ERROR_HANDLER;						\
 	cfi_endproc
 
-# define DOCARGS_0							\
-	str x30, [sp, -16]!;						\
-	cfi_adjust_cfa_offset (16);					\
-	cfi_rel_offset (x30, 0)
+# define DOCARGS_0
+# define DOCARGS_1
+# define DOCARGS_2	str x1, [sp, 16]
+# define DOCARGS_3	stp x1, x2, [sp, 16]
+# define DOCARGS_4	DOCARGS_3; str x3, [sp, 32]
+# define DOCARGS_5	DOCARGS_3; stp x3, x4, [sp, 32]
+# define DOCARGS_6	DOCARGS_5; str x5, [sp, 48]
 
 # define UNDOCARGS_0
-
-# define DOCARGS_1							\
-	DOCARGS_0;							\
-	str x0, [sp, -16]!;						\
-	cfi_adjust_cfa_offset (16);					\
-	cfi_rel_offset (x0, 0)
-
-# define UNDOCARGS_1							\
-	ldr x0, [sp], 16;						\
-	cfi_restore (x0);						\
-	cfi_adjust_cfa_offset (-16);					\
-
-# define DOCARGS_2							\
-	DOCARGS_1;							\
-	str x1, [sp, -16]!;						\
-	cfi_adjust_cfa_offset (16);					\
-	cfi_rel_offset (x1, 0)
-
-# define UNDOCARGS_2							\
-	ldr x1, [sp], 16;						\
-	cfi_restore (x1);						\
-	cfi_adjust_cfa_offset (-16);					\
-	UNDOCARGS_1
-
-# define DOCARGS_3							\
-	DOCARGS_2;							\
-	str x2, [sp, -16]!;						\
-	cfi_adjust_cfa_offset (16);					\
-	cfi_rel_offset (x2, 0)
-
-# define UNDOCARGS_3							\
-	ldr x2, [sp], 16;						\
-	cfi_restore (x2);						\
-	cfi_adjust_cfa_offset (-16);					\
-	UNDOCARGS_2
-
-# define DOCARGS_4							\
-	DOCARGS_3;							\
-	str x3, [sp, -16]!;						\
-	cfi_adjust_cfa_offset (16);					\
-	cfi_rel_offset (x3, 0)
-
-# define UNDOCARGS_4							\
-	ldr x3, [sp], 16;						\
-	cfi_restore (x3);						\
-	cfi_adjust_cfa_offset (-16);					\
-	UNDOCARGS_3
-
-# define DOCARGS_5							\
-	DOCARGS_4;							\
-	str x4, [sp, -16]!;						\
-	cfi_adjust_cfa_offset (16);					\
-	cfi_rel_offset (x4, 0)
-
-# define UNDOCARGS_5							\
-	ldr x4, [sp], 16;						\
-	cfi_restore (x4);						\
-	cfi_adjust_cfa_offset (-16);					\
-	UNDOCARGS_4
-
-# define DOCARGS_6							\
-	DOCARGS_5;							\
-	str x5, [sp, -16]!;						\
-	cfi_adjust_cfa_offset (16);					\
-	cfi_rel_offset (x5, 0)
-
-# define UNDOCARGS_6							\
-	ldr x5, [sp], 16;						\
-	cfi_restore (x5);						\
-	cfi_adjust_cfa_offset (-16);					\
-	UNDOCARGS_5
+# define UNDOCARGS_1	ldr x0, [sp, 8]
+# define UNDOCARGS_2	ldp x0, x1, [sp, 8]
+# define UNDOCARGS_3	UNDOCARGS_1; ldp x1, x2, [sp, 16]
+# define UNDOCARGS_4	UNDOCARGS_2; ldp x2, x3, [sp, 24]
+# define UNDOCARGS_5	UNDOCARGS_3; ldp x3, x4, [sp, 32]
+# define UNDOCARGS_6	UNDOCARGS_4; ldp x4, x5, [sp, 40]
 
 # ifdef IS_IN_libpthread
 #  define CENABLE	bl __pthread_enable_asynccancel