summary refs log tree commit diff
path: root/ChangeLog
diff options
context:
space:
mode:
authorH.J. Lu <hjl.tools@gmail.com>2015-10-15 05:23:42 -0700
committerH.J. Lu <hjl.tools@gmail.com>2015-10-15 05:23:58 -0700
commit98ad631cd0a77205734abf4f2bb368a8560a08cf (patch)
tree0c1c77ca47f7db8df6bf81395ad0d3d5ad91f82f /ChangeLog
parent83c01ab32b9aa7b27e4e88ed2969d14549e33c5c (diff)
downloadglibc-98ad631cd0a77205734abf4f2bb368a8560a08cf.tar.gz
glibc-98ad631cd0a77205734abf4f2bb368a8560a08cf.tar.xz
glibc-98ad631cd0a77205734abf4f2bb368a8560a08cf.zip
Optimize i386 syscall inlining for GCC 5
Since GCC 5 and above can properly spill %ebx when needed, we can inline
syscalls with 6 arguments if GCC 5 or above is used to compile glibc.
This patch rewrites INTERNAL_SYSCALL macros and skips __libc_do_syscall
for GCC 5.

For sysdeps/unix/sysv/linux/i386/brk.c, with -O2 -march=i686
-mtune=generic, GCC 5.2 now generates:

<__brk>:
   0:	push   %ebx
   1:	mov    $0x2d,%eax
   6:	mov    0x8(%esp),%ebx
   a:	call   b <__brk+0xb>	b: R_386_PC32	__x86.get_pc_thunk.dx
   f:	add    $0x2,%edx	11: R_386_GOTPC	_GLOBAL_OFFSET_TABLE_
  15:	call   *%gs:0x10
  1c:	mov    0x0(%edx),%edx	1e: R_386_GOT32	__curbrk
  22:	cmp    %eax,%ebx
  24:	mov    %eax,(%edx)
  26:	ja     30 <__brk+0x30>
  28:	xor    %eax,%eax
  2a:	pop    %ebx
  2b:	ret

instead of

<__brk>:
   0:	push   %ebx
   1:	mov    0x8(%esp),%ecx
   5:	call   6 <__brk+0x6>	6: R_386_PC32	__x86.get_pc_thunk.bx
   a:	add    $0x2,%ebx	c: R_386_GOTPC	_GLOBAL_OFFSET_TABLE_
  10:	xchg   %ecx,%ebx
  12:	mov    $0x2d,%eax
  17:	call   *%gs:0x10
  1e:	xchg   %ecx,%ebx
  20:	mov    %eax,%edx
  22:	mov    0x0(%ebx),%eax	24: R_386_GOT32	__curbrk
  28:	mov    %edx,(%eax)
  2a:	xor    %eax,%eax
  2c:	cmp    %edx,%ecx
  2e:	ja     38 <__brk+0x38>
  30:	pop    %ebx
  31:	ret

The new one is shorter by 2 instructions.

	* sysdeps/unix/sysv/linux/i386/libc-do-syscall.S
	(__libc_do_syscall): Defined only if !__GNUC_PREREQ (5,0).
	* sysdeps/unix/sysv/linux/i386/sysdep.h: Define assembler macros
	only if !__GNUC_PREREQ (5,0).
	(INTERNAL_SYSCALL_MAIN_6): Optimize for GCC 5.
	(INTERNAL_SYSCALL_MAIN_INLINE): Likewise.
	(INTERNAL_SYSCALL_NCS): Likewise.
	(LOADREGS_0): New macro for GCC 5.
	(ASMARGS_0): Likewise.
	(LOADREGS_1): Likewise.
	(ASMARGS_1): Likewise.
	(LOADREGS_2): Likewise.
	(ASMARGS_2): Likewise.
	(LOADREGS_3): Likewise.
	(ASMARGS_3): Likewise.
	(LOADREGS_4): Likewise.
	(ASMARGS_4): Likewise.
	(LOADREGS_5): Likewise.
	(ASMARGS_5): Likewise.
	(LOADREGS_6): Likewise.
	(ASMARGS_6): Likewise.
Diffstat (limited to 'ChangeLog')
-rw-r--r--ChangeLog24
1 files changed, 24 insertions, 0 deletions
diff --git a/ChangeLog b/ChangeLog
index ab795fe0dd..f220857b06 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,29 @@
 2015-10-15  H.J. Lu  <hongjiu.lu@intel.com>
 
+	* sysdeps/unix/sysv/linux/i386/libc-do-syscall.S
+	(__libc_do_syscall): Defined only if !__GNUC_PREREQ (5,0).
+	* sysdeps/unix/sysv/linux/i386/sysdep.h: Define assembler macros
+	only if !__GNUC_PREREQ (5,0).
+	(INTERNAL_SYSCALL_MAIN_6): Optimize for GCC 5.
+	(INTERNAL_SYSCALL_MAIN_INLINE): Likewise.
+	(INTERNAL_SYSCALL_NCS): Likewise.
+	(LOADREGS_0): New macro for GCC 5.
+	(ASMARGS_0): Likewise.
+	(LOADREGS_1): Likewise.
+	(ASMARGS_1): Likewise.
+	(LOADREGS_2): Likewise.
+	(ASMARGS_2): Likewise.
+	(LOADREGS_3): Likewise.
+	(ASMARGS_3): Likewise.
+	(LOADREGS_4): Likewise.
+	(ASMARGS_4): Likewise.
+	(LOADREGS_5): Likewise.
+	(ASMARGS_5): Likewise.
+	(LOADREGS_6): Likewise.
+	(ASMARGS_6): Likewise.
+
+2015-10-15  H.J. Lu  <hongjiu.lu@intel.com>
+
 	* sysdeps/unix/sysv/linux/i386/Makefile (CFLAGS-mmap.c): Add
 	-fomit-frame-pointer.
 	(CFLAGS-mmap64.c): Likewise.