diff --git a/dlls/ntdll/ntdll_misc.h b/dlls/ntdll/ntdll_misc.h
index dedf0484b55..40273d8944a 100644
--- a/dlls/ntdll/ntdll_misc.h
+++ b/dlls/ntdll/ntdll_misc.h
@@ -84,11 +84,6 @@ extern void WINAPI KiUserCallbackDispatcher(ULONG,void*,ULONG);
 extern void WINAPI KiUserCallbackDispatcherReturn(void);
 extern void (WINAPI *pWow64PrepareForException)( EXCEPTION_RECORD *rec, CONTEXT *context );
 
-#ifdef __arm64ec__
-extern void context_x64_to_arm( ARM64_NT_CONTEXT *arm_ctx, const CONTEXT *ctx );
-extern void context_arm_to_x64( CONTEXT *ctx, const ARM64_NT_CONTEXT *arm_ctx );
-#endif
-
 /* debug helpers */
 extern LPCSTR debugstr_us( const UNICODE_STRING *str );
 extern const char *debugstr_exception_code( DWORD code );
diff --git a/dlls/ntdll/signal_arm64ec.c b/dlls/ntdll/signal_arm64ec.c
index ddf37ea6545..3881a004aab 100644
--- a/dlls/ntdll/signal_arm64ec.c
+++ b/dlls/ntdll/signal_arm64ec.c
@@ -30,206 +30,13 @@
 #include "wine/exception.h"
 #include "wine/list.h"
 #include "ntdll_misc.h"
+#include "unwind.h"
 #include "wine/debug.h"
 #include "ntsyscalls.h"
 
-WINE_DEFAULT_DEBUG_CHANNEL(unwind);
-WINE_DECLARE_DEBUG_CHANNEL(seh);
+WINE_DEFAULT_DEBUG_CHANNEL(seh);
 WINE_DECLARE_DEBUG_CHANNEL(relay);
 
-
-static ULONG ctx_flags_x64_to_arm( ULONG flags )
-{
-    ULONG ret = CONTEXT_ARM64;
-
-    flags &= ~CONTEXT_AMD64;
-    if (flags & CONTEXT_AMD64_CONTROL) ret |= CONTEXT_ARM64_CONTROL;
-    if (flags & CONTEXT_AMD64_INTEGER) ret |= CONTEXT_ARM64_INTEGER;
-    if (flags & CONTEXT_AMD64_FLOATING_POINT) ret |= CONTEXT_ARM64_FLOATING_POINT;
-    return ret;
-}
-
-static ULONG ctx_flags_arm_to_x64( ULONG flags )
-{
-    ULONG ret = CONTEXT_AMD64;
-
-    flags &= ~CONTEXT_ARM64;
-    if (flags & CONTEXT_ARM64_CONTROL) ret |= CONTEXT_AMD64_CONTROL;
-    if (flags & CONTEXT_ARM64_INTEGER) ret |= CONTEXT_AMD64_INTEGER;
-    if (flags & CONTEXT_ARM64_FLOATING_POINT) ret |= CONTEXT_AMD64_FLOATING_POINT;
-    return ret;
-}
-
-static UINT eflags_to_cpsr( UINT eflags )
-{
-    UINT ret = 0;
-
-    if (eflags & 0x0001) ret |= 0x20000000;  /* carry */
-    if (eflags & 0x0040) ret |= 0x40000000;  /* zero */
-    if (eflags & 0x0080) ret |= 0x80000000;  /* negative */
-    if (eflags & 0x0800) ret |= 0x10000000;  /* overflow */
-    return ret;
-}
-
-static UINT cpsr_to_eflags( UINT cpsr )
-{
-    UINT ret = 0;
-
-    if (cpsr & 0x10000000) ret |= 0x0800;  /* overflow */
-    if (cpsr & 0x20000000) ret |= 0x0001;  /* carry */
-    if (cpsr & 0x40000000) ret |= 0x0040;  /* zero */
-    if (cpsr & 0x80000000) ret |= 0x0080;  /* negative */
-    return ret;
-}
-
-static UINT64 mxcsr_to_fpcsr( UINT mxcsr )
-{
-    UINT fpcr = 0, fpsr = 0;
-
-    if (mxcsr & 0x0001) fpsr |= 0x0001;    /* invalid operation */
-    if (mxcsr & 0x0002) fpsr |= 0x0080;    /* denormal */
-    if (mxcsr & 0x0004) fpsr |= 0x0002;    /* zero-divide */
-    if (mxcsr & 0x0008) fpsr |= 0x0004;    /* overflow */
-    if (mxcsr & 0x0010) fpsr |= 0x0008;    /* underflow */
-    if (mxcsr & 0x0020) fpsr |= 0x0010;    /* precision */
-
-    if (mxcsr & 0x0040) fpcr |= 0x0001;    /* denormals are zero */
-    if (mxcsr & 0x0080) fpcr |= 0x0100;    /* invalid operation mask */
-    if (mxcsr & 0x0100) fpcr |= 0x8000;    /* denormal mask */
-    if (mxcsr & 0x0200) fpcr |= 0x0200;    /* zero-divide mask */
-    if (mxcsr & 0x0400) fpcr |= 0x0400;    /* overflow mask */
-    if (mxcsr & 0x0800) fpcr |= 0x0800;    /* underflow mask */
-    if (mxcsr & 0x1000) fpcr |= 0x1000;    /* precision mask */
-    if (mxcsr & 0x2000) fpcr |= 0x800000;  /* round down */
-    if (mxcsr & 0x4000) fpcr |= 0x400000;  /* round up */
-    if (mxcsr & 0x8000) fpcr |= 0x1000000; /* flush to zero */
-    return fpcr | ((UINT64)fpsr << 32);
-}
-
-static UINT fpcsr_to_mxcsr( UINT fpcr, UINT fpsr )
-{
-    UINT ret = 0;
-
-    if (fpsr & 0x0001) ret |= 0x0001;      /* invalid operation */
-    if (fpsr & 0x0002) ret |= 0x0004;      /* zero-divide */
-    if (fpsr & 0x0004) ret |= 0x0008;      /* overflow */
-    if (fpsr & 0x0008) ret |= 0x0010;      /* underflow */
-    if (fpsr & 0x0010) ret |= 0x0020;      /* precision */
-    if (fpsr & 0x0080) ret |= 0x0002;      /* denormal */
-
-    if (fpcr & 0x0000001) ret |= 0x0040;   /* denormals are zero */
-    if (fpcr & 0x0000100) ret |= 0x0080;   /* invalid operation mask */
-    if (fpcr & 0x0000200) ret |= 0x0200;   /* zero-divide mask */
-    if (fpcr & 0x0000400) ret |= 0x0400;   /* overflow mask */
-    if (fpcr & 0x0000800) ret |= 0x0800;   /* underflow mask */
-    if (fpcr & 0x0001000) ret |= 0x1000;   /* precision mask */
-    if (fpcr & 0x0008000) ret |= 0x0100;   /* denormal mask */
-    if (fpcr & 0x0400000) ret |= 0x4000;   /* round up */
-    if (fpcr & 0x0800000) ret |= 0x2000;   /* round down */
-    if (fpcr & 0x1000000) ret |= 0x8000;   /* flush to zero */
-    return ret;
-}
-
-void context_x64_to_arm( ARM64_NT_CONTEXT *arm_ctx, const CONTEXT *ctx )
-{
-    ARM64EC_NT_CONTEXT *ec_ctx = (ARM64EC_NT_CONTEXT *)ctx;
-    UINT64 fpcsr;
-
-    arm_ctx->ContextFlags = ctx_flags_x64_to_arm( ec_ctx->ContextFlags );
-    arm_ctx->Cpsr = eflags_to_cpsr( ec_ctx->AMD64_EFlags );
-    arm_ctx->X0   = ec_ctx->X0;
-    arm_ctx->X1   = ec_ctx->X1;
-    arm_ctx->X2   = ec_ctx->X2;
-    arm_ctx->X3   = ec_ctx->X3;
-    arm_ctx->X4   = ec_ctx->X4;
-    arm_ctx->X5   = ec_ctx->X5;
-    arm_ctx->X6   = ec_ctx->X6;
-    arm_ctx->X7   = ec_ctx->X7;
-    arm_ctx->X8   = ec_ctx->X8;
-    arm_ctx->X9   = ec_ctx->X9;
-    arm_ctx->X10  = ec_ctx->X10;
-    arm_ctx->X11  = ec_ctx->X11;
-    arm_ctx->X12  = ec_ctx->X12;
-    arm_ctx->X13  = 0;
-    arm_ctx->X14  = 0;
-    arm_ctx->X15  = ec_ctx->X15;
-    arm_ctx->X16  = ec_ctx->X16_0 | ((DWORD64)ec_ctx->X16_1 << 16) | ((DWORD64)ec_ctx->X16_2 << 32) | ((DWORD64)ec_ctx->X16_3 << 48);
-    arm_ctx->X17  = ec_ctx->X17_0 | ((DWORD64)ec_ctx->X17_1 << 16) | ((DWORD64)ec_ctx->X17_2 << 32) | ((DWORD64)ec_ctx->X17_3 << 48);
-    arm_ctx->X18  = 0;
-    arm_ctx->X19  = ec_ctx->X19;
-    arm_ctx->X20  = ec_ctx->X20;
-    arm_ctx->X21  = ec_ctx->X21;
-    arm_ctx->X22  = ec_ctx->X22;
-    arm_ctx->X23  = 0;
-    arm_ctx->X24  = 0;
-    arm_ctx->X25  = ec_ctx->X25;
-    arm_ctx->X26  = ec_ctx->X26;
-    arm_ctx->X27  = ec_ctx->X27;
-    arm_ctx->X28  = 0;
-    arm_ctx->Fp   = ec_ctx->Fp;
-    arm_ctx->Lr   = ec_ctx->Lr;
-    arm_ctx->Sp   = ec_ctx->Sp;
-    arm_ctx->Pc   = ec_ctx->Pc;
-    memcpy( arm_ctx->V, ec_ctx->V, 16 * sizeof(arm_ctx->V[0]) );
-    memset( arm_ctx->V + 16, 0, sizeof(*arm_ctx) - offsetof( ARM64_NT_CONTEXT, V[16] ));
-    fpcsr = mxcsr_to_fpcsr( ec_ctx->AMD64_MxCsr );
-    arm_ctx->Fpcr = fpcsr;
-    arm_ctx->Fpsr = fpcsr >> 32;
-}
-
-void context_arm_to_x64( CONTEXT *ctx, const ARM64_NT_CONTEXT *arm_ctx )
-{
-    ARM64EC_NT_CONTEXT *ec_ctx = (ARM64EC_NT_CONTEXT *)ctx;
-
-    memset( ec_ctx, 0, sizeof(*ec_ctx) );
-    ec_ctx->ContextFlags = ctx_flags_arm_to_x64( arm_ctx->ContextFlags );
-    ec_ctx->AMD64_SegCs  = 0x33;
-    ec_ctx->AMD64_SegDs  = 0x2b;
-    ec_ctx->AMD64_SegEs  = 0x2b;
-    ec_ctx->AMD64_SegFs  = 0x53;
-    ec_ctx->AMD64_SegGs  = 0x2b;
-    ec_ctx->AMD64_SegSs  = 0x2b;
-    ec_ctx->AMD64_EFlags = cpsr_to_eflags( arm_ctx->Cpsr );
-    ec_ctx->AMD64_MxCsr  = ec_ctx->AMD64_MxCsr_copy = fpcsr_to_mxcsr( arm_ctx->Fpcr, arm_ctx->Fpsr );
-
-    ec_ctx->X8    = arm_ctx->X8;
-    ec_ctx->X0    = arm_ctx->X0;
-    ec_ctx->X1    = arm_ctx->X1;
-    ec_ctx->X27   = arm_ctx->X27;
-    ec_ctx->Sp    = arm_ctx->Sp;
-    ec_ctx->Fp    = arm_ctx->Fp;
-    ec_ctx->X25   = arm_ctx->X25;
-    ec_ctx->X26   = arm_ctx->X26;
-    ec_ctx->X2    = arm_ctx->X2;
-    ec_ctx->X3    = arm_ctx->X3;
-    ec_ctx->X4    = arm_ctx->X4;
-    ec_ctx->X5    = arm_ctx->X5;
-    ec_ctx->X19   = arm_ctx->X19;
-    ec_ctx->X20   = arm_ctx->X20;
-    ec_ctx->X21   = arm_ctx->X21;
-    ec_ctx->X22   = arm_ctx->X22;
-    ec_ctx->Pc    = arm_ctx->Pc;
-    ec_ctx->Lr    = arm_ctx->Lr;
-    ec_ctx->X6    = arm_ctx->X6;
-    ec_ctx->X7    = arm_ctx->X7;
-    ec_ctx->X9    = arm_ctx->X9;
-    ec_ctx->X10   = arm_ctx->X10;
-    ec_ctx->X11   = arm_ctx->X11;
-    ec_ctx->X12   = arm_ctx->X12;
-    ec_ctx->X15   = arm_ctx->X15;
-    ec_ctx->X16_0 = arm_ctx->X16;
-    ec_ctx->X16_1 = arm_ctx->X16 >> 16;
-    ec_ctx->X16_2 = arm_ctx->X16 >> 32;
-    ec_ctx->X16_3 = arm_ctx->X16 >> 48;
-    ec_ctx->X17_0 = arm_ctx->X17;
-    ec_ctx->X17_1 = arm_ctx->X17 >> 16;
-    ec_ctx->X17_2 = arm_ctx->X17 >> 32;
-    ec_ctx->X17_3 = arm_ctx->X17 >> 48;
-
-    memcpy( ec_ctx->V, arm_ctx->V, sizeof(ec_ctx->V) );
-}
-
-
 /*******************************************************************
  *         syscalls
  */
@@ -402,7 +209,7 @@ NTSTATUS WINAPI NtContinue( CONTEXT *context, BOOLEAN alertable )
 {
     ARM64_NT_CONTEXT arm_ctx;
 
-    context_x64_to_arm( &arm_ctx, context );
+    context_x64_to_arm( &arm_ctx, (ARM64EC_NT_CONTEXT *)context );
     return syscall_NtContinue( &arm_ctx, alertable );
 }
 
@@ -702,7 +509,7 @@ NTSTATUS WINAPI NtGetContextThread( HANDLE handle, CONTEXT *context )
     ARM64_NT_CONTEXT arm_ctx = { .ContextFlags = ctx_flags_x64_to_arm( context->ContextFlags ) };
     NTSTATUS status = syscall_NtGetContextThread( handle, &arm_ctx );
 
-    if (!status) context_arm_to_x64( context, &arm_ctx );
+    if (!status) context_arm_to_x64( (ARM64EC_NT_CONTEXT *)context, &arm_ctx );
     return status;
 }
 
@@ -1194,7 +1001,7 @@ NTSTATUS WINAPI NtRaiseException( EXCEPTION_RECORD *rec, CONTEXT *context, BOOL
 {
     ARM64_NT_CONTEXT arm_ctx;
 
-    context_x64_to_arm( &arm_ctx, context );
+    context_x64_to_arm( &arm_ctx, (ARM64EC_NT_CONTEXT *)context );
     return syscall_NtRaiseException( rec, &arm_ctx, first_chance );
 }
 
@@ -1336,7 +1143,7 @@ NTSTATUS WINAPI NtSetContextThread( HANDLE handle, const CONTEXT *context )
 {
     ARM64_NT_CONTEXT arm_ctx;
 
-    context_x64_to_arm( &arm_ctx, context );
+    context_x64_to_arm( &arm_ctx, (ARM64EC_NT_CONTEXT *)context );
     return syscall_NtSetContextThread( handle, &arm_ctx );
 }
 
@@ -1694,11 +1501,11 @@ void WINAPI dispatch_apc( void (CALLBACK *func)(ULONG_PTR,ULONG_PTR,ULONG_PTR,CO
                           ULONG_PTR arg1, ULONG_PTR arg2, ULONG_PTR arg3,
                           BOOLEAN alertable, ARM64_NT_CONTEXT *arm_ctx )
 {
-    CONTEXT context;
+    ARM64EC_NT_CONTEXT context;
 
     context_arm_to_x64( &context, arm_ctx );
-    func( arg1, arg2, arg3, &context );
-    NtContinue( &context, alertable );
+    func( arg1, arg2, arg3, &context.AMD64_Context );
+    NtContinue( &context.AMD64_Context, alertable );
 }
 __ASM_GLOBAL_FUNC( "#KiUserApcDispatcher",
                    __ASM_SEH(".seh_context\n\t")
@@ -1951,7 +1758,7 @@ void WINAPI RtlUserThreadStart( PRTL_THREAD_START_ROUTINE entry, void *arg )
  */
 void WINAPI LdrInitializeThunk( CONTEXT *arm_context, ULONG_PTR unk2, ULONG_PTR unk3, ULONG_PTR unk4 )
 {
-    CONTEXT context;
+    ARM64EC_NT_CONTEXT context;
 
     if (!__os_arm64x_check_call)
     {
@@ -1963,9 +1770,9 @@ void WINAPI LdrInitializeThunk( CONTEXT *arm_context, ULONG_PTR unk2, ULONG_PTR
     }
 
     context_arm_to_x64( &context, (ARM64_NT_CONTEXT *)arm_context );
-    loader_init( &context, (void **)&context.Rcx );
-    TRACE_(relay)( "\1Starting thread proc %p (arg=%p)\n", (void *)context.Rcx, (void *)context.Rdx );
-    NtContinue( &context, TRUE );
+    loader_init( &context.AMD64_Context, (void **)&context.X0 );
+    TRACE_(relay)( "\1Starting thread proc %p (arg=%p)\n", (void *)context.X0, (void *)context.X1 );
+    NtContinue( &context.AMD64_Context, TRUE );
 }
 
 
diff --git a/dlls/ntdll/unwind.c b/dlls/ntdll/unwind.c
index f13d3ba09ae..d6e86dd717a 100644
--- a/dlls/ntdll/unwind.c
+++ b/dlls/ntdll/unwind.c
@@ -31,6 +31,7 @@
 #include "wine/exception.h"
 #include "wine/list.h"
 #include "ntdll_misc.h"
+#include "unwind.h"
 #include "wine/debug.h"
 
 WINE_DEFAULT_DEBUG_CHANNEL(unwind);
@@ -1796,10 +1797,10 @@ PVOID WINAPI RtlVirtualUnwind( ULONG type, ULONG64 base, ULONG64 pc,
         ARM64_NT_CONTEXT arm_context;
         void *ret;
 
-        context_x64_to_arm( &arm_context, context );
+        context_x64_to_arm( &arm_context, (ARM64EC_NT_CONTEXT *)context );
         ret = RtlVirtualUnwind_arm64( type, base, pc, (ARM64_RUNTIME_FUNCTION *)function,
                                       &arm_context, data, frame_ret, NULL );
-        context_arm_to_x64( context, &arm_context );
+        context_arm_to_x64( (ARM64EC_NT_CONTEXT *)context, &arm_context );
         return ret;
     }
 #endif
diff --git a/dlls/ntdll/unwind.h b/dlls/ntdll/unwind.h
new file mode 100644
index 00000000000..1568b3ae7b1
--- /dev/null
+++ b/dlls/ntdll/unwind.h
@@ -0,0 +1,221 @@
+/*
+ * Exception unwinding definitions
+ *
+ * Copyright 2023 Alexandre Julliard
+ *
+ * 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
+ */
+
+#ifndef __WINE_NTDLL_UNWIND_H
+#define __WINE_NTDLL_UNWIND_H
+
+#include <stdarg.h>
+#include "windef.h"
+#include "winbase.h"
+#include "winnt.h"
+
+#if defined(__aarch64__) || defined(__arm64ec__)
+
+static inline ULONG ctx_flags_x64_to_arm( ULONG flags )
+{
+    ULONG ret = CONTEXT_ARM64;
+
+    flags &= ~CONTEXT_AMD64;
+    if (flags & CONTEXT_AMD64_CONTROL) ret |= CONTEXT_ARM64_CONTROL;
+    if (flags & CONTEXT_AMD64_INTEGER) ret |= CONTEXT_ARM64_INTEGER;
+    if (flags & CONTEXT_AMD64_FLOATING_POINT) ret |= CONTEXT_ARM64_FLOATING_POINT;
+    return ret;
+}
+
+static inline ULONG ctx_flags_arm_to_x64( ULONG flags )
+{
+    ULONG ret = CONTEXT_AMD64;
+
+    flags &= ~CONTEXT_ARM64;
+    if (flags & CONTEXT_ARM64_CONTROL) ret |= CONTEXT_AMD64_CONTROL;
+    if (flags & CONTEXT_ARM64_INTEGER) ret |= CONTEXT_AMD64_INTEGER;
+    if (flags & CONTEXT_ARM64_FLOATING_POINT) ret |= CONTEXT_AMD64_FLOATING_POINT;
+    return ret;
+}
+
+static inline UINT eflags_to_cpsr( UINT eflags )
+{
+    UINT ret = 0;
+
+    if (eflags & 0x0001) ret |= 0x20000000;  /* carry */
+    if (eflags & 0x0040) ret |= 0x40000000;  /* zero */
+    if (eflags & 0x0080) ret |= 0x80000000;  /* negative */
+    if (eflags & 0x0800) ret |= 0x10000000;  /* overflow */
+    return ret;
+}
+
+static inline UINT cpsr_to_eflags( UINT cpsr )
+{
+    UINT ret = 0;
+
+    if (cpsr & 0x10000000) ret |= 0x0800;  /* overflow */
+    if (cpsr & 0x20000000) ret |= 0x0001;  /* carry */
+    if (cpsr & 0x40000000) ret |= 0x0040;  /* zero */
+    if (cpsr & 0x80000000) ret |= 0x0080;  /* negative */
+    return ret;
+}
+
+static inline UINT64 mxcsr_to_fpcsr( UINT mxcsr )
+{
+    UINT fpcr = 0, fpsr = 0;
+
+    if (mxcsr & 0x0001) fpsr |= 0x0001;    /* invalid operation */
+    if (mxcsr & 0x0002) fpsr |= 0x0080;    /* denormal */
+    if (mxcsr & 0x0004) fpsr |= 0x0002;    /* zero-divide */
+    if (mxcsr & 0x0008) fpsr |= 0x0004;    /* overflow */
+    if (mxcsr & 0x0010) fpsr |= 0x0008;    /* underflow */
+    if (mxcsr & 0x0020) fpsr |= 0x0010;    /* precision */
+
+    if (mxcsr & 0x0040) fpcr |= 0x0001;    /* denormals are zero */
+    if (mxcsr & 0x0080) fpcr |= 0x0100;    /* invalid operation mask */
+    if (mxcsr & 0x0100) fpcr |= 0x8000;    /* denormal mask */
+    if (mxcsr & 0x0200) fpcr |= 0x0200;    /* zero-divide mask */
+    if (mxcsr & 0x0400) fpcr |= 0x0400;    /* overflow mask */
+    if (mxcsr & 0x0800) fpcr |= 0x0800;    /* underflow mask */
+    if (mxcsr & 0x1000) fpcr |= 0x1000;    /* precision mask */
+    if (mxcsr & 0x2000) fpcr |= 0x800000;  /* round down */
+    if (mxcsr & 0x4000) fpcr |= 0x400000;  /* round up */
+    if (mxcsr & 0x8000) fpcr |= 0x1000000; /* flush to zero */
+    return fpcr | ((UINT64)fpsr << 32);
+}
+
+static inline UINT fpcsr_to_mxcsr( UINT fpcr, UINT fpsr )
+{
+    UINT ret = 0;
+
+    if (fpsr & 0x0001) ret |= 0x0001;      /* invalid operation */
+    if (fpsr & 0x0002) ret |= 0x0004;      /* zero-divide */
+    if (fpsr & 0x0004) ret |= 0x0008;      /* overflow */
+    if (fpsr & 0x0008) ret |= 0x0010;      /* underflow */
+    if (fpsr & 0x0010) ret |= 0x0020;      /* precision */
+    if (fpsr & 0x0080) ret |= 0x0002;      /* denormal */
+
+    if (fpcr & 0x0000001) ret |= 0x0040;   /* denormals are zero */
+    if (fpcr & 0x0000100) ret |= 0x0080;   /* invalid operation mask */
+    if (fpcr & 0x0000200) ret |= 0x0200;   /* zero-divide mask */
+    if (fpcr & 0x0000400) ret |= 0x0400;   /* overflow mask */
+    if (fpcr & 0x0000800) ret |= 0x0800;   /* underflow mask */
+    if (fpcr & 0x0001000) ret |= 0x1000;   /* precision mask */
+    if (fpcr & 0x0008000) ret |= 0x0100;   /* denormal mask */
+    if (fpcr & 0x0400000) ret |= 0x4000;   /* round up */
+    if (fpcr & 0x0800000) ret |= 0x2000;   /* round down */
+    if (fpcr & 0x1000000) ret |= 0x8000;   /* flush to zero */
+    return ret;
+}
+
+static inline void context_x64_to_arm( ARM64_NT_CONTEXT *arm_ctx, const ARM64EC_NT_CONTEXT *ec_ctx )
+{
+    UINT64 fpcsr;
+
+    arm_ctx->ContextFlags = ctx_flags_x64_to_arm( ec_ctx->ContextFlags );
+    arm_ctx->Cpsr = eflags_to_cpsr( ec_ctx->AMD64_EFlags );
+    arm_ctx->X0   = ec_ctx->X0;
+    arm_ctx->X1   = ec_ctx->X1;
+    arm_ctx->X2   = ec_ctx->X2;
+    arm_ctx->X3   = ec_ctx->X3;
+    arm_ctx->X4   = ec_ctx->X4;
+    arm_ctx->X5   = ec_ctx->X5;
+    arm_ctx->X6   = ec_ctx->X6;
+    arm_ctx->X7   = ec_ctx->X7;
+    arm_ctx->X8   = ec_ctx->X8;
+    arm_ctx->X9   = ec_ctx->X9;
+    arm_ctx->X10  = ec_ctx->X10;
+    arm_ctx->X11  = ec_ctx->X11;
+    arm_ctx->X12  = ec_ctx->X12;
+    arm_ctx->X13  = 0;
+    arm_ctx->X14  = 0;
+    arm_ctx->X15  = ec_ctx->X15;
+    arm_ctx->X16  = ec_ctx->X16_0 | ((DWORD64)ec_ctx->X16_1 << 16) | ((DWORD64)ec_ctx->X16_2 << 32) | ((DWORD64)ec_ctx->X16_3 << 48);
+    arm_ctx->X17  = ec_ctx->X17_0 | ((DWORD64)ec_ctx->X17_1 << 16) | ((DWORD64)ec_ctx->X17_2 << 32) | ((DWORD64)ec_ctx->X17_3 << 48);
+    arm_ctx->X18  = 0;
+    arm_ctx->X19  = ec_ctx->X19;
+    arm_ctx->X20  = ec_ctx->X20;
+    arm_ctx->X21  = ec_ctx->X21;
+    arm_ctx->X22  = ec_ctx->X22;
+    arm_ctx->X23  = 0;
+    arm_ctx->X24  = 0;
+    arm_ctx->X25  = ec_ctx->X25;
+    arm_ctx->X26  = ec_ctx->X26;
+    arm_ctx->X27  = ec_ctx->X27;
+    arm_ctx->X28  = 0;
+    arm_ctx->Fp   = ec_ctx->Fp;
+    arm_ctx->Lr   = ec_ctx->Lr;
+    arm_ctx->Sp   = ec_ctx->Sp;
+    arm_ctx->Pc   = ec_ctx->Pc;
+    memcpy( arm_ctx->V, ec_ctx->V, 16 * sizeof(arm_ctx->V[0]) );
+    memset( arm_ctx->V + 16, 0, sizeof(*arm_ctx) - offsetof( ARM64_NT_CONTEXT, V[16] ));
+    fpcsr = mxcsr_to_fpcsr( ec_ctx->AMD64_MxCsr );
+    arm_ctx->Fpcr = fpcsr;
+    arm_ctx->Fpsr = fpcsr >> 32;
+}
+
+static inline void context_arm_to_x64( ARM64EC_NT_CONTEXT *ec_ctx, const ARM64_NT_CONTEXT *arm_ctx )
+{
+    memset( ec_ctx, 0, sizeof(*ec_ctx) );
+    ec_ctx->ContextFlags = ctx_flags_arm_to_x64( arm_ctx->ContextFlags );
+    ec_ctx->AMD64_SegCs  = 0x33;
+    ec_ctx->AMD64_SegDs  = 0x2b;
+    ec_ctx->AMD64_SegEs  = 0x2b;
+    ec_ctx->AMD64_SegFs  = 0x53;
+    ec_ctx->AMD64_SegGs  = 0x2b;
+    ec_ctx->AMD64_SegSs  = 0x2b;
+    ec_ctx->AMD64_EFlags = cpsr_to_eflags( arm_ctx->Cpsr );
+    ec_ctx->AMD64_MxCsr  = ec_ctx->AMD64_MxCsr_copy = fpcsr_to_mxcsr( arm_ctx->Fpcr, arm_ctx->Fpsr );
+
+    ec_ctx->X8    = arm_ctx->X8;
+    ec_ctx->X0    = arm_ctx->X0;
+    ec_ctx->X1    = arm_ctx->X1;
+    ec_ctx->X27   = arm_ctx->X27;
+    ec_ctx->Sp    = arm_ctx->Sp;
+    ec_ctx->Fp    = arm_ctx->Fp;
+    ec_ctx->X25   = arm_ctx->X25;
+    ec_ctx->X26   = arm_ctx->X26;
+    ec_ctx->X2    = arm_ctx->X2;
+    ec_ctx->X3    = arm_ctx->X3;
+    ec_ctx->X4    = arm_ctx->X4;
+    ec_ctx->X5    = arm_ctx->X5;
+    ec_ctx->X19   = arm_ctx->X19;
+    ec_ctx->X20   = arm_ctx->X20;
+    ec_ctx->X21   = arm_ctx->X21;
+    ec_ctx->X22   = arm_ctx->X22;
+    ec_ctx->Pc    = arm_ctx->Pc;
+    ec_ctx->Lr    = arm_ctx->Lr;
+    ec_ctx->X6    = arm_ctx->X6;
+    ec_ctx->X7    = arm_ctx->X7;
+    ec_ctx->X9    = arm_ctx->X9;
+    ec_ctx->X10   = arm_ctx->X10;
+    ec_ctx->X11   = arm_ctx->X11;
+    ec_ctx->X12   = arm_ctx->X12;
+    ec_ctx->X15   = arm_ctx->X15;
+    ec_ctx->X16_0 = arm_ctx->X16;
+    ec_ctx->X16_1 = arm_ctx->X16 >> 16;
+    ec_ctx->X16_2 = arm_ctx->X16 >> 32;
+    ec_ctx->X16_3 = arm_ctx->X16 >> 48;
+    ec_ctx->X17_0 = arm_ctx->X17;
+    ec_ctx->X17_1 = arm_ctx->X17 >> 16;
+    ec_ctx->X17_2 = arm_ctx->X17 >> 32;
+    ec_ctx->X17_3 = arm_ctx->X17 >> 48;
+
+    memcpy( ec_ctx->V, arm_ctx->V, sizeof(ec_ctx->V) );
+}
+
+#endif /* __aarch64__ || __arm64ec__ */
+
+#endif /* __WINE_NTDLL_UNWIND_H */