Arm64 support SIMD registers context to/from native context (#25757)
authorSteve MacLean <Steve.MacLean@microsoft.com>
Thu, 18 Jul 2019 08:14:40 +0000 (04:14 -0400)
committerSteve MacLean <Steve.MacLean@Microsoft.com>
Thu, 18 Jul 2019 19:04:13 +0000 (15:04 -0400)
src/pal/src/include/pal/context.h
src/pal/src/thread/context.cpp

index 146b9a0..69acd36 100644 (file)
@@ -277,6 +277,44 @@ inline void *FPREG_Xstate_Ymmh(const ucontext_t *uc)
 #define MCREG_Sp(mc)      ((mc).sp)
 #define MCREG_Pc(mc)      ((mc).pc)
 #define MCREG_Cpsr(mc)    ((mc).pstate)
+
+
+inline
+fpsimd_context* GetNativeSigSimdContext(native_context_t *mc)
+{
+    size_t size = 0;
+
+    do
+    {
+        fpsimd_context* fp = reinterpret_cast<fpsimd_context *>(&mc->uc_mcontext.__reserved[size]);
+
+        if(fp->head.magic == FPSIMD_MAGIC)
+        {
+            _ASSERTE(fp->head.size >= sizeof(fpsimd_context));
+            _ASSERTE(size + fp->head.size <= sizeof(mc->uc_mcontext.__reserved));
+
+            return fp;
+        }
+
+        if (fp->head.size == 0)
+        {
+            break;
+        }
+
+        size += fp->head.size;
+    } while (size + sizeof(fpsimd_context) <= sizeof(mc->uc_mcontext.__reserved));
+
+    _ASSERTE(false);
+
+    return nullptr;
+}
+
+inline
+const fpsimd_context* GetConstNativeSigSimdContext(const native_context_t *mc)
+{
+    return GetNativeSigSimdContext(const_cast<native_context_t*>(mc));
+}
+
 #else
     // For FreeBSD, as found in x86/ucontext.h
 #define MCREG_Rbp(mc)      ((mc).mc_rbp)
index 10b2db4..b65190d 100644 (file)
@@ -465,6 +465,17 @@ void CONTEXTToNativeContext(CONST CONTEXT *lpContext, native_context_t *native)
         {
             FPREG_Xmm(native, i) = lpContext->FltSave.XmmRegisters[i];
         }
+#elif defined(_ARM64_)
+        fpsimd_context* fp = GetNativeSigSimdContext(native);
+        if (fp)
+        {
+            fp->fpsr = lpContext->Fpsr;
+            fp->fpcr = lpContext->Fpcr;
+            for (int i = 0; i < 32; i++)
+            {
+                *(NEON128*) &fp->vregs[i] = lpContext->V[i];
+            }
+        }
 #endif
     }
 
@@ -563,6 +574,17 @@ void CONTEXTFromNativeContext(const native_context_t *native, LPCONTEXT lpContex
         {
             lpContext->FltSave.XmmRegisters[i] = FPREG_Xmm(native, i);
         }
+#elif defined(_ARM64_)
+        const fpsimd_context* fp = GetConstNativeSigSimdContext(native);
+        if (fp)
+        {
+            lpContext->Fpsr = fp->fpsr;
+            lpContext->Fpcr = fp->fpcr;
+            for (int i = 0; i < 32; i++)
+            {
+                lpContext->V[i] = *(NEON128*) &fp->vregs[i];
+            }
+        }
 #endif
     }