summaryrefslogtreecommitdiff
path: root/src/pal/src
diff options
context:
space:
mode:
authorSteve MacLean <Steve.MacLean@microsoft.com>2019-07-19 00:30:09 -0400
committerSteve MacLean <Steve.MacLean@Microsoft.com>2019-07-19 00:31:56 -0400
commite4ece90664bcbbfe2e5e2e1bcc33b3fe99a9f6cb (patch)
treef0161f7d65b07b951c3f7ae128c7754e8381074c /src/pal/src
parent46123f097e9e536e6dbb316c1f9e1ed1b15675c2 (diff)
downloadcoreclr-e4ece90664bcbbfe2e5e2e1bcc33b3fe99a9f6cb.tar.gz
coreclr-e4ece90664bcbbfe2e5e2e1bcc33b3fe99a9f6cb.tar.bz2
coreclr-e4ece90664bcbbfe2e5e2e1bcc33b3fe99a9f6cb.zip
Arm32 support VFP registers context to/from native context (#25775)
Diffstat (limited to 'src/pal/src')
-rw-r--r--src/pal/src/include/pal/context.h53
-rw-r--r--src/pal/src/thread/context.cpp26
2 files changed, 79 insertions, 0 deletions
diff --git a/src/pal/src/include/pal/context.h b/src/pal/src/include/pal/context.h
index 69acd361bb..1f7c7517b6 100644
--- a/src/pal/src/include/pal/context.h
+++ b/src/pal/src/include/pal/context.h
@@ -375,6 +375,59 @@ const fpsimd_context* GetConstNativeSigSimdContext(const native_context_t *mc)
#define MCREG_Pc(mc) ((mc).arm_pc)
#define MCREG_Cpsr(mc) ((mc).arm_cpsr)
+
+// Flatterned layout of the arm kernel struct vfp_sigframe
+struct VfpSigFrame
+{
+ DWORD magic;
+ DWORD size;
+ DWORD64 D[32]; // Some arm cpus have 16 D registers. The kernel will ignore the extra.
+ DWORD Fpscr;
+ DWORD Padding;
+ DWORD Fpexc;
+ DWORD Fpinst;
+ DWORD Fpinst2;
+ DWORD Padding2;
+};
+
+inline
+VfpSigFrame* GetNativeSigSimdContext(native_context_t *mc)
+{
+ size_t size = 0;
+
+ const DWORD VfpMagic = 0x56465001; // VFP_MAGIC from arm kernel
+
+ do
+ {
+ VfpSigFrame* fp = reinterpret_cast<VfpSigFrame *>(&mc->uc_regspace[size]);
+
+ if (fp->magic == VfpMagic)
+ {
+ _ASSERTE(fp->size == sizeof(VfpSigFrame));
+ _ASSERTE(size + fp->size <= sizeof(mc->uc_regspace));
+
+ return fp;
+ }
+
+ if (fp->size == 0)
+ {
+ break;
+ }
+
+ size += fp->size;
+ } while (size + sizeof(VfpSigFrame) <= sizeof(mc->uc_regspace));
+
+ // VFP is not required on all armv7 processors, this structure may not be present
+
+ return nullptr;
+}
+
+inline
+const VfpSigFrame* GetConstNativeSigSimdContext(const native_context_t *mc)
+{
+ return GetNativeSigSimdContext(const_cast<native_context_t*>(mc));
+}
+
#elif defined(_X86_)
#define MCREG_Ebx(mc) ((mc).mc_ebx)
diff --git a/src/pal/src/thread/context.cpp b/src/pal/src/thread/context.cpp
index b65190da72..cd2fe41bc4 100644
--- a/src/pal/src/thread/context.cpp
+++ b/src/pal/src/thread/context.cpp
@@ -476,6 +476,16 @@ void CONTEXTToNativeContext(CONST CONTEXT *lpContext, native_context_t *native)
*(NEON128*) &fp->vregs[i] = lpContext->V[i];
}
}
+#elif defined(_ARM_)
+ VfpSigFrame* fp = GetNativeSigSimdContext(native);
+ if (fp)
+ {
+ fp->Fpscr = lpContext->Fpscr;
+ for (int i = 0; i < 32; i++)
+ {
+ fp->D[i] = lpContext->D[i];
+ }
+ }
#endif
}
@@ -585,6 +595,22 @@ void CONTEXTFromNativeContext(const native_context_t *native, LPCONTEXT lpContex
lpContext->V[i] = *(NEON128*) &fp->vregs[i];
}
}
+#elif defined(_ARM_)
+ const VfpSigFrame* fp = GetConstNativeSigSimdContext(native);
+ if (fp)
+ {
+ lpContext->Fpscr = fp->Fpscr;
+ for (int i = 0; i < 32; i++)
+ {
+ lpContext->D[i] = fp->D[i];
+ }
+ }
+ else
+ {
+ // Floating point state is not valid
+ // Mark the context correctly
+ lpContext->ContextFlags &= ~(ULONG)CONTEXT_FLOATING_POINT;
+ }
#endif
}