[PATCH 4/5] ntdll/tests: Use __ASM_GLOBAL_FUNC to define YMM function wrappers.

Zebediah Figura z.figura12 at gmail.com
Thu Jun 24 00:16:04 CDT 2021


Signed-off-by: Zebediah Figura <z.figura12 at gmail.com>
---
Now that we can use __ASM_GLOBAL_FUNC everywhere, let's stop manually writing
out binary code where we don't need to.

The bodies of the functions are changed since we're no longer embedding the
parameters directly in the assembly, but rather passing them.

 dlls/ntdll/tests/exception.c | 205 ++++++++++-------------------------
 1 file changed, 59 insertions(+), 146 deletions(-)

diff --git a/dlls/ntdll/tests/exception.c b/dlls/ntdll/tests/exception.c
index 065226057b8..4c1253b9b89 100644
--- a/dlls/ntdll/tests/exception.c
+++ b/dlls/ntdll/tests/exception.c
@@ -30,6 +30,7 @@
 #include "winternl.h"
 #include "ddk/wdm.h"
 #include "excpt.h"
+#include "wine/asm.h"
 #include "wine/test.h"
 #include "intrin.h"
 
@@ -7638,131 +7639,70 @@ done:
     return ExceptionContinueExecution;
 }
 
-struct call_func_offsets
-{
-    unsigned int func_addr;
-    unsigned int func_param1;
-    unsigned int func_param2;
-    unsigned int ymm0_save;
-};
+int __cdecl call_func_set_ymm0( void *arg1, void *arg2, void *func, void *ymm0_save );
+int __cdecl call_func_reset_ymm_state( void *arg1, void *arg2, void *func, void *ymm0_save );
+
 #ifdef __x86_64__
-static BYTE call_func_code_set_ymm0[] =
-{
-    0x55,                         /* pushq %rbp */
-    0x48, 0xb8,                   /* mov imm,%rax */
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 
-    0x48, 0xb9,                   /* mov imm,%rcx */
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+__ASM_GLOBAL_FUNC( call_func_set_ymm0,
+    "pushq %rbx\n\t"
+    "movq %r9,%rbx\n\t"
+    "vmovups (%rbx),%ymm0\n\t"
+    "subq $0x20,%rsp\n\t"
+    "call *%r8\n\t"
+    "addq $0x20,%rsp\n\t"
+    "vmovups %ymm0,(%rbx)\n\t"
+    "popq %rbx\n\t"
+    "ret" );
 
-    0x48, 0xba,                   /* mov imm,%rdx */
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+__ASM_GLOBAL_FUNC( call_func_reset_ymm_state,
+    "pushq %rbx\n\t"
+    "movq %r9,%rbx\n\t"
+    "vzeroupper\n\t"
+    "xorps %xmm0,%xmm0\n\t"
+    "subq $0x20,%rsp\n\t"
+    "call *%r8\n\t"
+    "addq $0x20,%rsp\n\t"
+    "vmovups %ymm0,(%rbx)\n\t"
+    "popq %rbx\n\t"
+    "ret" );
 
-    0x48, 0xbd,                   /* mov imm,%rbp */
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-
-    0xc5, 0xfc, 0x10, 0x45, 0x00, /* vmovups (%rbp),%ymm0 */
-    0x48, 0x83, 0xec, 0x20,       /* sub $0x20,%rsp */
-    0xff, 0xd0,                   /* call *rax */
-    0x48, 0x83, 0xc4, 0x20,       /* add $0x20,%rsp */
-    0xc5, 0xfc, 0x11, 0x45, 0x00, /* vmovups %ymm0,(%rbp) */
-    0x5d,                         /* popq %rbp */
-    0xc3,                         /* ret  */
-};
-static BYTE call_func_code_reset_ymm_state[] =
-{
-    0x55,                         /* pushq %rbp */
-    0x48, 0xb8,                   /* mov imm,%rax */
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-
-    0x48, 0xb9,                   /* mov imm,%rcx */
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-
-    0x48, 0xba,                   /* mov imm,%rdx */
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-
-    0x48, 0xbd,                   /* mov imm,%rbp */
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-
-    0xc5, 0xf8, 0x77,             /* vzeroupper */
-    0x0f, 0x57, 0xc0,             /* xorps  %xmm0,%xmm0 */
-    0x48, 0x83, 0xec, 0x20,       /* sub $0x20,%rsp */
-    0xff, 0xd0,                   /* call *rax */
-    0x48, 0x83, 0xc4, 0x20,       /* add $0x20,%rsp */
-    0xc5, 0xfc, 0x11, 0x45, 0x00, /* vmovups %ymm0,(%rbp) */
-    0x5d,                         /* popq %rbp */
-    0xc3,                         /* ret  */
-};
-static const struct call_func_offsets call_func_offsets = {3, 13, 23, 33};
 #else
-static BYTE call_func_code_set_ymm0[] =
-{
-    0x55,                         /* pushl %ebp */
-    0xb8,                         /* mov imm,%eax */
-    0x00, 0x00, 0x00, 0x00,
 
-    0xb9,                         /* mov imm,%ecx */
-    0x00, 0x00, 0x00, 0x00,
+__ASM_GLOBAL_FUNC( call_func_set_ymm0,
+    "pushl %ebp\n\t"
+    "movl %esp,%ebp\n\t"
+    "movl 20(%ebp),%ecx\n\t"
+    "vmovups (%ecx),%ymm0\n\t"
+    "pushl 12(%ebp)\n\t"
+    "pushl 8(%ebp)\n\t"
+    "call *16(%ebp)\n\t"
+    "movl 20(%ebp),%ecx\n\t"
+    "vmovups %ymm0,(%ecx)\n\t"
+    "leave\n\t"
+    "ret" );
 
-    0xba,                         /* mov imm,%edx */
-    0x00, 0x00, 0x00, 0x00,
+__ASM_GLOBAL_FUNC( call_func_reset_ymm_state,
+    "pushl %ebp\n\t"
+    "movl %esp,%ebp\n\t"
+    "vzeroupper\n\t"
+    "xorps %xmm0,%xmm0\n\t"
+    "pushl 12(%ebp)\n\t"
+    "pushl 8(%ebp)\n\t"
+    "call *16(%ebp)\n\t"
+    "movl 20(%ebp),%ecx\n\t"
+    "vmovups %ymm0,(%ecx)\n\t"
+    "leave\n\t"
+    "ret" );
 
-    0xbd,                         /* mov imm,%ebp */
-    0x00, 0x00, 0x00, 0x00,
-
-    0x81, 0xfa, 0xef, 0xbe, 0xad, 0xde,
-                                  /* cmpl $0xdeadbeef, %edx */
-    0x74, 0x01,                   /* je 1f */
-    0x52,                         /* pushl %edx */
-    0x51,                         /* 1: pushl %ecx */
-    0xc5, 0xfc, 0x10, 0x45, 0x00, /* vmovups (%ebp),%ymm0 */
-    0xff, 0xd0,                   /* call *eax */
-    0xc5, 0xfc, 0x11, 0x45, 0x00, /* vmovups %ymm0,(%ebp) */
-    0x5d,                         /* popl %ebp */
-    0xc3,                         /* ret  */
-};
-static BYTE call_func_code_reset_ymm_state[] =
-{
-    0x55,                         /* pushl %ebp */
-    0xb8,                         /* mov imm,%eax */
-    0x00, 0x00, 0x00, 0x00,
-
-    0xb9,                         /* mov imm,%ecx */
-    0x00, 0x00, 0x00, 0x00,
-
-    0xba,                         /* mov imm,%edx */
-    0x00, 0x00, 0x00, 0x00,
-
-    0xbd,                         /* mov imm,%ebp */
-    0x00, 0x00, 0x00, 0x00,
-
-    0x81, 0xfa, 0xef, 0xbe, 0xad, 0xde,
-                                  /* cmpl $0xdeadbeef, %edx */
-    0x74, 0x01,                   /* je 1f */
-    0x52,                         /* pushl %edx */
-    0x51,                         /* 1: pushl %ecx */
-    0xc5, 0xf8, 0x77,             /* vzeroupper */
-    0x0f, 0x57, 0xc0,             /* xorps  %xmm0,%xmm0 */
-    0xff, 0xd0,                   /* call *eax */
-    0xc5, 0xfc, 0x11, 0x45, 0x00, /* vmovups %ymm0,(%ebp) */
-    0x5d,                         /* popl %ebp */
-    0xc3,                         /* ret  */
-};
-static const struct call_func_offsets call_func_offsets = {2, 7, 12, 17};
 #endif
 
 static DWORD WINAPI test_extended_context_thread(void *arg)
 {
-    ULONG (WINAPI* func)(void) = code_mem;
     static unsigned int data[8];
     unsigned int i;
 
-    memcpy(code_mem, call_func_code_reset_ymm_state, sizeof(call_func_code_reset_ymm_state));
-    *(void **)((BYTE *)code_mem + call_func_offsets.func_addr) = SuspendThread;
-    *(void **)((BYTE *)code_mem + call_func_offsets.func_param1) = (void *)GetCurrentThread();
-    *(void **)((BYTE *)code_mem + call_func_offsets.func_param2) = (void *)0xdeadbeef;
-    *(void **)((BYTE *)code_mem + call_func_offsets.ymm0_save) = data;
-    func();
+    call_func_reset_ymm_state(GetCurrentThread(), 0, SuspendThread, data);
 
     for (i = 0; i < 4; ++i)
         ok(!data[i], "Got unexpected data %#x, i %u.\n", data[i], i);
@@ -7770,19 +7710,9 @@ static DWORD WINAPI test_extended_context_thread(void *arg)
         ok(data[i] == 0x48484848, "Got unexpected data %#x, i %u.\n", data[i], i);
     memset(data, 0x68, sizeof(data));
 
-    memcpy(code_mem, call_func_code_set_ymm0, sizeof(call_func_code_set_ymm0));
-    *(void **)((BYTE *)code_mem + call_func_offsets.func_addr) = SuspendThread;
-    *(void **)((BYTE *)code_mem + call_func_offsets.func_param1) = (void *)GetCurrentThread();
-    *(void **)((BYTE *)code_mem + call_func_offsets.func_param2) = (void *)0xdeadbeef;
-    *(void **)((BYTE *)code_mem + call_func_offsets.ymm0_save) = data;
-    func();
+    call_func_set_ymm0(GetCurrentThread(), 0, SuspendThread, data);
 
-    memcpy(code_mem, call_func_code_reset_ymm_state, sizeof(call_func_code_reset_ymm_state));
-    *(void **)((BYTE *)code_mem + call_func_offsets.func_addr) = SuspendThread;
-    *(void **)((BYTE *)code_mem + call_func_offsets.func_param1) = (void *)GetCurrentThread();
-    *(void **)((BYTE *)code_mem + call_func_offsets.func_param2) = (void *)0xdeadbeef;
-    *(void **)((BYTE *)code_mem + call_func_offsets.ymm0_save) = data;
-    func();
+    call_func_reset_ymm_state(GetCurrentThread(), 0, SuspendThread, data);
     return 0;
 }
 
@@ -7874,7 +7804,6 @@ static void test_extended_context(void)
     unsigned int i, j, address_offset, test;
     ULONG ret, ret2, length, length2, align;
     ULONG flags, flags_fpx, expected_flags;
-    ULONG (WINAPI* func)(void) = code_mem;
     CONTEXT_EX *context_ex;
     CONTEXT *context;
     unsigned data[8];
@@ -8485,14 +8414,8 @@ static void test_extended_context(void)
     context_ex = (CONTEXT_EX *)(context + 1);
     xs = (XSTATE *)((BYTE *)context_ex + context_ex->XState.Offset);
 
-    *(void **)(call_func_code_set_ymm0 + call_func_offsets.func_addr) = RtlCaptureContext;
-    *(void **)(call_func_code_set_ymm0 + call_func_offsets.func_param1) = context;
-    *(void **)(call_func_code_set_ymm0 + call_func_offsets.func_param2) = (void *)0xdeadbeef;
-    *(void **)(call_func_code_set_ymm0 + call_func_offsets.ymm0_save) = data;
-    memcpy(code_mem, call_func_code_set_ymm0, sizeof(call_func_code_set_ymm0));
-
     memcpy(data, test_extended_context_data, sizeof(data));
-    func();
+    call_func_set_ymm0(context, 0, RtlCaptureContext, data);
     ok(context->ContextFlags == (CONTEXT_FULL | CONTEXT_SEGMENTS), "Got unexpected ContextFlags %#x.\n",
             context->ContextFlags);
     for (i = 0; i < 8; ++i)
@@ -8513,17 +8436,12 @@ static void test_extended_context(void)
     pSetXStateFeaturesMask(context, ~(ULONG64)0);
     ok(context->ContextFlags == expected_flags, "Got unexpected ContextFlags %#x.\n",
             context->ContextFlags);
-    *(void **)(call_func_code_set_ymm0 + call_func_offsets.func_addr) = GetThreadContext;
-    *(void **)(call_func_code_set_ymm0 + call_func_offsets.func_param1) = (void *)GetCurrentThread();
-    *(void **)(call_func_code_set_ymm0 + call_func_offsets.func_param2) = context;
-    *(void **)(call_func_code_set_ymm0 + call_func_offsets.ymm0_save) = data;
-    memcpy(code_mem, call_func_code_set_ymm0, sizeof(call_func_code_set_ymm0));
+
     xs->CompactionMask = 2;
     if (!compaction_enabled)
         xs->Mask = 0;
     context_ex->XState.Length = sizeof(XSTATE);
-
-    bret = func();
+    bret = call_func_set_ymm0(GetCurrentThread(), context, GetThreadContext, data);
     ok(bret, "Got unexpected bret %#x, GetLastError() %u.\n", bret, GetLastError());
 
     ok(context->ContextFlags == expected_flags, "Got unexpected ContextFlags %#x.\n",
@@ -8547,7 +8465,7 @@ static void test_extended_context(void)
     xs->CompactionMask = 4;
     xs->Mask = compaction_enabled ? 0 : 4;
     context_ex->XState.Length = sizeof(XSTATE) + 64;
-    bret = func();
+    bret = call_func_set_ymm0(GetCurrentThread(), context, GetThreadContext, data);
     ok(!bret && GetLastError() == ERROR_INVALID_PARAMETER,
             "Got unexpected bret %#x, GetLastError() %u.\n", bret, GetLastError());
     ok(context->ContextFlags == expected_flags, "Got unexpected ContextFlags %#x.\n",
@@ -8563,7 +8481,7 @@ static void test_extended_context(void)
     xs->CompactionMask = 4;
     xs->Mask = compaction_enabled ? 0 : 4;
     context_ex->XState.Length = offsetof(XSTATE, YmmContext);
-    bret = func();
+    bret = call_func_set_ymm0(GetCurrentThread(), context, GetThreadContext, data);
     ok(context->ContextFlags == expected_flags, "Got unexpected ContextFlags %#x.\n",
             context->ContextFlags);
     ok(!bret && GetLastError() == ERROR_MORE_DATA,
@@ -8579,7 +8497,7 @@ static void test_extended_context(void)
     context_ex->XState.Length = sizeof(XSTATE);
     xs->CompactionMask = 4;
     xs->Mask = compaction_enabled ? 0 : 4;
-    bret = func();
+    bret = call_func_set_ymm0(GetCurrentThread(), context, GetThreadContext, data);
     ok(bret, "Got unexpected bret %#x, GetLastError() %u.\n", bret, GetLastError());
 
     ok(context->ContextFlags == expected_flags, "Got unexpected ContextFlags %#x.\n",
@@ -8604,13 +8522,8 @@ static void test_extended_context(void)
     memset(&xs->YmmContext, 0xcc, sizeof(xs->YmmContext));
     ok(bret, "Got unexpected bret %#x.\n", bret);
     pSetXStateFeaturesMask(context, ~(ULONG64)0);
-    *(void **)(call_func_code_reset_ymm_state + call_func_offsets.func_addr) = GetThreadContext;
-    *(void **)(call_func_code_reset_ymm_state + call_func_offsets.func_param1) = (void *)GetCurrentThread();
-    *(void **)(call_func_code_reset_ymm_state + call_func_offsets.func_param2) = context;
-    *(void **)(call_func_code_reset_ymm_state + call_func_offsets.ymm0_save) = data;
-    memcpy(code_mem, call_func_code_reset_ymm_state, sizeof(call_func_code_reset_ymm_state));
 
-    bret = func();
+    bret = call_func_reset_ymm_state(GetCurrentThread(), context, GetThreadContext, data);
     ok(bret, "Got unexpected bret %#x, GetLastError() %u.\n", bret, GetLastError());
 
     expected_flags = CONTEXT_FULL | CONTEXT_XSTATE | CONTEXT_FLOATING_POINT;
-- 
2.30.2




More information about the wine-devel mailing list