From a1e553aa807809b01ae19d05a20376cd47b42fbd Mon Sep 17 00:00:00 2001 From: Alexandre Julliard Date: Thu, 2 May 2024 09:25:01 +0200 Subject: [PATCH] vcomp: Move the fork wrapper to a separate file. And build it as x86-64 code on ARM64EC. --- dlls/vcomp/Makefile.in | 1 + dlls/vcomp/fork.c | 173 ++++++++++++++++++++++++++++++++++++++ dlls/vcomp/main.c | 158 +--------------------------------- dlls/vcomp100/Makefile.in | 1 + dlls/vcomp110/Makefile.in | 1 + dlls/vcomp120/Makefile.in | 1 + dlls/vcomp140/Makefile.in | 1 + 7 files changed, 180 insertions(+), 156 deletions(-) create mode 100644 dlls/vcomp/fork.c diff --git a/dlls/vcomp/Makefile.in b/dlls/vcomp/Makefile.in index e2c199d4938..ec1f82cc33b 100644 --- a/dlls/vcomp/Makefile.in +++ b/dlls/vcomp/Makefile.in @@ -1,4 +1,5 @@ MODULE = vcomp.dll SOURCES = \ + fork.c \ main.c diff --git a/dlls/vcomp/fork.c b/dlls/vcomp/fork.c new file mode 100644 index 00000000000..7ec9f394c14 --- /dev/null +++ b/dlls/vcomp/fork.c @@ -0,0 +1,173 @@ +/* + * vcomp fork implementation + * + * Copyright 2012 Dan Kegel + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#if 0 +#pragma makedep arm64ec_x64 +#endif + +#include + +#include "windef.h" +#include "wine/asm.h" + +#ifdef __i386__ + +__ASM_GLOBAL_FUNC( _vcomp_fork_call_wrapper, + "pushl %ebp\n\t" + __ASM_CFI(".cfi_adjust_cfa_offset 4\n\t") + __ASM_CFI(".cfi_rel_offset %ebp,0\n\t") + "movl %esp,%ebp\n\t" + __ASM_CFI(".cfi_def_cfa_register %ebp\n\t") + "pushl %esi\n\t" + __ASM_CFI(".cfi_rel_offset %esi,-4\n\t") + "pushl %edi\n\t" + __ASM_CFI(".cfi_rel_offset %edi,-8\n\t") + "movl 12(%ebp),%edx\n\t" + "movl %esp,%edi\n\t" + "shll $2,%edx\n\t" + "jz 1f\n\t" + "subl %edx,%edi\n\t" + "andl $~15,%edi\n\t" + "movl %edi,%esp\n\t" + "movl 12(%ebp),%ecx\n\t" + "movl 16(%ebp),%esi\n\t" + "cld\n\t" + "rep; movsl\n" + "1:\tcall *8(%ebp)\n\t" + "leal -8(%ebp),%esp\n\t" + "popl %edi\n\t" + __ASM_CFI(".cfi_same_value %edi\n\t") + "popl %esi\n\t" + __ASM_CFI(".cfi_same_value %esi\n\t") + "popl %ebp\n\t" + __ASM_CFI(".cfi_def_cfa %esp,4\n\t") + __ASM_CFI(".cfi_same_value %ebp\n\t") + "ret" ) + +#elif defined __x86_64__ + +__ASM_GLOBAL_FUNC( _vcomp_fork_call_wrapper, + "pushq %rbp\n\t" + __ASM_SEH(".seh_pushreg %rbp\n\t") + __ASM_CFI(".cfi_adjust_cfa_offset 8\n\t") + __ASM_CFI(".cfi_rel_offset %rbp,0\n\t") + "movq %rsp,%rbp\n\t" + __ASM_SEH(".seh_setframe %rbp,0\n\t") + __ASM_CFI(".cfi_def_cfa_register %rbp\n\t") + "pushq %rsi\n\t" + __ASM_SEH(".seh_pushreg %rsi\n\t") + __ASM_CFI(".cfi_rel_offset %rsi,-8\n\t") + "pushq %rdi\n\t" + __ASM_SEH(".seh_pushreg %rdi\n\t") + __ASM_SEH(".seh_endprologue\n\t") + __ASM_CFI(".cfi_rel_offset %rdi,-16\n\t") + "movq %rcx,%rax\n\t" + "movq $4,%rcx\n\t" + "cmp %rcx,%rdx\n\t" + "cmovgq %rdx,%rcx\n\t" + "leaq 0(,%rcx,8),%rdx\n\t" + "subq %rdx,%rsp\n\t" + "andq $~15,%rsp\n\t" + "movq %rsp,%rdi\n\t" + "movq %r8,%rsi\n\t" + "rep; movsq\n\t" + "movq 0(%rsp),%rcx\n\t" + "movq 8(%rsp),%rdx\n\t" + "movq 16(%rsp),%r8\n\t" + "movq 24(%rsp),%r9\n\t" + "callq *%rax\n\t" + "leaq -16(%rbp),%rsp\n\t" + "popq %rdi\n\t" + __ASM_CFI(".cfi_same_value %rdi\n\t") + "popq %rsi\n\t" + __ASM_CFI(".cfi_same_value %rsi\n\t") + __ASM_CFI(".cfi_def_cfa_register %rsp\n\t") + "popq %rbp\n\t" + __ASM_CFI(".cfi_adjust_cfa_offset -8\n\t") + __ASM_CFI(".cfi_same_value %rbp\n\t") + "ret" ) + +#elif defined __arm__ + +__ASM_GLOBAL_FUNC( _vcomp_fork_call_wrapper, + "push {r4, r5, LR}\n\t" + "mov r4, r0\n\t" + "mov r5, SP\n\t" + "lsl r3, r1, #2\n\t" + "cmp r3, #0\n\t" + "beq 5f\n\t" + "sub SP, SP, r3\n\t" + "tst r1, #1\n\t" + "it eq\n\t" + "subeq SP, SP, #4\n\t" + "1:\tsub r3, r3, #4\n\t" + "ldr r0, [r2, r3]\n\t" + "str r0, [SP, r3]\n\t" + "cmp r3, #0\n\t" + "bgt 1b\n\t" + "cmp r1, #1\n\t" + "bgt 2f\n\t" + "pop {r0}\n\t" + "b 5f\n\t" + "2:\tcmp r1, #2\n\t" + "bgt 3f\n\t" + "pop {r0-r1}\n\t" + "b 5f\n\t" + "3:\tcmp r1, #3\n\t" + "bgt 4f\n\t" + "pop {r0-r2}\n\t" + "b 5f\n\t" + "4:\tpop {r0-r3}\n\t" + "5:\tblx r4\n\t" + "mov SP, r5\n\t" + "pop {r4, r5, PC}" ) + +#elif defined __aarch64__ + +__ASM_GLOBAL_FUNC( _vcomp_fork_call_wrapper, + "stp x29, x30, [SP,#-16]!\n\t" + ".seh_save_fplr_x 16\n\t" + "mov x29, SP\n\t" + ".seh_set_fp\n\t" + ".seh_endprologue\n\t" + "mov x9, x0\n\t" + "cbz w1, 4f\n\t" + "lsl w8, w1, #3\n\t" + "cmp w8, #64\n\t" + "b.ge 1f\n\t" + "mov w8, #64\n" + "1:\ttbz w8, #3, 2f\n\t" + "add w8, w8, #8\n" + "2:\tsub x10, x29, x8\n\t" + "mov sp, x10\n" + "3:\tldr x0, [x2], #8\n\t" + "str x0, [x10], #8\n\t" + "subs w1, w1, #1\n\t" + "b.ne 3b\n\t" + "ldp x0, x1, [sp], #16\n\t" + "ldp x2, x3, [sp], #16\n\t" + "ldp x4, x5, [sp], #16\n\t" + "ldp x6, x7, [sp], #16\n" + "4:\tblr x9\n\t" + "mov SP, x29\n\t" + "ldp x29, x30, [SP], #16\n\t" + "ret" ) + +#endif diff --git a/dlls/vcomp/main.c b/dlls/vcomp/main.c index 91afea33112..451e47e9f9e 100644 --- a/dlls/vcomp/main.c +++ b/dlls/vcomp/main.c @@ -120,6 +120,8 @@ struct vcomp_task_data unsigned int dynamic_chunksize; }; +extern void CDECL _vcomp_fork_call_wrapper(void *wrapper, int nargs, void **args); + static void **ptr_from_va_list(va_list valist) { return *(void ***)&valist; @@ -133,162 +135,6 @@ static void copy_va_list_data(void **args, va_list valist, int args_count) args[i] = va_arg(valist, void *); } -#if defined(__i386__) - -extern void CDECL _vcomp_fork_call_wrapper(void *wrapper, int nargs, void **args); -__ASM_GLOBAL_FUNC( _vcomp_fork_call_wrapper, - "pushl %ebp\n\t" - __ASM_CFI(".cfi_adjust_cfa_offset 4\n\t") - __ASM_CFI(".cfi_rel_offset %ebp,0\n\t") - "movl %esp,%ebp\n\t" - __ASM_CFI(".cfi_def_cfa_register %ebp\n\t") - "pushl %esi\n\t" - __ASM_CFI(".cfi_rel_offset %esi,-4\n\t") - "pushl %edi\n\t" - __ASM_CFI(".cfi_rel_offset %edi,-8\n\t") - "movl 12(%ebp),%edx\n\t" - "movl %esp,%edi\n\t" - "shll $2,%edx\n\t" - "jz 1f\n\t" - "subl %edx,%edi\n\t" - "andl $~15,%edi\n\t" - "movl %edi,%esp\n\t" - "movl 12(%ebp),%ecx\n\t" - "movl 16(%ebp),%esi\n\t" - "cld\n\t" - "rep; movsl\n" - "1:\tcall *8(%ebp)\n\t" - "leal -8(%ebp),%esp\n\t" - "popl %edi\n\t" - __ASM_CFI(".cfi_same_value %edi\n\t") - "popl %esi\n\t" - __ASM_CFI(".cfi_same_value %esi\n\t") - "popl %ebp\n\t" - __ASM_CFI(".cfi_def_cfa %esp,4\n\t") - __ASM_CFI(".cfi_same_value %ebp\n\t") - "ret" ) - -#elif defined(__x86_64__) - -extern void CDECL _vcomp_fork_call_wrapper(void *wrapper, int nargs, void **args); -__ASM_GLOBAL_FUNC( _vcomp_fork_call_wrapper, - "pushq %rbp\n\t" - __ASM_SEH(".seh_pushreg %rbp\n\t") - __ASM_CFI(".cfi_adjust_cfa_offset 8\n\t") - __ASM_CFI(".cfi_rel_offset %rbp,0\n\t") - "movq %rsp,%rbp\n\t" - __ASM_SEH(".seh_setframe %rbp,0\n\t") - __ASM_CFI(".cfi_def_cfa_register %rbp\n\t") - "pushq %rsi\n\t" - __ASM_SEH(".seh_pushreg %rsi\n\t") - __ASM_CFI(".cfi_rel_offset %rsi,-8\n\t") - "pushq %rdi\n\t" - __ASM_SEH(".seh_pushreg %rdi\n\t") - __ASM_SEH(".seh_endprologue\n\t") - __ASM_CFI(".cfi_rel_offset %rdi,-16\n\t") - "movq %rcx,%rax\n\t" - "movq $4,%rcx\n\t" - "cmp %rcx,%rdx\n\t" - "cmovgq %rdx,%rcx\n\t" - "leaq 0(,%rcx,8),%rdx\n\t" - "subq %rdx,%rsp\n\t" - "andq $~15,%rsp\n\t" - "movq %rsp,%rdi\n\t" - "movq %r8,%rsi\n\t" - "rep; movsq\n\t" - "movq 0(%rsp),%rcx\n\t" - "movq 8(%rsp),%rdx\n\t" - "movq 16(%rsp),%r8\n\t" - "movq 24(%rsp),%r9\n\t" - "callq *%rax\n\t" - "leaq -16(%rbp),%rsp\n\t" - "popq %rdi\n\t" - __ASM_CFI(".cfi_same_value %rdi\n\t") - "popq %rsi\n\t" - __ASM_CFI(".cfi_same_value %rsi\n\t") - __ASM_CFI(".cfi_def_cfa_register %rsp\n\t") - "popq %rbp\n\t" - __ASM_CFI(".cfi_adjust_cfa_offset -8\n\t") - __ASM_CFI(".cfi_same_value %rbp\n\t") - "ret") - -#elif defined(__arm__) - -extern void CDECL _vcomp_fork_call_wrapper(void *wrapper, int nargs, void **args); -__ASM_GLOBAL_FUNC( _vcomp_fork_call_wrapper, - "push {r4, r5, LR}\n\t" - "mov r4, r0\n\t" - "mov r5, SP\n\t" - "lsl r3, r1, #2\n\t" - "cmp r3, #0\n\t" - "beq 5f\n\t" - "sub SP, SP, r3\n\t" - "tst r1, #1\n\t" - "it eq\n\t" - "subeq SP, SP, #4\n\t" - "1:\tsub r3, r3, #4\n\t" - "ldr r0, [r2, r3]\n\t" - "str r0, [SP, r3]\n\t" - "cmp r3, #0\n\t" - "bgt 1b\n\t" - "cmp r1, #1\n\t" - "bgt 2f\n\t" - "pop {r0}\n\t" - "b 5f\n\t" - "2:\tcmp r1, #2\n\t" - "bgt 3f\n\t" - "pop {r0-r1}\n\t" - "b 5f\n\t" - "3:\tcmp r1, #3\n\t" - "bgt 4f\n\t" - "pop {r0-r2}\n\t" - "b 5f\n\t" - "4:\tpop {r0-r3}\n\t" - "5:\tblx r4\n\t" - "mov SP, r5\n\t" - "pop {r4, r5, PC}" ) - -#elif defined(__aarch64__) - -extern void CDECL _vcomp_fork_call_wrapper(void *wrapper, int nargs, void **args); -__ASM_GLOBAL_FUNC( _vcomp_fork_call_wrapper, - "stp x29, x30, [SP,#-16]!\n\t" - __ASM_SEH(".seh_save_fplr_x 16\n\t") - "mov x29, SP\n\t" - __ASM_SEH(".seh_set_fp\n\t") - __ASM_SEH(".seh_endprologue\n\t") - "mov x9, x0\n\t" - "cbz w1, 4f\n\t" - "lsl w8, w1, #3\n\t" - "cmp w8, #64\n\t" - "b.ge 1f\n\t" - "mov w8, #64\n" - "1:\ttbz w8, #3, 2f\n\t" - "add w8, w8, #8\n" - "2:\tsub x10, x29, x8\n\t" - "mov sp, x10\n" - "3:\tldr x0, [x2], #8\n\t" - "str x0, [x10], #8\n\t" - "subs w1, w1, #1\n\t" - "b.ne 3b\n\t" - "ldp x0, x1, [sp], #16\n\t" - "ldp x2, x3, [sp], #16\n\t" - "ldp x4, x5, [sp], #16\n\t" - "ldp x6, x7, [sp], #16\n" - "4:\tblr x9\n\t" - "mov SP, x29\n\t" - "ldp x29, x30, [SP], #16\n\t" - "ret\n" ) - -#else - -static void CDECL _vcomp_fork_call_wrapper(void *wrapper, int nargs, void **args) -{ - ERR("Not implemented for this architecture\n"); -} - -#endif - #if defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__)) static inline char interlocked_cmpxchg8(char *dest, char xchg, char compare) diff --git a/dlls/vcomp100/Makefile.in b/dlls/vcomp100/Makefile.in index 1c07bd69c4c..03a5f19e0a6 100644 --- a/dlls/vcomp100/Makefile.in +++ b/dlls/vcomp100/Makefile.in @@ -2,4 +2,5 @@ MODULE = vcomp100.dll PARENTSRC = ../vcomp SOURCES = \ + fork.c \ main.c diff --git a/dlls/vcomp110/Makefile.in b/dlls/vcomp110/Makefile.in index 120c15cd0a6..71f6d5e082c 100644 --- a/dlls/vcomp110/Makefile.in +++ b/dlls/vcomp110/Makefile.in @@ -2,4 +2,5 @@ MODULE = vcomp110.dll PARENTSRC = ../vcomp SOURCES = \ + fork.c \ main.c diff --git a/dlls/vcomp120/Makefile.in b/dlls/vcomp120/Makefile.in index cf2541d047d..f9858b24a2e 100644 --- a/dlls/vcomp120/Makefile.in +++ b/dlls/vcomp120/Makefile.in @@ -2,4 +2,5 @@ MODULE = vcomp120.dll PARENTSRC = ../vcomp SOURCES = \ + fork.c \ main.c diff --git a/dlls/vcomp140/Makefile.in b/dlls/vcomp140/Makefile.in index 3869c0c567d..19d33d71908 100644 --- a/dlls/vcomp140/Makefile.in +++ b/dlls/vcomp140/Makefile.in @@ -2,4 +2,5 @@ MODULE = vcomp140.dll PARENTSRC = ../vcomp SOURCES = \ + fork.c \ main.c