@@ -288,15 +288,19 @@ PORTABILITY_ASSERT("GcInfoDumper::ReportPointerRecord is not implemented on this
288288 assert (!" unimplemented on LOONGARCH yet" );
289289 iSPRegister = 0 ;
290290#elif defined(TARGET_RISCV64)
291- assert (!" unimplemented on RISCV64 yet" );
292- iSPRegister = 0 ;
291+ iSPRegister = (offsetof (T_CONTEXT , Sp) - offsetof (T_CONTEXT , R0 )) / sizeof (ULONGLONG );
293292#endif
294293
295294#if defined(TARGET_ARM) || defined(TARGET_ARM64)
296295 BYTE * pContext = (BYTE *)&(pRD->volatileCurrContextPointers );
297296#elif defined(TARGET_LOONGARCH64)
298297 assert (!" unimplemented on LOONGARCH yet" );
299298 BYTE * pContext = (BYTE *)pRD->pCurrentContext ;
299+ #elif defined(TARGET_RISCV64)
300+ assert (!" unimplemented on RISCV64 yet" );
301+ // TODO implement risc-v code, that should care about volatile registers (same as arm/arm64 architectures)
302+ // instead of default code.
303+ BYTE * pContext = (BYTE *)pRD->pCurrentContext ;
300304#else
301305 BYTE * pContext = (BYTE *)pRD->pCurrentContext ;
302306#endif
@@ -365,6 +369,8 @@ PORTABILITY_ASSERT("GcInfoDumper::ReportPointerRecord is not implemented on this
365369 }
366370#elif defined(TARGET_LOONGARCH64)
367371 assert (!" unimplemented on LOONGARCH yet" );
372+ #elif defined(TARGET_RISCV64)
373+ assert (!" unimplemented on RISCV64 yet" );
368374#endif
369375 {
370376 _ASSERTE (iReg < nCONTEXTRegisters);
@@ -392,6 +398,11 @@ PORTABILITY_ASSERT("GcInfoDumper::ReportPointerRecord is not implemented on this
392398#elif defined(TARGET_LOONGARCH64)
393399 assert (!" unimplemented on LOONGARCH yet" );
394400 pReg = (SIZE_T *)(pContext + rgRegisters[iReg].cbContextOffset );
401+ #elif defined(TARGET_RISCV64)
402+ assert (!" unimplemented on RISCV64 yet" );
403+ // TODO implement risc-v code, that should care about volatile registers (same as arm/arm64 architectures)
404+ // instead of default code.
405+ pReg = (SIZE_T *)(pContext + rgRegisters[iReg].cbContextOffset );
395406#else
396407 pReg = (SIZE_T *)(pContext + rgRegisters[iReg].cbContextOffset );
397408#endif
@@ -465,6 +476,14 @@ PORTABILITY_ASSERT("GcInfoDumper::ReportPointerRecord is not implemented on this
465476 assert (!" unimplemented on LOONGARCH yet" );
466477 // TODO: should confirm ?
467478 base = GC_SP_REL ;
479+ #elif defined(TARGET_RISCV64)
480+ assert (!" unimplemented on RISCV64 yet" );
481+ // TODO implement risc-v code, that should care about volatile registers (same as arm/arm64 architectures)
482+ // instead of default code.
483+ if (0 == ctx)
484+ base = GC_SP_REL ;
485+ else
486+ base = GC_CALLER_SP_REL ;
468487#else
469488 if (0 == ctx)
470489 base = GC_SP_REL ;
@@ -496,6 +515,11 @@ PORTABILITY_ASSERT("GcInfoDumper::ReportPointerRecord is not implemented on this
496515 pContext = (BYTE *)pRD->pCurrentContextPointers ;
497516#elif defined(TARGET_LOONGARCH64)
498517 assert (!" unimplemented on LOONGARCH yet" );
518+ #elif defined(TARGET_RISCV64)
519+ assert (!" unimplemented on RISCV64 yet" );
520+ // TODO implement risc-v code, that should care about volatile registers (same as arm/arm64 architectures)
521+ // instead of default code.
522+ pContext = (BYTE *)pRD->pCallerContext ;
499523#else
500524 pContext = (BYTE *)pRD->pCallerContext ;
501525#endif
@@ -703,8 +727,57 @@ GcInfoDumper::EnumerateStateChangesResults GcInfoDumper::EnumerateStateChanges (
703727#pragma message("Unimplemented for LOONGARCH64 yet.")
704728 assert (!" unimplemented on LOONGARCH yet" );
705729#elif defined(TARGET_RISCV64)
706- #pragma message("Unimplemented for RISCV64 yet.")
707- assert (!" unimplemented on RISCV64 yet" );
730+ FILL_REGS (pCurrentContext->R0 , 33 );
731+ FILL_REGS (pCallerContext->R0 , 33 );
732+
733+ regdisp.pCurrentContextPointers = ®disp.ctxPtrsOne ;
734+ regdisp.pCallerContextPointers = ®disp.ctxPtrsTwo ;
735+
736+ // Set S1
737+ regdisp.pCurrentContextPointers ->S1 = ®disp.pCurrentContext ->S1 ;
738+ regdisp.pCallerContextPointers ->S1 = ®disp.pCallerContext ->S1 ;
739+
740+ ULONG64 **ppCurrentReg = ®disp.pCurrentContextPointers ->S2 ;
741+ ULONG64 **ppCallerReg = ®disp.pCallerContextPointers ->S2 ;
742+ // Set S2-S11
743+ for (iReg = 0 ; iReg < 10 ; iReg++)
744+ {
745+ *(ppCurrentReg + iReg) = ®disp.pCurrentContext ->S2 + iReg;
746+ *(ppCallerReg + iReg) = ®disp.pCallerContext ->S2 + iReg;
747+ }
748+
749+ // Set Fp
750+ regdisp.pCurrentContextPointers ->Fp = ®disp.pCurrentContext ->Fp ;
751+ regdisp.pCallerContextPointers ->Fp = ®disp.pCallerContext ->Fp ;
752+
753+ // Set Gp
754+ regdisp.pCurrentContextPointers ->Gp = ®disp.pCurrentContext ->Gp ;
755+ regdisp.pCallerContextPointers ->Gp = ®disp.pCallerContext ->Gp ;
756+
757+ // Set Tp
758+ regdisp.pCurrentContextPointers ->Tp = ®disp.pCurrentContext ->Tp ;
759+ regdisp.pCallerContextPointers ->Tp = ®disp.pCallerContext ->Tp ;
760+
761+ // Set Ra
762+ regdisp.pCurrentContextPointers ->Ra = ®disp.pCurrentContext ->Ra ;
763+ regdisp.pCallerContextPointers ->Ra = ®disp.pCallerContext ->Ra ;
764+
765+ regdisp.volatileCurrContextPointers .R0 = ®disp.pCurrentContext ->R0 ;
766+ regdisp.volatileCurrContextPointers .A0 = ®disp.pCurrentContext ->A0 ;
767+ regdisp.volatileCurrContextPointers .A1 = ®disp.pCurrentContext ->A1 ;
768+ regdisp.volatileCurrContextPointers .A2 = ®disp.pCurrentContext ->A2 ;
769+ regdisp.volatileCurrContextPointers .A3 = ®disp.pCurrentContext ->A3 ;
770+ regdisp.volatileCurrContextPointers .A4 = ®disp.pCurrentContext ->A4 ;
771+ regdisp.volatileCurrContextPointers .A5 = ®disp.pCurrentContext ->A5 ;
772+ regdisp.volatileCurrContextPointers .A6 = ®disp.pCurrentContext ->A6 ;
773+ regdisp.volatileCurrContextPointers .A7 = ®disp.pCurrentContext ->A7 ;
774+ regdisp.volatileCurrContextPointers .T0 = ®disp.pCurrentContext ->T0 ;
775+ regdisp.volatileCurrContextPointers .T1 = ®disp.pCurrentContext ->T1 ;
776+ regdisp.volatileCurrContextPointers .T2 = ®disp.pCurrentContext ->T2 ;
777+ regdisp.volatileCurrContextPointers .T3 = ®disp.pCurrentContext ->T3 ;
778+ regdisp.volatileCurrContextPointers .T4 = ®disp.pCurrentContext ->T4 ;
779+ regdisp.volatileCurrContextPointers .T5 = ®disp.pCurrentContext ->T5 ;
780+ regdisp.volatileCurrContextPointers .T6 = ®disp.pCurrentContext ->T6 ;
708781#else
709782PORTABILITY_ASSERT (" GcInfoDumper::EnumerateStateChanges is not implemented on this platform." );
710783#endif
@@ -752,9 +825,9 @@ PORTABILITY_ASSERT("GcInfoDumper::EnumerateStateChanges is not implemented on th
752825 (GcInfoDecoderFlags)( DECODE_SECURITY_OBJECT
753826 | DECODE_CODE_LENGTH
754827 | DECODE_VARARG
755- #if defined(TARGET_ARM) || defined(TARGET_ARM64) || defined(TARGET_LOONGARCH64)
828+ #if defined(TARGET_ARM) || defined(TARGET_ARM64) || defined(TARGET_LOONGARCH64) || defined(TARGET_RISCV64)
756829 | DECODE_HAS_TAILCALLS
757- #endif // TARGET_ARM || TARGET_ARM64 || TARGET_LOONGARCH64
830+ #endif // TARGET_ARM || TARGET_ARM64 || TARGET_LOONGARCH64 || TARGET_RISCV64
758831
759832 | DECODE_INTERRUPTIBILITY ),
760833 offset);
@@ -778,6 +851,9 @@ PORTABILITY_ASSERT("GcInfoDumper::EnumerateStateChanges is not implemented on th
778851#elif defined(TARGET_LOONGARCH64)
779852#pragma message("Unimplemented for LOONGARCH64 yet.")
780853 assert (!" unimplemented on LOONGARCH yet" );
854+ #elif defined(TARGET_RISCV64)
855+ #pragma message("Unimplemented for RISCV64 yet.")
856+ assert (!" unimplemented on RISCV64 yet" );
781857#endif
782858 if (safePointDecoder.IsSafePoint (safePointOffset))
783859 {
0 commit comments