Skip to content
This repository was archived by the owner on Jan 23, 2023. It is now read-only.
Merged
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
57 changes: 57 additions & 0 deletions src/jit/codegencommon.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6325,7 +6325,9 @@ void CodeGen::genAllocLclFrame(unsigned frameSize, regNumber initReg, bool* pIni
}
#endif // !_TARGET_XARCH_

#if CPU_LOAD_STORE_ARCH || !defined(_TARGET_UNIX_)
instGen_Set_Reg_To_Zero(EA_PTRSIZE, initReg);
#endif

//
// Can't have a label inside the ReJIT padding area
Expand Down Expand Up @@ -6381,6 +6383,7 @@ void CodeGen::genAllocLclFrame(unsigned frameSize, regNumber initReg, bool* pIni

#else // !CPU_LOAD_STORE_ARCH

#ifndef _TARGET_UNIX_
// Code size for each instruction. We need this because the
// backward branch is hard-coded with the number of bytes to branch.
// The encoding differs based on the architecture and what register is
Expand Down Expand Up @@ -6419,6 +6422,60 @@ void CodeGen::genAllocLclFrame(unsigned frameSize, regNumber initReg, bool* pIni
#endif // !_TARGET_AMD64_

inst_IV(INS_jge, bytesForBackwardJump); // Branch backwards to start of loop
#else // _TARGET_UNIX_
// Code size for each instruction. We need this because the
// backward branch is hard-coded with the number of bytes to branch.
// The encoding differs based on the architecture and what register is
// used (namely, using RAX has a smaller encoding).
//
// For x86
// lea eax, [esp - frameSize]
// loop:
// lea esp, [esp - pageSize] 7
// test [esp], eax 3
// cmp esp, eax 2
// jge loop 2
// lea rsp, [rbp + frameSize]
//
// For AMD64 using RAX
// lea rax, [rsp - frameSize]
// loop:
// lea rsp, [rsp - pageSize] 8
// test [rsp], rax 4
// cmp rsp, rax 3
// jge loop 2
// lea rsp, [rax + frameSize]
//
// For AMD64 using RBP
// lea rbp, [rsp - frameSize]
// loop:
// lea rsp, [rsp - pageSize] 8
// test [rsp], rbp 4
// cmp rsp, rbp 3
// jge loop 2
// lea rsp, [rbp + frameSize]

int sPageSize = (int)pageSize;

getEmitter()->emitIns_R_AR(INS_lea, EA_PTRSIZE, initReg, REG_SPBASE, -((ssize_t)frameSize)); // get frame border

getEmitter()->emitIns_R_AR(INS_lea, EA_PTRSIZE, REG_SPBASE, REG_SPBASE, -sPageSize);
getEmitter()->emitIns_R_AR(INS_TEST, EA_PTRSIZE, initReg, REG_SPBASE, 0);
inst_RV_RV(INS_cmp, REG_SPBASE, initReg);

int bytesForBackwardJump;
#ifdef _TARGET_AMD64_
assert((initReg == REG_EAX) || (initReg == REG_EBP)); // We use RBP as initReg for EH funclets.
bytesForBackwardJump = -17;
#else // !_TARGET_AMD64_
assert(initReg == REG_EAX);
bytesForBackwardJump = -14;
#endif // !_TARGET_AMD64_

inst_IV(INS_jge, bytesForBackwardJump); // Branch backwards to start of loop

getEmitter()->emitIns_R_AR(INS_lea, EA_PTRSIZE, REG_SPBASE, initReg, frameSize); // restore stack pointer
#endif // _TARGET_UNIX_

#endif // !CPU_LOAD_STORE_ARCH

Expand Down