Skip to content
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

Handle more than 64 registers - Part 2 #102297

Merged
merged 8 commits into from
May 22, 2024
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
19 changes: 10 additions & 9 deletions src/coreclr/jit/codegenarm.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1926,14 +1926,15 @@ void CodeGen::genAllocLclFrame(unsigned frameSize, regNumber initReg, bool* pIni

void CodeGen::genPushFltRegs(regMaskTP regMask)
{
assert(regMask != 0); // Don't call uness we have some registers to push
assert((regMask & RBM_ALLFLOAT) == regMask); // Only floasting point registers should be in regMask
assert(regMask != 0); // Don't call unless we have some registers to push
assert((regMask & RBM_ALLFLOAT) == regMask); // Only floating point registers should be in regMask

regNumber lowReg = genRegNumFromMask(genFindLowestBit(regMask));
int slots = genCountBits(regMask);

// regMask should be contiguously set
regMaskTP tmpMask = ((regMask >> lowReg) + 1); // tmpMask should have a single bit set
assert((tmpMask & (tmpMask - 1)) == 0);
regMaskSmall tmpMask = ((regMask.getLow() >> lowReg) + 1); // tmpMask should have a single bit set
assert(genMaxOneBit(tmpMask));
assert(lowReg == REG_F16); // Currently we expect to start at F16 in the unwind codes

// Our calling convention requires that we only use vpush for TYP_DOUBLE registers
Expand All @@ -1951,8 +1952,8 @@ void CodeGen::genPopFltRegs(regMaskTP regMask)
regNumber lowReg = genRegNumFromMask(genFindLowestBit(regMask));
int slots = genCountBits(regMask);
// regMask should be contiguously set
regMaskTP tmpMask = ((regMask >> lowReg) + 1); // tmpMask should have a single bit set
assert((tmpMask & (tmpMask - 1)) == 0);
regMaskSmall tmpMask = ((regMask.getLow() >> lowReg) + 1); // tmpMask should have a single bit set
assert(genMaxOneBit(tmpMask));

// Our calling convention requires that we only use vpop for TYP_DOUBLE registers
noway_assert(floatRegCanHoldType(lowReg, TYP_DOUBLE));
Expand Down Expand Up @@ -2191,7 +2192,7 @@ void CodeGen::genPopCalleeSavedRegisters(bool jmpEpilog)
genUsedPopToReturn = false;
}

assert(FitsIn<int>(maskPopRegsInt));
assert(FitsIn<int>(maskPopRegsInt.getLow()));
inst_IV(INS_pop, (int)maskPopRegsInt);
compiler->unwindPopMaskInt(maskPopRegsInt);
}
Expand Down Expand Up @@ -2319,7 +2320,7 @@ void CodeGen::genFuncletProlog(BasicBlock* block)
regMaskTP maskStackAlloc = genStackAllocRegisterMask(genFuncletInfo.fiSpDelta, maskPushRegsFloat);
maskPushRegsInt |= maskStackAlloc;

assert(FitsIn<int>(maskPushRegsInt));
assert(FitsIn<int>(maskPushRegsInt.getLow()));
inst_IV(INS_push, (int)maskPushRegsInt);
compiler->unwindPushMaskInt(maskPushRegsInt);

Expand Down Expand Up @@ -2436,7 +2437,7 @@ void CodeGen::genFuncletEpilog()
compiler->unwindPopMaskFloat(maskPopRegsFloat);
}

assert(FitsIn<int>(maskPopRegsInt));
assert(FitsIn<int>(maskPopRegsInt.getLow()));
inst_IV(INS_pop, (int)maskPopRegsInt);
compiler->unwindPopMaskInt(maskPopRegsInt);

Expand Down
4 changes: 2 additions & 2 deletions src/coreclr/jit/codegenarm64.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -922,7 +922,7 @@ void CodeGen::genSaveCalleeSavedRegistersHelp(regMaskTP regsToSaveMask, int lowe
assert((spDelta % 16) == 0);

// We also can save FP and LR, even though they are not in RBM_CALLEE_SAVED.
assert(regsToSaveCount <= genCountBits(RBM_CALLEE_SAVED | RBM_FP | RBM_LR));
assert(regsToSaveCount <= genCountBits(regMaskTP(RBM_CALLEE_SAVED | RBM_FP | RBM_LR)));

// Save integer registers at higher addresses than floating-point registers.

Expand Down Expand Up @@ -1035,7 +1035,7 @@ void CodeGen::genRestoreCalleeSavedRegistersHelp(regMaskTP regsToRestoreMask, in
assert((spDelta % 16) == 0);

// We also can restore FP and LR, even though they are not in RBM_CALLEE_SAVED.
assert(regsToRestoreCount <= genCountBits(RBM_CALLEE_SAVED | RBM_FP | RBM_LR));
assert(regsToRestoreCount <= genCountBits(regMaskTP(RBM_CALLEE_SAVED | RBM_FP | RBM_LR)));

// Point past the end, to start. We predecrement to find the offset to load from.
static_assert_no_msg(REGSIZE_BYTES == FPSAVE_REGSIZE_BYTES);
Expand Down
2 changes: 1 addition & 1 deletion src/coreclr/jit/codegenarmarch.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4684,7 +4684,7 @@ void CodeGen::genPushCalleeSavedRegisters()

maskPushRegsInt |= genStackAllocRegisterMask(compiler->compLclFrameSize, maskPushRegsFloat);

assert(FitsIn<int>(maskPushRegsInt));
assert(FitsIn<int>(maskPushRegsInt.getLow()));
inst_IV(INS_push, (int)maskPushRegsInt);
compiler->unwindPushMaskInt(maskPushRegsInt);

Expand Down
4 changes: 2 additions & 2 deletions src/coreclr/jit/codegenloongarch64.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -535,7 +535,7 @@ void CodeGen::genSaveCalleeSavedRegistersHelp(regMaskTP regsToSaveMask, int lowe
return;
}

assert(genCountBits(regsToSaveMask) <= genCountBits(RBM_CALLEE_SAVED));
assert(genCountBits(regsToSaveMask) <= genCountBits(regMaskTP(RBM_CALLEE_SAVED)));

// Save integer registers at higher addresses than floating-point registers.

Expand Down Expand Up @@ -626,7 +626,7 @@ void CodeGen::genRestoreCalleeSavedRegistersHelp(regMaskTP regsToRestoreMask, in

unsigned regsToRestoreCount = genCountBits(regsToRestoreMask);
// The FP and RA are not in RBM_CALLEE_SAVED.
assert(regsToRestoreCount <= genCountBits(RBM_CALLEE_SAVED));
assert(regsToRestoreCount <= genCountBits(regMaskTP(RBM_CALLEE_SAVED)));

// Point past the end, to start. We predecrement to find the offset to load from.
static_assert_no_msg(REGSIZE_BYTES == FPSAVE_REGSIZE_BYTES);
Expand Down
4 changes: 2 additions & 2 deletions src/coreclr/jit/codegenriscv64.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -607,7 +607,7 @@ void CodeGen::genSaveCalleeSavedRegistersHelp(regMaskTP regsToSaveMask, int lowe

assert((spDelta % STACK_ALIGN) == 0);

assert(regsToSaveCount <= genCountBits(RBM_CALLEE_SAVED));
assert(regsToSaveCount <= genCountBits(regMaskTP(RBM_CALLEE_SAVED)));

// Save integer registers at higher addresses than floating-point registers.
regMaskTP maskSaveRegsFloat = regsToSaveMask & RBM_ALLFLOAT;
Expand Down Expand Up @@ -718,7 +718,7 @@ void CodeGen::genRestoreCalleeSavedRegistersHelp(regMaskTP regsToRestoreMask, in
assert((spDelta % STACK_ALIGN) == 0);

// We also can restore FP and RA, even though they are not in RBM_CALLEE_SAVED.
assert(regsToRestoreCount <= genCountBits(RBM_CALLEE_SAVED | RBM_FP | RBM_RA));
assert(regsToRestoreCount <= genCountBits(regMaskTP(RBM_CALLEE_SAVED | RBM_FP | RBM_RA)));

// Point past the end, to start. We predecrement to find the offset to load from.
static_assert_no_msg(REGSIZE_BYTES == FPSAVE_REGSIZE_BYTES);
Expand Down
33 changes: 0 additions & 33 deletions src/coreclr/jit/compiler.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,6 @@ inline bool genExactlyOneBit(T value)
return ((value != 0) && genMaxOneBit(value));
}

#ifdef TARGET_ARM64
inline regMaskTP genFindLowestBit(regMaskTP value)
{
return regMaskTP(genFindLowestBit(value.getLow()));
Expand All @@ -124,7 +123,6 @@ inline bool genExactlyOneBit(regMaskTP value)
{
return genExactlyOneBit(value.getLow());
}
#endif

/*****************************************************************************
*
Expand Down Expand Up @@ -169,17 +167,10 @@ inline unsigned uhi32(uint64_t value)
* A rather simple routine that counts the number of bits in a given number.
*/

inline unsigned genCountBits(uint64_t bits)
{
return BitOperations::PopCount(bits);
}

#ifdef TARGET_ARM64
inline unsigned genCountBits(regMaskTP mask)
{
return BitOperations::PopCount(mask.getLow());
}
#endif

/*****************************************************************************
*
Expand Down Expand Up @@ -948,19 +939,11 @@ inline regNumber genRegNumFromMask(regMaskTP mask)

/* Convert the mask to a register number */

#ifdef TARGET_ARM64
regNumber regNum = (regNumber)genLog2(mask.getLow());

/* Make sure we got it right */
assert(genRegMask(regNum) == mask.getLow());

#else
regNumber regNum = (regNumber)genLog2(mask);

/* Make sure we got it right */
assert(genRegMask(regNum) == mask);
#endif

return regNum;
}

Expand Down Expand Up @@ -4505,46 +4488,30 @@ inline void* operator new[](size_t sz, Compiler* compiler, CompMemKind cmk)

inline void printRegMask(regMaskTP mask)
{
#ifdef TARGET_ARM64
printf(REG_MASK_ALL_FMT, mask.getLow());
#else
printf(REG_MASK_ALL_FMT, mask);
#endif
}

inline char* regMaskToString(regMaskTP mask, Compiler* context)
{
const size_t cchRegMask = 24;
char* regmask = new (context, CMK_Unknown) char[cchRegMask];

#ifdef TARGET_ARM64
sprintf_s(regmask, cchRegMask, REG_MASK_ALL_FMT, mask.getLow());
#else
sprintf_s(regmask, cchRegMask, REG_MASK_ALL_FMT, mask);
#endif

return regmask;
}

inline void printRegMaskInt(regMaskTP mask)
{
#ifdef TARGET_ARM64
printf(REG_MASK_INT_FMT, (mask & RBM_ALLINT).getLow());
#else
printf(REG_MASK_INT_FMT, (mask & RBM_ALLINT));
#endif
}

inline char* regMaskIntToString(regMaskTP mask, Compiler* context)
{
const size_t cchRegMask = 24;
char* regmask = new (context, CMK_Unknown) char[cchRegMask];

#ifdef TARGET_ARM64
sprintf_s(regmask, cchRegMask, REG_MASK_INT_FMT, (mask & RBM_ALLINT).getLow());
#else
sprintf_s(regmask, cchRegMask, REG_MASK_INT_FMT, (mask & RBM_ALLINT));
#endif

return regmask;
}
Expand Down
2 changes: 1 addition & 1 deletion src/coreclr/jit/emit.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8787,7 +8787,7 @@ void emitter::emitRecordGCcall(BYTE* codePos, unsigned char callInstrSize)
callDsc* call;

#ifdef JIT32_GCENCODER
unsigned regs = (emitThisGCrefRegs | emitThisByrefRegs) & ~RBM_INTRET;
unsigned regs = (unsigned)(emitThisGCrefRegs | emitThisByrefRegs) & ~RBM_INTRET;

// The JIT32 GCInfo encoder allows us to (as the comment previously here said):
// "Bail if this is a totally boring call", but the GCInfoEncoder/Decoder interface
Expand Down
8 changes: 4 additions & 4 deletions src/coreclr/jit/emitarm.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5768,15 +5768,15 @@ size_t emitter::emitOutputInstr(insGroup* ig, instrDesc* id, BYTE** dp)
assert(REG_NA == (int)REG_NA);

VARSET_TP GCvars(VarSetOps::UninitVal());
regMaskTP gcrefRegs;
regMaskTP byrefRegs;

/* What instruction format have we got? */

switch (fmt)
{
int imm;
BYTE* addr;
regMaskTP gcrefRegs;
regMaskTP byrefRegs;
int imm;
BYTE* addr;

case IF_T1_A: // T1_A ................
sz = SMALL_IDSC_SIZE;
Expand Down
8 changes: 4 additions & 4 deletions src/coreclr/jit/emitxarch.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15792,6 +15792,7 @@ BYTE* emitter::emitOutputRI(BYTE* dst, instrDesc* id)
break;

case IF_RRW_CNS:
{
assert(id->idGCref() == GCT_BYREF);

#ifdef DEBUG
Expand All @@ -15813,7 +15814,7 @@ BYTE* emitter::emitOutputRI(BYTE* dst, instrDesc* id)
// Mark it as holding a GCT_BYREF
emitGCregLiveUpd(GCT_BYREF, id->idReg1(), dst);
break;

}
default:
#ifdef DEBUG
emitDispIns(id, false, false, false);
Expand Down Expand Up @@ -16606,6 +16607,8 @@ size_t emitter::emitOutputInstr(insGroup* ig, instrDesc* id, BYTE** dp)
assert(instrIs3opImul(id->idIns()) == 0 || size >= EA_4BYTE); // Has no 'w' bit

VARSET_TP GCvars(VarSetOps::UninitVal());
regMaskTP gcrefRegs;
regMaskTP byrefRegs;

// What instruction format have we got?
switch (insFmt)
Expand All @@ -16618,9 +16621,6 @@ size_t emitter::emitOutputInstr(insGroup* ig, instrDesc* id, BYTE** dp)
BYTE* addr;
bool recCall;

regMaskTP gcrefRegs;
regMaskTP byrefRegs;

/********************************************************************/
/* No operands */
/********************************************************************/
Expand Down
2 changes: 1 addition & 1 deletion src/coreclr/jit/gcencode.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2874,7 +2874,7 @@ size_t GCInfo::gcMakeRegPtrTable(BYTE* dest, int mask, const InfoHdr& header, un

if (compiler->lvaKeepAliveAndReportThis() && compiler->lvaTable[compiler->info.compThisArg].lvRegister)
{
unsigned thisRegMask = genRegMask(compiler->lvaTable[compiler->info.compThisArg].GetRegNum());
unsigned thisRegMask = (unsigned)genRegMask(compiler->lvaTable[compiler->info.compThisArg].GetRegNum());
unsigned thisPtrRegEnc = gceEncodeCalleeSavedRegs(thisRegMask) << 4;

if (thisPtrRegEnc)
Expand Down
2 changes: 1 addition & 1 deletion src/coreclr/jit/lsraxarch.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -442,7 +442,7 @@ int LinearScan::BuildNode(GenTree* tree)
// Comparand is preferenced to RAX.
// The remaining two operands can be in any reg other than RAX.

const unsigned nonRaxCandidates = availableIntRegs & ~RBM_RAX;
const regMaskTP nonRaxCandidates = availableIntRegs & ~RBM_RAX;
BuildUse(addr, nonRaxCandidates);
BuildUse(data, varTypeIsByte(tree) ? (nonRaxCandidates & RBM_BYTE_REGS) : nonRaxCandidates);
BuildUse(comparand, RBM_RAX);
Expand Down
Loading
Loading