Skip to content

Commit 3c5123e

Browse files
authored
[RISC-V] Add more gcdump and gcinfo code. (dotnet#94219)
* [RISC-V] Add more gcdump and gcinfo code. * Add more comments.
1 parent e7ab2f6 commit 3c5123e

File tree

2 files changed

+120
-9
lines changed

2 files changed

+120
-9
lines changed

src/coreclr/gcdump/gcdumpnonx86.cpp

Lines changed: 38 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,42 @@ PCSTR GetRegName (UINT32 regnum)
7373
assert(!"unimplemented on LOONGARCH yet");
7474
return "???";
7575
#elif defined(TARGET_RISCV64)
76-
assert(!"unimplemented on RISCV64 yet");
76+
switch (regnum)
77+
{
78+
case 0: return "r0";
79+
case 1: return "ra";
80+
case 2: return "sp";
81+
case 3: return "gp";
82+
case 4: return "tp";
83+
case 5: return "t0";
84+
case 6: return "t1";
85+
case 7: return "t2";
86+
case 8: return "fp";
87+
case 9: return "s1";
88+
case 10: return "a0";
89+
case 11: return "a1";
90+
case 12: return "a2";
91+
case 13: return "a3";
92+
case 14: return "a4";
93+
case 15: return "a5";
94+
case 16: return "a6";
95+
case 17: return "a7";
96+
case 18: return "s2";
97+
case 19: return "s3";
98+
case 20: return "s4";
99+
case 21: return "s5";
100+
case 22: return "s6";
101+
case 23: return "s7";
102+
case 24: return "s8";
103+
case 25: return "s9";
104+
case 26: return "s10";
105+
case 27: return "s11";
106+
case 28: return "t3";
107+
case 29: return "t4";
108+
case 30: return "t5";
109+
case 31: return "t6";
110+
}
111+
77112
return "???";
78113
#endif
79114
}
@@ -290,7 +325,7 @@ size_t GCDump::DumpGCTable(PTR_CBYTE gcInfoBlock,
290325
| DECODE_GC_LIFETIMES
291326
| DECODE_PROLOG_LENGTH
292327
| DECODE_RETURN_KIND
293-
#if defined(TARGET_ARM) || defined(TARGET_ARM64)
328+
#if defined(TARGET_ARM) || defined(TARGET_ARM64) || defined(TARGET_RISCV64)
294329
| DECODE_HAS_TAILCALLS
295330
#endif
296331
),
@@ -423,7 +458,7 @@ size_t GCDump::DumpGCTable(PTR_CBYTE gcInfoBlock,
423458

424459
#ifdef TARGET_AMD64
425460
gcPrintf("Wants Report Only Leaf: %u\n", hdrdecoder.WantsReportOnlyLeaf());
426-
#elif defined(TARGET_ARM) || defined(TARGET_ARM64)
461+
#elif defined(TARGET_ARM) || defined(TARGET_ARM64) || defined(TARGET_RISCV64)
427462
gcPrintf("Has tailcalls: %u\n", hdrdecoder.HasTailCalls());
428463
#endif // TARGET_AMD64
429464
#ifdef FIXED_STACK_PARAMETER_SCRATCH_AREA

src/coreclr/gcinfo/gcinfodumper.cpp

Lines changed: 82 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -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 = &regdisp.ctxPtrsOne;
734+
regdisp.pCallerContextPointers = &regdisp.ctxPtrsTwo;
735+
736+
// Set S1
737+
regdisp.pCurrentContextPointers->S1 = &regdisp.pCurrentContext->S1;
738+
regdisp.pCallerContextPointers ->S1 = &regdisp.pCallerContext ->S1;
739+
740+
ULONG64 **ppCurrentReg = &regdisp.pCurrentContextPointers->S2;
741+
ULONG64 **ppCallerReg = &regdisp.pCallerContextPointers ->S2;
742+
// Set S2-S11
743+
for (iReg = 0; iReg < 10; iReg++)
744+
{
745+
*(ppCurrentReg + iReg) = &regdisp.pCurrentContext->S2 + iReg;
746+
*(ppCallerReg + iReg) = &regdisp.pCallerContext ->S2 + iReg;
747+
}
748+
749+
// Set Fp
750+
regdisp.pCurrentContextPointers->Fp = &regdisp.pCurrentContext->Fp;
751+
regdisp.pCallerContextPointers ->Fp = &regdisp.pCallerContext ->Fp;
752+
753+
// Set Gp
754+
regdisp.pCurrentContextPointers->Gp = &regdisp.pCurrentContext->Gp;
755+
regdisp.pCallerContextPointers ->Gp = &regdisp.pCallerContext ->Gp;
756+
757+
// Set Tp
758+
regdisp.pCurrentContextPointers->Tp = &regdisp.pCurrentContext->Tp;
759+
regdisp.pCallerContextPointers ->Tp = &regdisp.pCallerContext ->Tp;
760+
761+
// Set Ra
762+
regdisp.pCurrentContextPointers->Ra = &regdisp.pCurrentContext->Ra;
763+
regdisp.pCallerContextPointers ->Ra = &regdisp.pCallerContext ->Ra;
764+
765+
regdisp.volatileCurrContextPointers.R0 = &regdisp.pCurrentContext->R0;
766+
regdisp.volatileCurrContextPointers.A0 = &regdisp.pCurrentContext->A0;
767+
regdisp.volatileCurrContextPointers.A1 = &regdisp.pCurrentContext->A1;
768+
regdisp.volatileCurrContextPointers.A2 = &regdisp.pCurrentContext->A2;
769+
regdisp.volatileCurrContextPointers.A3 = &regdisp.pCurrentContext->A3;
770+
regdisp.volatileCurrContextPointers.A4 = &regdisp.pCurrentContext->A4;
771+
regdisp.volatileCurrContextPointers.A5 = &regdisp.pCurrentContext->A5;
772+
regdisp.volatileCurrContextPointers.A6 = &regdisp.pCurrentContext->A6;
773+
regdisp.volatileCurrContextPointers.A7 = &regdisp.pCurrentContext->A7;
774+
regdisp.volatileCurrContextPointers.T0 = &regdisp.pCurrentContext->T0;
775+
regdisp.volatileCurrContextPointers.T1 = &regdisp.pCurrentContext->T1;
776+
regdisp.volatileCurrContextPointers.T2 = &regdisp.pCurrentContext->T2;
777+
regdisp.volatileCurrContextPointers.T3 = &regdisp.pCurrentContext->T3;
778+
regdisp.volatileCurrContextPointers.T4 = &regdisp.pCurrentContext->T4;
779+
regdisp.volatileCurrContextPointers.T5 = &regdisp.pCurrentContext->T5;
780+
regdisp.volatileCurrContextPointers.T6 = &regdisp.pCurrentContext->T6;
708781
#else
709782
PORTABILITY_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

Comments
 (0)