From 9f21318b107dc5122703191246863eaa1ac0a5cf Mon Sep 17 00:00:00 2001 From: Steve MacLean Date: Wed, 17 Jul 2019 13:28:11 -0400 Subject: Arm64 Fix Rtl*Context (#25745) Fix issues related to save restore of FPCR/FPSR/V0/V31 There were several bugs in the assembly causing FPCR/FPSR to overwrite V0 on RtlCaptureContext. Then restore from V0 on RtlRestoreContext --- src/pal/src/arch/arm64/asmconstants.h | 4 ++-- src/pal/src/arch/arm64/context2.S | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/pal/src/arch/arm64/asmconstants.h b/src/pal/src/arch/arm64/asmconstants.h index b2bf74461f..08502ed3b3 100644 --- a/src/pal/src/arch/arm64/asmconstants.h +++ b/src/pal/src/arch/arm64/asmconstants.h @@ -88,8 +88,8 @@ #define CONTEXT_V29 CONTEXT_V28+16 #define CONTEXT_V30 CONTEXT_V29+16 #define CONTEXT_V31 CONTEXT_V30+16 -#define CONTEXT_FLOAT_CONTROL_OFFSET CONTEXT_V31 +#define CONTEXT_FLOAT_CONTROL_OFFSET CONTEXT_V31+16 #define CONTEXT_Fpcr 0 -#define CONTEXT_Fpsr CONTEXT_Fpcr+4 +#define CONTEXT_Fpsr CONTEXT_Fpcr+8 #endif diff --git a/src/pal/src/arch/arm64/context2.S b/src/pal/src/arch/arm64/context2.S index 64a19c9df6..7b165c2314 100644 --- a/src/pal/src/arch/arm64/context2.S +++ b/src/pal/src/arch/arm64/context2.S @@ -99,9 +99,8 @@ LOCAL_LABEL(Done_CONTEXT_INTEGER): add x0, x0, CONTEXT_FLOAT_CONTROL_OFFSET mrs x1, fpcr mrs x2, fpsr - sub x0, x0, CONTEXT_FLOAT_CONTROL_OFFSET stp x1, x2, [x0, CONTEXT_Fpcr] - sub x0, x0, CONTEXT_NEON_OFFSET + sub x0, x0, CONTEXT_FLOAT_CONTROL_OFFSET + CONTEXT_NEON_OFFSET LOCAL_LABEL(Done_CONTEXT_FLOATING_POINT): @@ -173,10 +172,11 @@ LOCAL_LABEL(Restore_CONTEXT_FLOATING_POINT): ldp q26, q27, [x16, CONTEXT_V26] ldp q28, q29, [x16, CONTEXT_V28] ldp q30, q31, [x16, CONTEXT_V30] + add x16, x16, CONTEXT_FLOAT_CONTROL_OFFSET ldp x1, x2, [x16, CONTEXT_Fpcr] msr fpcr, x1 msr fpsr, x2 - sub x16, x16, CONTEXT_NEON_OFFSET + sub x16, x16, CONTEXT_FLOAT_CONTROL_OFFSET + CONTEXT_NEON_OFFSET LOCAL_LABEL(No_Restore_CONTEXT_FLOATING_POINT): tbz w17, #CONTEXT_INTEGER_BIT, LOCAL_LABEL(No_Restore_CONTEXT_INTEGER) -- cgit v1.2.3 From 89dbe8b65c9de8f7bb5dd993987f000f7e006c8f Mon Sep 17 00:00:00 2001 From: Steve MacLean Date: Thu, 18 Jul 2019 04:14:40 -0400 Subject: Arm64 support SIMD registers context to/from native context (#25757) --- src/pal/src/include/pal/context.h | 38 ++++++++++++++++++++++++++++++++++++++ src/pal/src/thread/context.cpp | 22 ++++++++++++++++++++++ 2 files changed, 60 insertions(+) (limited to 'src') diff --git a/src/pal/src/include/pal/context.h b/src/pal/src/include/pal/context.h index 146b9a0db9..69acd361bb 100644 --- a/src/pal/src/include/pal/context.h +++ b/src/pal/src/include/pal/context.h @@ -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(&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(mc)); +} + #else // For FreeBSD, as found in x86/ucontext.h #define MCREG_Rbp(mc) ((mc).mc_rbp) diff --git a/src/pal/src/thread/context.cpp b/src/pal/src/thread/context.cpp index 10b2db4ed0..b65190da72 100644 --- a/src/pal/src/thread/context.cpp +++ b/src/pal/src/thread/context.cpp @@ -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 } -- cgit v1.2.3 From 404e72adc3e721ef67b62c26a26c3e0112e67ed3 Mon Sep 17 00:00:00 2001 From: Steve MacLean Date: Thu, 18 Jul 2019 11:37:37 -0400 Subject: Arm64 restore d8-d15 in ThrowExceptionFromContextInternal (#25743) --- src/pal/src/arch/arm64/exceptionhelper.S | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'src') diff --git a/src/pal/src/arch/arm64/exceptionhelper.S b/src/pal/src/arch/arm64/exceptionhelper.S index c4499fb93f..93c9af1d06 100644 --- a/src/pal/src/arch/arm64/exceptionhelper.S +++ b/src/pal/src/arch/arm64/exceptionhelper.S @@ -31,6 +31,18 @@ LEAF_ENTRY ThrowExceptionFromContextInternal, _TEXT ldp x26,x27, [x0, #(CONTEXT_X26)] ldp x28,fp, [x0, #(CONTEXT_X28)] ldr lr, [x0, #(CONTEXT_Pc)] + + // Restore the lower 64 bits of v8-v15 + add x2, x0, CONTEXT_NEON_OFFSET + ldr d8, [x2, #(CONTEXT_V8 )] + ldr d9, [x2, #(CONTEXT_V9 )] + ldr d10, [x2, #(CONTEXT_V10)] + ldr d11, [x2, #(CONTEXT_V11)] + ldr d12, [x2, #(CONTEXT_V12)] + ldr d13, [x2, #(CONTEXT_V13)] + ldr d14, [x2, #(CONTEXT_V14)] + ldr d15, [x2, #(CONTEXT_V15)] + ldr x2, [x0, #(CONTEXT_Sp)] mov sp, x2 -- cgit v1.2.3 From 3f1804543d5021ea0cae4d46090e3a1ece96a7ba Mon Sep 17 00:00:00 2001 From: Steve MacLean Date: Thu, 18 Jul 2019 11:39:01 -0400 Subject: Arm64 : Fix ldr Dt/St emulation (#25729) --- src/debug/ee/arm64/arm64walker.cpp | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/debug/ee/arm64/arm64walker.cpp b/src/debug/ee/arm64/arm64walker.cpp index b38297b3ec..398d326e8a 100644 --- a/src/debug/ee/arm64/arm64walker.cpp +++ b/src/debug/ee/arm64/arm64walker.cpp @@ -200,12 +200,15 @@ BYTE* NativeWalker::SetupOrSimulateInstructionForPatchSkip(T_CONTEXT * context, switch (opc) { case 0: //4byte data into St - RegContents = 0xFFFFFFFF & RegContents; //zero the upper 32bit - SetReg(context, RegNum, RegContents); + SimdRegContents.Low = 0xFFFFFFFF & RegContents; //zero the upper 32bit + SimdRegContents.High = 0; + SetSimdReg(context, RegNum, SimdRegContents); + break; case 1: //8byte data into Dt - SetReg(context, RegNum, RegContents); + SimdRegContents.Low = RegContents; + SimdRegContents.High = 0; + SetSimdReg(context, RegNum, SimdRegContents); break; - case 2: //SIMD 16 byte data SimdRegContents = GetSimdMem(ip); SetSimdReg(context, RegNum, SimdRegContents); -- cgit v1.2.3 From 46123f097e9e536e6dbb316c1f9e1ed1b15675c2 Mon Sep 17 00:00:00 2001 From: Steve MacLean Date: Thu, 18 Jul 2019 16:12:06 -0400 Subject: Arm32 restore d8-d15 in ThrowExceptionFromContextInternal (#25777) --- src/pal/src/arch/arm/exceptionhelper.S | 33 +++++++++++++++++++++------------ 1 file changed, 21 insertions(+), 12 deletions(-) (limited to 'src') diff --git a/src/pal/src/arch/arm/exceptionhelper.S b/src/pal/src/arch/arm/exceptionhelper.S index 4e324ce3bd..1234305c09 100644 --- a/src/pal/src/arch/arm/exceptionhelper.S +++ b/src/pal/src/arch/arm/exceptionhelper.S @@ -21,18 +21,27 @@ LEAF_ENTRY ThrowExceptionFromContextInternal, _TEXT push_nonvol_reg {r7} /* FP. x64-RBP */ - ldr r4, [r0, #(CONTEXT_R4)] - ldr r5, [r0, #(CONTEXT_R5)] - ldr r6, [r0, #(CONTEXT_R6)] - ldr r7, [r0, #(CONTEXT_R7)] - ldr r8, [r0, #(CONTEXT_R8)] - ldr r9, [r0, #(CONTEXT_R9)] - ldr r10, [r0, #(CONTEXT_R10)] - ldr r11, [r0, #(CONTEXT_R11)] - ldr sp, [r0, #(CONTEXT_Sp)] - ldr lr, [r0, #(CONTEXT_Pc)] + ldr r4, [r0, #(CONTEXT_R4)] + ldr r5, [r0, #(CONTEXT_R5)] + ldr r6, [r0, #(CONTEXT_R6)] + ldr r7, [r0, #(CONTEXT_R7)] + ldr r8, [r0, #(CONTEXT_R8)] + ldr r9, [r0, #(CONTEXT_R9)] + ldr r10, [r0, #(CONTEXT_R10)] + ldr r11, [r0, #(CONTEXT_R11)] + ldr sp, [r0, #(CONTEXT_Sp)] + ldr lr, [r0, #(CONTEXT_Pc)] + + vldr d8, [r0, #(CONTEXT_D8)] + vldr d9, [r0, #(CONTEXT_D9)] + vldr d10, [r0, #(CONTEXT_D10)] + vldr d11, [r0, #(CONTEXT_D11)] + vldr d12, [r0, #(CONTEXT_D12)] + vldr d13, [r0, #(CONTEXT_D13)] + vldr d14, [r0, #(CONTEXT_D14)] + vldr d15, [r0, #(CONTEXT_D15)] // The PAL_SEHException pointer - mov r0, r1 - b EXTERNAL_C_FUNC(ThrowExceptionHelper) + mov r0, r1 + b EXTERNAL_C_FUNC(ThrowExceptionHelper) LEAF_END ThrowExceptionFromContextInternal, _TEXT -- cgit v1.2.3 From e4ece90664bcbbfe2e5e2e1bcc33b3fe99a9f6cb Mon Sep 17 00:00:00 2001 From: Steve MacLean Date: Fri, 19 Jul 2019 00:30:09 -0400 Subject: Arm32 support VFP registers context to/from native context (#25775) --- src/pal/src/include/pal/context.h | 53 +++++++++++++++++++++++++++++++++++++++ src/pal/src/thread/context.cpp | 26 +++++++++++++++++++ 2 files changed, 79 insertions(+) (limited to 'src') 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(&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(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 } -- cgit v1.2.3