Optimize i386 syscall inlining for GCC 5
commit98ad631cd0a77205734abf4f2bb368a8560a08cf
authorH.J. Lu <hjl.tools@gmail.com>
Thu, 15 Oct 2015 12:23:42 +0000 (15 05:23 -0700)
committerH.J. Lu <hjl.tools@gmail.com>
Thu, 15 Oct 2015 12:23:58 +0000 (15 05:23 -0700)
tree0c1c77ca47f7db8df6bf81395ad0d3d5ad91f82f
parent83c01ab32b9aa7b27e4e88ed2969d14549e33c5c
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.
ChangeLog
sysdeps/unix/sysv/linux/i386/libc-do-syscall.S
sysdeps/unix/sysv/linux/i386/sysdep.h