Module: wine Branch: master Commit: 07f37f21377e930aefeb1fef3ab9c3cf9daee84f URL: https://source.winehq.org/git/wine.git/?a=commit;h=07f37f21377e930aefeb1fef3...
Author: Alexandre Julliard julliard@winehq.org Date: Tue Aug 13 14:44:41 2019 +0200
ntdll: Add support for saving/restoring FPU state on ARM64.
Signed-off-by: Alexandre Julliard julliard@winehq.org
---
dlls/ntdll/signal_arm64.c | 36 ++++++++++++++++++++++++++++++------ 1 file changed, 30 insertions(+), 6 deletions(-)
diff --git a/dlls/ntdll/signal_arm64.c b/dlls/ntdll/signal_arm64.c index 900fd3b..2b5e1f1 100644 --- a/dlls/ntdll/signal_arm64.c +++ b/dlls/ntdll/signal_arm64.c @@ -81,8 +81,21 @@ static pthread_key_t teb_key; # define FP_sig(context) REGn_sig(29, context) /* Frame pointer */ # define LR_sig(context) REGn_sig(30, context) /* Link Register */
-/* Exceptions */ -# define FAULT_sig(context) REG_sig(fault_address, context) +static struct _aarch64_ctx *get_extended_sigcontext( ucontext_t *sigcontext, unsigned int magic ) +{ + struct _aarch64_ctx *ctx = (struct _aarch64_ctx *)sigcontext->uc_mcontext.__reserved; + while ((char *)ctx < (char *)(&sigcontext->uc_mcontext + 1) && ctx->magic && ctx->size) + { + if (ctx->magic == magic) return ctx; + ctx = (struct _aarch64_ctx *)((char *)ctx + ctx->size); + } + return NULL; +} + +static struct fpsimd_context *get_fpsimd_context( ucontext_t *sigcontext ) +{ + return (struct fpsimd_context *)get_extended_sigcontext( sigcontext, FPSIMD_MAGIC ); +}
#endif /* linux */
@@ -169,9 +182,15 @@ static void restore_context( const CONTEXT *context, ucontext_t *sigcontext ) * * Set the FPU context from a sigcontext. */ -static inline void save_fpu( CONTEXT *context, const ucontext_t *sigcontext ) +static void save_fpu( CONTEXT *context, ucontext_t *sigcontext ) { - FIXME( "Not implemented on ARM64\n" ); + struct fpsimd_context *fp = get_fpsimd_context( sigcontext ); + + if (!fp) return; + context->ContextFlags |= CONTEXT_FLOATING_POINT; + context->Fpcr = fp->fpcr; + context->Fpsr = fp->fpsr; + memcpy( context->V, fp->vregs, sizeof(context->V) ); }
@@ -180,9 +199,14 @@ static inline void save_fpu( CONTEXT *context, const ucontext_t *sigcontext ) * * Restore the FPU context to a sigcontext. */ -static inline void restore_fpu( CONTEXT *context, const ucontext_t *sigcontext ) +static void restore_fpu( CONTEXT *context, ucontext_t *sigcontext ) { - FIXME( "Not implemented on ARM64\n" ); + struct fpsimd_context *fp = get_fpsimd_context( sigcontext ); + + if (!fp) return; + fp->fpcr = context->Fpcr; + fp->fpsr = context->Fpsr; + memcpy( fp->vregs, context->V, sizeof(fp->vregs) ); }
/***********************************************************************