Skip to content

Commit e279a17

Browse files
shushanhfqiaopengcheng
and
qiaopengcheng
authored
[LoongArch64] add gc directory for LoongArch64. (#63071)
Co-authored-by: qiaopengcheng <[email protected]>
1 parent f2d4f88 commit e279a17

11 files changed

+174
-19
lines changed

src/coreclr/gc/env/gcenv.base.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -230,6 +230,11 @@ typedef DWORD (WINAPI *PTHREAD_START_ROUTINE)(void* lpThreadParameter);
230230
#define MemoryBarrier __sync_synchronize
231231
#endif // __arm__ || __aarch64__
232232

233+
#ifdef __loongarch64
234+
#define YieldProcessor() __asm__ volatile( "dbar 0; \n")
235+
#define MemoryBarrier __sync_synchronize
236+
#endif // __loongarch64
237+
233238
#endif // _MSC_VER
234239

235240
#ifdef _MSC_VER

src/coreclr/gc/env/gcenv.interlocked.inl

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,9 @@ __forceinline void Interlocked::ArmInterlockedOperationBarrier()
1717
// See PAL_ArmInterlockedOperationBarrier() in the PAL
1818
__sync_synchronize();
1919
#endif // HOST_ARM64
20+
#ifdef HOST_LOONGARCH64
21+
__sync_synchronize();
22+
#endif //HOST_LOONGARCH64
2023
}
2124
#endif // !_MSC_VER
2225

src/coreclr/gc/env/volatile.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -66,14 +66,16 @@
6666
#error The Volatile type is currently only defined for Visual C++ and GNU C++
6767
#endif
6868

69-
#if defined(__GNUC__) && !defined(HOST_X86) && !defined(HOST_AMD64) && !defined(HOST_ARM) && !defined(HOST_ARM64) && !defined(HOST_WASM)
70-
#error The Volatile type is currently only defined for GCC when targeting x86, AMD64, ARM, ARM64 or Wasm
69+
#if defined(__GNUC__) && !defined(HOST_X86) && !defined(HOST_AMD64) && !defined(HOST_ARM) && !defined(HOST_ARM64) && !defined(HOST_LOONGARCH64) && !defined(HOST_WASM)
70+
#error The Volatile type is currently only defined for GCC when targeting x86, AMD64, ARM, ARM64, LOONGARCH64 or Wasm
7171
#endif
7272

7373
#if defined(__GNUC__)
7474
#if defined(HOST_ARM) || defined(HOST_ARM64)
7575
// This is functionally equivalent to the MemoryBarrier() macro used on ARM on Windows.
7676
#define VOLATILE_MEMORY_BARRIER() asm volatile ("dmb ish" : : : "memory")
77+
#elif defined(HOST_LOONGARCH64)
78+
#define VOLATILE_MEMORY_BARRIER() asm volatile ("dbar 0 " : : : "memory")
7779
#else
7880
//
7981
// For GCC, we prevent reordering by the compiler by inserting the following after a volatile

src/coreclr/gc/gc.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5916,6 +5916,14 @@ extern "C" uint64_t __rdtsc();
59165916
#else // _MSC_VER
59175917
extern "C" ptrdiff_t get_cycle_count(void);
59185918
#endif // _MSC_VER
5919+
#elif defined(TARGET_LOONGARCH64)
5920+
static ptrdiff_t get_cycle_count()
5921+
{
5922+
////FIXME: TODO for LOONGARCH64:
5923+
//ptrdiff_t cycle;
5924+
__asm__ volatile ("break \n");
5925+
return 0;
5926+
}
59195927
#else
59205928
static ptrdiff_t get_cycle_count()
59215929
{

src/coreclr/gc/unix/gcenv.unix.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,8 @@ extern "C"
102102
# define __NR_membarrier 389
103103
# elif defined(__aarch64__)
104104
# define __NR_membarrier 283
105+
# elif defined(__loongarch64)
106+
# define __NR_membarrier 283
105107
# else
106108
# error Unknown architecture
107109
# endif
@@ -163,7 +165,7 @@ FOR_ALL_NUMA_FUNCTIONS
163165

164166
#endif // HAVE_NUMA_H
165167

166-
#if defined(HOST_ARM) || defined(HOST_ARM64)
168+
#if defined(HOST_ARM) || defined(HOST_ARM64) || defined(HOST_LOONGARCH64)
167169
#define SYSCONF_GET_NUMPROCS _SC_NPROCESSORS_CONF
168170
#else
169171
#define SYSCONF_GET_NUMPROCS _SC_NPROCESSORS_ONLN

src/coreclr/gcdump/gcdumpnonx86.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,9 @@ PCSTR GetRegName (UINT32 regnum)
6969
static CHAR szRegName[16];
7070
_snprintf_s(szRegName, ARRAY_SIZE(szRegName), sizeof(szRegName), "r%u", regnum);
7171
return szRegName;
72-
72+
#elif defined(TARGET_LOONGARCH64)
73+
assert(!"unimplemented on LOONGARCH yet");
74+
return "???";
7375
#endif
7476
}
7577

src/coreclr/gcinfo/gcinfodumper.cpp

Lines changed: 63 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -186,6 +186,44 @@ BOOL GcInfoDumper::ReportPointerRecord (
186186
REG(Lr, Lr),
187187
{ FIELD_OFFSET(T_CONTEXT, Sp) },
188188
#undef REG
189+
#elif defined(TARGET_LOONGARCH64)
190+
#undef REG
191+
#define REG(reg, field) { FIELD_OFFSET(Loongarch64VolatileContextPointer, field) }
192+
REG(zero, R0),
193+
REG(a0, A0),
194+
REG(a1, A1),
195+
REG(a2, A2),
196+
REG(a3, A3),
197+
REG(a4, A4),
198+
REG(a5, A5),
199+
REG(a6, A6),
200+
REG(a7, A7),
201+
REG(t0, T0),
202+
REG(t1, T1),
203+
REG(t2, T2),
204+
REG(t3, T3),
205+
REG(t4, T4),
206+
REG(t5, T5),
207+
REG(t6, T6),
208+
REG(t7, T7),
209+
REG(t8, T8),
210+
REG(x0, X0),
211+
#undef REG
212+
#define REG(reg, field) { FIELD_OFFSET(T_KNONVOLATILE_CONTEXT_POINTERS, field) }
213+
REG(s0, S0),
214+
REG(s1, S1),
215+
REG(s2, S2),
216+
REG(s3, S3),
217+
REG(s4, S4),
218+
REG(s5, S5),
219+
REG(s6, S6),
220+
REG(s7, S7),
221+
REG(s8, S8),
222+
REG(tp, Tp),
223+
REG(fp, Fp),
224+
REG(ra, Ra),
225+
{ FIELD_OFFSET(T_CONTEXT, Sp) },
226+
#undef REG
189227
#else
190228
PORTABILITY_ASSERT("GcInfoDumper::ReportPointerRecord is not implemented on this platform.")
191229
#endif
@@ -207,10 +245,16 @@ PORTABILITY_ASSERT("GcInfoDumper::ReportPointerRecord is not implemented on this
207245
#elif defined(TARGET_ARM)
208246
iSPRegister = (FIELD_OFFSET(T_CONTEXT, Sp) - FIELD_OFFSET(T_CONTEXT, R0)) / sizeof(ULONG);
209247
UINT iBFRegister = m_StackBaseRegister;
248+
#elif defined(TARGET_LOONGARCH64)
249+
assert(!"unimplemented on LOONGARCH yet");
250+
iSPRegister = 0;
210251
#endif
211252

212253
#if defined(TARGET_ARM) || defined(TARGET_ARM64)
213254
BYTE* pContext = (BYTE*)&(pRD->volatileCurrContextPointers);
255+
#elif defined(TARGET_LOONGARCH64)
256+
assert(!"unimplemented on LOONGARCH yet");
257+
BYTE* pContext = (BYTE*)pRD->pCurrentContext;
214258
#else
215259
BYTE* pContext = (BYTE*)pRD->pCurrentContext;
216260
#endif
@@ -277,6 +321,8 @@ PORTABILITY_ASSERT("GcInfoDumper::ReportPointerRecord is not implemented on this
277321
{
278322
break;
279323
}
324+
#elif defined(TARGET_LOONGARCH64)
325+
assert(!"unimplemented on LOONGARCH yet");
280326
#endif
281327
{
282328
_ASSERTE(iReg < nCONTEXTRegisters);
@@ -301,6 +347,9 @@ PORTABILITY_ASSERT("GcInfoDumper::ReportPointerRecord is not implemented on this
301347
{
302348
pReg = (SIZE_T*)((BYTE*)pRD->pCurrentContext + rgRegisters[iReg].cbContextOffset);
303349
}
350+
#elif defined(TARGET_LOONGARCH64)
351+
assert(!"unimplemented on LOONGARCH yet");
352+
pReg = (SIZE_T*)(pContext + rgRegisters[iReg].cbContextOffset);
304353
#else
305354
pReg = (SIZE_T*)(pContext + rgRegisters[iReg].cbContextOffset);
306355
#endif
@@ -370,6 +419,10 @@ PORTABILITY_ASSERT("GcInfoDumper::ReportPointerRecord is not implemented on this
370419
{
371420
#if defined(TARGET_ARM) || defined(TARGET_ARM64)
372421
base = GC_SP_REL;
422+
#elif defined(TARGET_LOONGARCH64)
423+
assert(!"unimplemented on LOONGARCH yet");
424+
//TODO: should confirm ?
425+
base = GC_SP_REL;
373426
#else
374427
if (0 == ctx)
375428
base = GC_SP_REL;
@@ -399,6 +452,8 @@ PORTABILITY_ASSERT("GcInfoDumper::ReportPointerRecord is not implemented on this
399452

400453
#if defined(TARGET_ARM) || defined(TARGET_ARM64)
401454
pContext = (BYTE*)pRD->pCurrentContextPointers;
455+
#elif defined(TARGET_LOONGARCH64)
456+
assert(!"unimplemented on LOONGARCH yet");
402457
#else
403458
pContext = (BYTE*)pRD->pCallerContext;
404459
#endif
@@ -602,6 +657,9 @@ GcInfoDumper::EnumerateStateChangesResults GcInfoDumper::EnumerateStateChanges (
602657
{
603658
*(ppVolatileReg+iReg) = &regdisp.pCurrentContext->X0 + iReg;
604659
}
660+
#elif defined(TARGET_LOONGARCH64)
661+
#pragma message("Unimplemented for LOONGARCH64 yet.")
662+
assert(!"unimplemented on LOONGARCH yet");
605663
#else
606664
PORTABILITY_ASSERT("GcInfoDumper::EnumerateStateChanges is not implemented on this platform.")
607665
#endif
@@ -649,9 +707,9 @@ PORTABILITY_ASSERT("GcInfoDumper::EnumerateStateChanges is not implemented on th
649707
(GcInfoDecoderFlags)( DECODE_SECURITY_OBJECT
650708
| DECODE_CODE_LENGTH
651709
| DECODE_VARARG
652-
#if defined(TARGET_ARM) || defined(TARGET_ARM64)
710+
#if defined(TARGET_ARM) || defined(TARGET_ARM64) || defined(TARGET_LOONGARCH64)
653711
| DECODE_HAS_TAILCALLS
654-
#endif // TARGET_ARM || TARGET_ARM64
712+
#endif // TARGET_ARM || TARGET_ARM64 || TARGET_LOONGARCH64
655713

656714
| DECODE_INTERRUPTIBILITY),
657715
offset);
@@ -672,6 +730,9 @@ PORTABILITY_ASSERT("GcInfoDumper::EnumerateStateChanges is not implemented on th
672730
UINT32 safePointOffset = offset;
673731
#if defined(TARGET_AMD64) || defined(TARGET_ARM) || defined(TARGET_ARM64)
674732
safePointOffset++;
733+
#elif defined(TARGET_LOONGARCH64)
734+
#pragma message("Unimplemented for LOONGARCH64 yet.")
735+
assert(!"unimplemented on LOONGARCH yet");
675736
#endif
676737
if(safePointDecoder.IsSafePoint(safePointOffset))
677738
{

src/coreclr/gcinfo/gcinfoencoder.cpp

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -487,7 +487,7 @@ GcInfoEncoder::GcInfoEncoder(
487487
m_ReversePInvokeFrameSlot = NO_REVERSE_PINVOKE_FRAME;
488488
#ifdef TARGET_AMD64
489489
m_WantsReportOnlyLeaf = false;
490-
#elif defined(TARGET_ARM) || defined(TARGET_ARM64)
490+
#elif defined(TARGET_ARM) || defined(TARGET_ARM64) || defined(TARGET_LOONGARCH64)
491491
m_HasTailCalls = false;
492492
#endif // TARGET_AMD64
493493
m_IsVarArg = false;
@@ -747,6 +747,9 @@ void GcInfoEncoder::SetStackBaseRegister( UINT32 regNum )
747747
_ASSERTE( regNum != NO_STACK_BASE_REGISTER );
748748
_ASSERTE(DENORMALIZE_STACK_BASE_REGISTER(NORMALIZE_STACK_BASE_REGISTER(regNum)) == regNum);
749749
_ASSERTE( m_StackBaseRegister == NO_STACK_BASE_REGISTER || m_StackBaseRegister == regNum );
750+
#if defined(TARGET_LOONGARCH64)
751+
assert(regNum == 3 || 22 == regNum);
752+
#endif
750753
m_StackBaseRegister = regNum;
751754
}
752755

@@ -762,7 +765,7 @@ void GcInfoEncoder::SetWantsReportOnlyLeaf()
762765
{
763766
m_WantsReportOnlyLeaf = true;
764767
}
765-
#elif defined(TARGET_ARM) || defined(TARGET_ARM64)
768+
#elif defined(TARGET_ARM) || defined(TARGET_ARM64) || defined(TARGET_LOONGARCH64)
766769
void GcInfoEncoder::SetHasTailCalls()
767770
{
768771
m_HasTailCalls = true;
@@ -1017,7 +1020,7 @@ void GcInfoEncoder::Build()
10171020
(m_SizeOfEditAndContinuePreservedArea == NO_SIZE_OF_EDIT_AND_CONTINUE_PRESERVED_AREA) &&
10181021
#ifdef TARGET_AMD64
10191022
!m_WantsReportOnlyLeaf &&
1020-
#elif defined(TARGET_ARM) || defined(TARGET_ARM64)
1023+
#elif defined(TARGET_ARM) || defined(TARGET_ARM64) || defined(TARGET_LOONGARCH64)
10211024
!m_HasTailCalls &&
10221025
#endif // TARGET_AMD64
10231026
!IsStructReturnKind(m_ReturnKind);
@@ -1028,6 +1031,9 @@ void GcInfoEncoder::Build()
10281031
{
10291032
// Slim encoding means nothing special, partially interruptible, maybe a default frame register
10301033
GCINFO_WRITE(m_Info1, 0, 1, FlagsSize); // Slim encoding
1034+
#if defined(TARGET_LOONGARCH64)
1035+
assert(m_StackBaseRegister == 22 || 3 == m_StackBaseRegister);
1036+
#endif
10311037
GCINFO_WRITE(m_Info1, (m_StackBaseRegister == NO_STACK_BASE_REGISTER) ? 0 : 1, 1, FlagsSize);
10321038

10331039
GCINFO_WRITE(m_Info1, m_ReturnKind, SIZE_OF_RETURN_KIND_IN_SLIM_HEADER, RetKindSize);
@@ -1040,10 +1046,13 @@ void GcInfoEncoder::Build()
10401046
GCINFO_WRITE(m_Info1, (hasGSCookie ? 1 : 0), 1, FlagsSize);
10411047
GCINFO_WRITE(m_Info1, ((m_PSPSymStackSlot != NO_PSP_SYM) ? 1 : 0), 1, FlagsSize);
10421048
GCINFO_WRITE(m_Info1, m_contextParamType, 2, FlagsSize);
1049+
#if defined(TARGET_LOONGARCH64)
1050+
assert(m_StackBaseRegister == 22 || 3 == m_StackBaseRegister);
1051+
#endif
10431052
GCINFO_WRITE(m_Info1, ((m_StackBaseRegister != NO_STACK_BASE_REGISTER) ? 1 : 0), 1, FlagsSize);
10441053
#ifdef TARGET_AMD64
10451054
GCINFO_WRITE(m_Info1, (m_WantsReportOnlyLeaf ? 1 : 0), 1, FlagsSize);
1046-
#elif defined(TARGET_ARM) || defined(TARGET_ARM64)
1055+
#elif defined(TARGET_ARM) || defined(TARGET_ARM64) || defined(TARGET_LOONGARCH64)
10471056
GCINFO_WRITE(m_Info1, (m_HasTailCalls ? 1 : 0), 1, FlagsSize);
10481057
#endif // TARGET_AMD64
10491058
GCINFO_WRITE(m_Info1, ((m_SizeOfEditAndContinuePreservedArea != NO_SIZE_OF_EDIT_AND_CONTINUE_PRESERVED_AREA) ? 1 : 0), 1, FlagsSize);
@@ -1140,6 +1149,9 @@ void GcInfoEncoder::Build()
11401149

11411150
if(!slimHeader && (m_StackBaseRegister != NO_STACK_BASE_REGISTER))
11421151
{
1152+
#if defined(TARGET_LOONGARCH64)
1153+
assert(m_StackBaseRegister == 22 || 3 == m_StackBaseRegister);
1154+
#endif
11431155
GCINFO_WRITE_VARL_U(m_Info1, NORMALIZE_STACK_BASE_REGISTER(m_StackBaseRegister), STACK_BASE_REGISTER_ENCBASE, StackBaseSize);
11441156
}
11451157

src/coreclr/inc/gcinfodecoder.h

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,8 @@ inline TADDR GetSP(T_CONTEXT* context)
8585
return (TADDR)context->Sp;
8686
#elif defined(TARGET_ARM64)
8787
return (TADDR)context->Sp;
88+
#elif defined(TARGET_LOONGARCH64)
89+
return (TADDR)context->Sp;
8890
#else
8991
_ASSERTE(!"nyi for platform");
9092
#endif
@@ -98,6 +100,8 @@ inline PCODE GetIP(T_CONTEXT* context)
98100
return (PCODE)context->Pc;
99101
#elif defined(TARGET_ARM64)
100102
return (PCODE)context->Pc;
103+
#elif defined(TARGET_LOONGARCH64)
104+
return (PCODE)context->Pc;
101105
#else
102106
_ASSERTE(!"nyi for platform");
103107
#endif
@@ -212,9 +216,9 @@ enum GcInfoDecoderFlags
212216
DECODE_EDIT_AND_CONTINUE = 0x800,
213217
DECODE_REVERSE_PINVOKE_VAR = 0x1000,
214218
DECODE_RETURN_KIND = 0x2000,
215-
#if defined(TARGET_ARM) || defined(TARGET_ARM64)
219+
#if defined(TARGET_ARM) || defined(TARGET_ARM64) || defined(TARGET_LOONGARCH64)
216220
DECODE_HAS_TAILCALLS = 0x4000,
217-
#endif // TARGET_ARM || TARGET_ARM64
221+
#endif // TARGET_ARM || TARGET_ARM64 || TARGET_LOONGARCH64
218222
};
219223

220224
enum GcInfoHeaderFlags
@@ -231,7 +235,7 @@ enum GcInfoHeaderFlags
231235
GC_INFO_HAS_STACK_BASE_REGISTER = 0x40,
232236
#ifdef TARGET_AMD64
233237
GC_INFO_WANTS_REPORT_ONLY_LEAF = 0x80,
234-
#elif defined(TARGET_ARM) || defined(TARGET_ARM64)
238+
#elif defined(TARGET_ARM) || defined(TARGET_ARM64) || defined(TARGET_LOONGARCH64)
235239
GC_INFO_HAS_TAILCALLS = 0x80,
236240
#endif // TARGET_AMD64
237241
GC_INFO_HAS_EDIT_AND_CONTINUE_PRESERVED_SLOTS = 0x100,
@@ -536,9 +540,9 @@ class GcInfoDecoder
536540
bool HasMethodTableGenericsInstContext();
537541
bool GetIsVarArg();
538542
bool WantsReportOnlyLeaf();
539-
#if defined(TARGET_ARM) || defined(TARGET_ARM64)
543+
#if defined(TARGET_ARM) || defined(TARGET_ARM64) || defined(TARGET_LOONGARCH64)
540544
bool HasTailCalls();
541-
#endif // TARGET_ARM || TARGET_ARM64
545+
#endif // TARGET_ARM || TARGET_ARM64 || TARGET_LOONGARCH64
542546
ReturnKind GetReturnKind();
543547
UINT32 GetCodeLength();
544548
UINT32 GetStackBaseRegister();
@@ -561,7 +565,7 @@ class GcInfoDecoder
561565
bool m_GenericSecretParamIsMT;
562566
#ifdef TARGET_AMD64
563567
bool m_WantsReportOnlyLeaf;
564-
#elif defined(TARGET_ARM) || defined(TARGET_ARM64)
568+
#elif defined(TARGET_ARM) || defined(TARGET_ARM64) || defined(TARGET_LOONGARCH64)
565569
bool m_HasTailCalls;
566570
#endif // TARGET_AMD64
567571
INT32 m_SecurityObjectStackSlot;

src/coreclr/inc/gcinfoencoder.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -440,7 +440,7 @@ class GcInfoEncoder
440440
// instead of once for each live function/funclet on the stack.
441441
// Called only by RyuJIT (not JIT64)
442442
void SetWantsReportOnlyLeaf();
443-
#elif defined(TARGET_ARM) || defined(TARGET_ARM64)
443+
#elif defined(TARGET_ARM) || defined(TARGET_ARM64) || defined(TARGET_LOONGARCH64)
444444
void SetHasTailCalls();
445445
#endif // TARGET_AMD64
446446

@@ -496,7 +496,7 @@ class GcInfoEncoder
496496
bool m_IsVarArg;
497497
#if defined(TARGET_AMD64)
498498
bool m_WantsReportOnlyLeaf;
499-
#elif defined(TARGET_ARM) || defined(TARGET_ARM64)
499+
#elif defined(TARGET_ARM) || defined(TARGET_ARM64) || defined(TARGET_LOONGARCH64)
500500
bool m_HasTailCalls;
501501
#endif // TARGET_AMD64
502502
INT32 m_SecurityObjectStackSlot;

0 commit comments

Comments
 (0)