Skip to content
This repository was archived by the owner on Jan 23, 2023. It is now read-only.

Commit e4ece90

Browse files
committed
Arm32 support VFP registers context to/from native context (#25775)
1 parent 46123f0 commit e4ece90

File tree

2 files changed

+79
-0
lines changed

2 files changed

+79
-0
lines changed

src/pal/src/include/pal/context.h

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -375,6 +375,59 @@ const fpsimd_context* GetConstNativeSigSimdContext(const native_context_t *mc)
375375
#define MCREG_Pc(mc) ((mc).arm_pc)
376376
#define MCREG_Cpsr(mc) ((mc).arm_cpsr)
377377

378+
379+
// Flatterned layout of the arm kernel struct vfp_sigframe
380+
struct VfpSigFrame
381+
{
382+
DWORD magic;
383+
DWORD size;
384+
DWORD64 D[32]; // Some arm cpus have 16 D registers. The kernel will ignore the extra.
385+
DWORD Fpscr;
386+
DWORD Padding;
387+
DWORD Fpexc;
388+
DWORD Fpinst;
389+
DWORD Fpinst2;
390+
DWORD Padding2;
391+
};
392+
393+
inline
394+
VfpSigFrame* GetNativeSigSimdContext(native_context_t *mc)
395+
{
396+
size_t size = 0;
397+
398+
const DWORD VfpMagic = 0x56465001; // VFP_MAGIC from arm kernel
399+
400+
do
401+
{
402+
VfpSigFrame* fp = reinterpret_cast<VfpSigFrame *>(&mc->uc_regspace[size]);
403+
404+
if (fp->magic == VfpMagic)
405+
{
406+
_ASSERTE(fp->size == sizeof(VfpSigFrame));
407+
_ASSERTE(size + fp->size <= sizeof(mc->uc_regspace));
408+
409+
return fp;
410+
}
411+
412+
if (fp->size == 0)
413+
{
414+
break;
415+
}
416+
417+
size += fp->size;
418+
} while (size + sizeof(VfpSigFrame) <= sizeof(mc->uc_regspace));
419+
420+
// VFP is not required on all armv7 processors, this structure may not be present
421+
422+
return nullptr;
423+
}
424+
425+
inline
426+
const VfpSigFrame* GetConstNativeSigSimdContext(const native_context_t *mc)
427+
{
428+
return GetNativeSigSimdContext(const_cast<native_context_t*>(mc));
429+
}
430+
378431
#elif defined(_X86_)
379432

380433
#define MCREG_Ebx(mc) ((mc).mc_ebx)

src/pal/src/thread/context.cpp

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -476,6 +476,16 @@ void CONTEXTToNativeContext(CONST CONTEXT *lpContext, native_context_t *native)
476476
*(NEON128*) &fp->vregs[i] = lpContext->V[i];
477477
}
478478
}
479+
#elif defined(_ARM_)
480+
VfpSigFrame* fp = GetNativeSigSimdContext(native);
481+
if (fp)
482+
{
483+
fp->Fpscr = lpContext->Fpscr;
484+
for (int i = 0; i < 32; i++)
485+
{
486+
fp->D[i] = lpContext->D[i];
487+
}
488+
}
479489
#endif
480490
}
481491

@@ -585,6 +595,22 @@ void CONTEXTFromNativeContext(const native_context_t *native, LPCONTEXT lpContex
585595
lpContext->V[i] = *(NEON128*) &fp->vregs[i];
586596
}
587597
}
598+
#elif defined(_ARM_)
599+
const VfpSigFrame* fp = GetConstNativeSigSimdContext(native);
600+
if (fp)
601+
{
602+
lpContext->Fpscr = fp->Fpscr;
603+
for (int i = 0; i < 32; i++)
604+
{
605+
lpContext->D[i] = fp->D[i];
606+
}
607+
}
608+
else
609+
{
610+
// Floating point state is not valid
611+
// Mark the context correctly
612+
lpContext->ContextFlags &= ~(ULONG)CONTEXT_FLOATING_POINT;
613+
}
588614
#endif
589615
}
590616

0 commit comments

Comments
 (0)