Skip to content

Commit 76a7d1e

Browse files
authored
[LoongArch64] Implement Inline TLS field access for LoongArch64. (#88819)
1 parent c6e8726 commit 76a7d1e

File tree

4 files changed

+35
-7
lines changed

4 files changed

+35
-7
lines changed

src/coreclr/jit/codegenloongarch64.cpp

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1966,7 +1966,14 @@ void CodeGen::genCodeForStoreLclVar(GenTreeLclVar* lclNode)
19661966
}
19671967
else // store into register (i.e move into register)
19681968
{
1969-
if (dataReg != targetReg)
1969+
if (data->IsIconHandle(GTF_ICON_TLS_HDL))
1970+
{
1971+
assert(data->AsIntCon()->IconValue() == 0);
1972+
emitAttr attr = emitActualTypeSize(targetType);
1973+
// need to load the address from $tp.
1974+
emit->emitIns_R_R_I(INS_ori, attr, targetReg, REG_TP, 0);
1975+
}
1976+
else if (dataReg != targetReg)
19701977
{
19711978
// Assign into targetReg when dataReg (from op1) is not the same register
19721979
inst_Mov(targetType, targetReg, dataReg, true, emitActualTypeSize(targetType));

src/coreclr/jit/helperexpansion.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -658,6 +658,12 @@ bool Compiler::fgExpandThreadLocalAccessForCall(BasicBlock** pBlock, Statement*
658658
// mrs xt, tpidr_elf0
659659
// mov xd, [xt+cns]
660660
tlsValue = gtNewIconHandleNode(0, GTF_ICON_TLS_HDL);
661+
#elif defined(TARGET_LOONGARCH64)
662+
// Code sequence to access thread local variable on linux/loongarch64:
663+
//
664+
// ori, targetReg, $tp, 0
665+
// load rd, targetReg, cns
666+
tlsValue = gtNewIconHandleNode(0, GTF_ICON_TLS_HDL);
661667
#else
662668
assert(!"Unsupported scenario of optimizing TLS access on Linux Arm32/x86");
663669
#endif

src/coreclr/vm/jitinterface.cpp

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1414,11 +1414,11 @@ static void* GetTlsIndexObjectAddress()
14141414
return GetThreadStaticDescriptor(p);
14151415
}
14161416

1417-
#elif TARGET_ARM64
1417+
#elif defined(TARGET_ARM64) || defined(TARGET_LOONGARCH64)
14181418

14191419
extern "C" size_t GetThreadStaticsVariableOffset();
14201420

1421-
#endif // TARGET_ARM64
1421+
#endif // TARGET_ARM64 || TARGET_LOONGARCH64
14221422
#endif // TARGET_WINDOWS
14231423

14241424

@@ -1452,10 +1452,11 @@ void CEEInfo::getThreadLocalStaticBlocksInfo (CORINFO_THREAD_STATIC_BLOCKS_INFO*
14521452
pInfo->tlsGetAddrFtnPtr = reinterpret_cast<void*>(&__tls_get_addr);
14531453
pInfo->tlsIndexObject = GetTlsIndexObjectAddress();
14541454

1455-
#elif defined(TARGET_ARM64)
1455+
#elif defined(TARGET_ARM64) || defined(TARGET_LOONGARCH64)
14561456

1457-
// For Linux/arm64, just get the offset of thread static variable, and during execution,
1458-
// this offset, taken from trpid_elp0 system register gives back the thread variable address.
1457+
// For Linux arm64/loongarch64, just get the offset of thread static variable, and during execution,
1458+
// this offset, arm64 taken from trpid_elp0 system register gives back the thread variable address.
1459+
// this offset, loongarch64 taken from $tp register gives back the thread variable address.
14591460
threadStaticBaseOffset = GetThreadStaticsVariableOffset();
14601461

14611462
#else
@@ -1600,7 +1601,7 @@ void CEEInfo::getFieldInfo (CORINFO_RESOLVED_TOKEN * pResolvedToken,
16001601

16011602
if (optimizeThreadStaticAccess)
16021603
{
1603-
// For windows x64/x86/arm64, linux x64/arm64:
1604+
// For windows x64/x86/arm64, linux x64/arm64/loongarch64:
16041605
// We convert the TLS access to the optimized helper where we will store
16051606
// the static blocks in TLS directly and access them via inline code.
16061607
if ((pResult->helper == CORINFO_HELP_GETSHARED_NONGCTHREADSTATIC_BASE_NOCTOR) ||

src/coreclr/vm/loongarch64/asmhelpers.S

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1079,3 +1079,17 @@ NESTED_ENTRY OnCallCountThresholdReachedStub, _TEXT, NoHandler
10791079
NESTED_END OnCallCountThresholdReachedStub, _TEXT
10801080

10811081
#endif // FEATURE_TIERED_COMPILATION
1082+
1083+
// ------------------------------------------------------------------
1084+
// size_t GetThreadStaticsVariableOffset()
1085+
1086+
// Helper to calculate the offset of native thread local variable `t_ThreadStatics` in TCB. The offset has to be found at runtime
1087+
// once linker does its relocation and fixup of thread locals. The offset, after calculation is returned in `$a0` register.
1088+
1089+
LEAF_ENTRY GetThreadStaticsVariableOffset, _TEXT
1090+
PROLOG_SAVE_REG_PAIR_INDEXED 22, 1, 16
1091+
la.tls.ie $a0, t_ThreadStatics
1092+
EPILOG_RESTORE_REG_PAIR_INDEXED 22, 1, 16
1093+
EPILOG_RETURN
1094+
LEAF_END GetThreadStaticsVariableOffset, _TEXT
1095+
// ------------------------------------------------------------------

0 commit comments

Comments
 (0)