From: Rémi Bernon rbernon@codeweavers.com
--- dlls/ntdll/unix/signal_i386.c | 13 +++++++++++++ dlls/ntdll/unix/signal_x86_64.c | 9 +++++++++ tools/winebuild/import.c | 1 + 3 files changed, 23 insertions(+)
diff --git a/dlls/ntdll/unix/signal_i386.c b/dlls/ntdll/unix/signal_i386.c index 262a0b8072f..60bd27712d8 100644 --- a/dlls/ntdll/unix/signal_i386.c +++ b/dlls/ntdll/unix/signal_i386.c @@ -2656,6 +2656,8 @@ __ASM_GLOBAL_FUNC( __wine_syscall_dispatcher, "jmp .L__wine_syscall_dispatcher_fpu_saved\n\t" "\n.L__wine_syscall_dispatcher_nofpu_save:\n\t" "orl $0x10,(%ecx)\n\t" /* frame->syscall_flags |= SYSCALL_NEED_XSTATE */ + "testl $0x40000000,%eax\n\t" /* __wine_unix_call_fast */ + "jnz .L__wine_syscall_dispatcher_unix_call_fast\n\t" "\n.L__wine_syscall_dispatcher_fpu_saved:\n\t" "movl %ecx,%esp\n\t" "movl 0x1c(%esp),%edx\n\t" /* frame->eax */ @@ -2673,6 +2675,17 @@ __ASM_GLOBAL_FUNC( __wine_syscall_dispatcher, "rep; movsl\n\t" "call *(%eax,%edx,4)\n\t" "leal -0x34(%ebp),%esp\n\t" + "jmp .L__wine_syscall_dispatcher_restore\n\t" + "\n.L__wine_syscall_dispatcher_unix_call_fast:\n\t" + "movl %ecx,%esp\n\t" + "subl $4,%esp\n\t" + "andl $~15,%esp\n\t" + "movl 0xc(%esi),%eax\n\t" + "movl %eax,(%esp)\n\t" + "movl 0x8(%esi),%eax\n\t" + "movl (%esi),%edx\n\t" + "call *(%edx,%eax,4)\n\t" + "leal -0x34(%ebp),%esp\n" "\n.L__wine_syscall_dispatcher_restore:\n\t" "" __ASM_CFI_CFA_IS_AT1(esp, 0x0c) diff --git a/dlls/ntdll/unix/signal_x86_64.c b/dlls/ntdll/unix/signal_x86_64.c index d123e381882..775949092b6 100644 --- a/dlls/ntdll/unix/signal_x86_64.c +++ b/dlls/ntdll/unix/signal_x86_64.c @@ -2753,6 +2753,8 @@ __ASM_GLOBAL_FUNC( __wine_syscall_dispatcher, "movq %rcx,%rsp\n\t" "movq 0x00(%rcx),%rax\n\t" "movq 0x18(%rcx),%rdx\n\t" + "testl $0x40000000,%eax\n\t" /* __wine_unix_call_fast */ + "jnz .L__wine_syscall_dispatcher_unix_call_fast\n\t" "movl %eax,%ebx\n\t" "shrl $8,%ebx\n\t" "andl $0x30,%ebx\n\t" /* syscall table number */ @@ -2777,6 +2779,13 @@ __ASM_GLOBAL_FUNC( __wine_syscall_dispatcher, "movq (%rbx),%r10\n\t" /* table->ServiceTable */ "callq *(%r10,%rax,8)\n\t" "leaq -0x98(%rbp),%rcx\n\t" + "jmp .L__wine_syscall_dispatcher_restore\n" + "\n.L__wine_syscall_dispatcher_unix_call_fast:\n\t" + "movq %r8,%rdi\n\t" + "subq $0x20,%rsp\n\t" + "andq $~15,%rsp\n\t" + "callq *(%r10,%rdx,8)\n\t" + "leaq -0x98(%rbp),%rcx\n\t" /* $rcx is now pointing to "frame" again */ __ASM_CFI(".cfi_restore_state\n\t") "\n.L__wine_syscall_dispatcher_restore:\n\t" diff --git a/tools/winebuild/import.c b/tools/winebuild/import.c index 18ca6eaef01..b504834063b 100644 --- a/tools/winebuild/import.c +++ b/tools/winebuild/import.c @@ -1386,6 +1386,7 @@ void output_syscalls( DLLSPEC *spec ) const char *name = get_link_name(odp); unsigned int id = (spec->syscall_table << 12) + i; if (odp->flags & FLAG_NOFPU) id |= (1u << 31); + if (strstr( name, "__wine_unix_call_fast" )) id |= (1u << 30);
output( "\t.align %d\n", get_alignment(16) ); output( "\t%s\n", func_declaration(name) );