Skip to content

Commit

Permalink
Adjust the calleeSavedRegs on top frame for LoongArch64/RISCV64 (dotn…
Browse files Browse the repository at this point in the history
…et#100962)

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      |
  • Loading branch information
shushanhf authored and michaelgsharp committed May 8, 2024
1 parent 97c7bf9 commit 6a6376e
Show file tree
Hide file tree
Showing 6 changed files with 450 additions and 726 deletions.
23 changes: 1 addition & 22 deletions src/coreclr/jit/codegen.h
Original file line number Diff line number Diff line change
Expand Up @@ -437,7 +437,7 @@ class CodeGen final : public CodeGenInterface

FuncletFrameInfoDsc genFuncletInfo;

#elif defined(TARGET_LOONGARCH64)
#elif defined(TARGET_LOONGARCH64) || defined(TARGET_RISCV64)

// A set of information that is used by funclet prolog and epilog generation.
// It is collected once, before funclet prologs and epilogs are generated,
Expand All @@ -448,26 +448,6 @@ class CodeGen final : public CodeGenInterface
int fiFunction_CallerSP_to_FP_delta; // Delta between caller SP and the frame pointer in the parent function
// (negative)
int fiSP_to_CalleeSaved_delta; // CalleeSaved register save offset from SP (positive)
int fiCalleeSavedPadding; // CalleeSaved offset padding (positive)
int fiSP_to_PSP_slot_delta; // PSP slot offset from SP (positive)
int fiCallerSP_to_PSP_slot_delta; // PSP slot offset from Caller SP (negative)
int fiSpDelta; // Stack pointer delta (negative)
};

FuncletFrameInfoDsc genFuncletInfo;

#elif defined(TARGET_RISCV64)

// A set of information that is used by funclet prolog and epilog generation.
// It is collected once, before funclet prologs and epilogs are generated,
// and used by all funclet prologs and epilogs, which must all be the same.
struct FuncletFrameInfoDsc
{
regMaskTP fiSaveRegs; // Set of callee-saved registers saved in the funclet prolog (includes RA)
int fiFunction_CallerSP_to_FP_delta; // Delta between caller SP and the frame pointer in the parent function
// (negative)
int fiSP_to_CalleeSaved_delta; // CalleeSaved register save offset from SP (positive)
int fiCalleeSavedPadding; // CalleeSaved offset padding (positive)
int fiSP_to_PSP_slot_delta; // PSP slot offset from SP (positive)
int fiCallerSP_to_PSP_slot_delta; // PSP slot offset from Caller SP (negative)
int fiSpDelta; // Stack pointer delta (negative)
Expand Down Expand Up @@ -1272,7 +1252,6 @@ class CodeGen final : public CodeGenInterface
void genJmpMethod(GenTree* jmp);
BasicBlock* genCallFinally(BasicBlock* block);
#if defined(TARGET_LOONGARCH64) || defined(TARGET_RISCV64)
// TODO: refactor for LA.
void genCodeForJumpCompare(GenTreeOpCC* tree);
#endif
#if defined(TARGET_ARM64)
Expand Down
17 changes: 5 additions & 12 deletions src/coreclr/jit/codegencommon.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4744,20 +4744,13 @@ void CodeGen::genFinalizeFrame()
#endif // defined(TARGET_XARCH)

#if defined(TARGET_LOONGARCH64) || defined(TARGET_RISCV64)
if (isFramePointerUsed())
{
// For a FP based frame we have to push/pop the FP register
//
maskCalleeRegsPushed |= RBM_FPBASE;
// This assert check that we are not using REG_FP
assert(!regSet.rsRegsModified(RBM_FPBASE));

// This assert check that we are not using REG_FP
// as both the frame pointer and as a codegen register
//
assert(!regSet.rsRegsModified(RBM_FPBASE));
}
assert(isFramePointerUsed());
// we always push FP/RA. See genPushCalleeSavedRegisters
maskCalleeRegsPushed |= (RBM_FPBASE | RBM_RA);

// we always push RA. See genPushCalleeSavedRegisters
maskCalleeRegsPushed |= RBM_RA;
#endif // TARGET_LOONGARCH64 || TARGET_RISCV64

compiler->compCalleeRegsPushed = genCountBits(maskCalleeRegsPushed);
Expand Down
Loading

0 comments on commit 6a6376e

Please sign in to comment.