Skip to content

[LoongArch64] Fix some bugs to make NativeAOT stable. #114618

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 10 commits into from
Apr 22, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -312,8 +312,6 @@ internal struct ReturnBlock
{
private IntPtr returnValue;
private IntPtr returnValue2;
private IntPtr returnValue3;
private IntPtr returnValue4;
}

[StructLayout(LayoutKind.Sequential)]
Expand Down Expand Up @@ -353,8 +351,8 @@ internal struct ArchitectureConstants

public const int NUM_ARGUMENT_REGISTERS = 8;
public const int ARGUMENTREGISTERS_SIZE = NUM_ARGUMENT_REGISTERS * 8;
public const int ENREGISTERED_RETURNTYPE_MAXSIZE = 32; // bytes (four FP registers: d0,d1,d2 and d3)
public const int ENREGISTERED_RETURNTYPE_INTEGER_MAXSIZE = 16; // bytes (two int registers: x0 and x1)
public const int ENREGISTERED_RETURNTYPE_MAXSIZE = 16; // bytes (two FP registers: f0, f1)
public const int ENREGISTERED_RETURNTYPE_INTEGER_MAXSIZE = 16; // bytes (two int registers: a0, a1)
public const int ENREGISTERED_RETURNTYPE_INTEGER_MAXSIZE_PRIMITIVE = 8;
public const int ENREGISTERED_PARAMTYPE_MAXSIZE = 16; // bytes (max value type size that can be passed by value)
public const int STACK_ELEM_SIZE = 8;
Expand Down
2 changes: 1 addition & 1 deletion src/coreclr/nativeaot/Runtime/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -245,7 +245,7 @@ endif()

add_definitions(-DFEATURE_BASICFREEZE)
add_definitions(-DFEATURE_CONSERVATIVE_GC)
if(CLR_CMAKE_TARGET_ARCH_AMD64 OR CLR_CMAKE_TARGET_ARCH_ARM64 OR CLR_CMAKE_TARGET_ARCH_RISCV64)
if(CLR_CMAKE_TARGET_ARCH_AMD64 OR CLR_CMAKE_TARGET_ARCH_ARM64 OR CLR_CMAKE_TARGET_ARCH_RISCV64 OR CLR_CMAKE_TARGET_ARCH_LOONGARCH64)
add_definitions(-DFEATURE_USE_SOFTWARE_WRITE_WATCH_FOR_GC_HEAP)
add_definitions(-DFEATURE_MANUALLY_MANAGED_CARD_BUNDLES)
endif()
Expand Down
2 changes: 1 addition & 1 deletion src/coreclr/nativeaot/Runtime/MiscHelpers.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -345,7 +345,7 @@ FCIMPL1(uint8_t *, RhGetCodeTarget, uint8_t * pCodeOrg)
pCode++;
}
// is this an indirect jump?
// pcalau12i $t7, imm20; ld.d $t7, $t7, imm12; jirl $r0, $t7, 0
// pcalau12i $rd, imm20; ld.d $rd, $rj, imm12; jirl $rd, $rj, 0
if ((pCode[0] & 0xfe000000) == 0x1a000000 &&
(pCode[1] & 0xffc00000) == 0x28c00000 &&
(pCode[2] & 0xfc000000) == 0x4c000000)
Expand Down
1 change: 0 additions & 1 deletion src/coreclr/nativeaot/Runtime/PalRedhawkCommon.h
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,6 @@ struct PAL_LIMITED_CONTEXT
uint64_t F[32 - 24]; // Only the F registers F24..F31 need to be preserved
// (F0-F23 are not preserved according to the ABI spec).


uintptr_t GetIp() const { return IP; }
uintptr_t GetSp() const { return SP; }
uintptr_t GetFp() const { return FP; }
Expand Down
15 changes: 8 additions & 7 deletions src/coreclr/nativeaot/Runtime/StackFrameIterator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -495,7 +495,7 @@ void StackFrameIterator::InternalInit(Thread * pThreadToWalk, PTR_PAL_LIMITED_CO
m_RegDisplay.pRA = (PTR_uintptr_t)PTR_TO_MEMBER_TADDR(PAL_LIMITED_CONTEXT, pCtx, RA);

//
// preserved vfp regs
// preserved fp regs
//
for (int32_t i = 0; i < 16 - 8; i++)
{
Expand Down Expand Up @@ -1282,6 +1282,7 @@ void StackFrameIterator::UnwindFuncletInvokeThunk()
m_RegDisplay.pR29 = SP++;
m_RegDisplay.pR30 = SP++;
m_RegDisplay.pR31 = SP++;
SP++; // for alignment padding

#elif defined(TARGET_RISCV64)
PTR_uint64_t f = (PTR_uint64_t)(m_RegDisplay.SP);
Expand Down Expand Up @@ -1476,12 +1477,12 @@ struct UniversalTransitionStackFrame
// Conservative GC reporting must be applied to everything between the base of the
// ReturnBlock and the top of the StackPassedArgs.
private:
uintptr_t m_pushedFP; // ChildSP+000 CallerSP-0F0 (0x08 bytes) (fp)
uintptr_t m_pushedRA; // ChildSP+008 CallerSP-0E8 (0x08 bytes) (ra)
Fp128 m_fpArgRegs[8]; // ChildSP+010 CallerSP-0E0 (0x80 bytes) (fa0-fa7)
uintptr_t m_returnBlock[4]; // ChildSP+090 CallerSP-060 (0x20 bytes)
uintptr_t m_intArgRegs[8]; // ChildSP+0B0 CallerSP-040 (0x40 bytes) (a0-a7)
uintptr_t m_stackPassedArgs[1]; // ChildSP+0F0 CallerSP+000 (unknown size)
uintptr_t m_pushedFP; // ChildSP+000 CallerSP-0A0 (0x08 bytes) (fp)
uintptr_t m_pushedRA; // ChildSP+008 CallerSP-098 (0x08 bytes) (ra)
uint64_t m_fpArgRegs[8]; // ChildSP+010 CallerSP-090 (0x40 bytes) (fa0-fa7)
uintptr_t m_returnBlock[2]; // ChildSP+050 CallerSP-050 (0x10 bytes)
uintptr_t m_intArgRegs[8]; // ChildSP+060 CallerSP-040 (0x40 bytes) (a0-a7)
uintptr_t m_stackPassedArgs[1]; // ChildSP+0A0 CallerSP+000 (unknown size)

public:
PTR_uintptr_t get_CallerSP() { return GET_POINTER_TO_FIELD(m_stackPassedArgs[0]); }
Expand Down
4 changes: 4 additions & 0 deletions src/coreclr/nativeaot/Runtime/ThunksMapping.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -244,10 +244,14 @@ EXTERN_C void* QCALLTYPE RhAllocateThunksMapping()
//jirl $r0, $t8, 0

int delta = (int)(pCurrentDataAddress - pCurrentThunkAddress);
ASSERT((-0x200000 <= delta) && (delta < 0x200000));

*((uint32_t*)pCurrentThunkAddress) = 0x18000013 | (((delta & 0x3FFFFC) >> 2) << 5);
pCurrentThunkAddress += 4;

delta += OS_PAGE_SIZE - POINTER_SIZE - (i * POINTER_SIZE * 2) - 4;
ASSERT((-0x200000 <= delta) && (delta < 0x200000));

*((uint32_t*)pCurrentThunkAddress) = 0x18000014 | (((delta & 0x3FFFFC) >> 2) << 5);
pCurrentThunkAddress += 4;

Expand Down
4 changes: 2 additions & 2 deletions src/coreclr/nativeaot/Runtime/gcenv.ee.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -399,7 +399,7 @@ void GCToEEInterface::StompWriteBarrier(WriteBarrierParameters* args)
// On architectures with strong ordering, we only need to prevent compiler reordering.
// Otherwise we put a process-wide fence here (so that we could use an ordinary read in the barrier)

#if defined(HOST_ARM64) || defined(HOST_ARM)
#if defined(HOST_ARM64) || defined(HOST_ARM) || defined(HOST_LOONGARCH64) || defined(HOST_RISCV64)
if (!is_runtime_suspended)
{
// If runtime is not suspended, force all threads to see the changed table before seeing updated heap boundaries.
Expand All @@ -411,7 +411,7 @@ void GCToEEInterface::StompWriteBarrier(WriteBarrierParameters* args)
g_lowest_address = args->lowest_address;
g_highest_address = args->highest_address;

#if defined(HOST_ARM64) || defined(HOST_ARM)
#if defined(HOST_ARM64) || defined(HOST_ARM) || defined(HOST_LOONGARCH64) || defined(HOST_RISCV64)
if (!is_runtime_suspended)
{
// If runtime is not suspended, force all threads to see the changed state before observing future allocations.
Expand Down
2 changes: 0 additions & 2 deletions src/coreclr/nativeaot/Runtime/inc/rhbinder.h
Original file line number Diff line number Diff line change
Expand Up @@ -341,8 +341,6 @@ enum PInvokeTransitionFrameFlags : uint64_t
#elif defined(TARGET_LOONGARCH64)
enum PInvokeTransitionFrameFlags : uint64_t
{
// NOTE: Keep in sync with src\coreclr\nativeaot\Runtime\loongarch64\AsmMacros.h

// NOTE: The order in which registers get pushed in the PInvokeTransitionFrame's m_PreservedRegs list has
// to match the order of these flags (that's also the order in which they are read in StackFrameIterator.cpp

Expand Down
6 changes: 2 additions & 4 deletions src/coreclr/nativeaot/Runtime/loongarch64/AllocFast.S
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,6 @@
#define OFFSETOF__Thread__m_alloc_context__alloc_ptr (OFFSETOF__Thread__m_eeAllocContext + OFFSETOF__ee_alloc_context__m_rgbAllocContextBuffer + OFFSETOF__gc_alloc_context__alloc_ptr)
#define OFFSETOF__Thread__m_eeAllocContext__combined_limit (OFFSETOF__Thread__m_eeAllocContext + OFFSETOF__ee_alloc_context__combined_limit)



// Allocate non-array, non-finalizable object. If the allocation doesn't fit into the current thread's
// allocation context then automatically fallback to the slow allocation path.
// $a0 == MethodTable
Expand Down Expand Up @@ -83,7 +81,7 @@ LOCAL_LABEL(RhpNewFast_RarePath):
bl C_FUNC(RhpGcAlloc)

// Set the new objects MethodTable pointer on success.
beq $a0, $zero, LOCAL_LABEL(NewOutOfMemory)
beqz $a0, LOCAL_LABEL(NewOutOfMemory)

.cfi_remember_state
POP_COOP_PINVOKE_FRAME
Expand Down Expand Up @@ -245,7 +243,7 @@ LOCAL_LABEL(RhpNewArray_Rare):
bl C_FUNC(RhpGcAlloc)

// Set the new objects MethodTable pointer and length on success.
beq $a0, $zero, LOCAL_LABEL(ArrayOutOfMemory)
beqz $a0, LOCAL_LABEL(ArrayOutOfMemory)

.cfi_remember_state
POP_COOP_PINVOKE_FRAME
Expand Down
22 changes: 11 additions & 11 deletions src/coreclr/nativeaot/Runtime/loongarch64/AsmOffsetsCpu.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ PLAT_ASM_OFFSET(8, ExInfo, m_pExContext)
PLAT_ASM_OFFSET(10, ExInfo, m_exception)
PLAT_ASM_OFFSET(18, ExInfo, m_kind)
PLAT_ASM_OFFSET(19, ExInfo, m_passNumber)
PLAT_ASM_OFFSET(1c, ExInfo, m_idxCurClause)
PLAT_ASM_OFFSET(1C, ExInfo, m_idxCurClause)
PLAT_ASM_OFFSET(20, ExInfo, m_frameIter)
PLAT_ASM_OFFSET(268, ExInfo, m_notifyDebuggerSP)

Expand Down Expand Up @@ -51,16 +51,16 @@ PLAT_ASM_OFFSET(70, PAL_LIMITED_CONTEXT, IP)
PLAT_ASM_SIZEOF(148, REGDISPLAY)
PLAT_ASM_OFFSET(18, REGDISPLAY, SP)

PLAT_ASM_OFFSET(b8, REGDISPLAY, pR23)
PLAT_ASM_OFFSET(c0, REGDISPLAY, pR24)
PLAT_ASM_OFFSET(c8, REGDISPLAY, pR25)
PLAT_ASM_OFFSET(d0, REGDISPLAY, pR26)
PLAT_ASM_OFFSET(d8, REGDISPLAY, pR27)
PLAT_ASM_OFFSET(e0, REGDISPLAY, pR28)
PLAT_ASM_OFFSET(e8, REGDISPLAY, pR29)
PLAT_ASM_OFFSET(f0, REGDISPLAY, pR30)
PLAT_ASM_OFFSET(f8, REGDISPLAY, pR31)
PLAT_ASM_OFFSET(B8, REGDISPLAY, pR23)
PLAT_ASM_OFFSET(C0, REGDISPLAY, pR24)
PLAT_ASM_OFFSET(C8, REGDISPLAY, pR25)
PLAT_ASM_OFFSET(D0, REGDISPLAY, pR26)
PLAT_ASM_OFFSET(D8, REGDISPLAY, pR27)
PLAT_ASM_OFFSET(E0, REGDISPLAY, pR28)
PLAT_ASM_OFFSET(E8, REGDISPLAY, pR29)
PLAT_ASM_OFFSET(F0, REGDISPLAY, pR30)
PLAT_ASM_OFFSET(F8, REGDISPLAY, pR31)
PLAT_ASM_OFFSET(10, REGDISPLAY, pR2)
PLAT_ASM_OFFSET(b0, REGDISPLAY, pFP)
PLAT_ASM_OFFSET(B0, REGDISPLAY, pFP)
PLAT_ASM_OFFSET(8, REGDISPLAY, pRA)
PLAT_ASM_OFFSET(108, REGDISPLAY, F)
27 changes: 15 additions & 12 deletions src/coreclr/nativeaot/Runtime/loongarch64/ExceptionHandling.S
Original file line number Diff line number Diff line change
Expand Up @@ -18,14 +18,15 @@
ori $a3, $sp, 0

// Setup a PAL_LIMITED_CONTEXT on the stack {
// Total stack: 0xC0 (0x68+0x58)
.if \exceptionType == HARDWARE_EXCEPTION
addi.d $sp, $sp, -0x50
.cfi_adjust_cfa_offset 0x50
addi.d $sp, $sp, -0x58
.cfi_adjust_cfa_offset 0x58
st.d $a3, $sp, 0 // a3 is the SP and a1 is the IP of the fault site
st.d $a1, $sp, 8
.else
PROLOG_STACK_ALLOC 0x50
.cfi_adjust_cfa_offset 0x50
PROLOG_STACK_ALLOC 0x58
.cfi_adjust_cfa_offset 0x58
st.d $a3, $sp, 0 // a3 is the SP and ra is the IP of the fault site
st.d $ra, $sp, 8
.endif
Expand All @@ -37,6 +38,8 @@
fst.d $f29, $sp, 0x38
fst.d $f30, $sp, 0x40
fst.d $f31, $sp, 0x48
// Slot at $sp+0x50 is alignment padding

PROLOG_SAVE_REG_PAIR_INDEXED 22, 1, 0x68
st.d $zero, $sp, 0x10 // locations reserved for return value, not used for exception handling
st.d $zero, $sp, 0x18
Expand All @@ -61,7 +64,7 @@
// sp in fp. If sp is saved in fp in prolog then it is not expected that fp can change in the body
// of method. However, this method needs to be able to change fp before calling funclet.
// This is required to access locals in funclet.
PROLOG_SAVE_REG_PAIR_NO_FP_INDEXED 22, 1, 0x58
PROLOG_SAVE_REG_PAIR_NO_FP_INDEXED 22, 1, 0x60
PROLOG_SAVE_REG_PAIR 23, 24, 0x10
PROLOG_SAVE_REG_PAIR 25, 26, 0x20
PROLOG_SAVE_REG_PAIR 27, 28, 0x30
Expand Down Expand Up @@ -92,7 +95,7 @@
EPILOG_RESTORE_REG_PAIR 27, 28, 0x30
EPILOG_RESTORE_REG_PAIR 29, 30, 0x40
EPILOG_RESTORE_REG 31, 0x50
EPILOG_RESTORE_REG_PAIR_INDEXED 22, 1, 0x58
EPILOG_RESTORE_REG_PAIR_INDEXED 22, 1, 0x60
.endm


Expand Down Expand Up @@ -160,7 +163,7 @@
ld.d $t3, \regdisplayReg, OFFSETOF__REGDISPLAY__pFP
st.d $fp, $t3, 0
//
// store vfp preserved regs
// store fp preserved regs
//
addi.d $t3, \regdisplayReg, OFFSETOF__REGDISPLAY__F
fst.d $f24, $t3, 0x00
Expand Down Expand Up @@ -288,7 +291,7 @@
// where the tail-calling thread had saved RA, which may not match where we have saved RA.

ld.d $a1, $a2, OFFSETOF__Thread__m_pvHijackedReturnAddress
beq $a1, $zero, LOCAL_LABEL(NotHijacked)
beqz $a1, LOCAL_LABEL(NotHijacked)

ld.d $a3, $a2, OFFSETOF__Thread__m_ppvHijackedReturnAddressLocation

Expand Down Expand Up @@ -504,7 +507,7 @@ LOCAL_LABEL(NotHijacked):

LOCAL_LABEL(PopExInfoLoop):
ld.d $a3, $a3, OFFSETOF__ExInfo__m_pPrevExInfo // a3 <- next ExInfo
beq $a3, $zero, LOCAL_LABEL(DonePopping) // if (pExInfo == null) { we're done }
beqz $a3, LOCAL_LABEL(DonePopping) // if (pExInfo == null) { we're done }
blt $a3, $a2, LOCAL_LABEL(PopExInfoLoop) // if (pExInfo < resume SP} { keep going }

LOCAL_LABEL(DonePopping):
Expand All @@ -513,10 +516,10 @@ LOCAL_LABEL(DonePopping):
PREPARE_EXTERNAL_VAR_INDIRECT_W RhpTrapThreads, $a3

bstrpick.d $t7, $a3, TrapThreadsFlags_AbortInProgress_Bit, TrapThreadsFlags_AbortInProgress_Bit
beq $t7, $zero, LOCAL_LABEL(NoAbort)
beqz $t7, LOCAL_LABEL(NoAbort)

ld.d $a3, $sp, rsp_offset_is_not_handling_thread_abort
bne $a3, $zero, LOCAL_LABEL(NoAbort)
bnez $a3, LOCAL_LABEL(NoAbort)

// It was the ThreadAbortException, so rethrow it
// reset SP
Expand Down Expand Up @@ -773,7 +776,7 @@ LOCAL_LABEL(NoAbort):

LOCAL_LABEL(Propagate_PopExInfoLoop):
ld.d $a3, $a3, OFFSETOF__ExInfo__m_pPrevExInfo // a3 <- next ExInfo
beq $a3, $zero, LOCAL_LABEL(Propagate_DonePopping) // if (pExInfo == null) { we're done }
beqz $a3, LOCAL_LABEL(Propagate_DonePopping) // if (pExInfo == null) { we're done }
blt $a3, $a2, LOCAL_LABEL(Propagate_PopExInfoLoop) // if (pExInfo < resume SP} { keep going }

LOCAL_LABEL(Propagate_DonePopping):
Expand Down
33 changes: 12 additions & 21 deletions src/coreclr/nativeaot/Runtime/loongarch64/GcProbe.S
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,11 @@
#include <unixasmmacros.inc>
#include "AsmOffsets.inc"

#define PROBE_FRAME_SIZE 0xC8 // 4 * 8 for fixed part of PInvokeTransitionFrame (fp, ra, m_pThread, m_Flags) +
// 9 * 8 for callee saved registers +
#define PROBE_FRAME_SIZE 0x90 // 4 * 8 for fixed part of PInvokeTransitionFrame (fp, ra, m_pThread, m_Flags) +
// 9 * 8 for callee saved registers +
// 1 * 8 for caller SP +
// 2 * 8 for int returns +
// 1 * 8 for alignment padding +
// 4 * 16 for FP returns
// 2 * 8 for FP returns

// See PUSH_COOP_PINVOKE_FRAME, this macro is very similar, but also saves return registers
// and accepts the register bitmask
Expand Down Expand Up @@ -42,13 +41,9 @@
st.d $a0, $sp, 0x70
st.d $a1, $sp, 0x78

// Slot at $sp+0x80 is alignment padding

// Save the FP return registers
fst.d $f0, $sp, 0x88
fst.d $f1, $sp, 0x90
fst.d $f2, $sp, 0x98
fst.d $f3, $sp, 0xA0
fst.d $f0, $sp, 0x80
fst.d $f1, $sp, 0x88

// Perform the rest of the PInvokeTransitionFrame initialization.
st.d \threadReg, $sp, OFFSETOF__PInvokeTransitionFrame__m_pThread // Thread * (unused by stackwalker)
Expand All @@ -58,8 +53,7 @@
st.d \trashReg, $sp, 0x68 // save caller's SP

// link the frame into the Thread
ori \trashReg, $sp, 0
st.d \trashReg, \threadReg, OFFSETOF__Thread__m_pDeferredTransitionFrame
st.d $sp, \threadReg, OFFSETOF__Thread__m_pDeferredTransitionFrame
.endm

//
Expand All @@ -74,10 +68,8 @@
ld.d $a1, $sp, 0x78

// Restore the FP return registers
fld.d $f0, $sp, 0x88
fld.d $f1, $sp, 0x90
fld.d $f2, $sp, 0x98
fld.d $f3, $sp, 0xA0
fld.d $f0, $sp, 0x80
fld.d $f1, $sp, 0x88

// Restore callee saved registers
EPILOG_RESTORE_REG_PAIR 23, 24, 0x20
Expand Down Expand Up @@ -126,12 +118,11 @@ NESTED_ENTRY RhpGcProbeHijack, _TEXT, NoHandler

PREPARE_EXTERNAL_VAR_INDIRECT_W RhpTrapThreads, $a3
bstrpick.d $t8, $a3, TrapThreadsFlags_TrapThreads_Bit, TrapThreadsFlags_TrapThreads_Bit
bne $t8, $zero, LOCAL_LABEL(WaitForGC)
bnez $t8, LOCAL_LABEL(WaitForGC)
jirl $r0, $ra, 0

LOCAL_LABEL(WaitForGC):
lu12i.w $t3, ((DEFAULT_FRAME_SAVE_FLAGS + PTFF_SAVE_R4 + PTFF_SAVE_R5 + PTFF_THREAD_HIJACK_HI) >> 12) & 0xfffff
ori $t3, $t3, (DEFAULT_FRAME_SAVE_FLAGS + PTFF_SAVE_R4 + PTFF_SAVE_R5 + PTFF_THREAD_HIJACK_HI) & 0xfff
li.d $t3, (DEFAULT_FRAME_SAVE_FLAGS + PTFF_SAVE_R4 + PTFF_SAVE_R5 + (PTFF_THREAD_HIJACK_HI << 32))
b C_FUNC(RhpWaitForGC)
NESTED_END RhpGcProbeHijack

Expand All @@ -145,7 +136,7 @@ NESTED_ENTRY RhpWaitForGC, _TEXT, NoHandler

ld.d $a2,$sp, OFFSETOF__PInvokeTransitionFrame__m_Flags
bstrpick.d $t8, $a2, PTFF_THREAD_ABORT_BIT, PTFF_THREAD_ABORT_BIT
bne $t8, $zero, LOCAL_LABEL(ThrowThreadAbort)
bnez $t8, LOCAL_LABEL(ThrowThreadAbort)

.cfi_remember_state
POP_PROBE_FRAME
Expand All @@ -163,7 +154,7 @@ NESTED_END RhpWaitForGC

LEAF_ENTRY RhpGcPoll
PREPARE_EXTERNAL_VAR_INDIRECT_W RhpTrapThreads, $a0
bne $a0, $zero, C_FUNC(RhpGcPollRare)
bnez $a0, C_FUNC(RhpGcPollRare)
jirl $r0, $ra, 0
LEAF_END RhpGcPoll

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,19 +12,19 @@
//
// RhCommonStub
//
// INPUT: tp: thunk's data block
// INPUT: t7: thunk's data block
//
// TRASHES: t0, t1, tp
// TRASHES: t0, t1, t7
//
LEAF_ENTRY RhCommonStub, _TEXT
// There are arbitrary callers passing arguments with arbitrary signatures.
// Custom calling convention:
// tp pointer to the current thunk's data block (data contains 2 pointer values: context + target pointers)
// t7 pointer to the current thunk's data block (data contains 2 pointer values: context + target pointers)

INLINE_GET_TLS_VAR $t0, C_FUNC(tls_thunkData)

// t0 = base address of TLS data
// tp = address of context cell in thunk's data
// t7 = address of context cell in thunk's data

// store thunk address in thread static
ld.d $t1, $t7, 0
Expand Down
Loading
Loading