Skip to content

Commit f94cc0d

Browse files
committed
Adjust the calleeSavedRegs on top frame for LoongArch64/RISCV64
to support the GSCookie. The frame layout: | | |-----------------------| | incoming arguments | +=======================+ <---- Caller's SP | Varargs regs space | // Only for varargs main functions; not used for LA64. |-----------------------| | MonitorAcquired | // 8 bytes; for synchronized methods |-----------------------| | PSP slot | // 8 bytes (omitted in NativeAOT ABI) |-----------------------| |Callee saved registers | // multiple of 8 bytes, not includting FP/RA |-----------------------| | Saved RA | // 8 bytes |-----------------------| | Saved FP | // 8 bytes |-----------------------| | possible GS cookie | |-----------------------| | locals, temps, etc. | |-----------------------| | possible GS cookie | |-----------------------| | Outgoing arg space | // multiple of 8 bytes; if required (i.e., #outsz != 0) |-----------------------| <---- Ambient SP | | | ~ | Stack grows ~ | | downward |
1 parent 4e702bc commit f94cc0d

7 files changed

+496
-722
lines changed

src/coreclr/jit/codegen.h

+1-22
Original file line numberDiff line numberDiff line change
@@ -437,7 +437,7 @@ class CodeGen final : public CodeGenInterface
437437

438438
FuncletFrameInfoDsc genFuncletInfo;
439439

440-
#elif defined(TARGET_LOONGARCH64)
440+
#elif defined(TARGET_LOONGARCH64) || defined(TARGET_RISCV64)
441441

442442
// A set of information that is used by funclet prolog and epilog generation.
443443
// It is collected once, before funclet prologs and epilogs are generated,
@@ -448,26 +448,6 @@ class CodeGen final : public CodeGenInterface
448448
int fiFunction_CallerSP_to_FP_delta; // Delta between caller SP and the frame pointer in the parent function
449449
// (negative)
450450
int fiSP_to_CalleeSaved_delta; // CalleeSaved register save offset from SP (positive)
451-
int fiCalleeSavedPadding; // CalleeSaved offset padding (positive)
452-
int fiSP_to_PSP_slot_delta; // PSP slot offset from SP (positive)
453-
int fiCallerSP_to_PSP_slot_delta; // PSP slot offset from Caller SP (negative)
454-
int fiSpDelta; // Stack pointer delta (negative)
455-
};
456-
457-
FuncletFrameInfoDsc genFuncletInfo;
458-
459-
#elif defined(TARGET_RISCV64)
460-
461-
// A set of information that is used by funclet prolog and epilog generation.
462-
// It is collected once, before funclet prologs and epilogs are generated,
463-
// and used by all funclet prologs and epilogs, which must all be the same.
464-
struct FuncletFrameInfoDsc
465-
{
466-
regMaskTP fiSaveRegs; // Set of callee-saved registers saved in the funclet prolog (includes RA)
467-
int fiFunction_CallerSP_to_FP_delta; // Delta between caller SP and the frame pointer in the parent function
468-
// (negative)
469-
int fiSP_to_CalleeSaved_delta; // CalleeSaved register save offset from SP (positive)
470-
int fiCalleeSavedPadding; // CalleeSaved offset padding (positive)
471451
int fiSP_to_PSP_slot_delta; // PSP slot offset from SP (positive)
472452
int fiCallerSP_to_PSP_slot_delta; // PSP slot offset from Caller SP (negative)
473453
int fiSpDelta; // Stack pointer delta (negative)
@@ -1272,7 +1252,6 @@ class CodeGen final : public CodeGenInterface
12721252
void genJmpMethod(GenTree* jmp);
12731253
BasicBlock* genCallFinally(BasicBlock* block);
12741254
#if defined(TARGET_LOONGARCH64) || defined(TARGET_RISCV64)
1275-
// TODO: refactor for LA.
12761255
void genCodeForJumpCompare(GenTreeOpCC* tree);
12771256
#endif
12781257
#if defined(TARGET_ARM64)

src/coreclr/jit/codegencommon.cpp

+39-14
Original file line numberDiff line numberDiff line change
@@ -4087,7 +4087,7 @@ void CodeGen::genEnregisterOSRArgsAndLocals()
40874087

40884088
GetEmitter()->emitIns_R_AR(ins_Load(lclTyp), size, varDsc->GetRegNum(), genFramePointerReg(), offset);
40894089

4090-
#elif defined(TARGET_ARM64) || defined(TARGET_LOONGARCH64) || defined(TARGET_RISCV64)
4090+
#elif defined(TARGET_ARM64)
40914091

40924092
// Patchpoint offset is from top of Tier0 frame
40934093
//
@@ -4119,7 +4119,39 @@ void CodeGen::genEnregisterOSRArgsAndLocals()
41194119

41204120
genInstrWithConstant(ins_Load(lclTyp), size, varDsc->GetRegNum(), genFramePointerReg(), offset, initReg);
41214121
*pInitRegZeroed = false;
4122-
#endif // TARGET_ARM64 || TARGET_LOONGARCH64 || TARGET_RISCV64
4122+
#elif defined(TARGET_LOONGARCH64) || defined(TARGET_RISCV64)
4123+
4124+
// Patchpoint offset is from top of Tier0 frame
4125+
//
4126+
// We need to determine the frame-pointer relative
4127+
// offset for this variable in the osr frame.
4128+
//
4129+
// First get the fp's relative offset within Tier0 frame
4130+
//
4131+
const int tier0FrameOffset = (int)compiler->info.compPatchpointInfo->CalleeSaveRegisters();
4132+
4133+
// then add the OSR frame size
4134+
//
4135+
const int osrFrameSize = genTotalFrameSize();
4136+
4137+
// then subtract OSR SP-FP delta
4138+
//
4139+
const int osrSpToFpDelta = genSPtoFPdelta();
4140+
4141+
// | => tier0 top of frame relative
4142+
// | + => tier0's fp relative offset
4143+
// | | + => osr bottom of frame (sp) relative
4144+
// | | | - => osr fp relative
4145+
// | | | |
4146+
const int offset = stkOffs + tier0FrameOffset + osrFrameSize - osrSpToFpDelta;
4147+
4148+
JITDUMP("---OSR--- V%02u (reg) Tier0 virtual offset %d OSR frame size %d OSR sp-fp "
4149+
"delta %d total offset %d (0x%x)\n",
4150+
varNum, stkOffs, osrFrameSize, osrSpToFpDelta, offset, offset);
4151+
4152+
genInstrWithConstant(ins_Load(lclTyp), size, varDsc->GetRegNum(), genFramePointerReg(), offset, initReg);
4153+
*pInitRegZeroed = false;
4154+
#endif // TARGET_LOONGARCH64 || TARGET_RISCV64
41234155
}
41244156
}
41254157

@@ -4745,20 +4777,13 @@ void CodeGen::genFinalizeFrame()
47454777
#endif // defined(TARGET_XARCH)
47464778

47474779
#if defined(TARGET_LOONGARCH64) || defined(TARGET_RISCV64)
4748-
if (isFramePointerUsed())
4749-
{
4750-
// For a FP based frame we have to push/pop the FP register
4751-
//
4752-
maskCalleeRegsPushed |= RBM_FPBASE;
4780+
// This assert check that we are not using REG_FP
4781+
assert(!regSet.rsRegsModified(RBM_FPBASE));
47534782

4754-
// This assert check that we are not using REG_FP
4755-
// as both the frame pointer and as a codegen register
4756-
//
4757-
assert(!regSet.rsRegsModified(RBM_FPBASE));
4758-
}
4783+
assert(isFramePointerUsed());
4784+
// we always push FP/RA. See genPushCalleeSavedRegisters
4785+
maskCalleeRegsPushed |= (RBM_FPBASE | RBM_RA);
47594786

4760-
// we always push RA. See genPushCalleeSavedRegisters
4761-
maskCalleeRegsPushed |= RBM_RA;
47624787
#endif // TARGET_LOONGARCH64 || TARGET_RISCV64
47634788

47644789
compiler->compCalleeRegsPushed = genCountBits(maskCalleeRegsPushed);

0 commit comments

Comments
 (0)