diff options
author | Steve MacLean <Steve.MacLean@microsoft.com> | 2019-07-19 00:30:09 -0400 |
---|---|---|
committer | Steve MacLean <Steve.MacLean@Microsoft.com> | 2019-07-19 00:31:56 -0400 |
commit | e4ece90664bcbbfe2e5e2e1bcc33b3fe99a9f6cb (patch) | |
tree | f0161f7d65b07b951c3f7ae128c7754e8381074c /src/pal/src | |
parent | 46123f097e9e536e6dbb316c1f9e1ed1b15675c2 (diff) | |
download | coreclr-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.h | 53 | ||||
-rw-r--r-- | src/pal/src/thread/context.cpp | 26 |
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 } |