diff --git a/src/coreclr/debug/createdump/threadinfo.h b/src/coreclr/debug/createdump/threadinfo.h index 0945233b9f6b4..b97326346830f 100644 --- a/src/coreclr/debug/createdump/threadinfo.h +++ b/src/coreclr/debug/createdump/threadinfo.h @@ -14,10 +14,10 @@ class CrashInfo; #if defined(__loongarch64) // See src/coreclr/pal/src/include/pal/context.h -#define MCREG_Ra(mc) ((mc).gpr[1]) -#define MCREG_Fp(mc) ((mc).gpr[22]) -#define MCREG_Sp(mc) ((mc).gpr[3]) -#define MCREG_Pc(mc) ((mc).pc) +#define MCREG_Ra(mc) ((mc).regs[1]) +#define MCREG_Fp(mc) ((mc).regs[22]) +#define MCREG_Sp(mc) ((mc).regs[3]) +#define MCREG_Pc(mc) ((mc).csr_era) #endif #if defined(__riscv) @@ -35,14 +35,6 @@ class CrashInfo; #if defined(__arm__) #define user_regs_struct user_regs #define user_fpregs_struct user_fpregs -#elif defined(__loongarch64) -// struct user_regs_struct {} defined `/usr/include/loongarch64-linux-gnu/sys/user.h` - -struct user_fpregs_struct -{ - unsigned long long fpregs[32]; - unsigned long fpscr; -} __attribute__((__packed__)); #elif defined(__riscv) struct user_fpregs_struct { @@ -63,6 +55,10 @@ struct user_vfpregs_struct } __attribute__((__packed__)); #endif +#if defined(__loongarch64) +#define user_fpregs_struct user_fp_struct +#endif + #define STACK_OVERFLOW_EXCEPTION 0x800703e9 class ThreadInfo diff --git a/src/coreclr/debug/createdump/threadinfounix.cpp b/src/coreclr/debug/createdump/threadinfounix.cpp index d1683b9b2b390..de1495ca09ddc 100644 --- a/src/coreclr/debug/createdump/threadinfounix.cpp +++ b/src/coreclr/debug/createdump/threadinfounix.cpp @@ -58,7 +58,7 @@ ThreadInfo::Initialize() #elif defined(__x86_64__) TRACE("Thread %04x RIP %016llx RSP %016llx\n", m_tid, (unsigned long long)m_gpRegisters.rip, (unsigned long long)m_gpRegisters.rsp); #elif defined(__loongarch64) - TRACE("Thread %04x PC %016llx SP %016llx\n", m_tid, (unsigned long long)m_gpRegisters.pc, (unsigned long long)m_gpRegisters.gpr[3]); + TRACE("Thread %04x PC %016llx SP %016llx\n", m_tid, (unsigned long long)m_gpRegisters.csr_era, (unsigned long long)m_gpRegisters.regs[3]); #elif defined(__riscv) TRACE("Thread %04x PC %016llx SP %016llx\n", m_tid, (unsigned long long)m_gpRegisters.pc, (unsigned long long)m_gpRegisters.sp); #else @@ -235,15 +235,16 @@ ThreadInfo::GetThreadContext(uint32_t flags, CONTEXT* context) const } if ((flags & CONTEXT_INTEGER) == CONTEXT_INTEGER) { - context->Tp = m_gpRegisters.gpr[2]; - memcpy(&context->A0, &m_gpRegisters.gpr[4], sizeof(context->A0)*(21 - 4 + 1)); - memcpy(&context->S0, &m_gpRegisters.gpr[23], sizeof(context->S0)*9); + context->Tp = m_gpRegisters.regs[2]; + memcpy(&context->A0, &m_gpRegisters.regs[4], sizeof(context->A0)*(21 - 4 + 1)); + memcpy(&context->S0, &m_gpRegisters.regs[23], sizeof(context->S0)*9); } if ((flags & CONTEXT_FLOATING_POINT) == CONTEXT_FLOATING_POINT) { - assert(sizeof(context->F) == sizeof(m_fpRegisters.fpregs)); - memcpy(context->F, m_fpRegisters.fpregs, sizeof(context->F)); - context->Fcsr = m_fpRegisters.fpscr; + assert(sizeof(context->F) == sizeof(m_fpRegisters.fpr)); + memcpy(context->F, m_fpRegisters.fpr, sizeof(context->F)); + context->Fcsr = m_fpRegisters.fcsr; + context->Fcc = m_fpRegisters.fcc; } #elif defined(__riscv) assert(!"TODO RISCV64 NYI"); diff --git a/src/coreclr/debug/ee/loongarch64/dbghelpers.S b/src/coreclr/debug/ee/loongarch64/dbghelpers.S index 25452aa6a5dfc..608e8aea41a71 100644 --- a/src/coreclr/debug/ee/loongarch64/dbghelpers.S +++ b/src/coreclr/debug/ee/loongarch64/dbghelpers.S @@ -26,7 +26,7 @@ NESTED_ENTRY FuncEvalHijack, _TEXT, UnhandledExceptionHandlerUnix bl C_FUNC(FuncEvalHijackWorker) EPILOG_STACK_FREE 32 - EPILOG_BRANCH_REG $v0 + EPILOG_BRANCH_REG $a0 NESTED_END FuncEvalHijack // This is the general purpose hijacking stub. The DacDbi Hijack primitive will diff --git a/src/coreclr/debug/inc/dbgtargetcontext.h b/src/coreclr/debug/inc/dbgtargetcontext.h index e23aaa7c2333b..8239b7228cb4d 100644 --- a/src/coreclr/debug/inc/dbgtargetcontext.h +++ b/src/coreclr/debug/inc/dbgtargetcontext.h @@ -535,6 +535,7 @@ typedef struct DECLSPEC_ALIGN(16) { // Floating Point Registers // ULONGLONG F[32]; + DWORD64 Fcc; DWORD Fcsr; } DT_CONTEXT; diff --git a/src/coreclr/debug/shared/loongarch64/primitives.cpp b/src/coreclr/debug/shared/loongarch64/primitives.cpp index abf63b48b8f0a..b7ca8a69c7573 100644 --- a/src/coreclr/debug/shared/loongarch64/primitives.cpp +++ b/src/coreclr/debug/shared/loongarch64/primitives.cpp @@ -61,6 +61,7 @@ void CORDbgCopyThreadContext(DT_CONTEXT* pDst, const DT_CONTEXT* pSrc) CopyContextChunk(&pDst->F[0], &pSrc->F[0], &pDst->F[32], DT_CONTEXT_FLOATING_POINT); pDst->Fcsr = pSrc->Fcsr; + pDst->Fcc = pSrc->Fcc; } } diff --git a/src/coreclr/gc/gc.cpp b/src/coreclr/gc/gc.cpp index 2650339ceb97c..c0763e5bfee0e 100644 --- a/src/coreclr/gc/gc.cpp +++ b/src/coreclr/gc/gc.cpp @@ -6228,7 +6228,7 @@ extern "C" uint64_t __rdtsc(); { ////FIXME: TODO for LOONGARCH64: //ptrdiff_t cycle; - __asm__ volatile ("break \n"); + __asm__ volatile ("break 0 \n"); return 0; } #else diff --git a/src/coreclr/inc/crosscomp.h b/src/coreclr/inc/crosscomp.h index e03eac034b36f..7d105a5ac1802 100644 --- a/src/coreclr/inc/crosscomp.h +++ b/src/coreclr/inc/crosscomp.h @@ -449,6 +449,7 @@ typedef struct DECLSPEC_ALIGN(16) _T_CONTEXT { // //TODO-LoongArch64: support the SIMD. ULONGLONG F[32]; + DWORD64 Fcc; DWORD Fcsr; } T_CONTEXT, *PT_CONTEXT; diff --git a/src/coreclr/pal/inc/pal.h b/src/coreclr/pal/inc/pal.h index 494e5625ff966..1f4f24f59fce4 100644 --- a/src/coreclr/pal/inc/pal.h +++ b/src/coreclr/pal/inc/pal.h @@ -2175,6 +2175,7 @@ typedef struct DECLSPEC_ALIGN(16) _CONTEXT { // // TODO-LoongArch64: support the SIMD. ULONGLONG F[32]; + DWORD64 Fcc; DWORD Fcsr; } CONTEXT, *PCONTEXT, *LPCONTEXT; diff --git a/src/coreclr/pal/inc/unixasmmacrosloongarch64.inc b/src/coreclr/pal/inc/unixasmmacrosloongarch64.inc index d71cf8f969b12..345d2e492b72d 100644 --- a/src/coreclr/pal/inc/unixasmmacrosloongarch64.inc +++ b/src/coreclr/pal/inc/unixasmmacrosloongarch64.inc @@ -137,12 +137,11 @@ C_FUNC(\Name\()_End): .endm .macro EMIT_BREAKPOINT - break + break 0 .endm .macro EPILOG_BRANCH Target b \Target - //break .endm .macro EPILOG_BRANCH_REG reg diff --git a/src/coreclr/pal/src/include/pal/context.h b/src/coreclr/pal/src/include/pal/context.h index 88566730e961b..6eeeaa6fed745 100644 --- a/src/coreclr/pal/src/include/pal/context.h +++ b/src/coreclr/pal/src/include/pal/context.h @@ -234,7 +234,7 @@ bool Xstate_IsAvx512Supported(); #define FPREG_MxCsr(uc) (((struct fxsave*)(&(uc)->uc_mcontext.__fpregs))->fx_mxcsr) #define FPREG_MxCsr_Mask(uc) (((struct fxsave*)(&(uc)->uc_mcontext.__fpregs))->fx_mxcsr_mask) -#endif // HOST_LOONGARCH64 +#endif // !HOST_LOONGARCH64 && !HOST_RISCV64 #else // HOST_64BIT diff --git a/src/coreclr/pal/src/thread/context.cpp b/src/coreclr/pal/src/thread/context.cpp index 7fa019711d093..07afeea40d486 100644 --- a/src/coreclr/pal/src/thread/context.cpp +++ b/src/coreclr/pal/src/thread/context.cpp @@ -734,11 +734,14 @@ void CONTEXTToNativeContext(CONST CONTEXT *lpContext, native_context_t *native) static_assert_no_msg(sizeof(fp->fprs) == sizeof(lpContext->Fpr)); memcpy(fp->fprs, lpContext->Fpr, sizeof(lpContext->Fpr)); #elif defined(HOST_LOONGARCH64) - native->uc_mcontext.__fcsr = lpContext->Fcsr; - for (int i = 0; i < 32; i++) - { - native->uc_mcontext.__fpregs[i].__val64[0] = lpContext->F[i]; - } + struct sctx_info* info = (struct sctx_info*) native->uc_mcontext.__extcontext; + // TODO-LoongArch: supports SIMD128 and SIMD256. + _ASSERTE(FPU_CTX_MAGIC == info->magic); + + struct fpu_context* fpr = (struct fpu_context*) ++info; + fpr->fcsr = lpContext->Fcsr; + fpr->fcc = lpContext->Fcc; + memcpy(fpr->regs, lpContext->F, sizeof(lpContext->F)); #elif defined(HOST_RISCV64) native->uc_mcontext.__fpregs.__d.__fcsr = lpContext->Fcsr; for (int i = 0; i < 32; i++) @@ -928,11 +931,14 @@ void CONTEXTFromNativeContext(const native_context_t *native, LPCONTEXT lpContex static_assert_no_msg(sizeof(fp->fprs) == sizeof(lpContext->Fpr)); memcpy(lpContext->Fpr, fp->fprs, sizeof(lpContext->Fpr)); #elif defined(HOST_LOONGARCH64) - lpContext->Fcsr = native->uc_mcontext.__fcsr; - for (int i = 0; i < 32; i++) - { - lpContext->F[i] = native->uc_mcontext.__fpregs[i].__val64[0]; - } + struct sctx_info* info = (struct sctx_info*) native->uc_mcontext.__extcontext; + // TODO-LoongArch: supports SIMD128 and SIMD256. + _ASSERTE(FPU_CTX_MAGIC == info->magic); + + struct fpu_context* fpr = (struct fpu_context*) ++info; + lpContext->Fcsr = fpr->fcsr; + lpContext->Fcc = fpr->fcc; + memcpy(lpContext->F, fpr->regs, sizeof(lpContext->F)); #elif defined(HOST_RISCV64) lpContext->Fcsr = native->uc_mcontext.__fpregs.__d.__fcsr; for (int i = 0; i < 32; i++) diff --git a/src/coreclr/unwinder/loongarch64/unwinder.cpp b/src/coreclr/unwinder/loongarch64/unwinder.cpp index 47d36ccbafc38..61cd235947603 100644 --- a/src/coreclr/unwinder/loongarch64/unwinder.cpp +++ b/src/coreclr/unwinder/loongarch64/unwinder.cpp @@ -74,6 +74,7 @@ typedef struct _LOONGARCH64_VFP_STATE { struct _LOONGARCH64_VFP_STATE *Link; // link to next state entry ULONG Fcsr; // FCSR register + ULONG64 Fcc; // Fcc flags. ULONG64 F[32]; // All F registers (0-31) } LOONGARCH64_VFP_STATE, *PLOONGARCH64_VFP_STATE, KLOONGARCH64_VFP_STATE, *PKLOONGARCH64_VFP_STATE; @@ -184,6 +185,7 @@ Return Value: { ULONG Fcsr; + ULONG Fcc; ULONG RegIndex; ULONG_PTR SourceAddress; ULONG_PTR StartingSp; @@ -238,6 +240,9 @@ Return Value: if (Fcsr != (ULONG)-1) { ContextRecord->Fcsr = Fcsr; + SourceAddress = VfpStateAddress + offsetof(KLOONGARCH64_VFP_STATE, Fcc); + Fcc = MEMORY_READ_DWORD(UnwindParams, SourceAddress); + ContextRecord->Fcc = Fcc; SourceAddress = VfpStateAddress + offsetof(KLOONGARCH64_VFP_STATE, F); for (RegIndex = 0; RegIndex < 32; RegIndex++) { @@ -328,6 +333,9 @@ Return Value: SourceAddress = StartingSp + offsetof(T_CONTEXT, Fcsr); ContextRecord->Fcsr = MEMORY_READ_DWORD(UnwindParams, SourceAddress); + SourceAddress = StartingSp + offsetof(T_CONTEXT, Fcc); + ContextRecord->Fcc = MEMORY_READ_DWORD(UnwindParams, SourceAddress); + // // Inherit the unwound-to-call flag from this context // diff --git a/src/coreclr/vm/loongarch64/asmhelpers.S b/src/coreclr/vm/loongarch64/asmhelpers.S index 7fcf19e94e7d3..f18e8c9a70956 100644 --- a/src/coreclr/vm/loongarch64/asmhelpers.S +++ b/src/coreclr/vm/loongarch64/asmhelpers.S @@ -412,7 +412,7 @@ LOCAL_LABEL(Done): // Its imperative that the return value of HelperMethodFrameRestoreState is zero // as it is used in the state machine to loop until it becomes zero. // Refer to HELPER_METHOD_FRAME_END macro for details. - ori $v0, $zero, 0 + ori $a0, $zero, 0 jirl $r0, $ra, 0 LEAF_END HelperMethodFrameRestoreState, _TEXT @@ -508,7 +508,7 @@ NESTED_ENTRY VirtualMethodFixupStub, _TEXT, NoHandler bl VirtualMethodFixupWorker ori $t4,$a0,0 - // On return, v0 contains the target to tailcall to + // On return, a0 contains the target to tailcall to // pop the stack and restore original register state RESTORE_FLOAT_ARGUMENT_REGISTERS $sp, 96 @@ -608,7 +608,7 @@ LEAF_ENTRY JIT_GetSharedGCStaticBase_SingleAppDomain, _TEXT andi $t8, $a2, 1 beq $t8, $zero, 1f //LOCAL_LABEL(JIT_GetSharedGCStaticBase_SingleAppDomain_CallHelper) - ld.d $v0, $a0, DomainLocalModule__m_pGCStatics + ld.d $a0, $a0, DomainLocalModule__m_pGCStatics jirl $r0, $ra, 0 1: @@ -771,8 +771,8 @@ NESTED_ENTRY OnHijackTripThread, _TEXT, NoHandler PROLOG_SAVE_REG 31, 80 // save any integral return value(s) - st.d $v0, $sp, 96 - st.d $v1, $sp, 104 + st.d $a0, $sp, 96 + st.d $a1, $sp, 104 // save any FP/HFA return value(s) fst.d $f0, $sp, 112 @@ -784,8 +784,8 @@ NESTED_ENTRY OnHijackTripThread, _TEXT, NoHandler // restore callee saved registers // restore any integral return value(s) - ld.d $v0, $sp, 96 - ld.d $v1, $sp, 104 + ld.d $a0, $sp, 96 + ld.d $a1, $sp, 104 // restore any FP/HFA return value(s) fst.d $f0, $sp, 112 @@ -987,9 +987,9 @@ DelayLoad_Helper\suffix: addi.d $a0, $sp, __PWTB_TransitionBlock // pTransitionBlock bl DynamicHelperWorker - bne $v0, $r0, LOCAL_LABEL(FakeProlog\suffix\()_0) + bne $a0, $r0, LOCAL_LABEL(FakeProlog\suffix\()_0) - ld.d $v0, $sp, __PWTB_ArgumentRegisters + ld.d $a0, $sp, __PWTB_ArgumentRegisters EPILOG_WITH_TRANSITION_BLOCK_RETURN LOCAL_LABEL(FakeProlog\suffix\()_0): ori $t4,$a0,0 diff --git a/src/coreclr/vm/loongarch64/pinvokestubs.S b/src/coreclr/vm/loongarch64/pinvokestubs.S index 48a4ec9cf668d..15d4398785b61 100644 --- a/src/coreclr/vm/loongarch64/pinvokestubs.S +++ b/src/coreclr/vm/loongarch64/pinvokestubs.S @@ -107,20 +107,20 @@ NESTED_ENTRY JIT_PInvokeBegin, _TEXT, NoHandler ld.d $t4, $sp, 0 st.d $t4, $s0, InlinedCallFrame__m_pCalleeSavedFP - // v0 = GetThread() + // a0 = GetThread() bl GetThreadHelper - st.d $v0, $s0, InlinedCallFrame__m_pThread + st.d $a0, $s0, InlinedCallFrame__m_pThread // pFrame->m_Next = pThread->m_pFrame; - ld.d $t4, $v0, Thread_m_pFrame + ld.d $t4, $a0, Thread_m_pFrame st.d $t4, $s0, Frame__m_Next // pThread->m_pFrame = pFrame; - st.d $s0, $v0, Thread_m_pFrame + st.d $s0, $a0, Thread_m_pFrame // pThread->m_fPreemptiveGCDisabled = 0 - st.w $zero, $v0, Thread_m_fPreemptiveGCDisabled + st.w $zero, $a0, Thread_m_fPreemptiveGCDisabled EPILOG_RESTORE_REG 23, 16 //the stack slot at $sp+24 is empty for 16 byte alignment EPILOG_RESTORE_REG_PAIR_INDEXED 22, 1, 32