From: Rémi Bernon rbernon@codeweavers.com
--- dlls/ntdll/unix/signal_i386.c | 14 ++++++++++++++ dlls/ntdll/unix/signal_x86_64.c | 14 ++++++++++++++ tools/winebuild/import.c | 1 + 3 files changed, 29 insertions(+)
diff --git a/dlls/ntdll/unix/signal_i386.c b/dlls/ntdll/unix/signal_i386.c index 36a8c630f11..b63999f23a0 100644 --- a/dlls/ntdll/unix/signal_i386.c +++ b/dlls/ntdll/unix/signal_i386.c @@ -2608,6 +2608,8 @@ __ASM_GLOBAL_FUNC( __wine_syscall_dispatcher, "testl $0x80000000,%eax\n\t" "jz .L__wine_syscall_dispatcher_save_fpu\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" "jmp .L__wine_syscall_dispatcher_fpu_saved\n\t"
"\n.L__wine_syscall_dispatcher_save_fpu:\n\t" @@ -2664,6 +2666,18 @@ __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 cb12793466e..b4980f58f35 100644 --- a/dlls/ntdll/unix/signal_x86_64.c +++ b/dlls/ntdll/unix/signal_x86_64.c @@ -2714,6 +2714,8 @@ __ASM_GLOBAL_FUNC( __wine_syscall_dispatcher, "fxsave64 0xc0(%rcx)\n\t"
"\n.L__wine_syscall_dispatcher_fpu_saved:\n\t" + /* remember state when $rcx is pointing to "frame" */ + __ASM_CFI(".cfi_remember_state\n\t") /* remember state when $rcx is pointing to "frame" */ __ASM_CFI(".cfi_remember_state\n\t") "leaq 0x98(%rcx),%rbp\n\t" @@ -2747,6 +2749,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 */ @@ -2773,6 +2777,16 @@ __ASM_GLOBAL_FUNC( __wine_syscall_dispatcher, "leaq -0x98(%rbp),%rcx\n\t" /* $rcx is now pointing to "frame" again */ __ASM_CFI(".cfi_restore_state\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" "movl 0x94(%rcx),%edx\n\t" /* frame->restore_flags */ 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) );